about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml37
-rw-r--r--.gitignore1
-rw-r--r--CONTRIBUTING.md2
-rw-r--r--INSTALL.md10
-rw-r--r--compiler/rustc_abi/src/extern_abi.rs11
-rw-r--r--compiler/rustc_abi/src/lib.rs2
-rw-r--r--compiler/rustc_ast/src/ast.rs71
-rw-r--r--compiler/rustc_ast/src/ast_traits.rs15
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs18
-rw-r--r--compiler/rustc_ast/src/token.rs296
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs2
-rw-r--r--compiler/rustc_ast/src/util/parser.rs42
-rw-r--r--compiler/rustc_ast/src/visit.rs3
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs35
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs1
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs22
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs122
-rw-r--r--compiler/rustc_ast_lowering/src/path.rs1
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs1
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs52
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/item.rs3
-rw-r--r--compiler/rustc_attr_parsing/src/parser.rs9
-rw-r--r--compiler/rustc_borrowck/src/type_check/constraint_conversion.rs6
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs41
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs19
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/generic/mod.rs11
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs3
-rw-r--r--compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch4
-rw-r--r--compiler/rustc_codegen_gcc/src/common.rs18
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/common.rs44
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs218
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs373
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs86
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs59
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs26
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs56
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/consts.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs15
-rw-r--r--compiler/rustc_data_structures/src/captures.rs8
-rw-r--r--compiler/rustc_data_structures/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/src/marker.rs10
-rw-r--r--compiler/rustc_data_structures/src/sharded.rs16
-rw-r--r--compiler/rustc_data_structures/src/sync.rs67
-rw-r--r--compiler/rustc_data_structures/src/sync/worker_local.rs11
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0373.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0804.md41
-rw-r--r--compiler/rustc_error_codes/src/lib.rs1
-rw-r--r--compiler/rustc_errors/src/lib.rs1
-rw-r--r--compiler/rustc_expand/src/base.rs16
-rw-r--r--compiler/rustc_expand/src/config.rs2
-rw-r--r--compiler/rustc_expand/src/expand.rs38
-rw-r--r--compiler/rustc_expand/src/mbe/macro_check.rs2
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs12
-rw-r--r--compiler/rustc_expand/src/mbe/quoted.rs4
-rw-r--r--compiler/rustc_expand/src/placeholders.rs24
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs71
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs7
-rw-r--r--compiler/rustc_feature/src/removed.rs2
-rw-r--r--compiler/rustc_feature/src/unstable.rs23
-rw-r--r--compiler/rustc_fluent_macro/src/fluent.rs4
-rw-r--r--compiler/rustc_hir/src/hir.rs4
-rw-r--r--compiler/rustc_hir/src/intravisit.rs6
-rw-r--r--compiler/rustc_hir/src/lang_items.rs3
-rw-r--r--compiler/rustc_hir/src/target.rs5
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl12
-rw-r--r--compiler/rustc_hir_analysis/src/check/always_applicable.rs (renamed from compiler/rustc_hir_analysis/src/check/dropck.rs)151
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs39
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs82
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs26
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs28
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs27
-rw-r--r--compiler/rustc_hir_analysis/src/errors/pattern_types.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs39
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs367
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/variance/constraints.rs10
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs16
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl9
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs28
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs29
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs37
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs62
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs24
-rw-r--r--compiler/rustc_interface/src/passes.rs4
-rw-r--r--compiler/rustc_lint/src/lib.rs5
-rw-r--r--compiler/rustc_lint/src/types.rs58
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs55
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp10
-rw-r--r--compiler/rustc_metadata/messages.ftl3
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs21
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs4
-rw-r--r--compiler/rustc_middle/src/mir/basic_blocks.rs3
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs42
-rw-r--r--compiler/rustc_middle/src/mir/traversal.rs37
-rw-r--r--compiler/rustc_middle/src/query/keys.rs8
-rw-r--r--compiler/rustc_middle/src/query/mod.rs13
-rw-r--r--compiler/rustc_middle/src/thir.rs47
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs6
-rw-r--r--compiler/rustc_middle/src/ty/assoc.rs20
-rw-r--r--compiler/rustc_middle/src/ty/context.rs5
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs10
-rw-r--r--compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs10
-rw-r--r--compiler/rustc_middle/src/ty/pattern.rs36
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs108
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs20
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs1
-rw-r--r--compiler/rustc_middle/src/ty/walk.rs6
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/match_pair.rs217
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/mod.rs59
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/simplify.rs71
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/test.rs17
-rw-r--r--compiler/rustc_mir_build/src/builder/matches/util.rs8
-rw-r--r--compiler/rustc_mir_transform/src/add_call_guards.rs61
-rw-r--r--compiler/rustc_mir_transform/src/deduce_param_attrs.rs29
-rw-r--r--compiler/rustc_mir_transform/src/ffi_unwind_calls.rs6
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs36
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs18
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs34
-rw-r--r--compiler/rustc_monomorphize/src/mono_checks/abi_check.rs6
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs49
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs18
-rw-r--r--compiler/rustc_parse/src/lexer/unicode_chars.rs12
-rw-r--r--compiler/rustc_parse/src/parser/attr.rs4
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs25
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs46
-rw-r--r--compiler/rustc_parse/src/parser/generics.rs65
-rw-r--r--compiler/rustc_parse/src/parser/item.rs90
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs8
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs18
-rw-r--r--compiler/rustc_parse/src/parser/path.rs5
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs15
-rw-r--r--compiler/rustc_parse/src/parser/tests.rs2
-rw-r--r--compiler/rustc_parse/src/parser/token_type.rs25
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs26
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/check_attr.rs50
-rw-r--r--compiler/rustc_passes/src/errors.rs8
-rw-r--r--compiler/rustc_query_system/src/query/caches.rs2
-rw-r--r--compiler/rustc_query_system/src/query/job.rs17
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs8
-rw-r--r--compiler/rustc_resolve/src/def_collector.rs8
-rw-r--r--compiler/rustc_resolve/src/late.rs40
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs53
-rw-r--r--compiler/rustc_session/src/config.rs72
-rw-r--r--compiler/rustc_session/src/utils.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs7
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs9
-rw-r--r--compiler/rustc_span/src/analyze_source_file.rs8
-rw-r--r--compiler/rustc_span/src/hygiene.rs3
-rw-r--r--compiler/rustc_span/src/lib.rs31
-rw-r--r--compiler/rustc_span/src/symbol.rs7
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs14
-rw-r--r--compiler/rustc_target/src/spec/mod.rs55
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs6
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs8
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs119
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs11
-rw-r--r--compiler/rustc_trait_selection/src/regions.rs14
-rw-r--r--compiler/rustc_trait_selection/src/traits/const_evaluatable.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/outlives_bounds.rs18
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs198
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs35
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs10
-rw-r--r--compiler/rustc_traits/src/implied_outlives_bounds.rs28
-rw-r--r--compiler/rustc_ty_utils/messages.ftl2
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs7
-rw-r--r--compiler/rustc_ty_utils/src/errors.rs6
-rw-r--r--compiler/rustc_ty_utils/src/instance.rs3
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs112
-rw-r--r--compiler/rustc_type_ir/src/solve/mod.rs5
-rw-r--r--compiler/stable_mir/src/lib.rs21
-rw-r--r--config.example.toml22
-rw-r--r--library/Cargo.lock8
-rw-r--r--library/alloc/Cargo.toml2
-rw-r--r--library/alloc/benches/slice.rs14
-rw-r--r--library/alloc/benches/vec.rs8
-rw-r--r--library/alloc/src/boxed.rs4
-rw-r--r--library/alloc/src/boxed/convert.rs28
-rw-r--r--library/alloc/src/boxed/thin.rs22
-rw-r--r--library/alloc/src/collections/btree/node/tests.rs8
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/raw_vec.rs4
-rw-r--r--library/alloc/src/raw_vec/tests.rs3
-rw-r--r--library/alloc/src/slice.rs4
-rw-r--r--library/alloc/src/string.rs9
-rw-r--r--library/alloc/src/sync.rs4
-rw-r--r--library/alloc/src/vec/in_place_collect.rs24
-rw-r--r--library/alloc/src/vec/mod.rs10
-rw-r--r--library/alloc/tests/arc.rs5
-rw-r--r--library/alloc/tests/rc.rs5
-rw-r--r--library/alloc/tests/slice.rs4
-rw-r--r--library/alloc/tests/sort/known_good_stable_sort.rs6
-rw-r--r--library/alloc/tests/thin_box.rs3
-rw-r--r--library/alloc/tests/vec.rs6
-rw-r--r--library/core/Cargo.toml2
-rw-r--r--library/core/src/alloc/layout.rs4
-rw-r--r--library/core/src/bstr.rs4
-rw-r--r--library/core/src/char/convert.rs16
-rw-r--r--library/core/src/clone.rs4
-rw-r--r--library/core/src/convert/mod.rs1
-rw-r--r--library/core/src/fmt/mod.rs66
-rw-r--r--library/core/src/hash/mod.rs4
-rw-r--r--library/core/src/hash/sip.rs6
-rw-r--r--library/core/src/intrinsics/mod.rs10
-rw-r--r--library/core/src/iter/adapters/map_windows.rs4
-rw-r--r--library/core/src/iter/sources/successors.rs16
-rw-r--r--library/core/src/lib.rs3
-rw-r--r--library/core/src/marker.rs9
-rw-r--r--library/core/src/marker/variance.rs12
-rw-r--r--library/core/src/mem/maybe_uninit.rs4
-rw-r--r--library/core/src/mem/mod.rs48
-rw-r--r--library/core/src/mem/transmutability.rs6
-rw-r--r--library/core/src/num/bignum.rs3
-rw-r--r--library/core/src/num/dec2flt/common.rs27
-rw-r--r--library/core/src/num/dec2flt/decimal.rs421
-rw-r--r--library/core/src/num/dec2flt/decimal_seq.rs379
-rw-r--r--library/core/src/num/dec2flt/float.rs272
-rw-r--r--library/core/src/num/dec2flt/fpu.rs1
-rw-r--r--library/core/src/num/dec2flt/lemire.rs22
-rw-r--r--library/core/src/num/dec2flt/mod.rs37
-rw-r--r--library/core/src/num/dec2flt/number.rs88
-rw-r--r--library/core/src/num/dec2flt/parse.rs10
-rw-r--r--library/core/src/num/dec2flt/slow.rs28
-rw-r--r--library/core/src/num/f32.rs6
-rw-r--r--library/core/src/num/f64.rs6
-rw-r--r--library/core/src/num/int_macros.rs18
-rw-r--r--library/core/src/num/mod.rs6
-rw-r--r--library/core/src/num/nonzero.rs5
-rw-r--r--library/core/src/num/uint_macros.rs20
-rw-r--r--library/core/src/ops/bit.rs2
-rw-r--r--library/core/src/pat.rs62
-rw-r--r--library/core/src/primitive_docs.rs28
-rw-r--r--library/core/src/ptr/alignment.rs8
-rw-r--r--library/core/src/ptr/const_ptr.rs26
-rw-r--r--library/core/src/ptr/metadata.rs2
-rw-r--r--library/core/src/ptr/mod.rs30
-rw-r--r--library/core/src/ptr/mut_ptr.rs30
-rw-r--r--library/core/src/ptr/non_null.rs26
-rw-r--r--library/core/src/slice/cmp.rs6
-rw-r--r--library/core/src/slice/memchr.rs5
-rw-r--r--library/core/src/slice/mod.rs63
-rw-r--r--library/core/src/slice/raw.rs8
-rw-r--r--library/core/src/slice/rotate.rs6
-rw-r--r--library/core/src/slice/sort/shared/smallsort.rs16
-rw-r--r--library/core/src/slice/sort/stable/mod.rs6
-rw-r--r--library/core/src/slice/sort/stable/quicksort.rs4
-rw-r--r--library/core/src/slice/sort/unstable/quicksort.rs8
-rw-r--r--library/core/src/str/count.rs2
-rw-r--r--library/core/src/str/validations.rs3
-rw-r--r--library/core/src/sync/atomic.rs4
-rw-r--r--library/coretests/benches/ascii/is_ascii.rs6
-rw-r--r--library/coretests/benches/iter.rs5
-rw-r--r--library/coretests/tests/alloc.rs1
-rw-r--r--library/coretests/tests/atomic.rs2
-rw-r--r--library/coretests/tests/hash/sip.rs4
-rw-r--r--library/coretests/tests/lib.rs2
-rw-r--r--library/coretests/tests/nonzero.rs1
-rw-r--r--library/coretests/tests/num/dec2flt/decimal.rs28
-rw-r--r--library/coretests/tests/num/dec2flt/decimal_seq.rs30
-rw-r--r--library/coretests/tests/num/dec2flt/float.rs48
-rw-r--r--library/coretests/tests/num/dec2flt/lemire.rs10
-rw-r--r--library/coretests/tests/num/dec2flt/mod.rs2
-rw-r--r--library/coretests/tests/num/dec2flt/parse.rs41
-rw-r--r--library/coretests/tests/ptr.rs28
-rw-r--r--library/coretests/tests/slice.rs7
-rw-r--r--library/panic_unwind/src/emcc.rs4
-rw-r--r--library/panic_unwind/src/seh.rs4
-rw-r--r--library/proc_macro/src/bridge/selfless_reify.rs2
-rw-r--r--library/std/Cargo.toml4
-rw-r--r--library/std/build.rs1
-rw-r--r--library/std/src/env.rs5
-rw-r--r--library/std/src/fs.rs8
-rw-r--r--library/std/src/fs/tests.rs2
-rw-r--r--library/std/src/io/error/tests.rs1
-rw-r--r--library/std/src/io/stdio.rs34
-rw-r--r--library/std/src/os/fd/tests.rs1
-rw-r--r--library/std/src/os/unix/io/tests.rs1
-rw-r--r--library/std/src/os/unix/net/addr.rs2
-rw-r--r--library/std/src/os/unix/net/listener.rs2
-rw-r--r--library/std/src/os/unix/net/ucred.rs14
-rw-r--r--library/std/src/os/wasi/io/tests.rs1
-rw-r--r--library/std/src/os/windows/io/tests.rs1
-rw-r--r--library/std/src/os/windows/process.rs8
-rw-r--r--library/std/src/os/xous/ffi.rs8
-rw-r--r--library/std/src/os/xous/services/log.rs4
-rw-r--r--library/std/src/sys/alloc/unix.rs2
-rw-r--r--library/std/src/sys/alloc/windows/tests.rs5
-rw-r--r--library/std/src/sys/io/is_terminal/windows.rs1
-rw-r--r--library/std/src/sys/net/connection/socket.rs16
-rw-r--r--library/std/src/sys/net/connection/socket/hermit.rs2
-rw-r--r--library/std/src/sys/net/connection/socket/solid.rs2
-rw-r--r--library/std/src/sys/net/connection/socket/unix.rs2
-rw-r--r--library/std/src/sys/net/connection/socket/wasip2.rs2
-rw-r--r--library/std/src/sys/net/connection/socket/windows.rs10
-rw-r--r--library/std/src/sys/net/connection/xous/udp.rs2
-rw-r--r--library/std/src/sys/pal/itron/thread.rs2
-rw-r--r--library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs42
-rw-r--r--library/std/src/sys/pal/uefi/args.rs1
-rw-r--r--library/std/src/sys/pal/uefi/helpers.rs63
-rw-r--r--library/std/src/sys/pal/uefi/process.rs4
-rw-r--r--library/std/src/sys/pal/uefi/tests.rs2
-rw-r--r--library/std/src/sys/pal/unix/fs.rs4
-rw-r--r--library/std/src/sys/pal/unix/futex.rs2
-rw-r--r--library/std/src/sys/pal/unix/process/process_common.rs5
-rw-r--r--library/std/src/sys/pal/unix/process/process_fuchsia.rs4
-rw-r--r--library/std/src/sys/pal/unix/process/process_unix.rs25
-rw-r--r--library/std/src/sys/pal/unix/stack_overflow.rs2
-rw-r--r--library/std/src/sys/pal/unix/thread.rs6
-rw-r--r--library/std/src/sys/pal/unix/weak.rs2
-rw-r--r--library/std/src/sys/pal/wasi/fd.rs8
-rw-r--r--library/std/src/sys/pal/wasi/fs.rs2
-rw-r--r--library/std/src/sys/pal/wasi/thread.rs7
-rw-r--r--library/std/src/sys/pal/windows/api.rs4
-rw-r--r--library/std/src/sys/pal/windows/c.rs6
-rw-r--r--library/std/src/sys/pal/windows/fs.rs27
-rw-r--r--library/std/src/sys/pal/windows/futex.rs4
-rw-r--r--library/std/src/sys/pal/windows/pipe.rs2
-rw-r--r--library/std/src/sys/pal/windows/process.rs8
-rw-r--r--library/std/src/sys/pal/windows/stdio.rs2
-rw-r--r--library/std/src/sys/pal/xous/stdio.rs2
-rw-r--r--library/std/src/sys/pal/zkvm/mod.rs2
-rw-r--r--library/std/src/sys/personality/dwarf/eh.rs5
-rw-r--r--library/std/src/sys/personality/dwarf/mod.rs4
-rw-r--r--library/std/src/sys/thread_local/key/xous.rs11
-rw-r--r--library/std/src/thread/tests.rs4
m---------library/stdarch0
-rw-r--r--library/unwind/src/unwinding.rs6
-rwxr-xr-xsrc/bootstrap/configure.py2
-rw-r--r--src/bootstrap/src/bin/main.rs13
-rw-r--r--src/bootstrap/src/bin/rustc.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs6
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs86
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs178
-rw-r--r--src/bootstrap/src/core/build_steps/tool.rs92
-rw-r--r--src/bootstrap/src/core/builder/mod.rs10
-rw-r--r--src/bootstrap/src/core/builder/tests.rs144
-rw-r--r--src/bootstrap/src/core/config/config.rs13
-rw-r--r--src/bootstrap/src/core/metadata.rs8
-rw-r--r--src/bootstrap/src/lib.rs33
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/bootstrap/src/utils/job.rs4
-rw-r--r--src/bootstrap/src/utils/metrics.rs8
-rw-r--r--src/build_helper/src/git.rs2
-rw-r--r--src/build_helper/src/metrics.rs88
-rw-r--r--src/ci/citool/Cargo.lock689
-rw-r--r--src/ci/citool/Cargo.toml8
-rw-r--r--src/ci/citool/src/cpu_usage.rs24
-rw-r--r--src/ci/citool/src/datadog.rs43
-rw-r--r--src/ci/citool/src/main.rs64
-rw-r--r--src/ci/citool/src/metrics.rs164
-rw-r--r--src/ci/citool/src/utils.rs11
-rw-r--r--src/ci/docker/README.md4
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile2
-rwxr-xr-xsrc/ci/docker/scripts/rfl-build.sh18
-rw-r--r--src/ci/github-actions/jobs.yml2
-rw-r--r--src/ci/package-lock.json5004
-rw-r--r--src/ci/package.json5
-rw-r--r--src/ci/scripts/upload-build-metrics.py86
-rw-r--r--src/doc/rustc-dev-guide/src/parallel-rustc.md2
-rw-r--r--src/doc/rustc-dev-guide/src/tests/compiletest.md30
-rw-r--r--src/doc/rustc-dev-guide/src/tests/directives.md8
-rw-r--r--src/doc/rustc-dev-guide/src/tests/running.md25
-rw-r--r--src/doc/rustc/src/SUMMARY.md2
-rw-r--r--src/doc/rustc/src/platform-support.md6
-rw-r--r--src/doc/rustc/src/platform-support/powerpc-unknown-linux-gnuspe.md20
-rw-r--r--src/doc/rustc/src/platform-support/powerpc-unknown-linux-muslspe.md4
-rw-r--r--src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md2
-rw-r--r--src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md26
-rw-r--r--src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md27
-rw-r--r--src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md27
-rwxr-xr-xsrc/etc/htmldocck.py14
-rwxr-xr-xsrc/etc/pre-push.sh14
-rw-r--r--src/etc/test-float-parse/src/gen/exhaustive.rs3
-rw-r--r--src/etc/test-float-parse/src/gen/fuzz.rs1
-rw-r--r--src/etc/test-float-parse/src/gen/sparse.rs1
-rw-r--r--src/etc/test-float-parse/src/lib.rs221
-rw-r--r--src/etc/test-float-parse/src/traits.rs8
-rw-r--r--src/etc/test-float-parse/src/ui.rs126
-rw-r--r--src/etc/test-float-parse/src/validate.rs46
-rw-r--r--src/librustdoc/Cargo.toml2
-rw-r--r--src/librustdoc/clean/cfg.rs4
-rw-r--r--src/librustdoc/clean/inline.rs10
-rw-r--r--src/librustdoc/clean/mod.rs121
-rw-r--r--src/librustdoc/clean/render_macro_matchers.rs13
-rw-r--r--src/librustdoc/clean/types.rs46
-rw-r--r--src/librustdoc/clean/utils.rs19
-rw-r--r--src/librustdoc/config.rs44
-rw-r--r--src/librustdoc/core.rs24
-rw-r--r--src/librustdoc/display.rs2
-rw-r--r--src/librustdoc/doctest/extracted.rs4
-rw-r--r--src/librustdoc/doctest/rust.rs5
-rw-r--r--src/librustdoc/formats/cache.rs4
-rw-r--r--src/librustdoc/html/format.rs158
-rw-r--r--src/librustdoc/html/highlight.rs91
-rw-r--r--src/librustdoc/html/markdown.rs17
-rw-r--r--src/librustdoc/html/render/mod.rs209
-rw-r--r--src/librustdoc/html/render/print_item.rs345
-rw-r--r--src/librustdoc/html/render/search_index.rs5
-rw-r--r--src/librustdoc/html/render/search_index/encode.rs4
-rw-r--r--src/librustdoc/html/render/sidebar.rs18
-rw-r--r--src/librustdoc/html/render/span_map.rs22
-rw-r--r--src/librustdoc/html/render/type_layout.rs6
-rw-r--r--src/librustdoc/html/render/write_shared.rs2
-rw-r--r--src/librustdoc/html/sources.rs2
-rw-r--r--src/librustdoc/html/static/js/rustdoc.d.ts17
-rw-r--r--src/librustdoc/html/static/js/search.js69
-rw-r--r--src/librustdoc/lib.rs12
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs61
-rw-r--r--src/librustdoc/passes/collect_trait_impls.rs33
-rw-r--r--src/librustdoc/passes/lint/html_tags.rs6
-rw-r--r--src/librustdoc/passes/lint/unportable_markdown.rs16
-rw-r--r--src/librustdoc/passes/propagate_stability.rs6
-rw-r--r--src/librustdoc/passes/strip_hidden.rs22
-rw-r--r--src/librustdoc/visit_lib.rs8
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils/mod.rs27
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs11
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs3
-rw-r--r--src/tools/compiletest/src/common.rs3
-rw-r--r--src/tools/compiletest/src/directive-list.rs2
-rw-r--r--src/tools/compiletest/src/header.rs16
-rw-r--r--src/tools/compiletest/src/header/cfg.rs10
-rw-r--r--src/tools/compiletest/src/header/tests.rs9
-rw-r--r--src/tools/compiletest/src/lib.rs50
-rw-r--r--src/tools/compiletest/src/raise_fd_limit.rs1
-rw-r--r--src/tools/compiletest/src/runtest.rs17
-rw-r--r--src/tools/compiletest/src/runtest/run_make.rs283
-rw-r--r--src/tools/jsondocck/src/main.rs43
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs25
-rw-r--r--src/tools/miri/src/machine.rs10
-rw-r--r--src/tools/miri/src/shims/native_lib.rs16
-rw-r--r--src/tools/miri/tests/native-lib/pass/ptr_write_access.rs40
-rw-r--r--src/tools/miri/tests/native-lib/ptr_read_access.c15
-rw-r--r--src/tools/miri/tests/native-lib/ptr_write_access.c55
-rw-r--r--src/tools/miri/tests/native-lib/scalar_arguments.c13
-rw-r--r--src/tools/miri/tests/pass/unsized.rs15
-rw-r--r--src/tools/opt-dist/src/main.rs1
-rw-r--r--src/tools/opt-dist/src/metrics.rs73
-rw-r--r--src/tools/run-make-support/src/artifact_names.rs17
-rw-r--r--src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs11
-rw-r--r--src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs55
-rw-r--r--src/tools/run-make-support/src/external_deps/rustc.rs33
-rw-r--r--src/tools/run-make-support/src/external_deps/rustdoc.rs31
-rw-r--r--src/tools/run-make-support/src/lib.rs2
-rw-r--r--src/tools/run-make-support/src/run.rs19
-rw-r--r--src/tools/run-make-support/src/util.rs6
-rw-r--r--src/tools/rust-analyzer/.github/workflows/autopublish.yaml2
-rw-r--r--src/tools/rust-analyzer/.github/workflows/ci.yaml2
-rw-r--r--src/tools/rust-analyzer/.github/workflows/fuzz.yml2
-rw-r--r--src/tools/rust-analyzer/.github/workflows/publish-libs.yaml2
-rw-r--r--src/tools/rust-analyzer/.github/workflows/release.yaml59
-rw-r--r--src/tools/rust-analyzer/.typos.toml2
-rw-r--r--src/tools/rust-analyzer/Cargo.lock33
-rw-r--r--src/tools/rust-analyzer/Cargo.toml13
-rw-r--r--src/tools/rust-analyzer/crates/base-db/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/cfg/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs4
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/item_tree.rs6
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-def/src/resolver.rs5
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/files.rs10
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/lib.rs54
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs35
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/db.rs7
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/display.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/drop.rs209
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer.rs9
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/layout.rs47
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/lib.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs11
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs261
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/utils.rs37
-rw-r--r--src/tools/rust-analyzer/crates/hir/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/lib.rs84
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics.rs19
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/semantics/source_to_def.rs2
-rw-r--r--src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs22
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs49
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs123
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs80
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs53
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs80
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs9
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs26
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs23
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs47
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_mut.rs15
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs19
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs62
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs22
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/tests/generated.rs19
-rw-r--r--src/tools/rust-analyzer/crates/ide-assists/src/utils.rs78
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs5
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/context/analysis.rs5
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/item.rs14
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-completion/src/render.rs28
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs34
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/lib.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/search.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/source_change.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs4
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/handlers/missing_unsafe.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/ide/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/doc_links.rs19
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs92
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/render.rs95
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/hover/tests.rs594
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs23
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/moniker.rs10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/static_index.rs1
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs343
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs21
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs6
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs20
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/macro_.rs128
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html20
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html18
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_const.html4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html10
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html2
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html4
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html16
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html16
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html16
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html16
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html50
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html18
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html116
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html8
-rw-r--r--src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs27
-rw-r--r--src/tools/rust-analyzer/crates/intern/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/mbe/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/mbe/src/parser.rs4
-rw-r--r--src/tools/rust-analyzer/crates/parser/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/input.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/output.rs5
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/syntax_kind/generated.rs19
-rw-r--r--src/tools/rust-analyzer/crates/paths/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/paths/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/profile/Cargo.toml3
-rw-r--r--src/tools/rust-analyzer/crates/profile/src/stop_watch.rs10
-rw-r--r--src/tools/rust-analyzer/crates/project-model/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs4
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/lib.rs2
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/project_json.rs12
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/sysroot.rs147
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/tests.rs14
-rw-r--r--src/tools/rust-analyzer/crates/project-model/src/workspace.rs238
-rw-r--r--src/tools/rust-analyzer/crates/project-model/test_data/is-proc-macro-project.json13
-rw-r--r--src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt501
-rw-r--r--src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt454
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs6
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs21
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/op_queue.rs2
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs4
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/hprof.rs3
-rw-r--r--src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/json.rs3
-rw-r--r--src/tools/rust-analyzer/crates/stdx/Cargo.toml4
-rw-r--r--src/tools/rust-analyzer/crates/stdx/src/anymap.rs3
-rw-r--r--src/tools/rust-analyzer/crates/stdx/src/assert.rs115
-rw-r--r--src/tools/rust-analyzer/crates/stdx/src/lib.rs5
-rw-r--r--src/tools/rust-analyzer/crates/stdx/src/macros.rs2
-rw-r--r--src/tools/rust-analyzer/crates/syntax-bridge/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/syntax/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/syntax/rust.ungram6
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/algo.rs26
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs4
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/make.rs2
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs49
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory.rs5
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs288
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs4
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs59
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs111
-rw-r--r--src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs6
-rw-r--r--src/tools/rust-analyzer/crates/test-utils/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/test-utils/src/assert_linear.rs2
-rw-r--r--src/tools/rust-analyzer/crates/test-utils/src/fixture.rs24
-rw-r--r--src/tools/rust-analyzer/crates/test-utils/src/lib.rs4
-rw-r--r--src/tools/rust-analyzer/crates/toolchain/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/tt/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/vfs/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/vfs/src/anchored_path.rs2
-rw-r--r--src/tools/rust-analyzer/crates/vfs/src/vfs_path.rs2
-rw-r--r--src/tools/rust-analyzer/docs/book/src/assists_generated.md38
-rw-r--r--src/tools/rust-analyzer/docs/book/src/configuration_generated.md5
-rw-r--r--src/tools/rust-analyzer/docs/book/src/contributing/setup.md14
-rw-r--r--src/tools/rust-analyzer/editors/code/.eslintignore2
-rw-r--r--src/tools/rust-analyzer/editors/code/.eslintrc.js46
-rw-r--r--src/tools/rust-analyzer/editors/code/.prettierrc.js5
-rw-r--r--src/tools/rust-analyzer/editors/code/eslint.config.mts48
-rw-r--r--src/tools/rust-analyzer/editors/code/package-lock.json3458
-rw-r--r--src/tools/rust-analyzer/editors/code/package.json61
-rw-r--r--src/tools/rust-analyzer/editors/code/prettier.config.mts12
-rw-r--r--src/tools/rust-analyzer/editors/code/src/bootstrap.ts4
-rw-r--r--src/tools/rust-analyzer/editors/code/src/client.ts507
-rw-r--r--src/tools/rust-analyzer/editors/code/src/commands.ts12
-rw-r--r--src/tools/rust-analyzer/editors/code/src/config.ts28
-rw-r--r--src/tools/rust-analyzer/editors/code/src/ctx.ts41
-rw-r--r--src/tools/rust-analyzer/editors/code/src/debug.ts9
-rw-r--r--src/tools/rust-analyzer/editors/code/src/diagnostics.ts44
-rw-r--r--src/tools/rust-analyzer/editors/code/src/lang_client.ts2
-rw-r--r--src/tools/rust-analyzer/editors/code/src/lsp_ext.ts1
-rw-r--r--src/tools/rust-analyzer/editors/code/src/main.ts1
-rw-r--r--src/tools/rust-analyzer/editors/code/src/persistent_state.ts1
-rw-r--r--src/tools/rust-analyzer/editors/code/src/snippets.ts4
-rw-r--r--src/tools/rust-analyzer/editors/code/src/syntax_tree_provider.ts2
-rw-r--r--src/tools/rust-analyzer/editors/code/src/test_explorer.ts2
-rw-r--r--src/tools/rust-analyzer/editors/code/src/toolchain.ts20
-rw-r--r--src/tools/rust-analyzer/editors/code/src/util.ts18
-rw-r--r--src/tools/rust-analyzer/editors/code/tests/unit/index.ts3
-rw-r--r--src/tools/rust-analyzer/editors/code/tests/unit/tasks.test.ts5
-rw-r--r--src/tools/rust-analyzer/editors/code/tsconfig.eslint.json2
-rw-r--r--src/tools/rust-analyzer/editors/code/tsconfig.json11
-rw-r--r--src/tools/rust-analyzer/lib/line-index/src/lib.rs24
-rw-r--r--src/tools/rust-analyzer/rust-version2
-rw-r--r--src/tools/rust-analyzer/xtask/src/dist.rs29
-rw-r--r--src/tools/rust-analyzer/xtask/src/flags.rs3
-rw-r--r--src/tools/rust-analyzer/xtask/src/release.rs2
-rw-r--r--src/tools/rustdoc/Cargo.toml2
-rw-r--r--src/tools/rustfmt/src/items.rs77
-rw-r--r--src/tools/rustfmt/src/macros.rs34
-rw-r--r--src/tools/rustfmt/src/spanned.rs7
-rw-r--r--src/tools/rustfmt/src/types.rs35
-rw-r--r--src/tools/rustfmt/tests/source/pin_sugar.rs10
-rw-r--r--src/tools/rustfmt/tests/target/cfg_attribute_in_where.rs116
-rw-r--r--src/tools/rustfmt/tests/target/pin_sugar.rs9
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt0
-rw-r--r--src/tools/tidy/src/lib.rs1
-rw-r--r--src/tools/tidy/src/main.rs2
-rw-r--r--src/tools/tidy/src/run_make_tests.rs104
-rw-r--r--src/tools/tidy/src/style.rs21
-rw-r--r--tests/assembly/stack-protector/stack-protector-heuristics-effect.rs32
-rw-r--r--tests/codegen/asm/critical.rs37
-rw-r--r--tests/codegen/issues/looping-over-ne-bytes-133528.rs17
-rw-r--r--tests/codegen/pattern_type_symbols.rs4
-rw-r--r--tests/codegen/slice-init.rs51
-rw-r--r--tests/crashes/129095.rs5
-rw-r--r--tests/crashes/132960.rs2
-rw-r--r--tests/crashes/132981.rs11
-rw-r--r--tests/crashes/134654.rs3
-rw-r--r--tests/crashes/135128.rs2
-rw-r--r--tests/crashes/135570.rs3
-rw-r--r--tests/debuginfo/unsized.rs21
-rw-r--r--tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff29
-rw-r--r--tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff41
-rw-r--r--tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs2
-rw-r--r--tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff32
-rw-r--r--tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff47
-rw-r--r--tests/mir-opt/inline/inline_box_fn.rs2
-rw-r--r--tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff13
-rw-r--r--tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff13
-rw-r--r--tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff24
-rw-r--r--tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff40
-rw-r--r--tests/mir-opt/inline/inline_diverging.rs3
-rw-r--r--tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff14
-rw-r--r--tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff22
-rw-r--r--tests/mir-opt/inline/issue_78442.rs5
-rw-r--r--tests/mir-opt/inline_fn_call_for_fn_def.rs19
-rw-r--r--tests/mir-opt/inline_fn_call_for_fn_def.test.Inline.diff34
-rw-r--r--tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir (renamed from tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir)0
-rw-r--r--tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir (renamed from tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir)0
-rw-r--r--tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir68
-rw-r--r--tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir68
-rw-r--r--tests/mir-opt/issues/issue_59352.rs2
-rw-r--r--tests/mir-opt/pattern_types.main.PreCodegen.after.mir4
-rw-r--r--tests/mir-opt/pattern_types.rs4
-rw-r--r--tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir6
-rw-r--r--tests/pretty/pin-ergonomics.rs24
-rw-r--r--tests/run-make/README.md36
-rw-r--r--tests/run-make/a-b-a-linker-guard/rmake.rs7
-rw-r--r--tests/run-make/linker-warning/rmake.rs2
-rw-r--r--tests/run-make/linker-warning/short-error.txt2
-rw-r--r--tests/run-make/raw-dylib-elf-verbatim-absolute/main.rs11
-rw-r--r--tests/run-make/raw-dylib-elf-verbatim-absolute/output.txt1
-rw-r--r--tests/run-make/raw-dylib-elf-verbatim-absolute/rmake.rs20
-rw-r--r--tests/run-make/raw-dylib-elf-verbatim/library.c3
-rw-r--r--tests/run-make/raw-dylib-elf-verbatim/main.rs11
-rw-r--r--tests/run-make/raw-dylib-elf-verbatim/output.txt1
-rw-r--r--tests/run-make/raw-dylib-elf-verbatim/rmake.rs31
-rw-r--r--tests/run-make/raw-dylib-elf/library.c3
-rw-r--r--tests/run-make/raw-dylib-elf/main.rs11
-rw-r--r--tests/run-make/raw-dylib-elf/output.txt1
-rw-r--r--tests/run-make/raw-dylib-elf/rmake.rs29
-rw-r--r--tests/run-make/repr128-dwarf/main.rs25
-rw-r--r--tests/run-make/repr128-dwarf/rmake.rs115
-rw-r--r--tests/run-make/reproducible-build/linker.rs2
-rw-r--r--tests/run-make/rustc-help/help-v.stdout2
-rw-r--r--tests/run-make/rustc-help/help.stdout2
-rw-r--r--tests/run-make/rustdoc-default-output/output-default.stdout2
-rw-r--r--tests/run-make/rustdoc-default-output/rmake.rs4
-rw-r--r--tests/run-make/rustdoc-dep-info/bar.rs1
-rw-r--r--tests/run-make/rustdoc-dep-info/doc.md1
-rw-r--r--tests/run-make/rustdoc-dep-info/foo.rs1
-rw-r--r--tests/run-make/rustdoc-dep-info/lib.rs6
-rw-r--r--tests/run-make/rustdoc-dep-info/rmake.rs21
-rw-r--r--tests/run-make/tools.mk209
-rw-r--r--tests/run-make/unstable-feature-usage-metrics/rmake.rs11
-rw-r--r--tests/run-make/version-verbose-commit-hash/rmake.rs4
-rw-r--r--tests/rustdoc-json/enums/discriminant/limits.rs1
-rw-r--r--tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs2
-rw-r--r--tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs2
-rw-r--r--tests/rustdoc-json/enums/discriminant/struct.rs2
-rw-r--r--tests/rustdoc-json/enums/discriminant/tuple.rs2
-rw-r--r--tests/rustdoc-json/enums/kind.rs2
-rw-r--r--tests/rustdoc-json/fn_pointer/abi.rs2
-rw-r--r--tests/rustdoc-json/fn_pointer/generics.rs2
-rw-r--r--tests/rustdoc-json/fn_pointer/qualifiers.rs2
-rw-r--r--tests/rustdoc-json/fns/abi.rs2
-rw-r--r--tests/rustdoc-json/fns/async_return.rs1
-rw-r--r--tests/rustdoc-json/fns/generic_args.rs2
-rw-r--r--tests/rustdoc-json/fns/generic_returns.rs2
-rw-r--r--tests/rustdoc-json/fns/generics.rs2
-rw-r--r--tests/rustdoc-json/generic-associated-types/gats.rs2
-rw-r--r--tests/rustdoc-json/impl-trait-in-assoc-type.rs1
-rw-r--r--tests/rustdoc-json/lifetime/longest.rs2
-rw-r--r--tests/rustdoc-json/lifetime/outlives.rs2
-rw-r--r--tests/rustdoc-json/lifetime/outlives_in_param.rs2
-rw-r--r--tests/rustdoc-json/lifetime/outlives_in_where.rs2
-rw-r--r--tests/rustdoc-json/methods/abi.rs2
-rw-r--r--tests/rustdoc-json/non_lifetime_binders.rs2
-rw-r--r--tests/rustdoc-json/path_name.rs1
-rw-r--r--tests/rustdoc-json/reexport/doc_inline_external_crate.rs1
-rw-r--r--tests/rustdoc-json/reexport/export_extern_crate_as_self.rs2
-rw-r--r--tests/rustdoc-json/reexport/private_twice_one_inline.rs1
-rw-r--r--tests/rustdoc-json/reexport/private_two_names.rs2
-rw-r--r--tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs2
-rw-r--r--tests/rustdoc-json/return_private.rs1
-rw-r--r--tests/rustdoc-json/statics/extern.rs1
-rw-r--r--tests/rustdoc-json/structs/with_primitives.rs2
-rw-r--r--tests/rustdoc-json/trait_alias.rs1
-rw-r--r--tests/rustdoc-json/traits/private_supertrait.rs2
-rw-r--r--tests/rustdoc-json/traits/self.rs2
-rw-r--r--tests/rustdoc-json/traits/supertrait.rs2
-rw-r--r--tests/rustdoc-json/traits/trait_alias.rs1
-rw-r--r--tests/rustdoc-json/type/dyn.rs1
-rw-r--r--tests/rustdoc-json/type/fn_lifetime.rs2
-rw-r--r--tests/rustdoc-json/type/generic_default.rs2
-rw-r--r--tests/rustdoc-json/type/hrtb.rs2
-rw-r--r--tests/rustdoc-json/type/inherent_associated_type.rs1
-rw-r--r--tests/rustdoc-json/type/inherent_associated_type_bound.rs1
-rw-r--r--tests/rustdoc-json/type/inherent_associated_type_projections.rs1
-rw-r--r--tests/rustdoc-ui/issues/issue-79494.rs2
-rw-r--r--tests/rustdoc-ui/issues/issue-79494.stderr6
-rw-r--r--tests/rustdoc-ui/target-feature-stability.rs28
-rw-r--r--tests/rustdoc-ui/track-diagnostics.rs3
-rw-r--r--tests/rustdoc-ui/track-diagnostics.stderr4
-rw-r--r--tests/rustdoc/doc-hidden-reexports-109449.rs18
-rw-r--r--tests/rustdoc/doc-hidden-source.rs16
-rw-r--r--tests/rustdoc/impl-parts-crosscrate.rs2
-rw-r--r--tests/rustdoc/impl-parts.rs2
-rw-r--r--tests/rustdoc/inline_cross/inline_hidden.rs4
-rw-r--r--tests/rustdoc/reexport-attr-merge.rs4
-rw-r--r--tests/rustdoc/reexport-doc-hidden-inside-private.rs4
-rw-r--r--tests/rustdoc/reexport-doc-hidden.rs4
-rw-r--r--tests/rustdoc/reexport-hidden-macro.rs2
-rw-r--r--tests/rustdoc/reexport-of-doc-hidden.rs12
-rw-r--r--tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout4
-rw-r--r--tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout2
-rw-r--r--tests/ui-fulldeps/stable-mir/check_ty_fold.rs12
-rw-r--r--tests/ui-fulldeps/stable-mir/crate-info.rs23
-rw-r--r--tests/ui-fulldeps/stable-mir/projections.rs10
-rw-r--r--tests/ui-fulldeps/stable-mir/smir_internal.rs2
-rw-r--r--tests/ui-fulldeps/stable-mir/smir_serde.rs24
-rw-r--r--tests/ui-fulldeps/stable-mir/smir_visitor.rs12
-rw-r--r--tests/ui/abi/c-zst.aarch64-darwin.stderr4
-rw-r--r--tests/ui/abi/c-zst.powerpc-linux.stderr4
-rw-r--r--tests/ui/abi/c-zst.s390x-linux.stderr4
-rw-r--r--tests/ui/abi/c-zst.sparc64-linux.stderr4
-rw-r--r--tests/ui/abi/c-zst.x86_64-linux.stderr4
-rw-r--r--tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr4
-rw-r--r--tests/ui/abi/debug.stderr48
-rw-r--r--tests/ui/abi/rust-cold-works-with-rustic-args.rs6
-rw-r--r--tests/ui/abi/sysv64-zst.stderr4
-rw-r--r--tests/ui/abi/unsized-args-in-c-abi-issues-94223-115845.rs7
-rw-r--r--tests/ui/abi/unsupported.aarch64.stderr110
-rw-r--r--tests/ui/abi/unsupported.arm.stderr99
-rw-r--r--tests/ui/abi/unsupported.i686.stderr77
-rw-r--r--tests/ui/abi/unsupported.riscv32.stderr99
-rw-r--r--tests/ui/abi/unsupported.riscv64.stderr99
-rw-r--r--tests/ui/abi/unsupported.x64.stderr99
-rw-r--r--tests/ui/associated-inherent-types/issue-109299-1.stderr4
-rw-r--r--tests/ui/associated-inherent-types/issue-109789.rs1
-rw-r--r--tests/ui/associated-inherent-types/issue-109789.stderr10
-rw-r--r--tests/ui/associated-inherent-types/issue-111404-1.rs1
-rw-r--r--tests/ui/associated-inherent-types/issue-111404-1.stderr10
-rw-r--r--tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr2
-rw-r--r--tests/ui/associated-inherent-types/not-found-self-type-differs.stderr4
-rw-r--r--tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr4
-rw-r--r--tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr2
-rw-r--r--tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr2
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.fixed40
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs3
-rw-r--r--tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr38
-rw-r--r--tests/ui/associated-types/ident-from-macro-expansion.rs23
-rw-r--r--tests/ui/associated-types/ident-from-macro-expansion.stderr22
-rw-r--r--tests/ui/async-await/async-closures/kind-due-to-rpit.rs14
-rw-r--r--tests/ui/async-await/async-closures/kind-due-to-rpit.stderr17
-rw-r--r--tests/ui/async-await/issues/issue-63388-2.rs1
-rw-r--r--tests/ui/async-await/issues/issue-63388-2.stderr14
-rw-r--r--tests/ui/async-await/pin-ergonomics/sugar-self.rs46
-rw-r--r--tests/ui/attributes/auxiliary/used_pre_main_constructor.rs9
-rw-r--r--tests/ui/attributes/decl_macro_ty_in_attr_macro.rs20
-rw-r--r--tests/ui/c-variadic/variadic-ffi-2.rs4
-rw-r--r--tests/ui/c-variadic/variadic-ffi-2.stderr6
-rw-r--r--tests/ui/cast/cast-rfc0401-vtable-kinds.rs16
-rw-r--r--tests/ui/cast/cast-rfc0401-vtable-kinds.stderr2
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-add-auto.rs14
-rw-r--r--tests/ui/cast/ptr-to-trait-obj-add-auto.stderr44
-rw-r--r--tests/ui/cmse-nonsecure/cmse-nonsecure-call/gate_test.stderr10
-rw-r--r--tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs8
-rw-r--r--tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr31
-rw-r--r--tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr20
-rw-r--r--tests/ui/coherence/coherence-orphan.rs5
-rw-r--r--tests/ui/coherence/coherence-overlap-negative-impls.rs44
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr12
-rw-r--r--tests/ui/const-generics/mgca/ambiguous-assoc-const.rs15
-rw-r--r--tests/ui/const-generics/mgca/ambiguous-assoc-const.stderr15
-rw-r--r--tests/ui/const-generics/mgca/assoc-const-without-type_const.rs14
-rw-r--r--tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr18
-rw-r--r--tests/ui/const-generics/mgca/assoc-const.rs15
-rw-r--r--tests/ui/const-generics/mgca/bad-type_const-syntax.rs17
-rw-r--r--tests/ui/const-generics/mgca/bad-type_const-syntax.stderr35
-rw-r--r--tests/ui/const-generics/mgca/inherent-const-gating.rs13
-rw-r--r--tests/ui/const-generics/mgca/inherent-const-gating.stderr13
-rw-r--r--tests/ui/consts/const-slice-array-deref.stderr1
-rw-r--r--tests/ui/consts/const-unsized.stderr4
-rw-r--r--tests/ui/consts/const_refs_to_static-ice-121413.stderr1
-rw-r--r--tests/ui/consts/dont-ctfe-unsized-initializer.rs7
-rw-r--r--tests/ui/consts/dont-ctfe-unsized-initializer.stderr21
-rw-r--r--tests/ui/consts/issue-39974.stderr12
-rw-r--r--tests/ui/coroutine/gen_block.e2024.stderr22
-rw-r--r--tests/ui/coroutine/gen_block.none.stderr4
-rw-r--r--tests/ui/coroutine/gen_block.rs4
-rw-r--r--tests/ui/crate-loading/crateresolve1.stderr6
-rw-r--r--tests/ui/crate-loading/crateresolve2.stderr6
-rw-r--r--tests/ui/diagnostic-width/E0271.ascii.stderr6
-rw-r--r--tests/ui/diagnostic-width/E0271.rs1
-rw-r--r--tests/ui/diagnostic-width/E0271.unicode.stderr6
-rw-r--r--tests/ui/diagnostic-width/binop.rs2
-rw-r--r--tests/ui/diagnostic-width/binop.stderr8
-rw-r--r--tests/ui/diagnostic-width/long-E0308.ascii.stderr16
-rw-r--r--tests/ui/diagnostic-width/long-E0308.rs3
-rw-r--r--tests/ui/diagnostic-width/long-E0308.unicode.stderr16
-rw-r--r--tests/ui/diagnostic-width/long-E0529.rs3
-rw-r--r--tests/ui/diagnostic-width/long-E0529.stderr4
-rw-r--r--tests/ui/diagnostic-width/long-E0609.rs3
-rw-r--r--tests/ui/diagnostic-width/long-E0609.stderr4
-rw-r--r--tests/ui/diagnostic-width/long-E0614.rs3
-rw-r--r--tests/ui/diagnostic-width/long-E0614.stderr4
-rw-r--r--tests/ui/diagnostic-width/long-E0618.rs3
-rw-r--r--tests/ui/diagnostic-width/long-E0618.stderr4
-rw-r--r--tests/ui/diagnostic-width/long-e0277.rs2
-rw-r--r--tests/ui/diagnostic-width/long-e0277.stderr8
-rw-r--r--tests/ui/diagnostic-width/non-copy-type-moved.rs2
-rw-r--r--tests/ui/diagnostic-width/non-copy-type-moved.stderr4
-rw-r--r--tests/ui/diagnostic-width/secondary-label-with-long-type.rs2
-rw-r--r--tests/ui/diagnostic-width/secondary-label-with-long-type.stderr4
-rw-r--r--tests/ui/dst/dst-bad-assign-3.rs6
-rw-r--r--tests/ui/dst/dst-bad-assign-3.stderr4
-rw-r--r--tests/ui/dst/dst-bad-coerce1.rs14
-rw-r--r--tests/ui/dst/dst-bad-coerce1.stderr32
-rw-r--r--tests/ui/dst/dst-bad-coerce3.rs12
-rw-r--r--tests/ui/dst/dst-bad-coerce3.stderr38
-rw-r--r--tests/ui/dst/dst-bad-coerce4.rs10
-rw-r--r--tests/ui/dst/dst-bad-coerce4.stderr15
-rw-r--r--tests/ui/dst/dst-bad-deep-2.rs8
-rw-r--r--tests/ui/dst/dst-bad-deep-2.stderr18
-rw-r--r--tests/ui/dynamically-sized-types/dst-irrefutable-bind.rs11
-rw-r--r--tests/ui/dynamically-sized-types/dst-raw.rs35
-rw-r--r--tests/ui/dynamically-sized-types/dst-trait-tuple.rs102
-rw-r--r--tests/ui/dynamically-sized-types/dst-tuple-no-reorder.rs26
-rw-r--r--tests/ui/dynamically-sized-types/dst-tuple-sole.rs79
-rw-r--r--tests/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs22
-rw-r--r--tests/ui/dynamically-sized-types/dst-tuple.rs119
-rw-r--r--tests/ui/error-codes/E0275.rs1
-rw-r--r--tests/ui/error-codes/E0275.stderr4
-rw-r--r--tests/ui/error-codes/E0462.stderr2
-rw-r--r--tests/ui/error-codes/E0464.stderr6
-rw-r--r--tests/ui/error-codes/E0523.stderr6
-rw-r--r--tests/ui/error-codes/E0582.stderr2
-rw-r--r--tests/ui/extern/issue-36122-accessing-externed-dst.stderr1
-rw-r--r--tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr11
-rw-r--r--tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr4
-rw-r--r--tests/ui/feature-gates/feature-gate-coroutines.none.stderr4
-rw-r--r--tests/ui/feature-gates/feature-gate-min-generic-const-args.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr15
-rw-r--r--tests/ui/feature-gates/feature-gate-pin_ergonomics.rs40
-rw-r--r--tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr88
-rw-r--r--tests/ui/feature-gates/feature-gate-raw-dylib-elf.rs9
-rw-r--r--tests/ui/feature-gates/feature-gate-raw-dylib-elf.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr883
-rw-r--r--tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr883
-rw-r--r--tests/ui/feature-gates/feature-gate-where_clause_attrs.rs162
-rw-r--r--tests/ui/feature-gates/feature-gate-yield-expr.rs9
-rw-r--r--tests/ui/feature-gates/feature-gate-yield-expr.stderr41
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr14
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs2
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.stderr14
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr2
-rw-r--r--tests/ui/hygiene/generate-mod.stderr6
-rw-r--r--tests/ui/hygiene/globs.stderr6
-rw-r--r--tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs2
-rw-r--r--tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr42
-rw-r--r--tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr2
-rw-r--r--tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs1
-rw-r--r--tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr12
-rw-r--r--tests/ui/impl-trait/unsize_tuple.rs15
-rw-r--r--tests/ui/implied-bounds/from-trait-impl.rs2
-rw-r--r--tests/ui/implied-bounds/from-trait-impl.stderr27
-rw-r--r--tests/ui/implied-bounds/normalization-nested.lifetime.stderr10
-rw-r--r--tests/ui/implied-bounds/normalization-nested.rs5
-rw-r--r--tests/ui/implied-bounds/normalization-placeholder-leak.fail.stderr34
-rw-r--r--tests/ui/implied-bounds/normalization-placeholder-leak.rs4
-rw-r--r--tests/ui/implied-bounds/sod_service_chain.rs8
-rw-r--r--tests/ui/implied-bounds/sod_service_chain.stderr76
-rw-r--r--tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr8
-rw-r--r--tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs3
-rw-r--r--tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr10
-rw-r--r--tests/ui/infinite/infinite-instantiation.rs2
-rw-r--r--tests/ui/infinite/infinite-instantiation.stderr6
-rw-r--r--tests/ui/invalid-compile-flags/print-without-arg.stderr2
-rw-r--r--tests/ui/issues/issue-106755.rs5
-rw-r--r--tests/ui/issues/issue-106755.stderr31
-rw-r--r--tests/ui/issues/issue-13497.rs1
-rw-r--r--tests/ui/issues/issue-13497.stderr14
-rw-r--r--tests/ui/issues/issue-20413.rs1
-rw-r--r--tests/ui/issues/issue-20413.stderr18
-rw-r--r--tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs2
-rw-r--r--tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr6
-rw-r--r--tests/ui/issues/issue-54410.stderr1
-rw-r--r--tests/ui/issues/issue-67552.rs2
-rw-r--r--tests/ui/issues/issue-67552.stderr6
-rw-r--r--tests/ui/issues/issue-8727.rs2
-rw-r--r--tests/ui/issues/issue-8727.stderr8
-rw-r--r--tests/ui/json/json-multiple.stderr2
-rw-r--r--tests/ui/json/json-options.stderr2
-rw-r--r--tests/ui/layout/debug.stderr36
-rw-r--r--tests/ui/layout/hexagon-enum.stderr20
-rw-r--r--tests/ui/layout/issue-84108.stderr18
-rw-r--r--tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr34
-rw-r--r--tests/ui/layout/issue-96185-overaligned-enum.stderr12
-rw-r--r--tests/ui/layout/thumb-enum.stderr20
-rw-r--r--tests/ui/layout/zero-sized-array-enum-niche.stderr26
-rw-r--r--tests/ui/lifetimes/issue-26638.rs1
-rw-r--r--tests/ui/lifetimes/issue-26638.stderr17
-rw-r--r--tests/ui/linkage-attr/raw-dylib/elf/multiple-libraries.rs37
-rw-r--r--tests/ui/linkage-attr/raw-dylib/elf/single-symbol.rs28
-rw-r--r--tests/ui/linkage-attr/raw-dylib/elf/verbatim.rs29
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-invalid-format.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-multiple.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-multiple.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unknown-value.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-x86-only.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-x86-only.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-and-name.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-and-name.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-and-name.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-and-name.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-multiple.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-multiple.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-large.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-large.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-large.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-large.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-unsupported-link-kind.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-unsupported-link-kind.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/multiple-declarations.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/multiple-declarations.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.elf.stderr13
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.notelf.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr)2
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.rs9
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.rs)0
-rw-r--r--tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr (renamed from tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr)0
-rw-r--r--tests/ui/lint/clashing-extern-fn.stderr2
-rw-r--r--tests/ui/lint/removed-lints/README.md4
-rw-r--r--tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs5
-rw-r--r--tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr10
-rw-r--r--tests/ui/macros/macro-parameter-span.stderr3
-rw-r--r--tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr3
-rw-r--r--tests/ui/methods/ident-from-macro-expansion.rs18
-rw-r--r--tests/ui/methods/ident-from-macro-expansion.stderr21
-rw-r--r--tests/ui/methods/inherent-bound-in-probe.rs2
-rw-r--r--tests/ui/methods/inherent-bound-in-probe.stderr8
-rw-r--r--tests/ui/nll/issue-97997.rs1
-rw-r--r--tests/ui/nll/issue-97997.stderr12
-rw-r--r--tests/ui/parser/bounds-lifetime-where.rs2
-rw-r--r--tests/ui/parser/bounds-lifetime-where.stderr4
-rw-r--r--tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr2
-rw-r--r--tests/ui/parser/ranges-precedence.rs28
-rw-r--r--tests/ui/recursion/issue-23122-2.rs1
-rw-r--r--tests/ui/recursion/issue-23122-2.stderr4
-rw-r--r--tests/ui/recursion/issue-83150.rs3
-rw-r--r--tests/ui/recursion/issue-83150.stderr8
-rw-r--r--tests/ui/recursion/recursion.rs2
-rw-r--r--tests/ui/recursion/recursion.stderr6
-rw-r--r--tests/ui/regions/issue-102374.rs1
-rw-r--r--tests/ui/regions/issue-102374.stderr2
-rw-r--r--tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr16
-rw-r--r--tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr16
-rw-r--r--tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr16
-rw-r--r--tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr16
-rw-r--r--tests/ui/repr/repr-c-int-dead-variants.stderr16
-rw-r--r--tests/ui/return/tail-expr-as-potential-return.rs1
-rw-r--r--tests/ui/return/tail-expr-as-potential-return.stderr4
-rw-r--r--tests/ui/rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.rs5
-rw-r--r--tests/ui/rmeta/emit-artifact-notifications.stderr2
-rw-r--r--tests/ui/specialization/defaultimpl/validation.rs15
-rw-r--r--tests/ui/specialization/defaultimpl/validation.stderr28
-rw-r--r--tests/ui/specialization/specialization-overlap-negative.rs4
-rw-r--r--tests/ui/specialization/specialization-overlap-negative.stderr17
-rw-r--r--tests/ui/static/issue-24446.stderr1
-rw-r--r--tests/ui/statics/unsized_type2.stderr1
-rw-r--r--tests/ui/stats/input-stats.stderr28
-rw-r--r--tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.rs2
-rw-r--r--tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.stderr13
-rw-r--r--tests/ui/structs/default-field-values/failures.rs4
-rw-r--r--tests/ui/structs/default-field-values/failures.stderr17
-rw-r--r--tests/ui/structs/default-field-values/field-references-param.rs29
-rw-r--r--tests/ui/structs/default-field-values/post-mono.direct.stderr23
-rw-r--r--tests/ui/structs/default-field-values/post-mono.indirect.stderr29
-rw-r--r--tests/ui/structs/default-field-values/post-mono.rs23
-rw-r--r--tests/ui/structs/ident-from-macro-expansion.rs19
-rw-r--r--tests/ui/structs/ident-from-macro-expansion.stderr14
-rw-r--r--tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs2
-rw-r--r--tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr40
-rw-r--r--tests/ui/suggestions/impl-trait-missing-lifetime.rs2
-rw-r--r--tests/ui/suggestions/impl-trait-missing-lifetime.stderr18
-rw-r--r--tests/ui/suggestions/missing-lt-for-hrtb.rs2
-rw-r--r--tests/ui/suggestions/missing-lt-for-hrtb.stderr24
-rw-r--r--tests/ui/target_modifiers/auxiliary/default_reg_struct_return.rs21
-rw-r--r--tests/ui/target_modifiers/auxiliary/wrong_regparm.rs21
-rw-r--r--tests/ui/target_modifiers/auxiliary/wrong_regparm_and_ret.rs21
-rw-r--r--tests/ui/target_modifiers/defaults_check.error.stderr4
-rw-r--r--tests/ui/target_modifiers/defaults_check.rs27
-rw-r--r--tests/ui/target_modifiers/incompatible_regparm.error_generated.stderr4
-rw-r--r--tests/ui/target_modifiers/incompatible_regparm.rs23
-rw-r--r--tests/ui/target_modifiers/two_flags.rs22
-rw-r--r--tests/ui/target_modifiers/two_flags.unknown_allowed.stderr4
-rw-r--r--tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr1
-rw-r--r--tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs22
-rw-r--r--tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr54
-rw-r--r--tests/ui/traits/negative-impls/negated-auto-traits-validity.rs22
-rw-r--r--tests/ui/traits/next-solver/unsize-good.rs6
-rw-r--r--tests/ui/traits/on_unimplemented_long_types.rs2
-rw-r--r--tests/ui/traits/on_unimplemented_long_types.stderr4
-rw-r--r--tests/ui/traits/trait-upcasting/dyn-to-dyn-star.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53092-2.rs6
-rw-r--r--tests/ui/type-alias-impl-trait/issue-53092-2.stderr50
-rw-r--r--tests/ui/type/pattern_types/nested.rs2
-rw-r--r--tests/ui/type/pattern_types/nested.stderr214
-rw-r--r--tests/ui/type/pattern_types/range_patterns.stderr22
-rw-r--r--tests/ui/type/pattern_types/range_patterns_unusable.stderr2
-rw-r--r--tests/ui/type/pattern_types/range_patterns_unusable_math.rs2
-rw-r--r--tests/ui/type/pattern_types/range_patterns_unusable_math.stderr4
-rw-r--r--tests/ui/type/pattern_types/reverse_range.rs13
-rw-r--r--tests/ui/type/pattern_types/reverse_range.stderr16
-rw-r--r--tests/ui/type/pattern_types/validity.rs2
-rw-r--r--tests/ui/type_length_limit.rs3
-rw-r--r--tests/ui/type_length_limit.stderr4
-rw-r--r--tests/ui/typeck/issue-84768.stderr2
-rw-r--r--tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr4
-rw-r--r--tests/ui/unpretty/deprecated-attr.rs19
-rw-r--r--tests/ui/unpretty/deprecated-attr.stdout28
-rw-r--r--tests/ui/unpretty/diagnostic-attr.rs13
-rw-r--r--tests/ui/unpretty/diagnostic-attr.stdout16
-rw-r--r--tests/ui/unsafe-binders/type-mismatch.rs9
-rw-r--r--tests/ui/unsafe-binders/type-mismatch.stderr34
-rw-r--r--tests/ui/unsafe-fields/unsafe-fields.rs2
-rw-r--r--tests/ui/unsafe-fields/unsafe-fields.stderr17
-rw-r--r--tests/ui/unsized-locals/rust-call.rs12
-rw-r--r--tests/ui/unsized-locals/rust-call.stderr13
-rw-r--r--tests/ui/unsized-locals/unsized-exprs-rpass.rs6
-rw-r--r--tests/ui/unsized-locals/unsized-exprs.rs7
-rw-r--r--tests/ui/unsized-locals/unsized-exprs.stderr16
-rw-r--r--tests/ui/unsized-locals/unsized-exprs2.rs5
-rw-r--r--tests/ui/unsized-locals/unsized-exprs2.stderr2
-rw-r--r--tests/ui/unsized/unsized-tuple-impls.rs21
-rw-r--r--tests/ui/wf/wf-normalization-sized.next.stderr20
-rw-r--r--tests/ui/where-clauses/cfg_attribute.a.stderr288
-rw-r--r--tests/ui/where-clauses/cfg_attribute.b.stderr288
-rw-r--r--tests/ui/where-clauses/cfg_attribute.rs183
-rw-r--r--tests/ui/where-clauses/unsupported_attribute.rs36
-rw-r--r--tests/ui/where-clauses/unsupported_attribute.stderr158
-rw-r--r--triagebot.toml19
-rwxr-xr-xx8
1158 files changed, 20267 insertions, 17597 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 73467ad267e..f166e0c0b41 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -58,8 +58,8 @@ jobs:
           COMMIT_MESSAGE: ${{ github.event.head_commit.message }}
         run: |
           cd src/ci/citool
-          cargo test
-          cargo run calculate-job-matrix >> $GITHUB_OUTPUT
+          CARGO_INCREMENTAL=0 cargo test
+          CARGO_INCREMENTAL=0 cargo run calculate-job-matrix >> $GITHUB_OUTPUT
         id: jobs
   job:
     name: ${{ matrix.full_name }}
@@ -182,19 +182,12 @@ jobs:
       - name: show the current environment
         run: src/ci/scripts/dump-environment.sh
 
-      # Temporary fix to unblock CI
-      # Remove the latest Windows SDK for 32-bit Windows MSVC builds.
-      # See issue https://github.com/rust-lang/rust/issues/137733 for more details.
-      - name: Remove Windows SDK 10.0.26100.0
-        shell: powershell
-        if: ${{ matrix.name == 'i686-msvc-1' || matrix.name == 'i686-msvc-2' || matrix.name == 'dist-i686-msvc' }}
+      # Pre-build citool before the following step uninstalls rustup
+      # Build it into the build directory, to avoid modifying sources
+      - name: build citool
         run: |
-          $kits = (Get-ItemProperty -path 'HKLM:\SOFTWARE\Microsoft\Windows Kits\Installed Roots').KitsRoot10
-          $sdk_version = "10.0.26100.0"
-
-          foreach ($kind in 'Bin', 'Lib', 'Include') {
-            Remove-Item -Force -Recurse $kits\$kind\$sdk_version -ErrorAction Continue
-          }
+          cd src/ci/citool
+          CARGO_INCREMENTAL=0 CARGO_TARGET_DIR=../../../build/citool cargo build
 
       - name: run the build
         # Redirect stderr to stdout to avoid reordering the two streams in the GHA logs.
@@ -232,16 +225,22 @@ jobs:
         # erroring about invalid credentials instead.
         if: github.event_name == 'push' || env.DEPLOY == '1' || env.DEPLOY_ALT == '1'
 
+      - name: postprocess metrics into the summary
+        run: |
+          if [ -f build/metrics.json ]; then
+            ./build/citool/debug/citool postprocess-metrics build/metrics.json ${GITHUB_STEP_SUMMARY}
+          elif [ -f obj/build/metrics.json ]; then
+            ./build/citool/debug/citool postprocess-metrics obj/build/metrics.json ${GITHUB_STEP_SUMMARY}
+          else
+            echo "No metrics.json found"
+          fi
+
       - name: upload job metrics to DataDog
         if: needs.calculate_matrix.outputs.run_type != 'pr'
         env:
-          DATADOG_SITE: datadoghq.com
           DATADOG_API_KEY: ${{ secrets.DATADOG_API_KEY }}
           DD_GITHUB_JOB_NAME: ${{ matrix.full_name }}
-        run: |
-          cd src/ci
-          npm ci
-          python3 scripts/upload-build-metrics.py ../../build/cpu-usage.csv
+        run: ./build/citool/debug/citool upload-build-metrics build/cpu-usage.csv
 
   # This job isused to tell bors the final status of the build, as there is no practical way to detect
   # when a workflow is successful listening to webhooks only in our current bors implementation (homu).
diff --git a/.gitignore b/.gitignore
index 2184e04f16b..b8cb31e8190 100644
--- a/.gitignore
+++ b/.gitignore
@@ -53,6 +53,7 @@ no_llvm_build
 /target
 /library/target
 /src/bootstrap/target
+/src/ci/citool/target
 /src/tools/x/target
 # Created by `x vendor`
 /vendor
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index a5ddff595f5..e155e253784 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -18,7 +18,7 @@ For submodules, changes need to be made against the repository corresponding the
 submodule, and not the main `rust-lang/rust` repository.
 
 For subtrees, prefer sending a PR against the subtree's repository if it does
-not need to be made against the main `rust-lang/rust` repostory (e.g. a
+not need to be made against the main `rust-lang/rust` repository (e.g. a
 rustc-dev-guide change that does not accompany a compiler change).
 
 ## About the [rustc-dev-guide]
diff --git a/INSTALL.md b/INSTALL.md
index 74fcc58348b..a46d3d70093 100644
--- a/INSTALL.md
+++ b/INSTALL.md
@@ -210,9 +210,13 @@ itself back on after some time).
 
 ### MSVC
 
-MSVC builds of Rust additionally require an installation of Visual Studio 2017
-(or later) so `rustc` can use its linker. The simplest way is to get
-[Visual Studio], check the "C++ build tools" and "Windows 10 SDK" workload.
+MSVC builds of Rust additionally requires an installation of:
+
+- Visual Studio 2022 (or later) build tools so `rustc` can use its linker. Older
+  Visual Studio versions such as 2019 *may* work but aren't actively tested.
+- A recent Windows 10 or 11 SDK.
+
+The simplest way is to get [Visual Studio], check the "C++ build tools".
 
 [Visual Studio]: https://visualstudio.microsoft.com/downloads/
 
diff --git a/compiler/rustc_abi/src/extern_abi.rs b/compiler/rustc_abi/src/extern_abi.rs
index 543c2f8ab12..4d70afd4e0b 100644
--- a/compiler/rustc_abi/src/extern_abi.rs
+++ b/compiler/rustc_abi/src/extern_abi.rs
@@ -191,6 +191,17 @@ impl StableOrd for ExternAbi {
 }
 
 impl ExternAbi {
+    /// An ABI "like Rust"
+    ///
+    /// These ABIs are fully controlled by the Rust compiler, which means they
+    /// - support unwinding with `-Cpanic=unwind`, unlike `extern "C"`
+    /// - often diverge from the C ABI
+    /// - are subject to change between compiler versions
+    pub fn is_rustic_abi(self) -> bool {
+        use ExternAbi::*;
+        matches!(self, Rust | RustCall | RustIntrinsic | RustCold)
+    }
+
     pub fn supports_varargs(self) -> bool {
         // * C and Cdecl obviously support varargs.
         // * C can be based on Aapcs, SysV64 or Win64, so they must support varargs.
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 2197dd68eaf..a59dc870aa3 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1812,7 +1812,7 @@ where
         f.debug_struct("Layout")
             .field("size", size)
             .field("align", align)
-            .field("abi", backend_repr)
+            .field("backend_repr", backend_repr)
             .field("fields", fields)
             .field("largest_niche", largest_niche)
             .field("uninhabited", uninhabited)
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 5c44fda2262..11fc409cf43 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -124,10 +124,19 @@ impl Path {
         self.segments.first().is_some_and(|segment| segment.ident.name == kw::PathRoot)
     }
 
-    /// If this path is a single identifier with no arguments, does not ensure
-    /// that the path resolves to a const param, the caller should check this.
-    pub fn is_potential_trivial_const_arg(&self) -> bool {
-        matches!(self.segments[..], [PathSegment { args: None, .. }])
+    /// Check if this path is potentially a trivial const arg, i.e., one that can _potentially_
+    /// be represented without an anon const in the HIR.
+    ///
+    /// If `allow_mgca_arg` is true (as should be the case in most situations when
+    /// `#![feature(min_generic_const_args)]` is enabled), then this always returns true
+    /// because all paths are valid.
+    ///
+    /// Otherwise, it returns true iff the path has exactly one segment, and it has no generic args
+    /// (i.e., it is _potentially_ a const parameter).
+    #[tracing::instrument(level = "debug", ret)]
+    pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
+        allow_mgca_arg
+            || self.segments.len() == 1 && self.segments.iter().all(|seg| seg.args.is_none())
     }
 }
 
@@ -417,9 +426,11 @@ impl WhereClause {
 /// A single predicate in a where-clause.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct WherePredicate {
+    pub attrs: AttrVec,
     pub kind: WherePredicateKind,
     pub id: NodeId,
     pub span: Span,
+    pub is_placeholder: bool,
 }
 
 /// Predicate kind in where-clause.
@@ -1206,22 +1217,31 @@ pub struct Expr {
 }
 
 impl Expr {
-    /// Could this expr be either `N`, or `{ N }`, where `N` is a const parameter.
+    /// Check if this expression is potentially a trivial const arg, i.e., one that can _potentially_
+    /// be represented without an anon const in the HIR.
+    ///
+    /// This will unwrap at most one block level (curly braces). After that, if the expression
+    /// is a path, it mostly dispatches to [`Path::is_potential_trivial_const_arg`].
+    /// See there for more info about `allow_mgca_arg`.
     ///
-    /// If this is not the case, name resolution does not resolve `N` when using
-    /// `min_const_generics` as more complex expressions are not supported.
+    /// The only additional thing to note is that when `allow_mgca_arg` is false, this function
+    /// will only allow paths with no qself, before dispatching to the `Path` function of
+    /// the same name.
     ///
-    /// Does not ensure that the path resolves to a const param, the caller should check this.
+    /// Does not ensure that the path resolves to a const param/item, the caller should check this.
     /// This also does not consider macros, so it's only correct after macro-expansion.
-    pub fn is_potential_trivial_const_arg(&self) -> bool {
+    pub fn is_potential_trivial_const_arg(&self, allow_mgca_arg: bool) -> bool {
         let this = self.maybe_unwrap_block();
-
-        if let ExprKind::Path(None, path) = &this.kind
-            && path.is_potential_trivial_const_arg()
-        {
-            true
+        if allow_mgca_arg {
+            matches!(this.kind, ExprKind::Path(..))
         } else {
-            false
+            if let ExprKind::Path(None, path) = &this.kind
+                && path.is_potential_trivial_const_arg(allow_mgca_arg)
+            {
+                true
+            } else {
+                false
+            }
         }
     }
 
@@ -2621,6 +2641,8 @@ pub enum SelfKind {
     Value(Mutability),
     /// `&'lt self`, `&'lt mut self`
     Region(Option<Lifetime>, Mutability),
+    /// `&'lt pin const self`, `&'lt pin mut self`
+    Pinned(Option<Lifetime>, Mutability),
     /// `self: TYPE`, `mut self: TYPE`
     Explicit(P<Ty>, Mutability),
 }
@@ -2630,6 +2652,8 @@ impl SelfKind {
         match self {
             SelfKind::Region(None, mutbl) => mutbl.ref_prefix_str().to_string(),
             SelfKind::Region(Some(lt), mutbl) => format!("&{lt} {}", mutbl.prefix_str()),
+            SelfKind::Pinned(None, mutbl) => format!("&pin {}", mutbl.ptr_str()),
+            SelfKind::Pinned(Some(lt), mutbl) => format!("&{lt} pin {}", mutbl.ptr_str()),
             SelfKind::Value(_) | SelfKind::Explicit(_, _) => {
                 unreachable!("if we had an explicit self, we wouldn't be here")
             }
@@ -2646,11 +2670,13 @@ impl Param {
             if ident.name == kw::SelfLower {
                 return match self.ty.kind {
                     TyKind::ImplicitSelf => Some(respan(self.pat.span, SelfKind::Value(mutbl))),
-                    TyKind::Ref(lt, MutTy { ref ty, mutbl })
-                    | TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
+                    TyKind::Ref(lt, MutTy { ref ty, mutbl }) if ty.kind.is_implicit_self() => {
+                        Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
+                    }
+                    TyKind::PinnedRef(lt, MutTy { ref ty, mutbl })
                         if ty.kind.is_implicit_self() =>
                     {
-                        Some(respan(self.pat.span, SelfKind::Region(lt, mutbl)))
+                        Some(respan(self.pat.span, SelfKind::Pinned(lt, mutbl)))
                     }
                     _ => Some(respan(
                         self.pat.span.to(self.ty.span),
@@ -2692,6 +2718,15 @@ impl Param {
                     tokens: None,
                 }),
             ),
+            SelfKind::Pinned(lt, mutbl) => (
+                mutbl,
+                P(Ty {
+                    id: DUMMY_NODE_ID,
+                    kind: TyKind::PinnedRef(lt, MutTy { ty: infer_ty, mutbl }),
+                    span,
+                    tokens: None,
+                }),
+            ),
         };
         Param {
             attrs,
diff --git a/compiler/rustc_ast/src/ast_traits.rs b/compiler/rustc_ast/src/ast_traits.rs
index 4a2d9559385..a37c0f92b12 100644
--- a/compiler/rustc_ast/src/ast_traits.rs
+++ b/compiler/rustc_ast/src/ast_traits.rs
@@ -11,7 +11,7 @@ use crate::tokenstream::LazyAttrTokenStream;
 use crate::{
     Arm, AssocItem, AttrItem, AttrKind, AttrVec, Attribute, Block, Crate, Expr, ExprField,
     FieldDef, ForeignItem, GenericParam, Item, NodeId, Param, Pat, PatField, Path, Stmt, StmtKind,
-    Ty, Variant, Visibility,
+    Ty, Variant, Visibility, WherePredicate,
 };
 
 /// A utility trait to reduce boilerplate.
@@ -79,6 +79,7 @@ impl_has_node_id!(
     Stmt,
     Ty,
     Variant,
+    WherePredicate,
 );
 
 impl<T: AstDeref<Target: HasNodeId>> HasNodeId for T {
@@ -127,7 +128,16 @@ macro_rules! impl_has_tokens_none {
 }
 
 impl_has_tokens!(AssocItem, AttrItem, Block, Expr, ForeignItem, Item, Pat, Path, Ty, Visibility);
-impl_has_tokens_none!(Arm, ExprField, FieldDef, GenericParam, Param, PatField, Variant);
+impl_has_tokens_none!(
+    Arm,
+    ExprField,
+    FieldDef,
+    GenericParam,
+    Param,
+    PatField,
+    Variant,
+    WherePredicate
+);
 
 impl<T: AstDeref<Target: HasTokens>> HasTokens for T {
     fn tokens(&self) -> Option<&LazyAttrTokenStream> {
@@ -279,6 +289,7 @@ impl_has_attrs!(
     Param,
     PatField,
     Variant,
+    WherePredicate,
 );
 impl_has_attrs_none!(Attribute, AttrItem, Block, Pat, Path, Ty, Visibility);
 
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 9be364e320b..f14646b5a99 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -338,8 +338,11 @@ pub trait MutVisitor: Sized {
         walk_where_clause(self, where_clause);
     }
 
-    fn visit_where_predicate(&mut self, where_predicate: &mut WherePredicate) {
-        walk_where_predicate(self, where_predicate)
+    fn flat_map_where_predicate(
+        &mut self,
+        where_predicate: WherePredicate,
+    ) -> SmallVec<[WherePredicate; 1]> {
+        walk_flat_map_where_predicate(self, where_predicate)
     }
 
     fn visit_where_predicate_kind(&mut self, kind: &mut WherePredicateKind) {
@@ -1097,15 +1100,20 @@ fn walk_ty_alias_where_clauses<T: MutVisitor>(vis: &mut T, tawcs: &mut TyAliasWh
 
 fn walk_where_clause<T: MutVisitor>(vis: &mut T, wc: &mut WhereClause) {
     let WhereClause { has_where_token: _, predicates, span } = wc;
-    visit_thin_vec(predicates, |predicate| vis.visit_where_predicate(predicate));
+    predicates.flat_map_in_place(|predicate| vis.flat_map_where_predicate(predicate));
     vis.visit_span(span);
 }
 
-pub fn walk_where_predicate<T: MutVisitor>(vis: &mut T, pred: &mut WherePredicate) {
-    let WherePredicate { kind, id, span } = pred;
+pub fn walk_flat_map_where_predicate<T: MutVisitor>(
+    vis: &mut T,
+    mut pred: WherePredicate,
+) -> SmallVec<[WherePredicate; 1]> {
+    let WherePredicate { attrs, kind, id, span, is_placeholder: _ } = &mut pred;
     vis.visit_id(id);
+    visit_attrs(vis, attrs);
     vis.visit_where_predicate_kind(kind);
     vis.visit_span(span);
+    smallvec![pred]
 }
 
 pub fn walk_where_predicate_kind<T: MutVisitor>(vis: &mut T, kind: &mut WherePredicateKind) {
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 6cd0e15c557..ff1edad725a 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -2,7 +2,6 @@ use std::borrow::Cow;
 use std::fmt;
 use std::sync::Arc;
 
-pub use BinOpToken::*;
 pub use LitKind::*;
 pub use Nonterminal::*;
 pub use NtExprKind::*;
@@ -26,21 +25,6 @@ pub enum CommentKind {
     Block,
 }
 
-#[derive(Clone, PartialEq, Encodable, Decodable, Hash, Debug, Copy)]
-#[derive(HashStable_Generic)]
-pub enum BinOpToken {
-    Plus,
-    Minus,
-    Star,
-    Slash,
-    Percent,
-    Caret,
-    And,
-    Or,
-    Shl,
-    Shr,
-}
-
 // This type must not implement `Hash` due to the unusual `PartialEq` impl below.
 #[derive(Copy, Clone, Debug, Encodable, Decodable, HashStable_Generic)]
 pub enum InvisibleOrigin {
@@ -376,11 +360,49 @@ pub enum TokenKind {
     /// `||`
     OrOr,
     /// `!`
-    Not,
+    Bang,
     /// `~`
     Tilde,
-    BinOp(BinOpToken),
-    BinOpEq(BinOpToken),
+    // `+`
+    Plus,
+    // `-`
+    Minus,
+    // `*`
+    Star,
+    // `/`
+    Slash,
+    // `%`
+    Percent,
+    // `^`
+    Caret,
+    // `&`
+    And,
+    // `|`
+    Or,
+    // `<<`
+    Shl,
+    // `>>`
+    Shr,
+    // `+=`
+    PlusEq,
+    // `-=`
+    MinusEq,
+    // `*=`
+    StarEq,
+    // `/=`
+    SlashEq,
+    // `%=`
+    PercentEq,
+    // `^=`
+    CaretEq,
+    // `&=`
+    AndEq,
+    // `|=`
+    OrEq,
+    // `<<=`
+    ShlEq,
+    // `>>=`
+    ShrEq,
 
     /* Structural symbols */
     /// `@`
@@ -500,31 +522,31 @@ impl TokenKind {
         Some(match (self, n) {
             (Le, 1) => (Lt, Eq),
             (EqEq, 1) => (Eq, Eq),
-            (Ne, 1) => (Not, Eq),
+            (Ne, 1) => (Bang, Eq),
             (Ge, 1) => (Gt, Eq),
-            (AndAnd, 1) => (BinOp(And), BinOp(And)),
-            (OrOr, 1) => (BinOp(Or), BinOp(Or)),
-            (BinOp(Shl), 1) => (Lt, Lt),
-            (BinOp(Shr), 1) => (Gt, Gt),
-            (BinOpEq(Plus), 1) => (BinOp(Plus), Eq),
-            (BinOpEq(Minus), 1) => (BinOp(Minus), Eq),
-            (BinOpEq(Star), 1) => (BinOp(Star), Eq),
-            (BinOpEq(Slash), 1) => (BinOp(Slash), Eq),
-            (BinOpEq(Percent), 1) => (BinOp(Percent), Eq),
-            (BinOpEq(Caret), 1) => (BinOp(Caret), Eq),
-            (BinOpEq(And), 1) => (BinOp(And), Eq),
-            (BinOpEq(Or), 1) => (BinOp(Or), Eq),
-            (BinOpEq(Shl), 1) => (Lt, Le),         // `<` + `<=`
-            (BinOpEq(Shl), 2) => (BinOp(Shl), Eq), // `<<` + `=`
-            (BinOpEq(Shr), 1) => (Gt, Ge),         // `>` + `>=`
-            (BinOpEq(Shr), 2) => (BinOp(Shr), Eq), // `>>` + `=`
+            (AndAnd, 1) => (And, And),
+            (OrOr, 1) => (Or, Or),
+            (Shl, 1) => (Lt, Lt),
+            (Shr, 1) => (Gt, Gt),
+            (PlusEq, 1) => (Plus, Eq),
+            (MinusEq, 1) => (Minus, Eq),
+            (StarEq, 1) => (Star, Eq),
+            (SlashEq, 1) => (Slash, Eq),
+            (PercentEq, 1) => (Percent, Eq),
+            (CaretEq, 1) => (Caret, Eq),
+            (AndEq, 1) => (And, Eq),
+            (OrEq, 1) => (Or, Eq),
+            (ShlEq, 1) => (Lt, Le),  // `<` + `<=`
+            (ShlEq, 2) => (Shl, Eq), // `<<` + `=`
+            (ShrEq, 1) => (Gt, Ge),  // `>` + `>=`
+            (ShrEq, 2) => (Shr, Eq), // `>>` + `=`
             (DotDot, 1) => (Dot, Dot),
             (DotDotDot, 1) => (Dot, DotDot), // `.` + `..`
             (DotDotDot, 2) => (DotDot, Dot), // `..` + `.`
             (DotDotEq, 2) => (DotDot, Eq),
             (PathSep, 1) => (Colon, Colon),
-            (RArrow, 1) => (BinOp(Minus), Gt),
-            (LArrow, 1) => (Lt, BinOp(Minus)),
+            (RArrow, 1) => (Minus, Gt),
+            (LArrow, 1) => (Lt, Minus),
             (FatArrow, 1) => (Eq, Gt),
             _ => return None,
         })
@@ -543,7 +565,7 @@ impl TokenKind {
     }
 
     pub fn should_end_const_arg(&self) -> bool {
-        matches!(self, Gt | Ge | BinOp(Shr) | BinOpEq(Shr))
+        matches!(self, Gt | Ge | Shr | ShrEq)
     }
 }
 
@@ -582,11 +604,11 @@ impl Token {
 
     pub fn is_punct(&self) -> bool {
         match self.kind {
-            Eq | Lt | Le | EqEq | Ne | Ge | Gt | AndAnd | OrOr | Not | Tilde | BinOp(_)
-            | BinOpEq(_) | At | Dot | DotDot | DotDotDot | DotDotEq | Comma | Semi | Colon
-            | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question | SingleQuote => {
-                true
-            }
+            Eq | Lt | Le | EqEq | Ne | Ge | Gt | AndAnd | OrOr | Bang | Tilde | Plus | Minus
+            | Star | Slash | Percent | Caret | And | Or | Shl | Shr | PlusEq | MinusEq | StarEq
+            | SlashEq | PercentEq | CaretEq | AndEq | OrEq | ShlEq | ShrEq | At | Dot | DotDot
+            | DotDotDot | DotDotEq | Comma | Semi | Colon | PathSep | RArrow | LArrow
+            | FatArrow | Pound | Dollar | Question | SingleQuote => true,
 
             OpenDelim(..) | CloseDelim(..) | Literal(..) | DocComment(..) | Ident(..)
             | NtIdent(..) | Lifetime(..) | NtLifetime(..) | Interpolated(..) | Eof => false,
@@ -594,7 +616,7 @@ impl Token {
     }
 
     pub fn is_like_plus(&self) -> bool {
-        matches!(self.kind, BinOp(Plus) | BinOpEq(Plus))
+        matches!(self.kind, Plus | PlusEq)
     }
 
     /// Returns `true` if the token can appear at the start of an expression.
@@ -608,15 +630,15 @@ impl Token {
                 ident_can_begin_expr(name, self.span, is_raw), // value name or keyword
             OpenDelim(Parenthesis | Brace | Bracket) | // tuple, array or block
             Literal(..)                       | // literal
-            Not                               | // operator not
-            BinOp(Minus)                      | // unary minus
-            BinOp(Star)                       | // dereference
-            BinOp(Or) | OrOr                  | // closure
-            BinOp(And)                        | // reference
+            Bang                              | // operator not
+            Minus                             | // unary minus
+            Star                              | // dereference
+            Or | OrOr                         | // closure
+            And                               | // reference
             AndAnd                            | // double reference
             // DotDotDot is no longer supported, but we need some way to display the error
             DotDot | DotDotDot | DotDotEq     | // range notation
-            Lt | BinOp(Shl)                   | // associated path
+            Lt | Shl                          | // associated path
             PathSep                           | // global path
             Lifetime(..)                      | // labeled loop
             Pound                             => true, // expression attributes
@@ -645,17 +667,16 @@ impl Token {
             Ident(..) | NtIdent(..) |
             OpenDelim(Delimiter::Parenthesis) |  // tuple pattern
             OpenDelim(Delimiter::Bracket) |      // slice pattern
-            BinOp(And) |                  // reference
-            BinOp(Minus) |                // negative literal
-            AndAnd |                      // double reference
-            Literal(_) |                  // literal
-            DotDot |                      // range pattern (future compat)
-            DotDotDot |                   // range pattern (future compat)
-            PathSep |                     // path
-            Lt |                          // path (UFCS constant)
-            BinOp(Shl) => true,           // path (double UFCS)
-            // leading vert `|` or-pattern
-            BinOp(Or) => matches!(pat_kind, PatWithOr),
+            And |                                // reference
+            Minus |                              // negative literal
+            AndAnd |                             // double reference
+            Literal(_) |                         // literal
+            DotDot |                             // range pattern (future compat)
+            DotDotDot |                          // range pattern (future compat)
+            PathSep |                            // path
+            Lt |                                 // path (UFCS constant)
+            Shl => true,                         // path (double UFCS)
+            Or => matches!(pat_kind, PatWithOr), // leading vert `|` or-pattern
             Interpolated(nt) =>
                 matches!(&**nt,
                     | NtExpr(..)
@@ -676,18 +697,18 @@ impl Token {
     /// Returns `true` if the token can appear at the start of a type.
     pub fn can_begin_type(&self) -> bool {
         match self.uninterpolate().kind {
-            Ident(name, is_raw)        =>
+            Ident(name, is_raw) =>
                 ident_can_begin_type(name, self.span, is_raw), // type name or keyword
             OpenDelim(Delimiter::Parenthesis) | // tuple
             OpenDelim(Delimiter::Bracket)     | // array
-            Not                         | // never
-            BinOp(Star)                 | // raw pointer
-            BinOp(And)                  | // reference
-            AndAnd                      | // double reference
-            Question                    | // maybe bound in trait object
-            Lifetime(..)                | // lifetime bound in trait object
-            Lt | BinOp(Shl)             | // associated path
-            PathSep                      => true, // global path
+            Bang                              | // never
+            Star                              | // raw pointer
+            And                               | // reference
+            AndAnd                            | // double reference
+            Question                          | // maybe bound in trait object
+            Lifetime(..)                      | // lifetime bound in trait object
+            Lt | Shl                          | // associated path
+            PathSep => true,                    // global path
             OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
                 MetaVarKind::Ty { .. } |
                 MetaVarKind::Path
@@ -701,7 +722,7 @@ impl Token {
     /// Returns `true` if the token can appear at the start of a const param.
     pub fn can_begin_const_arg(&self) -> bool {
         match self.kind {
-            OpenDelim(Delimiter::Brace) | Literal(..) | BinOp(Minus) => true,
+            OpenDelim(Delimiter::Brace) | Literal(..) | Minus => true,
             Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true,
             Interpolated(ref nt) => matches!(&**nt, NtExpr(..) | NtBlock(..) | NtLiteral(..)),
             OpenDelim(Delimiter::Invisible(InvisibleOrigin::MetaVar(
@@ -750,7 +771,7 @@ impl Token {
     /// Keep this in sync with and `Lit::from_token`, excluding unary negation.
     pub fn can_begin_literal_maybe_minus(&self) -> bool {
         match self.uninterpolate().kind {
-            Literal(..) | BinOp(Minus) => true,
+            Literal(..) | Minus => true,
             Ident(name, IdentIsRaw::No) if name.is_bool_lit() => true,
             Interpolated(ref nt) => match &**nt {
                 NtLiteral(_) => true,
@@ -875,7 +896,7 @@ impl Token {
     }
 
     pub fn is_qpath_start(&self) -> bool {
-        self == &Lt || self == &BinOp(Shl)
+        self == &Lt || self == &Shl
     }
 
     pub fn is_path_start(&self) -> bool {
@@ -967,59 +988,82 @@ impl Token {
     }
 
     pub fn glue(&self, joint: &Token) -> Option<Token> {
-        let kind = match self.kind {
-            Eq => match joint.kind {
-                Eq => EqEq,
-                Gt => FatArrow,
-                _ => return None,
-            },
-            Lt => match joint.kind {
-                Eq => Le,
-                Lt => BinOp(Shl),
-                Le => BinOpEq(Shl),
-                BinOp(Minus) => LArrow,
-                _ => return None,
-            },
-            Gt => match joint.kind {
-                Eq => Ge,
-                Gt => BinOp(Shr),
-                Ge => BinOpEq(Shr),
-                _ => return None,
-            },
-            Not => match joint.kind {
-                Eq => Ne,
-                _ => return None,
-            },
-            BinOp(op) => match joint.kind {
-                Eq => BinOpEq(op),
-                BinOp(And) if op == And => AndAnd,
-                BinOp(Or) if op == Or => OrOr,
-                Gt if op == Minus => RArrow,
-                _ => return None,
-            },
-            Dot => match joint.kind {
-                Dot => DotDot,
-                DotDot => DotDotDot,
-                _ => return None,
-            },
-            DotDot => match joint.kind {
-                Dot => DotDotDot,
-                Eq => DotDotEq,
-                _ => return None,
-            },
-            Colon => match joint.kind {
-                Colon => PathSep,
-                _ => return None,
-            },
-            SingleQuote => match joint.kind {
-                Ident(name, is_raw) => Lifetime(Symbol::intern(&format!("'{name}")), is_raw),
-                _ => return None,
-            },
+        let kind = match (&self.kind, &joint.kind) {
+            (Eq, Eq) => EqEq,
+            (Eq, Gt) => FatArrow,
+            (Eq, _) => return None,
+
+            (Lt, Eq) => Le,
+            (Lt, Lt) => Shl,
+            (Lt, Le) => ShlEq,
+            (Lt, Minus) => LArrow,
+            (Lt, _) => return None,
+
+            (Gt, Eq) => Ge,
+            (Gt, Gt) => Shr,
+            (Gt, Ge) => ShrEq,
+            (Gt, _) => return None,
+
+            (Bang, Eq) => Ne,
+            (Bang, _) => return None,
+
+            (Plus, Eq) => PlusEq,
+            (Plus, _) => return None,
+
+            (Minus, Eq) => MinusEq,
+            (Minus, Gt) => RArrow,
+            (Minus, _) => return None,
 
-            Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | BinOpEq(..) | At | DotDotDot
-            | DotDotEq | Comma | Semi | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar
-            | Question | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) | NtIdent(..)
-            | Lifetime(..) | NtLifetime(..) | Interpolated(..) | DocComment(..) | Eof => {
+            (Star, Eq) => StarEq,
+            (Star, _) => return None,
+
+            (Slash, Eq) => SlashEq,
+            (Slash, _) => return None,
+
+            (Percent, Eq) => PercentEq,
+            (Percent, _) => return None,
+
+            (Caret, Eq) => CaretEq,
+            (Caret, _) => return None,
+
+            (And, Eq) => AndEq,
+            (And, And) => AndAnd,
+            (And, _) => return None,
+
+            (Or, Eq) => OrEq,
+            (Or, Or) => OrOr,
+            (Or, _) => return None,
+
+            (Shl, Eq) => ShlEq,
+            (Shl, _) => return None,
+
+            (Shr, Eq) => ShrEq,
+            (Shr, _) => return None,
+
+            (Dot, Dot) => DotDot,
+            (Dot, DotDot) => DotDotDot,
+            (Dot, _) => return None,
+
+            (DotDot, Dot) => DotDotDot,
+            (DotDot, Eq) => DotDotEq,
+            (DotDot, _) => return None,
+
+            (Colon, Colon) => PathSep,
+            (Colon, _) => return None,
+
+            (SingleQuote, Ident(name, is_raw)) => {
+                Lifetime(Symbol::intern(&format!("'{name}")), *is_raw)
+            }
+            (SingleQuote, _) => return None,
+
+            (
+                Le | EqEq | Ne | Ge | AndAnd | OrOr | Tilde | PlusEq | MinusEq | StarEq | SlashEq
+                | PercentEq | CaretEq | AndEq | OrEq | ShlEq | ShrEq | At | DotDotDot | DotDotEq
+                | Comma | Semi | PathSep | RArrow | LArrow | FatArrow | Pound | Dollar | Question
+                | OpenDelim(..) | CloseDelim(..) | Literal(..) | Ident(..) | NtIdent(..)
+                | Lifetime(..) | NtLifetime(..) | Interpolated(..) | DocComment(..) | Eof,
+                _,
+            ) => {
                 return None;
             }
         };
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index 49ae8cc78fc..b9b20cf9376 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -651,7 +651,7 @@ impl TokenStream {
             if attr_style == AttrStyle::Inner {
                 vec![
                     TokenTree::token_joint(token::Pound, span),
-                    TokenTree::token_joint_hidden(token::Not, span),
+                    TokenTree::token_joint_hidden(token::Bang, span),
                     body,
                 ]
             } else {
diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs
index 69454967eed..98b1fc52ed7 100644
--- a/compiler/rustc_ast/src/util/parser.rs
+++ b/compiler/rustc_ast/src/util/parser.rs
@@ -1,7 +1,7 @@
 use rustc_span::kw;
 
 use crate::ast::{self, BinOpKind, RangeLimits};
-use crate::token::{self, BinOpToken, Token};
+use crate::token::{self, Token};
 
 /// Associative operator.
 #[derive(Copy, Clone, PartialEq, Debug)]
@@ -34,26 +34,26 @@ impl AssocOp {
         use AssocOp::*;
         match t.kind {
             token::Eq => Some(Assign),
-            token::BinOp(BinOpToken::Plus) => Some(Binary(BinOpKind::Add)),
-            token::BinOp(BinOpToken::Minus) => Some(Binary(BinOpKind::Sub)),
-            token::BinOp(BinOpToken::Star) => Some(Binary(BinOpKind::Mul)),
-            token::BinOp(BinOpToken::Slash) => Some(Binary(BinOpKind::Div)),
-            token::BinOp(BinOpToken::Percent) => Some(Binary(BinOpKind::Rem)),
-            token::BinOp(BinOpToken::Caret) => Some(Binary(BinOpKind::BitXor)),
-            token::BinOp(BinOpToken::And) => Some(Binary(BinOpKind::BitAnd)),
-            token::BinOp(BinOpToken::Or) => Some(Binary(BinOpKind::BitOr)),
-            token::BinOp(BinOpToken::Shl) => Some(Binary(BinOpKind::Shl)),
-            token::BinOp(BinOpToken::Shr) => Some(Binary(BinOpKind::Shr)),
-            token::BinOpEq(BinOpToken::Plus) => Some(AssignOp(BinOpKind::Add)),
-            token::BinOpEq(BinOpToken::Minus) => Some(AssignOp(BinOpKind::Sub)),
-            token::BinOpEq(BinOpToken::Star) => Some(AssignOp(BinOpKind::Mul)),
-            token::BinOpEq(BinOpToken::Slash) => Some(AssignOp(BinOpKind::Div)),
-            token::BinOpEq(BinOpToken::Percent) => Some(AssignOp(BinOpKind::Rem)),
-            token::BinOpEq(BinOpToken::Caret) => Some(AssignOp(BinOpKind::BitXor)),
-            token::BinOpEq(BinOpToken::And) => Some(AssignOp(BinOpKind::BitAnd)),
-            token::BinOpEq(BinOpToken::Or) => Some(AssignOp(BinOpKind::BitOr)),
-            token::BinOpEq(BinOpToken::Shl) => Some(AssignOp(BinOpKind::Shl)),
-            token::BinOpEq(BinOpToken::Shr) => Some(AssignOp(BinOpKind::Shr)),
+            token::Plus => Some(Binary(BinOpKind::Add)),
+            token::Minus => Some(Binary(BinOpKind::Sub)),
+            token::Star => Some(Binary(BinOpKind::Mul)),
+            token::Slash => Some(Binary(BinOpKind::Div)),
+            token::Percent => Some(Binary(BinOpKind::Rem)),
+            token::Caret => Some(Binary(BinOpKind::BitXor)),
+            token::And => Some(Binary(BinOpKind::BitAnd)),
+            token::Or => Some(Binary(BinOpKind::BitOr)),
+            token::Shl => Some(Binary(BinOpKind::Shl)),
+            token::Shr => Some(Binary(BinOpKind::Shr)),
+            token::PlusEq => Some(AssignOp(BinOpKind::Add)),
+            token::MinusEq => Some(AssignOp(BinOpKind::Sub)),
+            token::StarEq => Some(AssignOp(BinOpKind::Mul)),
+            token::SlashEq => Some(AssignOp(BinOpKind::Div)),
+            token::PercentEq => Some(AssignOp(BinOpKind::Rem)),
+            token::CaretEq => Some(AssignOp(BinOpKind::BitXor)),
+            token::AndEq => Some(AssignOp(BinOpKind::BitAnd)),
+            token::OrEq => Some(AssignOp(BinOpKind::BitOr)),
+            token::ShlEq => Some(AssignOp(BinOpKind::Shl)),
+            token::ShrEq => Some(AssignOp(BinOpKind::Shr)),
             token::Lt => Some(Binary(BinOpKind::Lt)),
             token::Le => Some(Binary(BinOpKind::Le)),
             token::Ge => Some(Binary(BinOpKind::Ge)),
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 1cb32b56875..37139e664f3 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -833,7 +833,8 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(
     visitor: &mut V,
     predicate: &'a WherePredicate,
 ) -> V::Result {
-    let WherePredicate { kind, id: _, span: _ } = predicate;
+    let WherePredicate { attrs, kind, id: _, span: _, is_placeholder: _ } = predicate;
+    walk_list!(visitor, visit_attribute, attrs);
     visitor.visit_where_predicate_kind(kind)
 }
 
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 9c3db7abc1c..c70fcdc84a3 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -1690,6 +1690,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
         let yielded =
             opt_expr.as_ref().map(|x| self.lower_expr(x)).unwrap_or_else(|| self.expr_unit(span));
 
+        if !self.tcx.features().yield_expr()
+            && !self.tcx.features().coroutines()
+            && !self.tcx.features().gen_blocks()
+        {
+            rustc_session::parse::feature_err(
+                &self.tcx.sess,
+                sym::yield_expr,
+                span,
+                fluent_generated::ast_lowering_yield,
+            )
+            .emit();
+        }
+
         let is_async_gen = match self.coroutine_kind {
             Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::Gen, _)) => false,
             Some(hir::CoroutineKind::Desugared(hir::CoroutineDesugaring::AsyncGen, _)) => true,
@@ -1714,28 +1727,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     None,
                 );
             }
-            Some(hir::CoroutineKind::Coroutine(_)) => {
-                if !self.tcx.features().coroutines() {
-                    rustc_session::parse::feature_err(
-                        &self.tcx.sess,
-                        sym::coroutines,
-                        span,
-                        fluent_generated::ast_lowering_yield,
-                    )
-                    .emit();
-                }
-                false
-            }
+            Some(hir::CoroutineKind::Coroutine(_)) => false,
             None => {
-                if !self.tcx.features().coroutines() {
-                    rustc_session::parse::feature_err(
-                        &self.tcx.sess,
-                        sym::coroutines,
-                        span,
-                        fluent_generated::ast_lowering_yield,
-                    )
-                    .emit();
-                }
                 let suggestion = self.current_item.map(|s| s.shrink_to_lo());
                 self.dcx().emit_err(YieldInClosure { span, suggestion });
                 self.coroutine_kind = Some(hir::CoroutineKind::Coroutine(Movability::Movable));
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index 15802101f71..5e89321e6ec 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -1728,6 +1728,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
     fn lower_where_predicate(&mut self, pred: &WherePredicate) -> hir::WherePredicate<'hir> {
         let hir_id = self.lower_node_id(pred.id);
         let span = self.lower_span(pred.span);
+        self.lower_attrs(hir_id, &pred.attrs, span);
         let kind = self.arena.alloc(match &pred.kind {
             WherePredicateKind::BoundPredicate(WhereBoundPredicate {
                 bound_generic_params,
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 13edcc10c9e..f5832068028 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -136,6 +136,7 @@ struct LoweringContext<'a, 'hir> {
 
     allow_try_trait: Arc<[Symbol]>,
     allow_gen_future: Arc<[Symbol]>,
+    allow_pattern_type: Arc<[Symbol]>,
     allow_async_iterator: Arc<[Symbol]>,
     allow_for_await: Arc<[Symbol]>,
     allow_async_fn_traits: Arc<[Symbol]>,
@@ -176,6 +177,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             impl_trait_defs: Vec::new(),
             impl_trait_bounds: Vec::new(),
             allow_try_trait: [sym::try_trait_v2, sym::yeet_desugar_details].into(),
+            allow_pattern_type: [sym::pattern_types, sym::pattern_type_range_trait].into(),
             allow_gen_future: if tcx.features().async_fn_track_caller() {
                 [sym::gen_future, sym::closure_track_caller].into()
             } else {
@@ -926,7 +928,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     if let Some(first_char) = constraint.ident.as_str().chars().next()
                         && first_char.is_ascii_lowercase()
                     {
-                        tracing::info!(?data, ?data.inputs);
                         let err = match (&data.inputs[..], &data.output) {
                             ([_, ..], FnRetTy::Default(_)) => {
                                 errors::BadReturnTypeNotation::Inputs { span: data.inputs_span }
@@ -1094,7 +1095,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                             .and_then(|partial_res| partial_res.full_res())
                         {
                             if !res.matches_ns(Namespace::TypeNS)
-                                && path.is_potential_trivial_const_arg()
+                                && path.is_potential_trivial_const_arg(false)
                             {
                                 debug!(
                                     "lower_generic_arg: Lowering type argument as const argument: {:?}",
@@ -1365,7 +1366,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 }
             }
             TyKind::Pat(ty, pat) => {
-                hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat))
+                hir::TyKind::Pat(self.lower_ty(ty, itctx), self.lower_ty_pat(pat, ty.span))
             }
             TyKind::MacCall(_) => {
                 span_bug!(t.span, "`TyKind::MacCall` should have been expanded by now")
@@ -2061,8 +2062,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     ) -> &'hir hir::ConstArg<'hir> {
         let tcx = self.tcx;
 
-        // FIXME(min_generic_const_args): we only allow one-segment const paths for now
-        let ct_kind = if path.is_potential_trivial_const_arg()
+        let ct_kind = if path
+            .is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
             && (tcx.features().min_generic_const_args()
                 || matches!(res, Res::Def(DefKind::ConstParam, _)))
         {
@@ -2072,7 +2073,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 path,
                 ParamMode::Optional,
                 AllowReturnTypeNotation::No,
-                // FIXME(min_generic_const_args): update for `fn foo() -> Bar<FOO<impl Trait>>` support
+                // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
                 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                 None,
             );
@@ -2136,19 +2137,18 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         };
         let maybe_res =
             self.resolver.get_partial_res(expr.id).and_then(|partial_res| partial_res.full_res());
-        // FIXME(min_generic_const_args): we only allow one-segment const paths for now
-        if let ExprKind::Path(None, path) = &expr.kind
-            && path.is_potential_trivial_const_arg()
+        if let ExprKind::Path(qself, path) = &expr.kind
+            && path.is_potential_trivial_const_arg(tcx.features().min_generic_const_args())
             && (tcx.features().min_generic_const_args()
                 || matches!(maybe_res, Some(Res::Def(DefKind::ConstParam, _))))
         {
             let qpath = self.lower_qpath(
                 expr.id,
-                &None,
+                qself,
                 path,
                 ParamMode::Optional,
                 AllowReturnTypeNotation::No,
-                // FIXME(min_generic_const_args): update for `fn foo() -> Bar<FOO<impl Trait>>` support
+                // FIXME(mgca): update for `fn foo() -> Bar<FOO<impl Trait>>` support
                 ImplTraitContext::Disallowed(ImplTraitPosition::Path),
                 None,
             );
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index 2dcfe7c745d..728981dea5f 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -3,11 +3,11 @@ use std::sync::Arc;
 use rustc_ast::ptr::P;
 use rustc_ast::*;
 use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_hir as hir;
-use rustc_hir::def::Res;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::{self as hir, LangItem};
 use rustc_middle::span_bug;
 use rustc_span::source_map::{Spanned, respan};
-use rustc_span::{Ident, Span};
+use rustc_span::{DesugaringKind, Ident, Span, kw};
 
 use super::errors::{
     ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding,
@@ -430,22 +430,124 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         self.arena.alloc(hir::PatExpr { hir_id: self.lower_node_id(expr.id), span, kind })
     }
 
-    pub(crate) fn lower_ty_pat(&mut self, pattern: &TyPat) -> &'hir hir::TyPat<'hir> {
-        self.arena.alloc(self.lower_ty_pat_mut(pattern))
+    pub(crate) fn lower_ty_pat(
+        &mut self,
+        pattern: &TyPat,
+        base_type: Span,
+    ) -> &'hir hir::TyPat<'hir> {
+        self.arena.alloc(self.lower_ty_pat_mut(pattern, base_type))
     }
 
-    fn lower_ty_pat_mut(&mut self, pattern: &TyPat) -> hir::TyPat<'hir> {
+    fn lower_ty_pat_mut(&mut self, pattern: &TyPat, base_type: Span) -> hir::TyPat<'hir> {
         // loop here to avoid recursion
         let pat_hir_id = self.lower_node_id(pattern.id);
         let node = match &pattern.kind {
-            TyPatKind::Range(e1, e2, Spanned { node: end, .. }) => hir::TyPatKind::Range(
-                e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
-                e2.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)),
-                self.lower_range_end(end, e2.is_some()),
+            TyPatKind::Range(e1, e2, Spanned { node: end, span }) => hir::TyPatKind::Range(
+                e1.as_deref().map(|e| self.lower_anon_const_to_const_arg(e)).unwrap_or_else(|| {
+                    self.lower_ty_pat_range_end(
+                        hir::LangItem::RangeMin,
+                        span.shrink_to_lo(),
+                        base_type,
+                    )
+                }),
+                e2.as_deref()
+                    .map(|e| match end {
+                        RangeEnd::Included(..) => self.lower_anon_const_to_const_arg(e),
+                        RangeEnd::Excluded => self.lower_excluded_range_end(e),
+                    })
+                    .unwrap_or_else(|| {
+                        self.lower_ty_pat_range_end(
+                            hir::LangItem::RangeMax,
+                            span.shrink_to_hi(),
+                            base_type,
+                        )
+                    }),
             ),
             TyPatKind::Err(guar) => hir::TyPatKind::Err(*guar),
         };
 
         hir::TyPat { hir_id: pat_hir_id, kind: node, span: self.lower_span(pattern.span) }
     }
+
+    /// Lowers the range end of an exclusive range (`2..5`) to an inclusive range 2..=(5 - 1).
+    /// This way the type system doesn't have to handle the distinction between inclusive/exclusive ranges.
+    fn lower_excluded_range_end(&mut self, e: &AnonConst) -> &'hir hir::ConstArg<'hir> {
+        let span = self.lower_span(e.value.span);
+        let unstable_span = self.mark_span_with_reason(
+            DesugaringKind::PatTyRange,
+            span,
+            Some(Arc::clone(&self.allow_pattern_type)),
+        );
+        let anon_const = self.with_new_scopes(span, |this| {
+            let def_id = this.local_def_id(e.id);
+            let hir_id = this.lower_node_id(e.id);
+            let body = this.lower_body(|this| {
+                // Need to use a custom function as we can't just subtract `1` from a `char`.
+                let kind = hir::ExprKind::Path(this.make_lang_item_qpath(
+                    hir::LangItem::RangeSub,
+                    unstable_span,
+                    None,
+                ));
+                let fn_def = this.arena.alloc(hir::Expr { hir_id: this.next_id(), kind, span });
+                let args = this.arena.alloc([this.lower_expr_mut(&e.value)]);
+                (
+                    &[],
+                    hir::Expr {
+                        hir_id: this.next_id(),
+                        kind: hir::ExprKind::Call(fn_def, args),
+                        span,
+                    },
+                )
+            });
+            hir::AnonConst { def_id, hir_id, body, span }
+        });
+        self.arena.alloc(hir::ConstArg {
+            hir_id: self.next_id(),
+            kind: hir::ConstArgKind::Anon(self.arena.alloc(anon_const)),
+        })
+    }
+
+    /// When a range has no end specified (`1..` or `1..=`) or no start specified (`..5` or `..=5`),
+    /// we instead use a constant of the MAX/MIN of the type.
+    /// This way the type system does not have to handle the lack of a start/end.
+    fn lower_ty_pat_range_end(
+        &mut self,
+        lang_item: LangItem,
+        span: Span,
+        base_type: Span,
+    ) -> &'hir hir::ConstArg<'hir> {
+        let parent_def_id = self.current_hir_id_owner.def_id;
+        let node_id = self.next_node_id();
+
+        // Add a definition for the in-band const def.
+        // We're generating a range end that didn't exist in the AST,
+        // so the def collector didn't create the def ahead of time. That's why we have to do
+        // it here.
+        let def_id = self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, span);
+        let hir_id = self.lower_node_id(node_id);
+
+        let unstable_span = self.mark_span_with_reason(
+            DesugaringKind::PatTyRange,
+            self.lower_span(span),
+            Some(Arc::clone(&self.allow_pattern_type)),
+        );
+        let span = self.lower_span(base_type);
+
+        let path_expr = hir::Expr {
+            hir_id: self.next_id(),
+            kind: hir::ExprKind::Path(self.make_lang_item_qpath(lang_item, unstable_span, None)),
+            span,
+        };
+
+        let ct = self.with_new_scopes(span, |this| {
+            self.arena.alloc(hir::AnonConst {
+                def_id,
+                hir_id,
+                body: this.lower_body(|_this| (&[], path_expr)),
+                span,
+            })
+        });
+        let hir_id = self.next_id();
+        self.arena.alloc(hir::ConstArg { kind: hir::ConstArgKind::Anon(ct), hir_id })
+    }
 }
diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs
index 6b6244b05aa..d00c797755f 100644
--- a/compiler/rustc_ast_lowering/src/path.rs
+++ b/compiler/rustc_ast_lowering/src/path.rs
@@ -268,7 +268,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 }
                 GenericArgs::Parenthesized(data) => match generic_args_mode {
                     GenericArgsMode::ReturnTypeNotation => {
-                        tracing::info!(?data, ?data.inputs);
                         let err = match (&data.inputs[..], &data.output) {
                             ([_, ..], FnRetTy::Default(_)) => {
                                 BadReturnTypeNotation::Inputs { span: data.inputs_span }
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 0f80e49320e..de11fe770c5 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -503,6 +503,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
     gate_all!(unsafe_binders, "unsafe binder types are experimental");
     gate_all!(contracts, "contracts are incomplete");
     gate_all!(contracts_internals, "contract internal machinery is for internal use only");
+    gate_all!(where_clause_attrs, "attributes in `where` clause are unstable");
 
     if !visitor.features.never_patterns() {
         if let Some(spans) = spans.get(&sym::never_patterns) {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index 44e956dc37f..01fc272a458 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -11,9 +11,7 @@ use std::sync::Arc;
 
 use rustc_ast::attr::AttrIdGenerator;
 use rustc_ast::ptr::P;
-use rustc_ast::token::{
-    self, BinOpToken, CommentKind, Delimiter, IdentIsRaw, Nonterminal, Token, TokenKind,
-};
+use rustc_ast::token::{self, CommentKind, Delimiter, IdentIsRaw, Nonterminal, Token, TokenKind};
 use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree};
 use rustc_ast::util::classify;
 use rustc_ast::util::comments::{Comment, CommentStyle};
@@ -319,7 +317,7 @@ fn space_between(tt1: &TokenTree, tt2: &TokenTree) -> bool {
         (tt1, Tok(Token { kind: Comma | Semi | Dot, .. }, _)) if !is_punct(tt1) => false,
 
         // IDENT + `!`: `println!()`, but `if !x { ... }` needs a space after the `if`
-        (Tok(Token { kind: Ident(sym, is_raw), span }, _), Tok(Token { kind: Not, .. }, _))
+        (Tok(Token { kind: Ident(sym, is_raw), span }, _), Tok(Token { kind: Bang, .. }, _))
             if !Ident::new(*sym, *span).is_reserved() || matches!(is_raw, IdentIsRaw::Yes) =>
         {
             false
@@ -344,21 +342,6 @@ fn space_between(tt1: &TokenTree, tt2: &TokenTree) -> bool {
     }
 }
 
-fn binop_to_string(op: BinOpToken) -> &'static str {
-    match op {
-        token::Plus => "+",
-        token::Minus => "-",
-        token::Star => "*",
-        token::Slash => "/",
-        token::Percent => "%",
-        token::Caret => "^",
-        token::And => "&",
-        token::Or => "|",
-        token::Shl => "<<",
-        token::Shr => ">>",
-    }
-}
-
 pub fn doc_comment_to_string(
     comment_kind: CommentKind,
     attr_style: ast::AttrStyle,
@@ -913,12 +896,30 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
             token::Ne => "!=".into(),
             token::Ge => ">=".into(),
             token::Gt => ">".into(),
-            token::Not => "!".into(),
+            token::Bang => "!".into(),
             token::Tilde => "~".into(),
             token::OrOr => "||".into(),
             token::AndAnd => "&&".into(),
-            token::BinOp(op) => binop_to_string(op).into(),
-            token::BinOpEq(op) => format!("{}=", binop_to_string(op)).into(),
+            token::Plus => "+".into(),
+            token::Minus => "-".into(),
+            token::Star => "*".into(),
+            token::Slash => "/".into(),
+            token::Percent => "%".into(),
+            token::Caret => "^".into(),
+            token::And => "&".into(),
+            token::Or => "|".into(),
+            token::Shl => "<<".into(),
+            token::Shr => ">>".into(),
+            token::PlusEq => "+=".into(),
+            token::MinusEq => "-=".into(),
+            token::StarEq => "*=".into(),
+            token::SlashEq => "/=".into(),
+            token::PercentEq => "%=".into(),
+            token::CaretEq => "^=".into(),
+            token::AndEq => "&=".into(),
+            token::OrEq => "|=".into(),
+            token::ShlEq => "<<=".into(),
+            token::ShrEq => ">>=".into(),
 
             /* Structural symbols */
             token::At => "@".into(),
@@ -1782,6 +1783,13 @@ impl<'a> State<'a> {
                 self.print_mutability(*m, false);
                 self.word("self")
             }
+            SelfKind::Pinned(lt, m) => {
+                self.word("&");
+                self.print_opt_lifetime(lt);
+                self.word("pin ");
+                self.print_mutability(*m, true);
+                self.word("self")
+            }
             SelfKind::Explicit(typ, m) => {
                 self.print_mutability(*m, false);
                 self.word("self");
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/item.rs b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
index c10b5ad34e1..ced0cbd2fef 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/item.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/item.rs
@@ -735,7 +735,8 @@ impl<'a> State<'a> {
     }
 
     pub fn print_where_predicate(&mut self, predicate: &ast::WherePredicate) {
-        let ast::WherePredicate { kind, id: _, span: _ } = predicate;
+        let ast::WherePredicate { attrs, kind, id: _, span: _, is_placeholder: _ } = predicate;
+        self.print_outer_attributes(attrs);
         match kind {
             ast::WherePredicateKind::BoundPredicate(where_bound_predicate) => {
                 self.print_where_bound_predicate(where_bound_predicate);
diff --git a/compiler/rustc_attr_parsing/src/parser.rs b/compiler/rustc_attr_parsing/src/parser.rs
index 96fc9d7d9ac..f0cce26f4e2 100644
--- a/compiler/rustc_attr_parsing/src/parser.rs
+++ b/compiler/rustc_attr_parsing/src/parser.rs
@@ -473,6 +473,15 @@ impl<'a> MetaItemListParserContext<'a> {
         {
             self.inside_delimiters.next();
             return Some(MetaItemOrLitParser::Lit(lit));
+        } else if let Some(TokenTree::Delimited(.., Delimiter::Invisible(_), inner_tokens)) =
+            self.inside_delimiters.peek()
+        {
+            self.inside_delimiters.next();
+            return MetaItemListParserContext {
+                inside_delimiters: inner_tokens.iter().peekable(),
+                dcx: self.dcx,
+            }
+            .next();
         }
 
         // or a path.
diff --git a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
index 3b48ca305c4..8dff40ba6ac 100644
--- a/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
+++ b/compiler/rustc_borrowck/src/type_check/constraint_conversion.rs
@@ -1,4 +1,4 @@
-use rustc_hir::def_id::DefId;
+use rustc_hir::def_id::LocalDefId;
 use rustc_infer::infer::canonical::QueryRegionConstraints;
 use rustc_infer::infer::outlives::env::RegionBoundPairs;
 use rustc_infer::infer::outlives::obligations::{TypeOutlives, TypeOutlivesDelegate};
@@ -88,7 +88,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
     pub(crate) fn apply_closure_requirements(
         &mut self,
         closure_requirements: &ClosureRegionRequirements<'tcx>,
-        closure_def_id: DefId,
+        closure_def_id: LocalDefId,
         closure_args: ty::GenericArgsRef<'tcx>,
     ) {
         // Extract the values of the free regions in `closure_args`
@@ -98,7 +98,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
             self.tcx,
             closure_args,
             closure_requirements.num_external_vids,
-            closure_def_id.expect_local(),
+            closure_def_id,
         );
         debug!(?closure_mapping);
 
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 6d05696e146..c1e23cb5411 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -328,9 +328,8 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
         }
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, location: Location) {
-        debug!(?constant, ?location, "visit_const_operand");
-
         self.super_const_operand(constant, location);
         let ty = constant.const_.ty();
 
@@ -339,14 +338,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
             self.typeck.constraints.liveness_constraints.add_location(live_region_vid, location);
         });
 
-        // HACK(compiler-errors): Constants that are gathered into Body.required_consts
-        // have their locations erased...
-        let locations = if location != Location::START {
-            location.to_locations()
-        } else {
-            Locations::All(constant.span)
-        };
-
+        let locations = location.to_locations();
         if let Some(annotation_index) = constant.user_ty {
             if let Err(terr) = self.typeck.relate_type_and_user_type(
                 constant.const_.ty(),
@@ -491,9 +483,28 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for TypeVerifier<'a, 'b, 'tcx> {
         }
     }
 
+    #[instrument(level = "debug", skip(self))]
     fn visit_body(&mut self, body: &Body<'tcx>) {
-        // The types of local_decls are checked above which is called in super_body.
-        self.super_body(body);
+        // We intentionally do not recurse into `body.required_consts` or
+        // `body.mentioned_items` here as the MIR at this phase should still
+        // refer to all items and we don't want to check them multiple times.
+
+        for (local, local_decl) in body.local_decls.iter_enumerated() {
+            self.visit_local_decl(local, local_decl);
+        }
+
+        for (block, block_data) in body.basic_blocks.iter_enumerated() {
+            let mut location = Location { block, statement_index: 0 };
+            for stmt in &block_data.statements {
+                if !stmt.source_info.span.is_dummy() {
+                    self.last_span = stmt.source_info.span;
+                }
+                self.visit_statement(stmt, location);
+                location.statement_index += 1;
+            }
+
+            self.visit_terminator(block_data.terminator(), location);
+        }
     }
 }
 
@@ -2120,8 +2131,8 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                                 //
                                 // Note that other checks (such as denying `dyn Send` -> `dyn
                                 // Debug`) are in `rustc_hir_typeck`.
-                                if let ty::Dynamic(src_tty, _src_lt, _) = *src_tail.kind()
-                                    && let ty::Dynamic(dst_tty, dst_lt, _) = *dst_tail.kind()
+                                if let ty::Dynamic(src_tty, _src_lt, ty::Dyn) = *src_tail.kind()
+                                    && let ty::Dynamic(dst_tty, dst_lt, ty::Dyn) = *dst_tail.kind()
                                     && src_tty.principal().is_some()
                                     && dst_tty.principal().is_some()
                                 {
@@ -2582,7 +2593,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 ConstraintCategory::Boring, // same as above.
                 self.constraints,
             )
-            .apply_closure_requirements(closure_requirements, def_id.to_def_id(), args);
+            .apply_closure_requirements(closure_requirements, def_id, args);
         }
 
         // Now equate closure args to regions inherited from `typeck_root_def_id`. Fixes #98589.
diff --git a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
index 5aed9f76f14..46b79e09780 100644
--- a/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/coerce_pointee.rs
@@ -300,13 +300,16 @@ pub(crate) fn expand_deriving_coerce_pointee(
                 to_ty: &s_ty,
                 rewritten: false,
             };
-            let mut predicate = ast::WherePredicate {
-                kind: ast::WherePredicateKind::BoundPredicate(bound.clone()),
-                span: predicate.span,
-                id: ast::DUMMY_NODE_ID,
-            };
-            substitution.visit_where_predicate(&mut predicate);
+            let mut kind = ast::WherePredicateKind::BoundPredicate(bound.clone());
+            substitution.visit_where_predicate_kind(&mut kind);
             if substitution.rewritten {
+                let predicate = ast::WherePredicate {
+                    attrs: predicate.attrs.clone(),
+                    kind,
+                    span: predicate.span,
+                    id: ast::DUMMY_NODE_ID,
+                    is_placeholder: false,
+                };
                 impl_generics.where_clause.predicates.push(predicate);
             }
         }
@@ -388,8 +391,8 @@ impl<'a> ast::mut_visit::MutVisitor for TypeSubstitution<'a> {
         }
     }
 
-    fn visit_where_predicate(&mut self, where_predicate: &mut ast::WherePredicate) {
-        match &mut where_predicate.kind {
+    fn visit_where_predicate_kind(&mut self, kind: &mut ast::WherePredicateKind) {
+        match kind {
             rustc_ast::WherePredicateKind::BoundPredicate(bound) => {
                 bound
                     .bound_generic_params
diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
index 6b59ac25827..5402b5a1ae9 100644
--- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs
@@ -687,9 +687,11 @@ impl<'a> TraitDef<'a> {
         // and similarly for where clauses
         where_clause.predicates.extend(generics.where_clause.predicates.iter().map(|clause| {
             ast::WherePredicate {
+                attrs: clause.attrs.clone(),
                 kind: clause.kind.clone(),
                 id: ast::DUMMY_NODE_ID,
                 span: clause.span.with_ctxt(ctxt),
+                is_placeholder: false,
             }
         }));
 
@@ -744,8 +746,13 @@ impl<'a> TraitDef<'a> {
                         };
 
                         let kind = ast::WherePredicateKind::BoundPredicate(predicate);
-                        let predicate =
-                            ast::WherePredicate { kind, id: ast::DUMMY_NODE_ID, span: self.span };
+                        let predicate = ast::WherePredicate {
+                            attrs: ThinVec::new(),
+                            kind,
+                            id: ast::DUMMY_NODE_ID,
+                            span: self.span,
+                            is_placeholder: false,
+                        };
                         where_clause.predicates.push(predicate);
                     }
                 }
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 90447da6680..6dbd8a7ac01 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -190,7 +190,8 @@ fn make_format_args(
                                 && let [stmt] = block.stmts.as_slice()
                                 && let StmtKind::Expr(expr) = &stmt.kind
                                 && let ExprKind::Path(None, path) = &expr.kind
-                                && path.is_potential_trivial_const_arg()
+                                && path.segments.len() == 1
+                                && path.segments[0].args.is_none()
                             {
                                 err.multipart_suggestion(
                                     "quote your inlined format argument to use as string literal",
diff --git a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
index bedc6ca11b3..c2027863b00 100644
--- a/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
+++ b/compiler/rustc_codegen_cranelift/patches/0029-stdlib-Disable-f16-and-f128-in-compiler-builtins.patch
@@ -16,8 +16,8 @@ index 7165c3e48af..968552ad435 100644
  
  [dependencies]
  core = { path = "../core", public = true }
--compiler_builtins = { version = "=0.1.148", features = ['rustc-dep-of-std'] }
-+compiler_builtins = { version = "=0.1.148", features = ['rustc-dep-of-std', 'no-f16-f128'] }
+-compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std'] }
++compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std', 'no-f16-f128'] }
  
  [dev-dependencies]
  rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs
index 20a3482aaa2..628e34badf9 100644
--- a/compiler/rustc_codegen_gcc/src/common.rs
+++ b/compiler/rustc_codegen_gcc/src/common.rs
@@ -64,11 +64,6 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         if type_is_pointer(typ) { self.context.new_null(typ) } else { self.const_int(typ, 0) }
     }
 
-    fn is_undef(&self, _val: RValue<'gcc>) -> bool {
-        // FIXME: actually check for undef
-        false
-    }
-
     fn const_undef(&self, typ: Type<'gcc>) -> RValue<'gcc> {
         let local = self.current_func.borrow().expect("func").new_local(None, typ, "undefined");
         if typ.is_struct().is_some() {
@@ -146,13 +141,12 @@ impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
     }
 
     fn const_str(&self, s: &str) -> (RValue<'gcc>, RValue<'gcc>) {
-        let str_global = *self
-            .const_str_cache
-            .borrow_mut()
-            .raw_entry_mut()
-            .from_key(s)
-            .or_insert_with(|| (s.to_owned(), self.global_string(s)))
-            .1;
+        let mut const_str_cache = self.const_str_cache.borrow_mut();
+        let str_global = const_str_cache.get(s).copied().unwrap_or_else(|| {
+            let g = self.global_string(s);
+            const_str_cache.insert(s.to_owned(), g);
+            g
+        });
         let len = s.len();
         let cs = self.const_ptrcast(
             str_global.get_address(None),
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index 9d91aab72ab..f090597f953 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -16,7 +16,7 @@
 #![allow(internal_features)]
 #![doc(rust_logo)]
 #![feature(rustdoc_internals)]
-#![feature(rustc_private, decl_macro, never_type, trusted_len, hash_raw_entry, let_chains)]
+#![feature(rustc_private, decl_macro, never_type, trusted_len, let_chains)]
 #![allow(broken_intra_doc_links)]
 #![recursion_limit = "256"]
 #![warn(rust_2018_idioms)]
diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index 0621b893e75..f264e3419e4 100644
--- a/compiler/rustc_codegen_llvm/src/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
@@ -127,10 +127,6 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         unsafe { llvm::LLVMGetUndef(t) }
     }
 
-    fn is_undef(&self, v: &'ll Value) -> bool {
-        unsafe { llvm::LLVMIsUndef(v) == True }
-    }
-
     fn const_poison(&self, t: &'ll Type) -> &'ll Value {
         unsafe { llvm::LLVMGetPoison(t) }
     }
@@ -209,28 +205,24 @@ impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     }
 
     fn const_str(&self, s: &str) -> (&'ll Value, &'ll Value) {
-        let str_global = *self
-            .const_str_cache
-            .borrow_mut()
-            .raw_entry_mut()
-            .from_key(s)
-            .or_insert_with(|| {
-                let sc = self.const_bytes(s.as_bytes());
-                let sym = self.generate_local_symbol_name("str");
-                let g = self.define_global(&sym, self.val_ty(sc)).unwrap_or_else(|| {
-                    bug!("symbol `{}` is already defined", sym);
-                });
-                llvm::set_initializer(g, sc);
-                unsafe {
-                    llvm::LLVMSetGlobalConstant(g, True);
-                    llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global);
-                }
-                llvm::set_linkage(g, llvm::Linkage::InternalLinkage);
-                // Cast to default address space if globals are in a different addrspace
-                let g = self.const_pointercast(g, self.type_ptr());
-                (s.to_owned(), g)
-            })
-            .1;
+        let mut const_str_cache = self.const_str_cache.borrow_mut();
+        let str_global = const_str_cache.get(s).copied().unwrap_or_else(|| {
+            let sc = self.const_bytes(s.as_bytes());
+            let sym = self.generate_local_symbol_name("str");
+            let g = self.define_global(&sym, self.val_ty(sc)).unwrap_or_else(|| {
+                bug!("symbol `{}` is already defined", sym);
+            });
+            llvm::set_initializer(g, sc);
+            unsafe {
+                llvm::LLVMSetGlobalConstant(g, True);
+                llvm::LLVMSetUnnamedAddress(g, llvm::UnnamedAddr::Global);
+            }
+            llvm::set_linkage(g, llvm::Linkage::InternalLinkage);
+            // Cast to default address space if globals are in a different addrspace
+            let g = self.const_pointercast(g, self.type_ptr());
+            const_str_cache.insert(s.to_owned(), g);
+            g
+        });
         let len = s.len();
         (str_global, self.const_usize(len as u64))
     }
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index c88372db491..8f72307eeba 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -12,7 +12,6 @@
 #![feature(exact_size_is_empty)]
 #![feature(extern_types)]
 #![feature(file_buffered)]
-#![feature(hash_raw_entry)]
 #![feature(if_let_guard)]
 #![feature(impl_trait_in_assoc_type)]
 #![feature(iter_intersperse)]
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 2dc14e4613d..e3d0b928c97 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -1046,7 +1046,6 @@ unsafe extern "C" {
     pub(crate) fn LLVMMetadataTypeInContext(C: &Context) -> &Type;
 
     // Operations on all values
-    pub(crate) fn LLVMIsUndef(Val: &Value) -> Bool;
     pub(crate) fn LLVMTypeOf(Val: &Value) -> &Type;
     pub(crate) fn LLVMGetValueName2(Val: &Value, Length: *mut size_t) -> *const c_char;
     pub(crate) fn LLVMSetValueName2(Val: &Value, Name: *const c_char, NameLen: size_t);
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 5054ae561c0..a170b2e3b6a 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1,3 +1,5 @@
+mod raw_dylib;
+
 use std::collections::BTreeSet;
 use std::ffi::OsString;
 use std::fs::{File, OpenOptions, read};
@@ -12,7 +14,7 @@ use itertools::Itertools;
 use regex::Regex;
 use rustc_arena::TypedArena;
 use rustc_ast::CRATE_NODE_ID;
-use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
+use rustc_data_structures::fx::FxIndexSet;
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::temp_dir::MaybeTempDir;
 use rustc_errors::{DiagCtxtHandle, LintDiagnostic};
@@ -30,7 +32,6 @@ use rustc_session::config::{
     self, CFGuard, CrateType, DebugInfo, LinkerFeaturesCli, OutFileName, OutputFilenames,
     OutputType, PrintKind, SplitDwarfKind, Strip,
 };
-use rustc_session::cstore::DllImport;
 use rustc_session::lint::builtin::LINKER_MESSAGES;
 use rustc_session::output::{check_file_is_writeable, invalid_output_for_target, out_filename};
 use rustc_session::search_paths::PathKind;
@@ -41,22 +42,21 @@ use rustc_session::{Session, filesearch};
 use rustc_span::Symbol;
 use rustc_target::spec::crt_objects::CrtObjects;
 use rustc_target::spec::{
-    Cc, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault, LinkerFeatures,
-    LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy, RelocModel, RelroLevel, SanitizerSet,
-    SplitDebuginfo,
+    BinaryFormat, Cc, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault,
+    LinkerFeatures, LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy, RelocModel, RelroLevel,
+    SanitizerSet, SplitDebuginfo,
 };
 use tempfile::Builder as TempFileBuilder;
 use tracing::{debug, info, warn};
 
-use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder, ImportLibraryItem};
+use super::archive::{ArchiveBuilder, ArchiveBuilderBuilder};
 use super::command::Command;
 use super::linker::{self, Linker};
 use super::metadata::{MetadataPosition, create_wrapper_file};
 use super::rpath::{self, RPathConfig};
 use super::{apple, versioned_llvm_target};
 use crate::{
-    CodegenResults, CompiledModule, CrateInfo, NativeLib, common, errors,
-    looks_like_rust_object_file,
+    CodegenResults, CompiledModule, CrateInfo, NativeLib, errors, looks_like_rust_object_file,
 };
 
 pub fn ensure_removed(dcx: DiagCtxtHandle<'_>, path: &Path) {
@@ -376,16 +376,22 @@ fn link_rlib<'a>(
         }
     }
 
-    for output_path in create_dll_import_libs(
-        sess,
-        archive_builder_builder,
-        codegen_results.crate_info.used_libraries.iter(),
-        tmpdir.as_ref(),
-        true,
-    ) {
-        ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|error| {
-            sess.dcx().emit_fatal(errors::AddNativeLibrary { library_path: output_path, error });
-        });
+    // On Windows, we add the raw-dylib import libraries to the rlibs already.
+    // But on ELF, this is not possible, as a shared object cannot be a member of a static library.
+    // Instead, we add all raw-dylibs to the final link on ELF.
+    if sess.target.is_like_windows {
+        for output_path in raw_dylib::create_raw_dylib_dll_import_libs(
+            sess,
+            archive_builder_builder,
+            codegen_results.crate_info.used_libraries.iter(),
+            tmpdir.as_ref(),
+            true,
+        ) {
+            ab.add_archive(&output_path, Box::new(|_| false)).unwrap_or_else(|error| {
+                sess.dcx()
+                    .emit_fatal(errors::AddNativeLibrary { library_path: output_path, error });
+            });
+        }
     }
 
     if let Some(trailing_metadata) = trailing_metadata {
@@ -426,108 +432,6 @@ fn link_rlib<'a>(
     ab
 }
 
-/// Extract all symbols defined in raw-dylib libraries, collated by library name.
-///
-/// If we have multiple extern blocks that specify symbols defined in the same raw-dylib library,
-/// then the CodegenResults value contains one NativeLib instance for each block. However, the
-/// linker appears to expect only a single import library for each library used, so we need to
-/// collate the symbols together by library name before generating the import libraries.
-fn collate_raw_dylibs<'a>(
-    sess: &Session,
-    used_libraries: impl IntoIterator<Item = &'a NativeLib>,
-) -> Vec<(String, Vec<DllImport>)> {
-    // Use index maps to preserve original order of imports and libraries.
-    let mut dylib_table = FxIndexMap::<String, FxIndexMap<Symbol, &DllImport>>::default();
-
-    for lib in used_libraries {
-        if lib.kind == NativeLibKind::RawDylib {
-            let ext = if lib.verbatim { "" } else { ".dll" };
-            let name = format!("{}{}", lib.name, ext);
-            let imports = dylib_table.entry(name.clone()).or_default();
-            for import in &lib.dll_imports {
-                if let Some(old_import) = imports.insert(import.name, import) {
-                    // FIXME: when we add support for ordinals, figure out if we need to do anything
-                    // if we have two DllImport values with the same name but different ordinals.
-                    if import.calling_convention != old_import.calling_convention {
-                        sess.dcx().emit_err(errors::MultipleExternalFuncDecl {
-                            span: import.span,
-                            function: import.name,
-                            library_name: &name,
-                        });
-                    }
-                }
-            }
-        }
-    }
-    sess.dcx().abort_if_errors();
-    dylib_table
-        .into_iter()
-        .map(|(name, imports)| {
-            (name, imports.into_iter().map(|(_, import)| import.clone()).collect())
-        })
-        .collect()
-}
-
-fn create_dll_import_libs<'a>(
-    sess: &Session,
-    archive_builder_builder: &dyn ArchiveBuilderBuilder,
-    used_libraries: impl IntoIterator<Item = &'a NativeLib>,
-    tmpdir: &Path,
-    is_direct_dependency: bool,
-) -> Vec<PathBuf> {
-    collate_raw_dylibs(sess, used_libraries)
-        .into_iter()
-        .map(|(raw_dylib_name, raw_dylib_imports)| {
-            let name_suffix = if is_direct_dependency { "_imports" } else { "_imports_indirect" };
-            let output_path = tmpdir.join(format!("{raw_dylib_name}{name_suffix}.lib"));
-
-            let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(&sess.target);
-
-            let items: Vec<ImportLibraryItem> = raw_dylib_imports
-                .iter()
-                .map(|import: &DllImport| {
-                    if sess.target.arch == "x86" {
-                        ImportLibraryItem {
-                            name: common::i686_decorated_name(
-                                import,
-                                mingw_gnu_toolchain,
-                                false,
-                                false,
-                            ),
-                            ordinal: import.ordinal(),
-                            symbol_name: import.is_missing_decorations().then(|| {
-                                common::i686_decorated_name(
-                                    import,
-                                    mingw_gnu_toolchain,
-                                    false,
-                                    true,
-                                )
-                            }),
-                            is_data: !import.is_fn,
-                        }
-                    } else {
-                        ImportLibraryItem {
-                            name: import.name.to_string(),
-                            ordinal: import.ordinal(),
-                            symbol_name: None,
-                            is_data: !import.is_fn,
-                        }
-                    }
-                })
-                .collect();
-
-            archive_builder_builder.create_dll_import_lib(
-                sess,
-                &raw_dylib_name,
-                items,
-                &output_path,
-            );
-
-            output_path
-        })
-        .collect()
-}
-
 /// Create a static archive.
 ///
 /// This is essentially the same thing as an rlib, but it also involves adding all of the upstream
@@ -2422,15 +2326,39 @@ fn linker_with_args(
         link_output_kind,
     );
 
+    // Raw-dylibs from all crates.
+    let raw_dylib_dir = tmpdir.join("raw-dylibs");
+    if sess.target.binary_format == BinaryFormat::Elf {
+        // On ELF we can't pass the raw-dylibs stubs to the linker as a path,
+        // instead we need to pass them via -l. To find the stub, we need to add
+        // the directory of the stub to the linker search path.
+        // We make an extra directory for this to avoid polluting the search path.
+        if let Err(error) = fs::create_dir(&raw_dylib_dir) {
+            sess.dcx().emit_fatal(errors::CreateTempDir { error })
+        }
+        cmd.include_path(&raw_dylib_dir);
+    }
+
     // Link with the import library generated for any raw-dylib functions.
-    for output_path in create_dll_import_libs(
-        sess,
-        archive_builder_builder,
-        codegen_results.crate_info.used_libraries.iter(),
-        tmpdir,
-        true,
-    ) {
-        cmd.add_object(&output_path);
+    if sess.target.is_like_windows {
+        for output_path in raw_dylib::create_raw_dylib_dll_import_libs(
+            sess,
+            archive_builder_builder,
+            codegen_results.crate_info.used_libraries.iter(),
+            tmpdir,
+            true,
+        ) {
+            cmd.add_object(&output_path);
+        }
+    } else {
+        for link_path in raw_dylib::create_raw_dylib_elf_stub_shared_objects(
+            sess,
+            codegen_results.crate_info.used_libraries.iter(),
+            &raw_dylib_dir,
+        ) {
+            // Always use verbatim linkage, see comments in create_raw_dylib_elf_stub_shared_objects.
+            cmd.link_dylib_by_name(&link_path, true, false);
+        }
     }
     // As with add_upstream_native_libraries, we need to add the upstream raw-dylib symbols in case
     // they are used within inlined functions or instantiated generic functions. We do this *after*
@@ -2449,19 +2377,35 @@ fn linker_with_args(
         .native_libraries
         .iter()
         .filter_map(|(&cnum, libraries)| {
-            (dependency_linkage[cnum] != Linkage::Static).then_some(libraries)
+            if sess.target.is_like_windows {
+                (dependency_linkage[cnum] != Linkage::Static).then_some(libraries)
+            } else {
+                Some(libraries)
+            }
         })
         .flatten()
         .collect::<Vec<_>>();
     native_libraries_from_nonstatics.sort_unstable_by(|a, b| a.name.as_str().cmp(b.name.as_str()));
-    for output_path in create_dll_import_libs(
-        sess,
-        archive_builder_builder,
-        native_libraries_from_nonstatics,
-        tmpdir,
-        false,
-    ) {
-        cmd.add_object(&output_path);
+
+    if sess.target.is_like_windows {
+        for output_path in raw_dylib::create_raw_dylib_dll_import_libs(
+            sess,
+            archive_builder_builder,
+            native_libraries_from_nonstatics,
+            tmpdir,
+            false,
+        ) {
+            cmd.add_object(&output_path);
+        }
+    } else {
+        for link_path in raw_dylib::create_raw_dylib_elf_stub_shared_objects(
+            sess,
+            native_libraries_from_nonstatics,
+            &raw_dylib_dir,
+        ) {
+            // Always use verbatim linkage, see comments in create_raw_dylib_elf_stub_shared_objects.
+            cmd.link_dylib_by_name(&link_path, true, false);
+        }
     }
 
     // Library linking above uses some global state for things like `-Bstatic`/`-Bdynamic` to make
diff --git a/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
new file mode 100644
index 00000000000..2c24378afe1
--- /dev/null
+++ b/compiler/rustc_codegen_ssa/src/back/link/raw_dylib.rs
@@ -0,0 +1,373 @@
+use std::fs;
+use std::io::{BufWriter, Write};
+use std::path::{Path, PathBuf};
+
+use rustc_abi::Endian;
+use rustc_data_structures::base_n::{CASE_INSENSITIVE, ToBaseN};
+use rustc_data_structures::fx::FxIndexMap;
+use rustc_data_structures::stable_hasher::StableHasher;
+use rustc_hashes::Hash128;
+use rustc_session::Session;
+use rustc_session::cstore::DllImport;
+use rustc_session::utils::NativeLibKind;
+use rustc_span::Symbol;
+
+use crate::back::archive::ImportLibraryItem;
+use crate::back::link::ArchiveBuilderBuilder;
+use crate::errors::ErrorCreatingImportLibrary;
+use crate::{NativeLib, common, errors};
+
+/// Extract all symbols defined in raw-dylib libraries, collated by library name.
+///
+/// If we have multiple extern blocks that specify symbols defined in the same raw-dylib library,
+/// then the CodegenResults value contains one NativeLib instance for each block. However, the
+/// linker appears to expect only a single import library for each library used, so we need to
+/// collate the symbols together by library name before generating the import libraries.
+fn collate_raw_dylibs_windows<'a>(
+    sess: &Session,
+    used_libraries: impl IntoIterator<Item = &'a NativeLib>,
+) -> Vec<(String, Vec<DllImport>)> {
+    // Use index maps to preserve original order of imports and libraries.
+    let mut dylib_table = FxIndexMap::<String, FxIndexMap<Symbol, &DllImport>>::default();
+
+    for lib in used_libraries {
+        if lib.kind == NativeLibKind::RawDylib {
+            let ext = if lib.verbatim { "" } else { ".dll" };
+            let name = format!("{}{}", lib.name, ext);
+            let imports = dylib_table.entry(name.clone()).or_default();
+            for import in &lib.dll_imports {
+                if let Some(old_import) = imports.insert(import.name, import) {
+                    // FIXME: when we add support for ordinals, figure out if we need to do anything
+                    // if we have two DllImport values with the same name but different ordinals.
+                    if import.calling_convention != old_import.calling_convention {
+                        sess.dcx().emit_err(errors::MultipleExternalFuncDecl {
+                            span: import.span,
+                            function: import.name,
+                            library_name: &name,
+                        });
+                    }
+                }
+            }
+        }
+    }
+    sess.dcx().abort_if_errors();
+    dylib_table
+        .into_iter()
+        .map(|(name, imports)| {
+            (name, imports.into_iter().map(|(_, import)| import.clone()).collect())
+        })
+        .collect()
+}
+
+pub(super) fn create_raw_dylib_dll_import_libs<'a>(
+    sess: &Session,
+    archive_builder_builder: &dyn ArchiveBuilderBuilder,
+    used_libraries: impl IntoIterator<Item = &'a NativeLib>,
+    tmpdir: &Path,
+    is_direct_dependency: bool,
+) -> Vec<PathBuf> {
+    collate_raw_dylibs_windows(sess, used_libraries)
+        .into_iter()
+        .map(|(raw_dylib_name, raw_dylib_imports)| {
+            let name_suffix = if is_direct_dependency { "_imports" } else { "_imports_indirect" };
+            let output_path = tmpdir.join(format!("{raw_dylib_name}{name_suffix}.lib"));
+
+            let mingw_gnu_toolchain = common::is_mingw_gnu_toolchain(&sess.target);
+
+            let items: Vec<ImportLibraryItem> = raw_dylib_imports
+                .iter()
+                .map(|import: &DllImport| {
+                    if sess.target.arch == "x86" {
+                        ImportLibraryItem {
+                            name: common::i686_decorated_name(
+                                import,
+                                mingw_gnu_toolchain,
+                                false,
+                                false,
+                            ),
+                            ordinal: import.ordinal(),
+                            symbol_name: import.is_missing_decorations().then(|| {
+                                common::i686_decorated_name(
+                                    import,
+                                    mingw_gnu_toolchain,
+                                    false,
+                                    true,
+                                )
+                            }),
+                            is_data: !import.is_fn,
+                        }
+                    } else {
+                        ImportLibraryItem {
+                            name: import.name.to_string(),
+                            ordinal: import.ordinal(),
+                            symbol_name: None,
+                            is_data: !import.is_fn,
+                        }
+                    }
+                })
+                .collect();
+
+            archive_builder_builder.create_dll_import_lib(
+                sess,
+                &raw_dylib_name,
+                items,
+                &output_path,
+            );
+
+            output_path
+        })
+        .collect()
+}
+
+/// Extract all symbols defined in raw-dylib libraries, collated by library name.
+///
+/// If we have multiple extern blocks that specify symbols defined in the same raw-dylib library,
+/// then the CodegenResults value contains one NativeLib instance for each block. However, the
+/// linker appears to expect only a single import library for each library used, so we need to
+/// collate the symbols together by library name before generating the import libraries.
+fn collate_raw_dylibs_elf<'a>(
+    sess: &Session,
+    used_libraries: impl IntoIterator<Item = &'a NativeLib>,
+) -> Vec<(String, Vec<DllImport>)> {
+    // Use index maps to preserve original order of imports and libraries.
+    let mut dylib_table = FxIndexMap::<String, FxIndexMap<Symbol, &DllImport>>::default();
+
+    for lib in used_libraries {
+        if lib.kind == NativeLibKind::RawDylib {
+            let filename = if lib.verbatim {
+                lib.name.as_str().to_owned()
+            } else {
+                let ext = sess.target.dll_suffix.as_ref();
+                let prefix = sess.target.dll_prefix.as_ref();
+                format!("{prefix}{}{ext}", lib.name)
+            };
+
+            let imports = dylib_table.entry(filename.clone()).or_default();
+            for import in &lib.dll_imports {
+                imports.insert(import.name, import);
+            }
+        }
+    }
+    sess.dcx().abort_if_errors();
+    dylib_table
+        .into_iter()
+        .map(|(name, imports)| {
+            (name, imports.into_iter().map(|(_, import)| import.clone()).collect())
+        })
+        .collect()
+}
+
+pub(super) fn create_raw_dylib_elf_stub_shared_objects<'a>(
+    sess: &Session,
+    used_libraries: impl IntoIterator<Item = &'a NativeLib>,
+    raw_dylib_so_dir: &Path,
+) -> Vec<String> {
+    collate_raw_dylibs_elf(sess, used_libraries)
+        .into_iter()
+        .map(|(load_filename, raw_dylib_imports)| {
+            use std::hash::Hash;
+
+            // `load_filename` is the *target/loader* filename that will end up in NEEDED.
+            // Usually this will be something like `libc.so` or `libc.so.6` but with
+            // verbatim it might also be an absolute path.
+            // To be able to support this properly, we always put this load filename
+            // into the SONAME of the library and link it via a temporary file with a random name.
+            // This also avoids naming conflicts with non-raw-dylib linkage of the same library.
+
+            let shared_object = create_elf_raw_dylib_stub(sess, &load_filename, &raw_dylib_imports);
+
+            let mut file_name_hasher = StableHasher::new();
+            load_filename.hash(&mut file_name_hasher);
+            for raw_dylib in raw_dylib_imports {
+                raw_dylib.name.as_str().hash(&mut file_name_hasher);
+            }
+
+            let library_filename: Hash128 = file_name_hasher.finish();
+            let temporary_lib_name = format!(
+                "{}{}{}",
+                sess.target.dll_prefix,
+                library_filename.as_u128().to_base_fixed_len(CASE_INSENSITIVE),
+                sess.target.dll_suffix
+            );
+            let link_path = raw_dylib_so_dir.join(&temporary_lib_name);
+
+            let file = match fs::File::create_new(&link_path) {
+                Ok(file) => file,
+                Err(error) => sess.dcx().emit_fatal(ErrorCreatingImportLibrary {
+                    lib_name: &load_filename,
+                    error: error.to_string(),
+                }),
+            };
+            if let Err(error) = BufWriter::new(file).write_all(&shared_object) {
+                sess.dcx().emit_fatal(ErrorCreatingImportLibrary {
+                    lib_name: &load_filename,
+                    error: error.to_string(),
+                });
+            };
+
+            temporary_lib_name
+        })
+        .collect()
+}
+
+/// Create an ELF .so stub file for raw-dylib.
+/// It exports all the provided symbols, but is otherwise empty.
+fn create_elf_raw_dylib_stub(sess: &Session, soname: &str, symbols: &[DllImport]) -> Vec<u8> {
+    use object::write::elf as write;
+    use object::{Architecture, elf};
+
+    let mut stub_buf = Vec::new();
+
+    // Build the stub ELF using the object crate.
+    // The high-level portable API does not allow for the fine-grained control we need,
+    // so this uses the low-level object::write::elf API.
+    // The low-level API consists of two stages: reservation and writing.
+    // We first reserve space for all the things in the binary and then write them.
+    // It is important that the order of reservation matches the order of writing.
+    // The object crate contains many debug asserts that fire if you get this wrong.
+
+    let endianness = match sess.target.options.endian {
+        Endian::Little => object::Endianness::Little,
+        Endian::Big => object::Endianness::Big,
+    };
+    let mut stub = write::Writer::new(endianness, true, &mut stub_buf);
+
+    // These initial reservations don't reserve any bytes in the binary yet,
+    // they just allocate in the internal data structures.
+
+    // First, we crate the dynamic symbol table. It starts with a null symbol
+    // and then all the symbols and their dynamic strings.
+    stub.reserve_null_dynamic_symbol_index();
+
+    let dynstrs = symbols
+        .iter()
+        .map(|sym| {
+            stub.reserve_dynamic_symbol_index();
+            (sym, stub.add_dynamic_string(sym.name.as_str().as_bytes()))
+        })
+        .collect::<Vec<_>>();
+
+    let soname = stub.add_dynamic_string(soname.as_bytes());
+
+    // Reserve the sections.
+    // We have the minimal sections for a dynamic SO and .text where we point our dummy symbols to.
+    stub.reserve_shstrtab_section_index();
+    let text_section_name = stub.add_section_name(".text".as_bytes());
+    let text_section = stub.reserve_section_index();
+    stub.reserve_dynstr_section_index();
+    stub.reserve_dynsym_section_index();
+    stub.reserve_dynamic_section_index();
+
+    // These reservations now determine the actual layout order of the object file.
+    stub.reserve_file_header();
+    stub.reserve_shstrtab();
+    stub.reserve_section_headers();
+    stub.reserve_dynstr();
+    stub.reserve_dynsym();
+    stub.reserve_dynamic(2); // DT_SONAME, DT_NULL
+
+    // First write the ELF header with the arch information.
+    let Some((arch, sub_arch)) = sess.target.object_architecture(&sess.unstable_target_features)
+    else {
+        sess.dcx().fatal(format!(
+            "raw-dylib is not supported for the architecture `{}`",
+            sess.target.arch
+        ));
+    };
+    let e_machine = match (arch, sub_arch) {
+        (Architecture::Aarch64, None) => elf::EM_AARCH64,
+        (Architecture::Aarch64_Ilp32, None) => elf::EM_AARCH64,
+        (Architecture::Arm, None) => elf::EM_ARM,
+        (Architecture::Avr, None) => elf::EM_AVR,
+        (Architecture::Bpf, None) => elf::EM_BPF,
+        (Architecture::Csky, None) => elf::EM_CSKY,
+        (Architecture::E2K32, None) => elf::EM_MCST_ELBRUS,
+        (Architecture::E2K64, None) => elf::EM_MCST_ELBRUS,
+        (Architecture::I386, None) => elf::EM_386,
+        (Architecture::X86_64, None) => elf::EM_X86_64,
+        (Architecture::X86_64_X32, None) => elf::EM_X86_64,
+        (Architecture::Hexagon, None) => elf::EM_HEXAGON,
+        (Architecture::LoongArch64, None) => elf::EM_LOONGARCH,
+        (Architecture::M68k, None) => elf::EM_68K,
+        (Architecture::Mips, None) => elf::EM_MIPS,
+        (Architecture::Mips64, None) => elf::EM_MIPS,
+        (Architecture::Mips64_N32, None) => elf::EM_MIPS,
+        (Architecture::Msp430, None) => elf::EM_MSP430,
+        (Architecture::PowerPc, None) => elf::EM_PPC,
+        (Architecture::PowerPc64, None) => elf::EM_PPC64,
+        (Architecture::Riscv32, None) => elf::EM_RISCV,
+        (Architecture::Riscv64, None) => elf::EM_RISCV,
+        (Architecture::S390x, None) => elf::EM_S390,
+        (Architecture::Sbf, None) => elf::EM_SBF,
+        (Architecture::Sharc, None) => elf::EM_SHARC,
+        (Architecture::Sparc, None) => elf::EM_SPARC,
+        (Architecture::Sparc32Plus, None) => elf::EM_SPARC32PLUS,
+        (Architecture::Sparc64, None) => elf::EM_SPARCV9,
+        (Architecture::Xtensa, None) => elf::EM_XTENSA,
+        _ => {
+            sess.dcx().fatal(format!(
+                "raw-dylib is not supported for the architecture `{}`",
+                sess.target.arch
+            ));
+        }
+    };
+
+    stub.write_file_header(&write::FileHeader {
+        os_abi: crate::back::metadata::elf_os_abi(sess),
+        abi_version: 0,
+        e_type: object::elf::ET_DYN,
+        e_machine,
+        e_entry: 0,
+        e_flags: crate::back::metadata::elf_e_flags(arch, sess),
+    })
+    .unwrap();
+
+    // .shstrtab
+    stub.write_shstrtab();
+
+    // Section headers
+    stub.write_null_section_header();
+    stub.write_shstrtab_section_header();
+    // Create a dummy .text section for our dummy symbols.
+    stub.write_section_header(&write::SectionHeader {
+        name: Some(text_section_name),
+        sh_type: elf::SHT_PROGBITS,
+        sh_flags: 0,
+        sh_addr: 0,
+        sh_offset: 0,
+        sh_size: 0,
+        sh_link: 0,
+        sh_info: 0,
+        sh_addralign: 1,
+        sh_entsize: 0,
+    });
+    stub.write_dynstr_section_header(0);
+    stub.write_dynsym_section_header(0, 1);
+    stub.write_dynamic_section_header(0);
+
+    // .dynstr
+    stub.write_dynstr();
+
+    // .dynsym
+    stub.write_null_dynamic_symbol();
+    for (_, name) in dynstrs {
+        stub.write_dynamic_symbol(&write::Sym {
+            name: Some(name),
+            st_info: (elf::STB_GLOBAL << 4) | elf::STT_NOTYPE,
+            st_other: elf::STV_DEFAULT,
+            section: Some(text_section),
+            st_shndx: 0, // ignored by object in favor of the `section` field
+            st_value: 0,
+            st_size: 0,
+        });
+    }
+
+    // .dynamic
+    // the DT_SONAME will be used by the linker to populate DT_NEEDED
+    // which the loader uses to find the library.
+    // DT_NULL terminates the .dynamic table.
+    stub.write_dynamic_string(elf::DT_SONAME, soname);
+    stub.write_dynamic(elf::DT_NULL, 0);
+
+    stub_buf
+}
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 3aacbcde1a7..68b453ff424 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -9,8 +9,7 @@ use itertools::Itertools;
 use object::write::{self, StandardSegment, Symbol, SymbolSection};
 use object::{
     Architecture, BinaryFormat, Endianness, FileFlags, Object, ObjectSection, ObjectSymbol,
-    SectionFlags, SectionKind, SubArchitecture, SymbolFlags, SymbolKind, SymbolScope, elf, pe,
-    xcoff,
+    SectionFlags, SectionKind, SymbolFlags, SymbolKind, SymbolScope, elf, pe, xcoff,
 };
 use rustc_abi::Endian;
 use rustc_data_structures::memmap::Mmap;
@@ -206,51 +205,10 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
         Endian::Little => Endianness::Little,
         Endian::Big => Endianness::Big,
     };
-    let (architecture, sub_architecture) = match &sess.target.arch[..] {
-        "arm" => (Architecture::Arm, None),
-        "aarch64" => (
-            if sess.target.pointer_width == 32 {
-                Architecture::Aarch64_Ilp32
-            } else {
-                Architecture::Aarch64
-            },
-            None,
-        ),
-        "x86" => (Architecture::I386, None),
-        "s390x" => (Architecture::S390x, None),
-        "mips" | "mips32r6" => (Architecture::Mips, None),
-        "mips64" | "mips64r6" => (Architecture::Mips64, None),
-        "x86_64" => (
-            if sess.target.pointer_width == 32 {
-                Architecture::X86_64_X32
-            } else {
-                Architecture::X86_64
-            },
-            None,
-        ),
-        "powerpc" => (Architecture::PowerPc, None),
-        "powerpc64" => (Architecture::PowerPc64, None),
-        "riscv32" => (Architecture::Riscv32, None),
-        "riscv64" => (Architecture::Riscv64, None),
-        "sparc" => {
-            if sess.unstable_target_features.contains(&sym::v8plus) {
-                // Target uses V8+, aka EM_SPARC32PLUS, aka 64-bit V9 but in 32-bit mode
-                (Architecture::Sparc32Plus, None)
-            } else {
-                // Target uses V7 or V8, aka EM_SPARC
-                (Architecture::Sparc, None)
-            }
-        }
-        "sparc64" => (Architecture::Sparc64, None),
-        "avr" => (Architecture::Avr, None),
-        "msp430" => (Architecture::Msp430, None),
-        "hexagon" => (Architecture::Hexagon, None),
-        "bpf" => (Architecture::Bpf, None),
-        "loongarch64" => (Architecture::LoongArch64, None),
-        "csky" => (Architecture::Csky, None),
-        "arm64ec" => (Architecture::Aarch64, Some(SubArchitecture::Arm64EC)),
-        // Unsupported architecture.
-        _ => return None,
+    let Some((architecture, sub_architecture)) =
+        sess.target.object_architecture(&sess.unstable_target_features)
+    else {
+        return None;
     };
     let binary_format = sess.target.binary_format.to_object();
 
@@ -292,7 +250,26 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
 
         file.set_mangling(original_mangling);
     }
-    let e_flags = match architecture {
+    let e_flags = elf_e_flags(architecture, sess);
+    // adapted from LLVM's `MCELFObjectTargetWriter::getOSABI`
+    let os_abi = elf_os_abi(sess);
+    let abi_version = 0;
+    add_gnu_property_note(&mut file, architecture, binary_format, endianness);
+    file.flags = FileFlags::Elf { os_abi, abi_version, e_flags };
+    Some(file)
+}
+
+pub(super) fn elf_os_abi(sess: &Session) -> u8 {
+    match sess.target.options.os.as_ref() {
+        "hermit" => elf::ELFOSABI_STANDALONE,
+        "freebsd" => elf::ELFOSABI_FREEBSD,
+        "solaris" => elf::ELFOSABI_SOLARIS,
+        _ => elf::ELFOSABI_NONE,
+    }
+}
+
+pub(super) fn elf_e_flags(architecture: Architecture, sess: &Session) -> u32 {
+    match architecture {
         Architecture::Mips => {
             let arch = match sess.target.options.cpu.as_ref() {
                 "mips1" => elf::EF_MIPS_ARCH_1,
@@ -387,18 +364,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
             e_flags
         }
         _ => 0,
-    };
-    // adapted from LLVM's `MCELFObjectTargetWriter::getOSABI`
-    let os_abi = match sess.target.options.os.as_ref() {
-        "hermit" => elf::ELFOSABI_STANDALONE,
-        "freebsd" => elf::ELFOSABI_FREEBSD,
-        "solaris" => elf::ELFOSABI_SOLARIS,
-        _ => elf::ELFOSABI_NONE,
-    };
-    let abi_version = 0;
-    add_gnu_property_note(&mut file, architecture, binary_format, endianness);
-    file.flags = FileFlags::Elf { os_abi, abi_version, e_flags };
-    Some(file)
+    }
 }
 
 /// Mach-O files contain information about:
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 4b33bdeadba..acae09b2c25 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -203,30 +203,14 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
         let alloc_align = alloc.inner().align;
         assert!(alloc_align >= layout.align.abi);
 
-        // Returns `None` when the value is partially undefined or any byte of it has provenance.
-        // Otherwise returns the value or (if the entire value is undef) returns an undef.
         let read_scalar = |start, size, s: abi::Scalar, ty| {
-            let range = alloc_range(start, size);
             match alloc.0.read_scalar(
                 bx,
-                range,
+                alloc_range(start, size),
                 /*read_provenance*/ matches!(s.primitive(), abi::Primitive::Pointer(_)),
             ) {
-                Ok(val) => Some(bx.scalar_to_backend(val, s, ty)),
-                Err(_) => {
-                    // We may have failed due to partial provenance or unexpected provenance,
-                    // continue down the normal code path if so.
-                    if alloc.0.provenance().range_empty(range, &bx.tcx())
-                        // Since `read_scalar` failed, but there were no relocations involved, the
-                        // bytes must be partially or fully uninitialized. Thus we can now unwrap the
-                        // information about the range of uninit bytes and check if it's the full range.
-                        && alloc.0.init_mask().is_range_initialized(range).unwrap_err() == range
-                    {
-                        Some(bx.const_undef(ty))
-                    } else {
-                        None
-                    }
-                }
+                Ok(val) => bx.scalar_to_backend(val, s, ty),
+                Err(_) => bx.const_poison(ty),
             }
         };
 
@@ -237,14 +221,16 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
         // check that walks over the type of `mplace` to make sure it is truly correct to treat this
         // like a `Scalar` (or `ScalarPair`).
         match layout.backend_repr {
-            BackendRepr::Scalar(s) => {
+            BackendRepr::Scalar(s @ abi::Scalar::Initialized { .. }) => {
                 let size = s.size(bx);
                 assert_eq!(size, layout.size, "abi::Scalar size does not match layout size");
-                if let Some(val) = read_scalar(offset, size, s, bx.immediate_backend_type(layout)) {
-                    return OperandRef { val: OperandValue::Immediate(val), layout };
-                }
+                let val = read_scalar(offset, size, s, bx.immediate_backend_type(layout));
+                OperandRef { val: OperandValue::Immediate(val), layout }
             }
-            BackendRepr::ScalarPair(a, b) => {
+            BackendRepr::ScalarPair(
+                a @ abi::Scalar::Initialized { .. },
+                b @ abi::Scalar::Initialized { .. },
+            ) => {
                 let (a_size, b_size) = (a.size(bx), b.size(bx));
                 let b_offset = (offset + a_size).align_to(b.align(bx).abi);
                 assert!(b_offset.bytes() > 0);
@@ -260,21 +246,20 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
                     b,
                     bx.scalar_pair_element_backend_type(layout, 1, true),
                 );
-                if let (Some(a_val), Some(b_val)) = (a_val, b_val) {
-                    return OperandRef { val: OperandValue::Pair(a_val, b_val), layout };
-                }
+                OperandRef { val: OperandValue::Pair(a_val, b_val), layout }
+            }
+            _ if layout.is_zst() => OperandRef::zero_sized(layout),
+            _ => {
+                // Neither a scalar nor scalar pair. Load from a place
+                // FIXME: should we cache `const_data_from_alloc` to avoid repeating this for the
+                // same `ConstAllocation`?
+                let init = bx.const_data_from_alloc(alloc);
+                let base_addr = bx.static_addr_of(init, alloc_align, None);
+
+                let llval = bx.const_ptr_byte_offset(base_addr, offset);
+                bx.load_operand(PlaceRef::new_sized(llval, layout))
             }
-            _ if layout.is_zst() => return OperandRef::zero_sized(layout),
-            _ => {}
         }
-        // Neither a scalar nor scalar pair. Load from a place
-        // FIXME: should we cache `const_data_from_alloc` to avoid repeating this for the
-        // same `ConstAllocation`?
-        let init = bx.const_data_from_alloc(alloc);
-        let base_addr = bx.static_addr_of(init, alloc_align, None);
-
-        let llval = bx.const_ptr_byte_offset(base_addr, offset);
-        bx.load_operand(PlaceRef::new_sized(llval, layout))
     }
 
     /// Asserts that this operand refers to a scalar and returns
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 67555d40332..ff555f4273c 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -8,7 +8,7 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
 use rustc_middle::{bug, mir, span_bug};
 use rustc_session::config::OptLevel;
 use rustc_span::{DUMMY_SP, Span};
-use tracing::{debug, instrument, trace};
+use tracing::{debug, instrument};
 
 use super::operand::{OperandRef, OperandValue};
 use super::place::PlaceRef;
@@ -93,8 +93,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     return;
                 }
 
-                // If `v` is an integer constant whose value is just a single byte repeated N times,
-                // emit a `memset` filling the entire `dest` with that byte.
                 let try_init_all_same = |bx: &mut Bx, v| {
                     let start = dest.val.llval;
                     let size = bx.const_usize(dest.layout.size.bytes());
@@ -119,33 +117,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     false
                 };
 
-                trace!(?cg_elem.val);
                 match cg_elem.val {
                     OperandValue::Immediate(v) => {
                         if try_init_all_same(bx, v) {
                             return;
                         }
                     }
-                    OperandValue::Pair(a, b) => {
-                        let a_is_undef = bx.cx().is_undef(a);
-                        match (a_is_undef, bx.cx().is_undef(b)) {
-                            // Can happen for uninit unions
-                            (true, true) => {
-                                // FIXME: can we produce better output here?
-                            }
-                            (false, true) | (true, false) => {
-                                let val = if a_is_undef { b } else { a };
-                                if try_init_all_same(bx, val) {
-                                    return;
-                                }
-                            }
-                            (false, false) => {
-                                // FIXME: if both are the same value, use try_init_all_same
-                            }
-                        }
-                    }
-                    OperandValue::ZeroSized => unreachable!("checked above"),
-                    OperandValue::Ref(..) => {}
+                    _ => (),
                 }
 
                 let count = self
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index d8b9bdb55da..95a5e96fe46 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -10,7 +10,7 @@ use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::parse::feature_err;
 use rustc_span::{Span, Symbol, sym};
-use rustc_target::target_features;
+use rustc_target::target_features::{self, Stability};
 
 use crate::errors;
 
@@ -87,12 +87,17 @@ pub(crate) fn from_target_feature_attr(
                     // But ensure the ABI does not forbid enabling this.
                     // Here we do assume that LLVM doesn't add even more implied features
                     // we don't know about, at least no features that would have ABI effects!
-                    if abi_feature_constraints.incompatible.contains(&name.as_str()) {
-                        tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
-                            span: item.span(),
-                            feature: name.as_str(),
-                            reason: "this feature is incompatible with the target ABI",
-                        });
+                    // We skip this logic in rustdoc, where we want to allow all target features of
+                    // all targets, so we can't check their ABI compatibility and anyway we are not
+                    // generating code so "it's fine".
+                    if !tcx.sess.opts.actually_rustdoc {
+                        if abi_feature_constraints.incompatible.contains(&name.as_str()) {
+                            tcx.dcx().emit_err(errors::ForbiddenTargetFeatureAttr {
+                                span: item.span(),
+                                feature: name.as_str(),
+                                reason: "this feature is incompatible with the target ABI",
+                            });
+                        }
                     }
                     target_features.push(TargetFeature { name, implied: name != feature_sym })
                 }
@@ -142,11 +147,38 @@ pub(crate) fn provide(providers: &mut Providers) {
         rust_target_features: |tcx, cnum| {
             assert_eq!(cnum, LOCAL_CRATE);
             if tcx.sess.opts.actually_rustdoc {
-                // rustdoc needs to be able to document functions that use all the features, so
-                // whitelist them all
-                rustc_target::target_features::all_rust_features()
-                    .map(|(a, b)| (a.to_string(), b))
-                    .collect()
+                // HACK: rustdoc would like to pretend that we have all the target features, so we
+                // have to merge all the lists into one. To ensure an unstable target never prevents
+                // a stable one from working, we merge the stability info of all instances of the
+                // same target feature name, with the "most stable" taking precedence. And then we
+                // hope that this doesn't cause issues anywhere else in the compiler...
+                let mut result: UnordMap<String, Stability> = Default::default();
+                for (name, stability) in rustc_target::target_features::all_rust_features() {
+                    use std::collections::hash_map::Entry;
+                    match result.entry(name.to_owned()) {
+                        Entry::Vacant(vacant_entry) => {
+                            vacant_entry.insert(stability);
+                        }
+                        Entry::Occupied(mut occupied_entry) => {
+                            // Merge the two stabilities, "more stable" taking precedence.
+                            match (occupied_entry.get(), stability) {
+                                (Stability::Stable, _)
+                                | (
+                                    Stability::Unstable { .. },
+                                    Stability::Unstable { .. } | Stability::Forbidden { .. },
+                                )
+                                | (Stability::Forbidden { .. }, Stability::Forbidden { .. }) => {
+                                    // The stability in the entry is at least as good as the new one, just keep it.
+                                }
+                                _ => {
+                                    // Overwrite stabilite.
+                                    occupied_entry.insert(stability);
+                                }
+                            }
+                        }
+                    }
+                }
+                result
             } else {
                 tcx.sess
                     .target
diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs
index 5cfb56ebace..dc6b68ceff7 100644
--- a/compiler/rustc_codegen_ssa/src/traits/consts.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs
@@ -9,7 +9,6 @@ pub trait ConstCodegenMethods<'tcx>: BackendTypes {
     /// Generate an uninitialized value (matching uninitialized memory in MIR).
     /// Whether memory is initialized or not is tracked byte-for-byte.
     fn const_undef(&self, t: Self::Type) -> Self::Value;
-    fn is_undef(&self, v: Self::Value) -> bool;
     /// Generate a fake value. Poison always affects the entire value, even if just a single byte is
     /// poison. This can only be used in codepaths that are already UB, i.e., UB-free Rust code
     /// (including code that e.g. copies uninit memory with `MaybeUninit`) can never encounter a
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 4f4b6785844..ce0b5a350e0 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -955,18 +955,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
 
     /// Handle the effect an FFI call might have on the state of allocations.
     /// This overapproximates the modifications which external code might make to memory:
-    /// We set all reachable allocations as initialized, mark all provenances as exposed
+    /// We set all reachable allocations as initialized, mark all reachable provenances as exposed
     /// and overwrite them with `Provenance::WILDCARD`.
-    pub fn prepare_for_native_call(
-        &mut self,
-        id: AllocId,
-        initial_prov: M::Provenance,
-    ) -> InterpResult<'tcx> {
-        // Expose provenance of the root allocation.
-        M::expose_provenance(self, initial_prov)?;
-
+    ///
+    /// The allocations in `ids` are assumed to be already exposed.
+    pub fn prepare_for_native_call(&mut self, ids: Vec<AllocId>) -> InterpResult<'tcx> {
         let mut done = FxHashSet::default();
-        let mut todo = vec![id];
+        let mut todo = ids;
         while let Some(id) = todo.pop() {
             if !done.insert(id) {
                 // We already saw this allocation before, don't process it again.
diff --git a/compiler/rustc_data_structures/src/captures.rs b/compiler/rustc_data_structures/src/captures.rs
deleted file mode 100644
index 677ccb31454..00000000000
--- a/compiler/rustc_data_structures/src/captures.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-/// "Signaling" trait used in impl trait to tag lifetimes that you may
-/// need to capture but don't really need for other reasons.
-/// Basically a workaround; see [this comment] for details.
-///
-/// [this comment]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999
-pub trait Captures<'a> {}
-
-impl<'a, T: ?Sized> Captures<'a> for T {}
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 66d3834d857..a3b62b46919 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -48,7 +48,6 @@ pub use rustc_index::static_assert_size;
 pub mod aligned;
 pub mod base_n;
 pub mod binary_search_util;
-pub mod captures;
 pub mod fingerprint;
 pub mod flat_map_in_place;
 pub mod flock;
diff --git a/compiler/rustc_data_structures/src/marker.rs b/compiler/rustc_data_structures/src/marker.rs
index 6ae97222f77..4cacc269709 100644
--- a/compiler/rustc_data_structures/src/marker.rs
+++ b/compiler/rustc_data_structures/src/marker.rs
@@ -1,3 +1,5 @@
+use std::alloc::Allocator;
+
 #[rustc_on_unimplemented(message = "`{Self}` doesn't implement `DynSend`. \
             Add it to `rustc_data_structures::marker` or use `IntoDynSyncSend` if it's already `Send`")]
 // This is an auto trait for types which can be sent across threads if `sync::is_dyn_thread_safe()`
@@ -28,8 +30,8 @@ impls_dyn_send_neg!(
     [*const T where T: ?Sized]
     [*mut T where T: ?Sized]
     [std::ptr::NonNull<T> where T: ?Sized]
-    [std::rc::Rc<T> where T: ?Sized]
-    [std::rc::Weak<T> where T: ?Sized]
+    [std::rc::Rc<T, A> where T: ?Sized, A: Allocator]
+    [std::rc::Weak<T, A> where T: ?Sized, A: Allocator]
     [std::sync::MutexGuard<'_, T> where T: ?Sized]
     [std::sync::RwLockReadGuard<'_, T> where T: ?Sized]
     [std::sync::RwLockWriteGuard<'_, T> where T: ?Sized]
@@ -96,8 +98,8 @@ impls_dyn_sync_neg!(
     [std::cell::RefCell<T> where T: ?Sized]
     [std::cell::UnsafeCell<T> where T: ?Sized]
     [std::ptr::NonNull<T> where T: ?Sized]
-    [std::rc::Rc<T> where T: ?Sized]
-    [std::rc::Weak<T> where T: ?Sized]
+    [std::rc::Rc<T, A> where T: ?Sized, A: Allocator]
+    [std::rc::Weak<T, A> where T: ?Sized, A: Allocator]
     [std::cell::OnceCell<T> where T]
     [std::sync::mpsc::Receiver<T> where T]
     [std::sync::mpsc::Sender<T> where T]
diff --git a/compiler/rustc_data_structures/src/sharded.rs b/compiler/rustc_data_structures/src/sharded.rs
index 5a53f8af5f8..e6be9c256f0 100644
--- a/compiler/rustc_data_structures/src/sharded.rs
+++ b/compiler/rustc_data_structures/src/sharded.rs
@@ -43,10 +43,10 @@ impl<T> Sharded<T> {
 
     /// The shard is selected by hashing `val` with `FxHasher`.
     #[inline]
-    pub fn get_shard_by_value<K: Hash + ?Sized>(&self, _val: &K) -> &Lock<T> {
+    pub fn get_shard_by_value<K: Hash + ?Sized>(&self, val: &K) -> &Lock<T> {
         match self {
             Self::Single(single) => single,
-            Self::Shards(..) => self.get_shard_by_hash(make_hash(_val)),
+            Self::Shards(..) => self.get_shard_by_hash(make_hash(val)),
         }
     }
 
@@ -56,12 +56,12 @@ impl<T> Sharded<T> {
     }
 
     #[inline]
-    pub fn get_shard_by_index(&self, _i: usize) -> &Lock<T> {
+    pub fn get_shard_by_index(&self, i: usize) -> &Lock<T> {
         match self {
             Self::Single(single) => single,
             Self::Shards(shards) => {
                 // SAFETY: The index gets ANDed with the shard mask, ensuring it is always inbounds.
-                unsafe { &shards.get_unchecked(_i & (SHARDS - 1)).0 }
+                unsafe { &shards.get_unchecked(i & (SHARDS - 1)).0 }
             }
         }
     }
@@ -69,7 +69,7 @@ impl<T> Sharded<T> {
     /// The shard is selected by hashing `val` with `FxHasher`.
     #[inline]
     #[track_caller]
-    pub fn lock_shard_by_value<K: Hash + ?Sized>(&self, _val: &K) -> LockGuard<'_, T> {
+    pub fn lock_shard_by_value<K: Hash + ?Sized>(&self, val: &K) -> LockGuard<'_, T> {
         match self {
             Self::Single(single) => {
                 // Synchronization is disabled so use the `lock_assume_no_sync` method optimized
@@ -79,7 +79,7 @@ impl<T> Sharded<T> {
                 // `might_be_dyn_thread_safe` was also false.
                 unsafe { single.lock_assume(Mode::NoSync) }
             }
-            Self::Shards(..) => self.lock_shard_by_hash(make_hash(_val)),
+            Self::Shards(..) => self.lock_shard_by_hash(make_hash(val)),
         }
     }
 
@@ -91,7 +91,7 @@ impl<T> Sharded<T> {
 
     #[inline]
     #[track_caller]
-    pub fn lock_shard_by_index(&self, _i: usize) -> LockGuard<'_, T> {
+    pub fn lock_shard_by_index(&self, i: usize) -> LockGuard<'_, T> {
         match self {
             Self::Single(single) => {
                 // Synchronization is disabled so use the `lock_assume_no_sync` method optimized
@@ -109,7 +109,7 @@ impl<T> Sharded<T> {
                 // always inbounds.
                 // SAFETY (lock_assume_sync): We know `is_dyn_thread_safe` was true when creating
                 // the lock thus `might_be_dyn_thread_safe` was also true.
-                unsafe { shards.get_unchecked(_i & (SHARDS - 1)).0.lock_assume(Mode::Sync) }
+                unsafe { shards.get_unchecked(i & (SHARDS - 1)).0.lock_assume(Mode::Sync) }
             }
         }
     }
diff --git a/compiler/rustc_data_structures/src/sync.rs b/compiler/rustc_data_structures/src/sync.rs
index 37b54fe38ff..a1cc75c4985 100644
--- a/compiler/rustc_data_structures/src/sync.rs
+++ b/compiler/rustc_data_structures/src/sync.rs
@@ -18,42 +18,54 @@
 //!
 //! | Type                    | Serial version      | Parallel version                |
 //! | ----------------------- | ------------------- | ------------------------------- |
-//! | `LRef<'a, T>` [^2]      | `&'a mut T`         | `&'a T`                         |
-//! |                         |                     |                                 |
 //! | `Lock<T>`               | `RefCell<T>`        | `RefCell<T>` or                 |
 //! |                         |                     | `parking_lot::Mutex<T>`         |
 //! | `RwLock<T>`             | `RefCell<T>`        | `parking_lot::RwLock<T>`        |
 //! | `MTLock<T>`        [^1] | `T`                 | `Lock<T>`                       |
-//! | `MTLockRef<'a, T>` [^2] | `&'a mut MTLock<T>` | `&'a MTLock<T>`                 |
 //! |                         |                     |                                 |
 //! | `ParallelIterator`      | `Iterator`          | `rayon::iter::ParallelIterator` |
 //!
 //! [^1]: `MTLock` is similar to `Lock`, but the serial version avoids the cost
 //! of a `RefCell`. This is appropriate when interior mutability is not
 //! required.
-//!
-//! [^2]: `MTRef`, `MTLockRef` are type aliases.
 
 use std::collections::HashMap;
 use std::hash::{BuildHasher, Hash};
 
-pub use crate::marker::*;
+pub use parking_lot::{
+    MappedRwLockReadGuard as MappedReadGuard, MappedRwLockWriteGuard as MappedWriteGuard,
+    RwLockReadGuard as ReadGuard, RwLockWriteGuard as WriteGuard,
+};
 
-mod lock;
+pub use self::atomic::AtomicU64;
+pub use self::freeze::{FreezeLock, FreezeReadGuard, FreezeWriteGuard};
 #[doc(no_inline)]
-pub use lock::{Lock, LockGuard, Mode};
-
-mod worker_local;
-pub use worker_local::{Registry, WorkerLocal};
+pub use self::lock::{Lock, LockGuard, Mode};
+pub use self::mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode};
+pub use self::parallel::{
+    join, par_for_each_in, par_map, parallel_guard, scope, try_par_for_each_in,
+};
+pub use self::vec::{AppendOnlyIndexVec, AppendOnlyVec};
+pub use self::worker_local::{Registry, WorkerLocal};
+pub use crate::marker::*;
 
+mod freeze;
+mod lock;
 mod parallel;
-pub use parallel::{join, par_for_each_in, par_map, parallel_guard, scope, try_par_for_each_in};
-pub use vec::{AppendOnlyIndexVec, AppendOnlyVec};
-
 mod vec;
+mod worker_local;
 
-mod freeze;
-pub use freeze::{FreezeLock, FreezeReadGuard, FreezeWriteGuard};
+/// Keep the conditional imports together in a submodule, so that import-sorting
+/// doesn't split them up.
+mod atomic {
+    // Most hosts can just use a regular AtomicU64.
+    #[cfg(target_has_atomic = "64")]
+    pub use std::sync::atomic::AtomicU64;
+
+    // Some 32-bit hosts don't have AtomicU64, so use a fallback.
+    #[cfg(not(target_has_atomic = "64"))]
+    pub use portable_atomic::AtomicU64;
+}
 
 mod mode {
     use std::sync::atomic::{AtomicU8, Ordering};
@@ -97,21 +109,6 @@ mod mode {
 
 // FIXME(parallel_compiler): Get rid of these aliases across the compiler.
 
-pub use std::sync::OnceLock;
-// Use portable AtomicU64 for targets without native 64-bit atomics
-#[cfg(target_has_atomic = "64")]
-pub use std::sync::atomic::AtomicU64;
-
-pub use mode::{is_dyn_thread_safe, set_dyn_thread_safe_mode};
-pub use parking_lot::{
-    MappedRwLockReadGuard as MappedReadGuard, MappedRwLockWriteGuard as MappedWriteGuard,
-    RwLockReadGuard as ReadGuard, RwLockWriteGuard as WriteGuard,
-};
-#[cfg(not(target_has_atomic = "64"))]
-pub use portable_atomic::AtomicU64;
-
-pub type LRef<'a, T> = &'a T;
-
 #[derive(Debug, Default)]
 pub struct MTLock<T>(Lock<T>);
 
@@ -142,14 +139,10 @@ impl<T> MTLock<T> {
     }
 }
 
-use parking_lot::RwLock as InnerRwLock;
-
 /// This makes locks panic if they are already held.
 /// It is only useful when you are running in a single thread
 const ERROR_CHECKING: bool = false;
 
-pub type MTLockRef<'a, T> = LRef<'a, MTLock<T>>;
-
 #[derive(Default)]
 #[repr(align(64))]
 pub struct CacheAligned<T>(pub T);
@@ -167,12 +160,12 @@ impl<K: Eq + Hash, V: Eq, S: BuildHasher> HashMapExt<K, V> for HashMap<K, V, S>
 }
 
 #[derive(Debug, Default)]
-pub struct RwLock<T>(InnerRwLock<T>);
+pub struct RwLock<T>(parking_lot::RwLock<T>);
 
 impl<T> RwLock<T> {
     #[inline(always)]
     pub fn new(inner: T) -> Self {
-        RwLock(InnerRwLock::new(inner))
+        RwLock(parking_lot::RwLock::new(inner))
     }
 
     #[inline(always)]
diff --git a/compiler/rustc_data_structures/src/sync/worker_local.rs b/compiler/rustc_data_structures/src/sync/worker_local.rs
index 402ec9827bb..d75af009850 100644
--- a/compiler/rustc_data_structures/src/sync/worker_local.rs
+++ b/compiler/rustc_data_structures/src/sync/worker_local.rs
@@ -106,6 +106,12 @@ pub struct WorkerLocal<T> {
     registry: Registry,
 }
 
+// This is safe because the `deref` call will return a reference to a `T` unique to each thread
+// or it will panic for threads without an associated local. So there isn't a need for `T` to do
+// it's own synchronization. The `verify` method on `RegistryId` has an issue where the id
+// can be reused, but `WorkerLocal` has a reference to `Registry` which will prevent any reuse.
+unsafe impl<T: Send> Sync for WorkerLocal<T> {}
+
 impl<T> WorkerLocal<T> {
     /// Creates a new worker local where the `initial` closure computes the
     /// value this worker local should take for each thread in the registry.
@@ -132,11 +138,6 @@ impl<T> Deref for WorkerLocal<T> {
     fn deref(&self) -> &T {
         // This is safe because `verify` will only return values less than
         // `self.registry.thread_limit` which is the size of the `self.locals` array.
-
-        // The `deref` call will return a reference to a `T` unique to each thread
-        // or it will panic for threads without an associated local. So there isn't a need for `T` to do
-        // it's own synchronization. The `verify` method on `RegistryId` has an issue where the id
-        // can be reused, but `WorkerLocal` has a reference to `Registry` which will prevent any reuse.
         unsafe { &self.locals.get_unchecked(self.registry.id().verify()).0 }
     }
 }
diff --git a/compiler/rustc_error_codes/src/error_codes/E0373.md b/compiler/rustc_error_codes/src/error_codes/E0373.md
index d4d26007aa5..b9db8072597 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0373.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0373.md
@@ -3,7 +3,7 @@ A captured variable in a closure may not live long enough.
 Erroneous code example:
 
 ```compile_fail,E0373
-fn foo() -> Box<Fn(u32) -> u32> {
+fn foo() -> Box<dyn Fn(u32) -> u32> {
     let x = 0u32;
     Box::new(|y| x + y)
 }
@@ -42,7 +42,7 @@ This approach moves (or copies, where possible) data into the closure, rather
 than taking references to it. For example:
 
 ```
-fn foo() -> Box<Fn(u32) -> u32> {
+fn foo() -> Box<dyn Fn(u32) -> u32> {
     let x = 0u32;
     Box::new(move |y| x + y)
 }
diff --git a/compiler/rustc_error_codes/src/error_codes/E0804.md b/compiler/rustc_error_codes/src/error_codes/E0804.md
new file mode 100644
index 00000000000..9a6937c0b52
--- /dev/null
+++ b/compiler/rustc_error_codes/src/error_codes/E0804.md
@@ -0,0 +1,41 @@
+An auto trait cannot be added to the bounds of a `dyn Trait` type via
+a pointer cast.
+
+Erroneous code example:
+
+```rust,edition2021,compile_fail,E0804
+let ptr: *const dyn core::any::Any = &();
+_ = ptr as *const (dyn core::any::Any + Send);
+```
+
+Adding an auto trait can make the vtable invalid, potentially causing
+UB in safe code afterwards. For example:
+
+```rust,edition2021,no_run
+use core::{mem::transmute, ptr::NonNull};
+
+trait Trait {
+    fn f(&self)
+    where
+        Self: Send;
+}
+
+impl Trait for NonNull<()> {
+    fn f(&self) {
+        unreachable!()
+    }
+}
+
+fn main() {
+    let unsend: &dyn Trait = &NonNull::dangling();
+    let bad: &(dyn Trait + Send) = unsafe { transmute(unsend) };
+    // This crashes, since the vtable for `NonNull as dyn Trait` does
+    // not have an entry for `Trait::f`.
+    bad.f();
+}
+```
+
+To fix this error, you can use `transmute` rather than pointer casts,
+but you must ensure that the vtable is valid for the pointer's type
+before calling a method on the trait object or allowing other code to
+do so.
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index 098ca42be2b..d53d5678832 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -547,6 +547,7 @@ E0800: 0800,
 E0801: 0801,
 E0802: 0802,
 E0803: 0803,
+E0804: 0804,
         );
     )
 }
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index afced1d803f..86959b28e53 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -627,7 +627,6 @@ pub enum StashKey {
     MaybeFruTypo,
     CallAssocMethod,
     AssociatedTypeSuggestion,
-    MaybeForgetReturn,
     /// Query cycle detected, stashing in favor of a better error.
     Cycle,
     UndeterminedMacroResolution,
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 4a250145308..86b12f6be4e 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -53,6 +53,7 @@ pub enum Annotatable {
     Param(ast::Param),
     FieldDef(ast::FieldDef),
     Variant(ast::Variant),
+    WherePredicate(ast::WherePredicate),
     Crate(ast::Crate),
 }
 
@@ -71,6 +72,7 @@ impl Annotatable {
             Annotatable::Param(p) => p.span,
             Annotatable::FieldDef(sf) => sf.span,
             Annotatable::Variant(v) => v.span,
+            Annotatable::WherePredicate(wp) => wp.span,
             Annotatable::Crate(c) => c.spans.inner_span,
         }
     }
@@ -89,6 +91,7 @@ impl Annotatable {
             Annotatable::Param(p) => p.visit_attrs(f),
             Annotatable::FieldDef(sf) => sf.visit_attrs(f),
             Annotatable::Variant(v) => v.visit_attrs(f),
+            Annotatable::WherePredicate(wp) => wp.visit_attrs(f),
             Annotatable::Crate(c) => c.visit_attrs(f),
         }
     }
@@ -107,6 +110,7 @@ impl Annotatable {
             Annotatable::Param(p) => visitor.visit_param(p),
             Annotatable::FieldDef(sf) => visitor.visit_field_def(sf),
             Annotatable::Variant(v) => visitor.visit_variant(v),
+            Annotatable::WherePredicate(wp) => visitor.visit_where_predicate(wp),
             Annotatable::Crate(c) => visitor.visit_crate(c),
         }
     }
@@ -128,6 +132,7 @@ impl Annotatable {
             | Annotatable::Param(..)
             | Annotatable::FieldDef(..)
             | Annotatable::Variant(..)
+            | Annotatable::WherePredicate(..)
             | Annotatable::Crate(..) => panic!("unexpected annotatable"),
         }
     }
@@ -223,6 +228,13 @@ impl Annotatable {
         }
     }
 
+    pub fn expect_where_predicate(self) -> ast::WherePredicate {
+        match self {
+            Annotatable::WherePredicate(wp) => wp,
+            _ => panic!("expected where predicate"),
+        }
+    }
+
     pub fn expect_crate(self) -> ast::Crate {
         match self {
             Annotatable::Crate(krate) => krate,
@@ -446,6 +458,10 @@ pub trait MacResult {
         None
     }
 
+    fn make_where_predicates(self: Box<Self>) -> Option<SmallVec<[ast::WherePredicate; 1]>> {
+        None
+    }
+
     fn make_crate(self: Box<Self>) -> Option<ast::Crate> {
         // Fn-like macros cannot produce a crate.
         unreachable!()
diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs
index 83255b82017..5570c0c38e8 100644
--- a/compiler/rustc_expand/src/config.rs
+++ b/compiler/rustc_expand/src/config.rs
@@ -328,7 +328,7 @@ impl<'a> StripUnconfigured<'a> {
 
         // For inner attributes, we do the same thing for the `!` in `#![attr]`.
         let mut trees = if cfg_attr.style == AttrStyle::Inner {
-            let Some(TokenTree::Token(bang_token @ Token { kind: TokenKind::Not, .. }, _)) =
+            let Some(TokenTree::Token(bang_token @ Token { kind: TokenKind::Bang, .. }, _)) =
                 orig_trees.next()
             else {
                 panic!("Bad tokens for attribute {cfg_attr:?}");
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index e3f31ebeca3..c523bcece72 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -227,6 +227,12 @@ ast_fragments! {
     Variants(SmallVec<[ast::Variant; 1]>) {
         "variant"; many fn flat_map_variant; fn visit_variant(); fn make_variants;
     }
+    WherePredicates(SmallVec<[ast::WherePredicate; 1]>) {
+        "where predicate";
+        many fn flat_map_where_predicate;
+        fn visit_where_predicate();
+        fn make_where_predicates;
+     }
     Crate(ast::Crate) { "crate"; one fn visit_crate; fn visit_crate; fn make_crate; }
 }
 
@@ -259,7 +265,8 @@ impl AstFragmentKind {
             | AstFragmentKind::GenericParams
             | AstFragmentKind::Params
             | AstFragmentKind::FieldDefs
-            | AstFragmentKind::Variants => SupportsMacroExpansion::No,
+            | AstFragmentKind::Variants
+            | AstFragmentKind::WherePredicates => SupportsMacroExpansion::No,
         }
     }
 
@@ -290,6 +297,9 @@ impl AstFragmentKind {
             AstFragmentKind::Variants => {
                 AstFragment::Variants(items.map(Annotatable::expect_variant).collect())
             }
+            AstFragmentKind::WherePredicates => AstFragment::WherePredicates(
+                items.map(Annotatable::expect_where_predicate).collect(),
+            ),
             AstFragmentKind::Items => {
                 AstFragment::Items(items.map(Annotatable::expect_item).collect())
             }
@@ -865,7 +875,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             | Annotatable::GenericParam(..)
             | Annotatable::Param(..)
             | Annotatable::FieldDef(..)
-            | Annotatable::Variant(..) => panic!("unexpected annotatable"),
+            | Annotatable::Variant(..)
+            | Annotatable::WherePredicate(..) => panic!("unexpected annotatable"),
         };
         if self.cx.ecfg.features.proc_macro_hygiene() {
             return;
@@ -1002,7 +1013,8 @@ pub fn parse_ast_fragment<'a>(
         | AstFragmentKind::GenericParams
         | AstFragmentKind::Params
         | AstFragmentKind::FieldDefs
-        | AstFragmentKind::Variants => panic!("unexpected AST fragment kind"),
+        | AstFragmentKind::Variants
+        | AstFragmentKind::WherePredicates => panic!("unexpected AST fragment kind"),
     })
 }
 
@@ -1414,6 +1426,19 @@ impl InvocationCollectorNode for ast::Variant {
     }
 }
 
+impl InvocationCollectorNode for ast::WherePredicate {
+    const KIND: AstFragmentKind = AstFragmentKind::WherePredicates;
+    fn to_annotatable(self) -> Annotatable {
+        Annotatable::WherePredicate(self)
+    }
+    fn fragment_to_output(fragment: AstFragment) -> Self::OutputTy {
+        fragment.make_where_predicates()
+    }
+    fn walk_flat_map<V: MutVisitor>(self, visitor: &mut V) -> Self::OutputTy {
+        walk_flat_map_where_predicate(visitor, self)
+    }
+}
+
 impl InvocationCollectorNode for ast::FieldDef {
     const KIND: AstFragmentKind = AstFragmentKind::FieldDefs;
     fn to_annotatable(self) -> Annotatable {
@@ -2116,6 +2141,13 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
         self.flat_map_node(node)
     }
 
+    fn flat_map_where_predicate(
+        &mut self,
+        node: ast::WherePredicate,
+    ) -> SmallVec<[ast::WherePredicate; 1]> {
+        self.flat_map_node(node)
+    }
+
     fn flat_map_field_def(&mut self, node: ast::FieldDef) -> SmallVec<[ast::FieldDef; 1]> {
         self.flat_map_node(node)
     }
diff --git a/compiler/rustc_expand/src/mbe/macro_check.rs b/compiler/rustc_expand/src/mbe/macro_check.rs
index 729dec2bfbd..1a2db233b7a 100644
--- a/compiler/rustc_expand/src/mbe/macro_check.rs
+++ b/compiler/rustc_expand/src/mbe/macro_check.rs
@@ -432,7 +432,7 @@ fn check_nested_occurrences(
             }
             (
                 NestedMacroState::MacroRules,
-                &TokenTree::Token(Token { kind: TokenKind::Not, .. }),
+                &TokenTree::Token(Token { kind: TokenKind::Bang, .. }),
             ) => {
                 state = NestedMacroState::MacroRulesNot;
             }
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index cc7e3e65105..5577c8902da 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -690,7 +690,7 @@ fn has_compile_error_macro(rhs: &mbe::TokenTree) -> bool {
                     && let TokenKind::Ident(ident, _) = ident.kind
                     && ident == sym::compile_error
                     && let mbe::TokenTree::Token(bang) = bang
-                    && let TokenKind::Not = bang.kind
+                    && let TokenKind::Bang = bang.kind
                     && let mbe::TokenTree::Delimited(.., del) = args
                     && !del.delim.skip()
                 {
@@ -1135,7 +1135,7 @@ fn check_matcher_core<'tt>(
                         && matches!(kind, NonterminalKind::Pat(PatParam { inferred: true }))
                         && matches!(
                             next_token,
-                            TokenTree::Token(token) if *token == BinOp(token::BinOpToken::Or)
+                            TokenTree::Token(token) if *token == token::Or
                         )
                     {
                         // It is suggestion to use pat_param, for example: $x:pat -> $x:pat_param.
@@ -1177,7 +1177,7 @@ fn check_matcher_core<'tt>(
 
                             if kind == NonterminalKind::Pat(PatWithOr)
                                 && sess.psess.edition.at_least_rust_2021()
-                                && next_token.is_token(&BinOp(token::BinOpToken::Or))
+                                && next_token.is_token(&token::Or)
                             {
                                 let suggestion = quoted_tt_to_string(&TokenTree::MetaVarDecl(
                                     span,
@@ -1296,7 +1296,7 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
                 const TOKENS: &[&str] = &["`=>`", "`,`", "`=`", "`|`", "`if`", "`in`"];
                 match tok {
                     TokenTree::Token(token) => match token.kind {
-                        FatArrow | Comma | Eq | BinOp(token::Or) => IsInFollow::Yes,
+                        FatArrow | Comma | Eq | Or => IsInFollow::Yes,
                         Ident(name, IdentIsRaw::No) if name == kw::If || name == kw::In => {
                             IsInFollow::Yes
                         }
@@ -1332,9 +1332,9 @@ fn is_in_follow(tok: &mbe::TokenTree, kind: NonterminalKind) -> IsInFollow {
                         | Colon
                         | Eq
                         | Gt
-                        | BinOp(token::Shr)
+                        | Shr
                         | Semi
-                        | BinOp(token::Or) => IsInFollow::Yes,
+                        | Or => IsInFollow::Yes,
                         Ident(name, IdentIsRaw::No) if name == kw::As || name == kw::Where => {
                             IsInFollow::Yes
                         }
diff --git a/compiler/rustc_expand/src/mbe/quoted.rs b/compiler/rustc_expand/src/mbe/quoted.rs
index b9a06157907..8cb001391c5 100644
--- a/compiler/rustc_expand/src/mbe/quoted.rs
+++ b/compiler/rustc_expand/src/mbe/quoted.rs
@@ -302,8 +302,8 @@ fn parse_tree<'a>(
 /// `None`.
 fn kleene_op(token: &Token) -> Option<KleeneOp> {
     match token.kind {
-        token::BinOp(token::Star) => Some(KleeneOp::ZeroOrMore),
-        token::BinOp(token::Plus) => Some(KleeneOp::OneOrMore),
+        token::Star => Some(KleeneOp::ZeroOrMore),
+        token::Plus => Some(KleeneOp::OneOrMore),
         token::Question => Some(KleeneOp::ZeroOrOne),
         _ => None,
     }
diff --git a/compiler/rustc_expand/src/placeholders.rs b/compiler/rustc_expand/src/placeholders.rs
index e969f2d4fb5..3a470924c7f 100644
--- a/compiler/rustc_expand/src/placeholders.rs
+++ b/compiler/rustc_expand/src/placeholders.rs
@@ -188,6 +188,19 @@ pub(crate) fn placeholder(
             vis,
             is_placeholder: true,
         }]),
+        AstFragmentKind::WherePredicates => {
+            AstFragment::WherePredicates(smallvec![ast::WherePredicate {
+                attrs: Default::default(),
+                id,
+                span,
+                kind: ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
+                    bound_generic_params: Default::default(),
+                    bounded_ty: ty(),
+                    bounds: Default::default(),
+                }),
+                is_placeholder: true,
+            }])
+        }
     }
 }
 
@@ -267,6 +280,17 @@ impl MutVisitor for PlaceholderExpander {
         }
     }
 
+    fn flat_map_where_predicate(
+        &mut self,
+        predicate: ast::WherePredicate,
+    ) -> SmallVec<[ast::WherePredicate; 1]> {
+        if predicate.is_placeholder {
+            self.remove(predicate.id).make_where_predicates()
+        } else {
+            walk_flat_map_where_predicate(self, predicate)
+        }
+    }
+
     fn flat_map_item(&mut self, item: P<ast::Item>) -> SmallVec<[P<ast::Item>; 1]> {
         match item.kind {
             ast::ItemKind::MacCall(_) => self.remove(item.id).make_items(),
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 5581a6e6508..007241437ec 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -180,28 +180,28 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
                 Gt => op(">"),
                 AndAnd => op("&&"),
                 OrOr => op("||"),
-                Not => op("!"),
+                Bang => op("!"),
                 Tilde => op("~"),
-                BinOp(Plus) => op("+"),
-                BinOp(Minus) => op("-"),
-                BinOp(Star) => op("*"),
-                BinOp(Slash) => op("/"),
-                BinOp(Percent) => op("%"),
-                BinOp(Caret) => op("^"),
-                BinOp(And) => op("&"),
-                BinOp(Or) => op("|"),
-                BinOp(Shl) => op("<<"),
-                BinOp(Shr) => op(">>"),
-                BinOpEq(Plus) => op("+="),
-                BinOpEq(Minus) => op("-="),
-                BinOpEq(Star) => op("*="),
-                BinOpEq(Slash) => op("/="),
-                BinOpEq(Percent) => op("%="),
-                BinOpEq(Caret) => op("^="),
-                BinOpEq(And) => op("&="),
-                BinOpEq(Or) => op("|="),
-                BinOpEq(Shl) => op("<<="),
-                BinOpEq(Shr) => op(">>="),
+                Plus => op("+"),
+                Minus => op("-"),
+                Star => op("*"),
+                Slash => op("/"),
+                Percent => op("%"),
+                Caret => op("^"),
+                And => op("&"),
+                Or => op("|"),
+                Shl => op("<<"),
+                Shr => op(">>"),
+                PlusEq => op("+="),
+                MinusEq => op("-="),
+                StarEq => op("*="),
+                SlashEq => op("/="),
+                PercentEq => op("%="),
+                CaretEq => op("^="),
+                AndEq => op("&="),
+                OrEq => op("|="),
+                ShlEq => op("<<="),
+                ShrEq => op(">>="),
                 At => op("@"),
                 Dot => op("."),
                 DotDot => op(".."),
@@ -322,16 +322,16 @@ impl ToInternal<SmallVec<[tokenstream::TokenTree; 2]>>
                     b'=' => Eq,
                     b'<' => Lt,
                     b'>' => Gt,
-                    b'!' => Not,
+                    b'!' => Bang,
                     b'~' => Tilde,
-                    b'+' => BinOp(Plus),
-                    b'-' => BinOp(Minus),
-                    b'*' => BinOp(Star),
-                    b'/' => BinOp(Slash),
-                    b'%' => BinOp(Percent),
-                    b'^' => BinOp(Caret),
-                    b'&' => BinOp(And),
-                    b'|' => BinOp(Or),
+                    b'+' => Plus,
+                    b'-' => Minus,
+                    b'*' => Star,
+                    b'/' => Slash,
+                    b'%' => Percent,
+                    b'^' => Caret,
+                    b'&' => And,
+                    b'|' => Or,
                     b'@' => At,
                     b'.' => Dot,
                     b',' => Comma,
@@ -372,10 +372,9 @@ impl ToInternal<SmallVec<[tokenstream::TokenTree; 2]>>
                 suffix,
                 span,
             }) if symbol.as_str().starts_with('-') => {
-                let minus = BinOp(BinOpToken::Minus);
                 let symbol = Symbol::intern(&symbol.as_str()[1..]);
                 let integer = TokenKind::lit(token::Integer, symbol, suffix);
-                let a = tokenstream::TokenTree::token_joint_hidden(minus, span);
+                let a = tokenstream::TokenTree::token_joint_hidden(Minus, span);
                 let b = tokenstream::TokenTree::token_alone(integer, span);
                 smallvec![a, b]
             }
@@ -385,10 +384,9 @@ impl ToInternal<SmallVec<[tokenstream::TokenTree; 2]>>
                 suffix,
                 span,
             }) if symbol.as_str().starts_with('-') => {
-                let minus = BinOp(BinOpToken::Minus);
                 let symbol = Symbol::intern(&symbol.as_str()[1..]);
                 let float = TokenKind::lit(token::Float, symbol, suffix);
-                let a = tokenstream::TokenTree::token_joint_hidden(minus, span);
+                let a = tokenstream::TokenTree::token_joint_hidden(Minus, span);
                 let b = tokenstream::TokenTree::token_alone(float, span);
                 smallvec![a, b]
             }
@@ -599,10 +597,7 @@ impl server::TokenStream for Rustc<'_, '_> {
                         Ok(Self::TokenStream::from_iter([
                             // FIXME: The span of the `-` token is lost when
                             // parsing, so we cannot faithfully recover it here.
-                            tokenstream::TokenTree::token_joint_hidden(
-                                token::BinOp(token::Minus),
-                                e.span,
-                            ),
+                            tokenstream::TokenTree::token_joint_hidden(token::Minus, e.span),
                             tokenstream::TokenTree::token_alone(token::Literal(*token_lit), e.span),
                         ]))
                     }
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 306535bf764..40857e0066e 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -576,6 +576,13 @@ pub static BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         EncodeCrossCrate::Yes, experimental!(patchable_function_entry)
     ),
 
+    // Probably temporary component of min_generic_const_args.
+    // `#[type_const] const ASSOC: usize;`
+    gated!(
+        type_const, Normal, template!(Word), ErrorFollowing,
+        EncodeCrossCrate::Yes, min_generic_const_args, experimental!(type_const),
+    ),
+
     // ==========================================================================
     // Internal attributes: Stability, deprecation, and unsafe:
     // ==========================================================================
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index fc58b66ad35..47e4f9a2fe8 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -244,6 +244,8 @@ declare_features! (
     /// Allows unnamed fields of struct and union type
     (removed, unnamed_fields, "1.83.0", Some(49804), Some("feature needs redesign")),
     (removed, unsafe_no_drop_flag, "1.0.0", None, None),
+    (removed, unsized_tuple_coercion, "CURRENT_RUSTC_VERSION", Some(42877),
+     Some("The feature restricts possible layouts for tuples, and this restriction is not worth it.")),
     /// Allows `union` fields that don't implement `Copy` as long as they don't have any drop glue.
     (removed, untagged_unions, "1.13.0", Some(55149),
      Some("unions with `Copy` and `ManuallyDrop` fields are stable; there is no intent to stabilize more")),
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 0acd3b0f800..c6e992573d6 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -1,6 +1,7 @@
 //! List of the unstable feature gates.
 
 use std::path::PathBuf;
+use std::time::{SystemTime, UNIX_EPOCH};
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_span::{Span, Symbol, sym};
@@ -601,6 +602,8 @@ declare_features! (
     (unstable, precise_capturing_in_traits, "1.83.0", Some(130044)),
     /// Allows macro attributes on expressions, statements and non-inline modules.
     (unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
+    /// Allows the use of raw-dylibs on ELF platforms
+    (incomplete, raw_dylib_elf, "CURRENT_RUSTC_VERSION", Some(135694)),
     /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024.
     (incomplete, ref_pat_eat_one_layer_2024, "1.79.0", Some(123076)),
     /// Makes `&` and `&mut` patterns eat only one layer of references in Rust 2024—structural variant
@@ -657,16 +660,17 @@ declare_features! (
     (internal, unsized_fn_params, "1.49.0", Some(48055)),
     /// Allows unsized rvalues at arguments and parameters.
     (incomplete, unsized_locals, "1.30.0", Some(48055)),
-    /// Allows unsized tuple coercion.
-    (unstable, unsized_tuple_coercion, "1.20.0", Some(42877)),
     /// Allows using the `#[used(linker)]` (or `#[used(compiler)]`) attribute.
     (unstable, used_with_arg, "1.60.0", Some(93798)),
+    /// Allows use of attributes in `where` clauses.
+    (unstable, where_clause_attrs, "CURRENT_RUSTC_VERSION", Some(115590)),
     /// Allows use of x86 `AMX` target-feature attributes and intrinsics
     (unstable, x86_amx_intrinsics, "1.81.0", Some(126622)),
     /// Allows use of the `xop` target-feature
     (unstable, xop_target_feature, "1.81.0", Some(127208)),
     /// Allows `do yeet` expressions
     (unstable, yeet_expr, "1.62.0", Some(96373)),
+    (unstable, yield_expr, "CURRENT_RUSTC_VERSION", Some(43122)),
     // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
     // Features are listed in alphabetical order. Tidy will fail if you don't keep it this way.
     // !!!!    !!!!    !!!!    !!!!   !!!!    !!!!    !!!!    !!!!    !!!!    !!!!    !!!!
@@ -683,11 +687,13 @@ impl Features {
     ) -> Result<(), Box<dyn std::error::Error>> {
         #[derive(serde::Serialize)]
         struct LibFeature {
+            timestamp: u128,
             symbol: String,
         }
 
         #[derive(serde::Serialize)]
         struct LangFeature {
+            timestamp: u128,
             symbol: String,
             since: Option<String>,
         }
@@ -701,10 +707,20 @@ impl Features {
         let metrics_file = std::fs::File::create(metrics_path)?;
         let metrics_file = std::io::BufWriter::new(metrics_file);
 
+        let now = || {
+            SystemTime::now()
+                .duration_since(UNIX_EPOCH)
+                .expect("system time should always be greater than the unix epoch")
+                .as_nanos()
+        };
+
         let lib_features = self
             .enabled_lib_features
             .iter()
-            .map(|EnabledLibFeature { gate_name, .. }| LibFeature { symbol: gate_name.to_string() })
+            .map(|EnabledLibFeature { gate_name, .. }| LibFeature {
+                symbol: gate_name.to_string(),
+                timestamp: now(),
+            })
             .collect();
 
         let lang_features = self
@@ -713,6 +729,7 @@ impl Features {
             .map(|EnabledLangFeature { gate_name, stable_since, .. }| LangFeature {
                 symbol: gate_name.to_string(),
                 since: stable_since.map(|since| since.to_string()),
+                timestamp: now(),
             })
             .collect();
 
diff --git a/compiler/rustc_fluent_macro/src/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs
index d4604c27e6d..b04fd1b48f7 100644
--- a/compiler/rustc_fluent_macro/src/fluent.rs
+++ b/compiler/rustc_fluent_macro/src/fluent.rs
@@ -78,8 +78,8 @@ fn failed(crate_name: &Ident) -> proc_macro::TokenStream {
 
 /// See [rustc_fluent_macro::fluent_messages].
 pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::TokenStream {
-    let crate_name = std::env::var("CARGO_PKG_NAME")
-        // If `CARGO_PKG_NAME` is missing, then we're probably running in a test, so use
+    let crate_name = std::env::var("CARGO_CRATE_NAME")
+        // If `CARGO_CRATE_NAME` is missing, then we're probably running in a test, so use
         // `no_crate`.
         .unwrap_or_else(|_| "no_crate".to_string())
         .replace("rustc_", "");
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 399f1f4b237..df305e6e769 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1600,7 +1600,7 @@ pub struct PatField<'hir> {
     pub span: Span,
 }
 
-#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic)]
+#[derive(Copy, Clone, PartialEq, Debug, HashStable_Generic, Hash, Eq, Encodable, Decodable)]
 pub enum RangeEnd {
     Included,
     Excluded,
@@ -1668,7 +1668,7 @@ pub enum PatExprKind<'hir> {
 #[derive(Debug, Clone, Copy, HashStable_Generic)]
 pub enum TyPatKind<'hir> {
     /// A range pattern (e.g., `1..=2` or `1..2`).
-    Range(Option<&'hir ConstArg<'hir>>, Option<&'hir ConstArg<'hir>>, RangeEnd),
+    Range(&'hir ConstArg<'hir>, &'hir ConstArg<'hir>),
 
     /// A placeholder for a pattern that wasn't well formed in some way.
     Err(ErrorGuaranteed),
diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs
index e349e23f7dc..41eb5b45bd1 100644
--- a/compiler/rustc_hir/src/intravisit.rs
+++ b/compiler/rustc_hir/src/intravisit.rs
@@ -708,9 +708,9 @@ pub fn walk_arm<'v, V: Visitor<'v>>(visitor: &mut V, arm: &'v Arm<'v>) -> V::Res
 pub fn walk_ty_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v TyPat<'v>) -> V::Result {
     try_visit!(visitor.visit_id(pattern.hir_id));
     match pattern.kind {
-        TyPatKind::Range(lower_bound, upper_bound, _) => {
-            visit_opt!(visitor, visit_const_arg_unambig, lower_bound);
-            visit_opt!(visitor, visit_const_arg_unambig, upper_bound);
+        TyPatKind::Range(lower_bound, upper_bound) => {
+            try_visit!(visitor.visit_const_arg_unambig(lower_bound));
+            try_visit!(visitor.visit_const_arg_unambig(upper_bound));
         }
         TyPatKind::Err(_) => (),
     }
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index f5626937ec4..c3b14a4e06c 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -418,6 +418,9 @@ language_item_table! {
     Range,                   sym::Range,               range_struct,               Target::Struct,         GenericRequirement::None;
     RangeToInclusive,        sym::RangeToInclusive,    range_to_inclusive_struct,  Target::Struct,         GenericRequirement::None;
     RangeTo,                 sym::RangeTo,             range_to_struct,            Target::Struct,         GenericRequirement::None;
+    RangeMax,                sym::RangeMax,            range_max,                  Target::AssocConst,     GenericRequirement::Exact(0);
+    RangeMin,                sym::RangeMin,            range_min,                  Target::AssocConst,     GenericRequirement::Exact(0);
+    RangeSub,                sym::RangeSub,            range_sub,                  Target::Method(MethodKind::Trait { body: false }),     GenericRequirement::Exact(0);
 
     // `new_range` types that are `Copy + IntoIterator`
     RangeFromCopy,           sym::RangeFromCopy,       range_from_copy_struct,     Target::Struct,         GenericRequirement::None;
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
index 70e95a84e68..601898023fc 100644
--- a/compiler/rustc_hir/src/target.rs
+++ b/compiler/rustc_hir/src/target.rs
@@ -56,6 +56,7 @@ pub enum Target {
     Param,
     PatField,
     ExprField,
+    WherePredicate,
 }
 
 impl Display for Target {
@@ -96,7 +97,8 @@ impl Target {
             | Target::MacroDef
             | Target::Param
             | Target::PatField
-            | Target::ExprField => false,
+            | Target::ExprField
+            | Target::WherePredicate => false,
         }
     }
 
@@ -217,6 +219,7 @@ impl Target {
             Target::Param => "function param",
             Target::PatField => "pattern field",
             Target::ExprField => "struct field",
+            Target::WherePredicate => "where predicate",
         }
     }
 }
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 3f75cce0092..935f4de6c58 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -244,9 +244,6 @@ hir_analysis_inherent_ty_outside_relevant = cannot define inherent `impl` for a
     .help = consider moving this inherent impl into the crate defining the type if possible
     .span_help = alternatively add `#[rustc_allow_incoherent_impl]` to the relevant impl items
 
-hir_analysis_invalid_base_type = `{$ty}` is not a valid base type for range patterns
-    .note = range patterns only support integers
-
 hir_analysis_invalid_generic_receiver_ty = invalid generic `self` parameter type: `{$receiver_ty}`
     .note = type of `self` must not be a method generic parameter type
 
@@ -278,13 +275,6 @@ hir_analysis_invalid_union_field =
 hir_analysis_invalid_union_field_sugg =
     wrap the field type in `ManuallyDrop<...>`
 
-hir_analysis_invalid_unsafe_field =
-    field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe
-    .note = unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
-
-hir_analysis_invalid_unsafe_field_sugg =
-    wrap the field type in `ManuallyDrop<...>`
-
 hir_analysis_late_bound_const_in_apit = `impl Trait` can only mention const parameters from an fn or impl
     .label = const parameter declared here
 
@@ -620,6 +610,8 @@ hir_analysis_variances_of = {$variances}
 hir_analysis_where_clause_on_main = `main` function is not allowed to have a `where` clause
     .label = `main` cannot have a `where` clause
 
+hir_analysis_within_macro = due to this macro variable
+
 hir_analysis_wrong_number_of_generic_arguments_to_intrinsic =
     intrinsic has wrong number of {$descr} parameters: found {$found}, expected {$expected}
     .label = expected {$expected} {$descr} {$expected ->
diff --git a/compiler/rustc_hir_analysis/src/check/dropck.rs b/compiler/rustc_hir_analysis/src/check/always_applicable.rs
index d7dfe482da4..ba5b61d3fce 100644
--- a/compiler/rustc_hir_analysis/src/check/dropck.rs
+++ b/compiler/rustc_hir_analysis/src/check/always_applicable.rs
@@ -1,8 +1,15 @@
+//! This module contains methods that assist in checking that impls are general
+//! enough, i.e. that they always apply to every valid instantaiton of the ADT
+//! they're implemented for.
+//!
+//! This is necessary for `Drop` and negative impls to be well-formed.
+
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::codes::*;
 use rustc_errors::{ErrorGuaranteed, struct_span_code_err};
 use rustc_infer::infer::{RegionResolutionError, TyCtxtInferExt};
 use rustc_infer::traits::{ObligationCause, ObligationCauseCode};
+use rustc_middle::span_bug;
 use rustc_middle::ty::util::CheckRegions;
 use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt, TypingMode};
 use rustc_trait_selection::regions::InferCtxtRegionExt;
@@ -27,11 +34,12 @@ use crate::hir::def_id::{DefId, LocalDefId};
 /// 3. Any bounds on the generic parameters must be reflected in the
 ///    struct/enum definition for the nominal type itself (i.e.
 ///    cannot do `struct S<T>; impl<T:Clone> Drop for S<T> { ... }`).
-///
 pub(crate) fn check_drop_impl(
     tcx: TyCtxt<'_>,
     drop_impl_did: DefId,
 ) -> Result<(), ErrorGuaranteed> {
+    let drop_impl_did = drop_impl_did.expect_local();
+
     match tcx.impl_polarity(drop_impl_did) {
         ty::ImplPolarity::Positive => {}
         ty::ImplPolarity::Negative => {
@@ -45,55 +53,107 @@ pub(crate) fn check_drop_impl(
             }));
         }
     }
-    let dtor_self_type = tcx.type_of(drop_impl_did).instantiate_identity();
-    match dtor_self_type.kind() {
+
+    tcx.ensure_ok().orphan_check_impl(drop_impl_did)?;
+
+    let dtor_impl_trait_ref = tcx.impl_trait_ref(drop_impl_did).unwrap().instantiate_identity();
+
+    match dtor_impl_trait_ref.self_ty().kind() {
         ty::Adt(adt_def, adt_to_impl_args) => {
-            ensure_drop_params_and_item_params_correspond(
+            ensure_impl_params_and_item_params_correspond(
                 tcx,
-                drop_impl_did.expect_local(),
+                drop_impl_did,
                 adt_def.did(),
                 adt_to_impl_args,
             )?;
 
-            ensure_drop_predicates_are_implied_by_item_defn(
+            ensure_impl_predicates_are_implied_by_item_defn(
                 tcx,
-                drop_impl_did.expect_local(),
-                adt_def.did().expect_local(),
+                drop_impl_did,
+                adt_def.did(),
                 adt_to_impl_args,
             )
         }
         _ => {
-            // Destructors only work on nominal types. This was
-            // already checked by coherence, but compilation may
-            // not have been terminated.
-            let span = tcx.def_span(drop_impl_did);
-            let reported = tcx.dcx().span_delayed_bug(
-                span,
-                format!("should have been rejected by coherence check: {dtor_self_type}"),
-            );
-            Err(reported)
+            span_bug!(tcx.def_span(drop_impl_did), "incoherent impl of Drop");
         }
     }
 }
 
-fn ensure_drop_params_and_item_params_correspond<'tcx>(
+pub(crate) fn check_negative_auto_trait_impl<'tcx>(
     tcx: TyCtxt<'tcx>,
-    drop_impl_did: LocalDefId,
-    self_type_did: DefId,
+    impl_def_id: LocalDefId,
+    impl_trait_ref: ty::TraitRef<'tcx>,
+    polarity: ty::ImplPolarity,
+) -> Result<(), ErrorGuaranteed> {
+    let ty::ImplPolarity::Negative = polarity else {
+        return Ok(());
+    };
+
+    if !tcx.trait_is_auto(impl_trait_ref.def_id) {
+        return Ok(());
+    }
+
+    if tcx.defaultness(impl_def_id).is_default() {
+        tcx.dcx().span_delayed_bug(tcx.def_span(impl_def_id), "default impl cannot be negative");
+    }
+
+    tcx.ensure_ok().orphan_check_impl(impl_def_id)?;
+
+    match impl_trait_ref.self_ty().kind() {
+        ty::Adt(adt_def, adt_to_impl_args) => {
+            ensure_impl_params_and_item_params_correspond(
+                tcx,
+                impl_def_id,
+                adt_def.did(),
+                adt_to_impl_args,
+            )?;
+
+            ensure_impl_predicates_are_implied_by_item_defn(
+                tcx,
+                impl_def_id,
+                adt_def.did(),
+                adt_to_impl_args,
+            )
+        }
+        _ => {
+            if tcx.features().auto_traits() {
+                // NOTE: We ignore the applicability check for negative auto impls
+                // defined in libcore. In the (almost impossible) future where we
+                // stabilize auto impls, then the proper applicability check MUST
+                // be implemented here to handle non-ADT rigid types.
+                Ok(())
+            } else {
+                span_bug!(tcx.def_span(impl_def_id), "incoherent impl of negative auto trait");
+            }
+        }
+    }
+}
+
+fn ensure_impl_params_and_item_params_correspond<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    impl_def_id: LocalDefId,
+    adt_def_id: DefId,
     adt_to_impl_args: GenericArgsRef<'tcx>,
 ) -> Result<(), ErrorGuaranteed> {
     let Err(arg) = tcx.uses_unique_generic_params(adt_to_impl_args, CheckRegions::OnlyParam) else {
         return Ok(());
     };
 
-    let drop_impl_span = tcx.def_span(drop_impl_did);
-    let item_span = tcx.def_span(self_type_did);
-    let self_descr = tcx.def_descr(self_type_did);
+    let impl_span = tcx.def_span(impl_def_id);
+    let item_span = tcx.def_span(adt_def_id);
+    let self_descr = tcx.def_descr(adt_def_id);
+    let polarity = match tcx.impl_polarity(impl_def_id) {
+        ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
+        ty::ImplPolarity::Negative => "!",
+    };
+    let trait_name = tcx
+        .item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait"));
     let mut err = struct_span_code_err!(
         tcx.dcx(),
-        drop_impl_span,
+        impl_span,
         E0366,
-        "`Drop` impls cannot be specialized"
+        "`{polarity}{trait_name}` impls cannot be specialized",
     );
     match arg {
         ty::util::NotUniqueParam::DuplicateParam(arg) => {
@@ -116,17 +176,22 @@ fn ensure_drop_params_and_item_params_correspond<'tcx>(
 /// Confirms that all predicates defined on the `Drop` impl (`drop_impl_def_id`) are able to be
 /// proven from within `adt_def_id`'s environment. I.e. all the predicates on the impl are
 /// implied by the ADT being well formed.
-fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
+fn ensure_impl_predicates_are_implied_by_item_defn<'tcx>(
     tcx: TyCtxt<'tcx>,
-    drop_impl_def_id: LocalDefId,
-    adt_def_id: LocalDefId,
+    impl_def_id: LocalDefId,
+    adt_def_id: DefId,
     adt_to_impl_args: GenericArgsRef<'tcx>,
 ) -> Result<(), ErrorGuaranteed> {
     let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
     let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
 
-    let impl_span = tcx.def_span(drop_impl_def_id.to_def_id());
-
+    let impl_span = tcx.def_span(impl_def_id.to_def_id());
+    let trait_name = tcx
+        .item_name(tcx.trait_id_of_impl(impl_def_id.to_def_id()).expect("expected impl of trait"));
+    let polarity = match tcx.impl_polarity(impl_def_id) {
+        ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => "",
+        ty::ImplPolarity::Negative => "!",
+    };
     // Take the param-env of the adt and instantiate the args that show up in
     // the implementation's self type. This gives us the assumptions that the
     // self ty of the implementation is allowed to know just from it being a
@@ -145,17 +210,21 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
     let adt_env =
         ty::EarlyBinder::bind(tcx.param_env(adt_def_id)).instantiate(tcx, adt_to_impl_args);
 
-    let fresh_impl_args = infcx.fresh_args_for_item(impl_span, drop_impl_def_id.to_def_id());
+    let fresh_impl_args = infcx.fresh_args_for_item(impl_span, impl_def_id.to_def_id());
     let fresh_adt_ty =
-        tcx.impl_trait_ref(drop_impl_def_id).unwrap().instantiate(tcx, fresh_impl_args).self_ty();
+        tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(tcx, fresh_impl_args).self_ty();
 
     ocx.eq(&ObligationCause::dummy_with_span(impl_span), adt_env, fresh_adt_ty, impl_adt_ty)
-        .unwrap();
+        .expect("equating fully generic trait ref should never fail");
 
-    for (clause, span) in tcx.predicates_of(drop_impl_def_id).instantiate(tcx, fresh_impl_args) {
-        let normalize_cause = traits::ObligationCause::misc(span, adt_def_id);
+    for (clause, span) in tcx.predicates_of(impl_def_id).instantiate(tcx, fresh_impl_args) {
+        let normalize_cause = traits::ObligationCause::misc(span, impl_def_id);
         let pred = ocx.normalize(&normalize_cause, adt_env, clause);
-        let cause = traits::ObligationCause::new(span, adt_def_id, ObligationCauseCode::DropImpl);
+        let cause = traits::ObligationCause::new(
+            span,
+            impl_def_id,
+            ObligationCauseCode::AlwaysApplicableImpl,
+        );
         ocx.register_obligation(traits::Obligation::new(tcx, cause, adt_env, pred));
     }
 
@@ -173,13 +242,13 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
             let root_predicate = error.root_obligation.predicate;
             if root_predicates.insert(root_predicate) {
                 let item_span = tcx.def_span(adt_def_id);
-                let self_descr = tcx.def_descr(adt_def_id.to_def_id());
+                let self_descr = tcx.def_descr(adt_def_id);
                 guar = Some(
                     struct_span_code_err!(
                         tcx.dcx(),
                         error.root_obligation.cause.span,
                         E0367,
-                        "`Drop` impl requires `{root_predicate}` \
+                        "`{polarity}{trait_name}` impl requires `{root_predicate}` \
                         but the {self_descr} it is implemented for does not",
                     )
                     .with_span_note(item_span, "the implementor must specify the same requirement")
@@ -190,12 +259,12 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
         return Err(guar.unwrap());
     }
 
-    let errors = ocx.infcx.resolve_regions(adt_def_id, adt_env, []);
+    let errors = ocx.infcx.resolve_regions(impl_def_id, adt_env, []);
     if !errors.is_empty() {
         let mut guar = None;
         for error in errors {
             let item_span = tcx.def_span(adt_def_id);
-            let self_descr = tcx.def_descr(adt_def_id.to_def_id());
+            let self_descr = tcx.def_descr(adt_def_id);
             let outlives = match error {
                 RegionResolutionError::ConcreteFailure(_, a, b) => format!("{b}: {a}"),
                 RegionResolutionError::GenericBoundFailure(_, generic, r) => {
@@ -212,7 +281,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'tcx>(
                     tcx.dcx(),
                     error.origin().span(),
                     E0367,
-                    "`Drop` impl requires `{outlives}` \
+                    "`{polarity}{trait_name}` impl requires `{outlives}` \
                     but the {self_descr} it is implemented for does not",
                 )
                 .with_span_note(item_span, "the implementor must specify the same requirement")
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index f2331f3fd8e..8f9997cb62c 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -70,7 +70,6 @@ fn check_struct(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 
     check_transparent(tcx, def);
     check_packed(tcx, span, def);
-    check_unsafe_fields(tcx, def_id);
 }
 
 fn check_union(tcx: TyCtxt<'_>, def_id: LocalDefId) {
@@ -144,36 +143,6 @@ fn check_union_fields(tcx: TyCtxt<'_>, span: Span, item_def_id: LocalDefId) -> b
     true
 }
 
-/// Check that the unsafe fields do not need dropping.
-fn check_unsafe_fields(tcx: TyCtxt<'_>, item_def_id: LocalDefId) {
-    let span = tcx.def_span(item_def_id);
-    let def = tcx.adt_def(item_def_id);
-
-    let typing_env = ty::TypingEnv::non_body_analysis(tcx, item_def_id);
-    let args = ty::GenericArgs::identity_for_item(tcx, item_def_id);
-
-    for field in def.all_fields() {
-        if !field.safety.is_unsafe() {
-            continue;
-        }
-
-        if !allowed_union_or_unsafe_field(tcx, field.ty(tcx, args), typing_env, span) {
-            let hir::Node::Field(field) = tcx.hir_node_by_def_id(field.did.expect_local()) else {
-                unreachable!("field has to correspond to hir field")
-            };
-            let ty_span = field.ty.span;
-            tcx.dcx().emit_err(errors::InvalidUnsafeField {
-                field_span: field.span,
-                sugg: errors::InvalidUnsafeFieldSuggestion {
-                    lo: ty_span.shrink_to_lo(),
-                    hi: ty_span.shrink_to_hi(),
-                },
-                note: (),
-            });
-        }
-    }
-}
-
 /// Check that a `static` is inhabited.
 fn check_static_inhabited(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     // Make sure statics are inhabited.
@@ -745,14 +714,10 @@ fn check_static_linkage(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
     match tcx.def_kind(def_id) {
         DefKind::Static { .. } => {
-            tcx.ensure_ok().typeck(def_id);
-            maybe_check_static_with_link_section(tcx, def_id);
             check_static_inhabited(tcx, def_id);
             check_static_linkage(tcx, def_id);
         }
-        DefKind::Const => {
-            tcx.ensure_ok().typeck(def_id);
-        }
+        DefKind::Const => {}
         DefKind::Enum => {
             check_enum(tcx, def_id);
         }
@@ -766,7 +731,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                     ExternAbi::Rust,
                 )
             }
-            // Everything else is checked entirely within check_item_body
         }
         DefKind::Impl { of_trait } => {
             if of_trait && let Some(impl_trait_header) = tcx.impl_trait_header(def_id) {
@@ -1517,7 +1481,6 @@ fn check_enum(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 
     detect_discriminant_duplicate(tcx, def);
     check_transparent(tcx, def);
-    check_unsafe_fields(tcx, def_id);
 }
 
 /// Part of enum check. Given the discriminants of an enum, errors if two or more discriminants are equal
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 1c5455710db..9c28fac809d 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -62,9 +62,9 @@ a type parameter).
 
 */
 
+pub mod always_applicable;
 mod check;
 mod compare_impl_item;
-pub mod dropck;
 mod entry;
 pub mod intrinsic;
 pub mod intrinsicck;
@@ -113,11 +113,11 @@ pub fn provide(providers: &mut Providers) {
 }
 
 fn adt_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::Destructor> {
-    tcx.calculate_dtor(def_id.to_def_id(), dropck::check_drop_impl)
+    tcx.calculate_dtor(def_id.to_def_id(), always_applicable::check_drop_impl)
 }
 
 fn adt_async_destructor(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<ty::AsyncDestructor> {
-    tcx.calculate_async_dtor(def_id.to_def_id(), dropck::check_drop_impl)
+    tcx.calculate_async_dtor(def_id.to_def_id(), always_applicable::check_drop_impl)
 }
 
 /// Given a `DefId` for an opaque type in return position, find its parent item's return
@@ -145,7 +145,7 @@ pub fn forbid_intrinsic_abi(tcx: TyCtxt<'_>, sp: Span, abi: ExternAbi) {
     }
 }
 
-fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) {
+pub(super) fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) {
     // Only restricted on wasm target for now
     if !tcx.sess.target.is_like_wasm {
         return;
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index d72cf00293f..a400aaa8142 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -126,13 +126,14 @@ where
 
     let infcx_compat = infcx.fork();
 
-    // We specifically want to call the non-compat version of `implied_bounds_tys`; we do this always.
+    // We specifically want to *disable* the implied bounds hack, first,
+    // so we can detect when failures are due to bevy's implied bounds.
     let outlives_env = OutlivesEnvironment::new_with_implied_bounds_compat(
         &infcx,
         body_def_id,
         param_env,
         assumed_wf_types.iter().copied(),
-        false,
+        true,
     );
 
     lint_redundant_lifetimes(tcx, body_def_id, &outlives_env);
@@ -142,53 +143,22 @@ where
         return Ok(());
     }
 
-    let is_bevy = assumed_wf_types.visit_with(&mut ContainsBevyParamSet { tcx }).is_break();
-
-    // If we have set `no_implied_bounds_compat`, then do not attempt compatibility.
-    // We could also just always enter if `is_bevy`, and call `implied_bounds_tys`,
-    // but that does result in slightly more work when this option is set and
-    // just obscures what we mean here anyways. Let's just be explicit.
-    if is_bevy && !infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat {
-        let outlives_env = OutlivesEnvironment::new_with_implied_bounds_compat(
-            &infcx,
-            body_def_id,
-            param_env,
-            assumed_wf_types,
-            true,
-        );
-        let errors_compat = infcx_compat.resolve_regions_with_outlives_env(&outlives_env);
-        if errors_compat.is_empty() {
-            Ok(())
-        } else {
-            Err(infcx_compat.err_ctxt().report_region_errors(body_def_id, &errors_compat))
-        }
+    let outlives_env = OutlivesEnvironment::new_with_implied_bounds_compat(
+        &infcx_compat,
+        body_def_id,
+        param_env,
+        assumed_wf_types,
+        // Don't *disable* the implied bounds hack; though this will only apply
+        // the implied bounds hack if this contains `bevy_ecs`'s `ParamSet` type.
+        false,
+    );
+    let errors_compat = infcx_compat.resolve_regions_with_outlives_env(&outlives_env);
+    if errors_compat.is_empty() {
+        // FIXME: Once we fix bevy, this would be the place to insert a warning
+        // to upgrade bevy.
+        Ok(())
     } else {
-        Err(infcx.err_ctxt().report_region_errors(body_def_id, &errors))
-    }
-}
-
-struct ContainsBevyParamSet<'tcx> {
-    tcx: TyCtxt<'tcx>,
-}
-
-impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsBevyParamSet<'tcx> {
-    type Result = ControlFlow<()>;
-
-    fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
-        // We only care to match `ParamSet<T>` or `&ParamSet<T>`.
-        match t.kind() {
-            ty::Adt(def, _) => {
-                if self.tcx.item_name(def.did()) == sym::ParamSet
-                    && self.tcx.crate_name(def.did().krate) == sym::bevy_ecs
-                {
-                    return ControlFlow::Break(());
-                }
-            }
-            ty::Ref(_, ty, _) => ty.visit_with(self)?,
-            _ => {}
-        }
-
-        ControlFlow::Continue(())
+        Err(infcx_compat.err_ctxt().report_region_errors(body_def_id, &errors_compat))
     }
 }
 
@@ -201,7 +171,7 @@ fn check_well_formed(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Result<(), ErrorGua
         hir::Node::ImplItem(item) => check_impl_item(tcx, item),
         hir::Node::ForeignItem(item) => check_foreign_item(tcx, item),
         hir::Node::OpaqueTy(_) => Ok(crate::check::check::check_item_type(tcx, def_id)),
-        _ => unreachable!(),
+        _ => unreachable!("{node:?}"),
     };
 
     if let Some(generics) = node.generics() {
@@ -1108,7 +1078,13 @@ fn check_associated_item(
                 let ty = tcx.type_of(item.def_id).instantiate_identity();
                 let ty = wfcx.normalize(span, Some(WellFormedLoc::Ty(item_id)), ty);
                 wfcx.register_wf_obligation(span, loc, ty.into());
-                check_sized_if_body(wfcx, item.def_id.expect_local(), ty, Some(span));
+                check_sized_if_body(
+                    wfcx,
+                    item.def_id.expect_local(),
+                    ty,
+                    Some(span),
+                    ObligationCauseCode::SizedConstOrStatic,
+                );
                 Ok(())
             }
             ty::AssocKind::Fn => {
@@ -1354,7 +1330,7 @@ fn check_item_type(
                 traits::ObligationCause::new(
                     ty_span,
                     wfcx.body_def_id,
-                    ObligationCauseCode::WellFormed(None),
+                    ObligationCauseCode::SizedConstOrStatic,
                 ),
                 wfcx.param_env,
                 item_ty,
@@ -1698,6 +1674,7 @@ fn check_fn_or_method<'tcx>(
             hir::FnRetTy::Return(ty) => Some(ty.span),
             hir::FnRetTy::DefaultReturn(_) => None,
         },
+        ObligationCauseCode::SizedReturnType,
     );
 }
 
@@ -1706,13 +1683,14 @@ fn check_sized_if_body<'tcx>(
     def_id: LocalDefId,
     ty: Ty<'tcx>,
     maybe_span: Option<Span>,
+    code: ObligationCauseCode<'tcx>,
 ) {
     let tcx = wfcx.tcx();
     if let Some(body) = tcx.hir_maybe_body_owned_by(def_id) {
         let span = maybe_span.unwrap_or(body.value.span);
 
         wfcx.register_bound(
-            ObligationCause::new(span, def_id, traits::ObligationCauseCode::SizedReturnType),
+            ObligationCause::new(span, def_id, code),
             wfcx.param_env,
             ty,
             tcx.require_lang_item(LangItem::Sized, Some(span)),
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index 0245d4c9fe4..b5c6c2f3861 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -16,6 +16,7 @@ use rustc_span::{ErrorGuaranteed, sym};
 use rustc_type_ir::elaborate;
 use tracing::debug;
 
+use crate::check::always_applicable;
 use crate::errors;
 
 mod builtin;
@@ -24,11 +25,12 @@ mod inherent_impls_overlap;
 mod orphan;
 mod unsafety;
 
-fn check_impl(
-    tcx: TyCtxt<'_>,
+fn check_impl<'tcx>(
+    tcx: TyCtxt<'tcx>,
     impl_def_id: LocalDefId,
-    trait_ref: ty::TraitRef<'_>,
-    trait_def: &ty::TraitDef,
+    trait_ref: ty::TraitRef<'tcx>,
+    trait_def: &'tcx ty::TraitDef,
+    polarity: ty::ImplPolarity,
 ) -> Result<(), ErrorGuaranteed> {
     debug!(
         "(checking implementation) adding impl for trait '{:?}', item '{}'",
@@ -44,6 +46,12 @@ fn check_impl(
 
     enforce_trait_manually_implementable(tcx, impl_def_id, trait_ref.def_id, trait_def)
         .and(enforce_empty_impls_for_marker_traits(tcx, impl_def_id, trait_ref.def_id, trait_def))
+        .and(always_applicable::check_negative_auto_trait_impl(
+            tcx,
+            impl_def_id,
+            trait_ref,
+            polarity,
+        ))
 }
 
 fn enforce_trait_manually_implementable(
@@ -154,16 +162,16 @@ fn coherent_trait(tcx: TyCtxt<'_>, def_id: DefId) -> Result<(), ErrorGuaranteed>
     let mut res = tcx.ensure_ok().specialization_graph_of(def_id);
 
     for &impl_def_id in impls {
-        let trait_header = tcx.impl_trait_header(impl_def_id).unwrap();
-        let trait_ref = trait_header.trait_ref.instantiate_identity();
+        let impl_header = tcx.impl_trait_header(impl_def_id).unwrap();
+        let trait_ref = impl_header.trait_ref.instantiate_identity();
         let trait_def = tcx.trait_def(trait_ref.def_id);
 
         res = res
-            .and(check_impl(tcx, impl_def_id, trait_ref, trait_def))
+            .and(check_impl(tcx, impl_def_id, trait_ref, trait_def, impl_header.polarity))
             .and(check_object_overlap(tcx, impl_def_id, trait_ref))
-            .and(unsafety::check_item(tcx, impl_def_id, trait_header, trait_def))
+            .and(unsafety::check_item(tcx, impl_def_id, impl_header, trait_def))
             .and(tcx.ensure_ok().orphan_check_impl(impl_def_id))
-            .and(builtin::check_trait(tcx, def_id, impl_def_id, trait_header));
+            .and(builtin::check_trait(tcx, def_id, impl_def_id, impl_header));
     }
 
     res
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 027aa5554a4..49523912b14 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -45,6 +45,7 @@ use tracing::{debug, instrument};
 
 use crate::check::intrinsic::intrinsic_operation_unsafety;
 use crate::errors;
+use crate::hir_ty_lowering::errors::assoc_kind_str;
 use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer, RegionInferReason};
 
 pub(crate) mod dump;
@@ -443,13 +444,14 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
         self.tcx.at(span).type_param_predicates((self.item_def_id, def_id, assoc_name))
     }
 
-    fn lower_assoc_ty(
+    fn lower_assoc_shared(
         &self,
         span: Span,
         item_def_id: DefId,
-        item_segment: &hir::PathSegment<'tcx>,
+        item_segment: &rustc_hir::PathSegment<'tcx>,
         poly_trait_ref: ty::PolyTraitRef<'tcx>,
-    ) -> Ty<'tcx> {
+        kind: ty::AssocKind,
+    ) -> Result<(DefId, ty::GenericArgsRef<'tcx>), ErrorGuaranteed> {
         if let Some(trait_ref) = poly_trait_ref.no_bound_vars() {
             let item_args = self.lowerer().lower_generic_args_of_assoc_item(
                 span,
@@ -457,7 +459,7 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
                 item_segment,
                 trait_ref.args,
             );
-            Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
+            Ok((item_def_id, item_args))
         } else {
             // There are no late-bound regions; we can just ignore the binder.
             let (mut mpart_sugg, mut inferred_sugg) = (None, None);
@@ -518,16 +520,14 @@ impl<'tcx> HirTyLowerer<'tcx> for ItemCtxt<'tcx> {
                 }
                 _ => {}
             }
-            Ty::new_error(
-                self.tcx(),
-                self.tcx().dcx().emit_err(errors::AssociatedItemTraitUninferredGenericParams {
-                    span,
-                    inferred_sugg,
-                    bound,
-                    mpart_sugg,
-                    what: "type",
-                }),
-            )
+
+            Err(self.tcx().dcx().emit_err(errors::AssociatedItemTraitUninferredGenericParams {
+                span,
+                inferred_sugg,
+                bound,
+                mpart_sugg,
+                what: assoc_kind_str(kind),
+            }))
         }
     }
 
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index af1338e50d0..a153ce8ea90 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -187,6 +187,8 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                         Some(parent_did)
                     }
                     Node::TyPat(_) => Some(parent_did),
+                    // Field default values inherit the ADT's generics.
+                    Node::Field(_) => Some(parent_did),
                     _ => None,
                 }
             }
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 852533ff5c9..4c6c2504126 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -11,8 +11,6 @@ use rustc_middle::ty::Ty;
 use rustc_span::{Ident, Span, Symbol};
 
 use crate::fluent_generated as fluent;
-mod pattern_types;
-pub(crate) use pattern_types::*;
 pub(crate) mod wrong_number_of_generic_args;
 
 mod precise_captures;
@@ -84,6 +82,8 @@ pub(crate) struct AssocItemNotFound<'a> {
     pub label: Option<AssocItemNotFoundLabel<'a>>,
     #[subdiagnostic]
     pub sugg: Option<AssocItemNotFoundSugg<'a>>,
+    #[label(hir_analysis_within_macro)]
+    pub within_macro_span: Option<Span>,
 }
 
 #[derive(Subdiagnostic)]
@@ -711,17 +711,6 @@ pub(crate) struct InvalidUnionField {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_invalid_unsafe_field, code = E0740)]
-pub(crate) struct InvalidUnsafeField {
-    #[primary_span]
-    pub field_span: Span,
-    #[subdiagnostic]
-    pub sugg: InvalidUnsafeFieldSuggestion,
-    #[note]
-    pub note: (),
-}
-
-#[derive(Diagnostic)]
 #[diag(hir_analysis_return_type_notation_on_non_rpitit)]
 pub(crate) struct ReturnTypeNotationOnNonRpitit<'tcx> {
     #[primary_span]
@@ -742,18 +731,6 @@ pub(crate) struct InvalidUnionFieldSuggestion {
     pub hi: Span,
 }
 
-#[derive(Subdiagnostic)]
-#[multipart_suggestion(
-    hir_analysis_invalid_unsafe_field_sugg,
-    applicability = "machine-applicable"
-)]
-pub(crate) struct InvalidUnsafeFieldSuggestion {
-    #[suggestion_part(code = "std::mem::ManuallyDrop<")]
-    pub lo: Span,
-    #[suggestion_part(code = ">")]
-    pub hi: Span,
-}
-
 #[derive(Diagnostic)]
 #[diag(hir_analysis_return_type_notation_equality_bound)]
 pub(crate) struct ReturnTypeNotationEqualityBound {
diff --git a/compiler/rustc_hir_analysis/src/errors/pattern_types.rs b/compiler/rustc_hir_analysis/src/errors/pattern_types.rs
deleted file mode 100644
index ec7b3aaa1c1..00000000000
--- a/compiler/rustc_hir_analysis/src/errors/pattern_types.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-use rustc_macros::Diagnostic;
-use rustc_middle::ty::Ty;
-use rustc_span::Span;
-
-#[derive(Diagnostic)]
-#[diag(hir_analysis_invalid_base_type)]
-pub(crate) struct InvalidBaseType<'tcx> {
-    pub ty: Ty<'tcx>,
-    #[primary_span]
-    pub ty_span: Span,
-    pub pat: &'static str,
-    #[note]
-    pub pat_span: Span,
-}
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index dd346ed1f97..60af36da6e2 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -468,11 +468,13 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
                 // Good error for `where Trait::method(..): Send`.
                 let Some(self_ty) = opt_self_ty else {
-                    return self.error_missing_qpath_self_ty(
+                    let guar = self.error_missing_qpath_self_ty(
                         trait_def_id,
                         hir_ty.span,
                         item_segment,
+                        ty::AssocKind::Type,
                     );
+                    return Ty::new_error(tcx, guar);
                 };
                 let self_ty = self.lower_ty(self_ty);
 
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 922578792ba..ace5e34b382 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -151,6 +151,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             qself: &qself_str,
             label: None,
             sugg: None,
+            // Try to get the span of the identifier within the path's syntax context
+            // (if that's different).
+            within_macro_span: assoc_name.span.within_macro(span, tcx.sess.source_map()),
         };
 
         if is_dummy {
@@ -385,14 +388,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         })
     }
 
-    pub(super) fn report_ambiguous_assoc_ty(
+    pub(super) fn report_ambiguous_assoc(
         &self,
         span: Span,
         types: &[String],
         traits: &[String],
         name: Symbol,
+        kind: ty::AssocKind,
     ) -> ErrorGuaranteed {
-        let mut err = struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated type");
+        let kind_str = assoc_kind_str(kind);
+        let mut err =
+            struct_span_code_err!(self.dcx(), span, E0223, "ambiguous associated {kind_str}");
         if self
             .tcx()
             .resolutions(())
@@ -417,7 +423,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         span,
                         format!(
                             "if there were a type named `Type` that implements a trait named \
-                             `Trait` with associated type `{name}`, you could use the \
+                             `Trait` with associated {kind_str} `{name}`, you could use the \
                              fully-qualified path",
                         ),
                         format!("<Type as Trait>::{name}"),
@@ -440,7 +446,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         span,
                         format!(
                             "if there were a type named `Example` that implemented one of the \
-                             traits with associated type `{name}`, you could use the \
+                             traits with associated {kind_str} `{name}`, you could use the \
                              fully-qualified path",
                         ),
                         traits.iter().map(|trait_str| format!("<Example as {trait_str}>::{name}")),
@@ -451,7 +457,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     err.span_suggestion_verbose(
                         span,
                         format!(
-                            "if there were a trait named `Example` with associated type `{name}` \
+                            "if there were a trait named `Example` with associated {kind_str} `{name}` \
                              implemented for `{type_str}`, you could use the fully-qualified path",
                         ),
                         format!("<{type_str} as Example>::{name}"),
@@ -462,7 +468,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     err.span_suggestions(
                         span,
                         format!(
-                            "if there were a trait named `Example` with associated type `{name}` \
+                            "if there were a trait named `Example` with associated {kind_str} `{name}` \
                              implemented for one of the types, you could use the fully-qualified \
                              path",
                         ),
@@ -491,7 +497,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         err.emit()
     }
 
-    pub(crate) fn complain_about_ambiguous_inherent_assoc_ty(
+    pub(crate) fn complain_about_ambiguous_inherent_assoc(
         &self,
         name: Ident,
         candidates: Vec<DefId>,
@@ -552,13 +558,14 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     }
 
     // FIXME(inherent_associated_types): Find similarly named associated types and suggest them.
-    pub(crate) fn complain_about_inherent_assoc_ty_not_found(
+    pub(crate) fn complain_about_inherent_assoc_not_found(
         &self,
         name: Ident,
         self_ty: Ty<'tcx>,
         candidates: Vec<(DefId, (DefId, DefId))>,
         fulfillment_errors: Vec<FulfillmentError<'tcx>>,
         span: Span,
+        kind: ty::AssocKind,
     ) -> ErrorGuaranteed {
         // FIXME(fmease): This was copied in parts from an old version of `rustc_hir_typeck::method::suggest`.
         // Either
@@ -568,12 +575,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         let tcx = self.tcx();
 
+        let kind_str = assoc_kind_str(kind);
         let adt_did = self_ty.ty_adt_def().map(|def| def.did());
         let add_def_label = |err: &mut Diag<'_>| {
             if let Some(did) = adt_did {
                 err.span_label(
                     tcx.def_span(did),
-                    format!("associated item `{name}` not found for this {}", tcx.def_descr(did)),
+                    format!(
+                        "associated {kind_str} `{name}` not found for this {}",
+                        tcx.def_descr(did)
+                    ),
                 );
             }
         };
@@ -600,11 +611,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 self.dcx(),
                 name.span,
                 E0220,
-                "associated type `{name}` not found for `{self_ty}` in the current scope"
+                "associated {kind_str} `{name}` not found for `{self_ty}` in the current scope"
             );
             err.span_label(name.span, format!("associated item not found in `{self_ty}`"));
             err.note(format!(
-                "the associated type was found for\n{type_candidates}{additional_types}",
+                "the associated {kind_str} was found for\n{type_candidates}{additional_types}",
             ));
             add_def_label(&mut err);
             return err.emit();
@@ -685,7 +696,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         let mut err = self.dcx().struct_span_err(
             name.span,
-            format!("the associated type `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied")
+            format!("the associated {kind_str} `{name}` exists for `{self_ty}`, but its trait bounds were not satisfied")
         );
         if !bounds.is_empty() {
             err.note(format!(
@@ -695,7 +706,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         }
         err.span_label(
             name.span,
-            format!("associated type cannot be referenced on `{self_ty}` due to unsatisfied trait bounds")
+            format!("associated {kind_str} cannot be referenced on `{self_ty}` due to unsatisfied trait bounds")
         );
 
         for (span, mut bounds) in bound_spans {
@@ -1614,7 +1625,7 @@ fn generics_args_err_extend<'a>(
     }
 }
 
-pub(super) fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
+pub(crate) fn assoc_kind_str(kind: ty::AssocKind) -> &'static str {
     match kind {
         ty::AssocKind::Fn => "function",
         ty::AssocKind::Const => "constant",
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
index fa58f12c553..60a60f6415a 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
@@ -115,7 +115,7 @@ fn generic_arg_mismatch_err(
                     body.value.kind
                 && let Res::Def(DefKind::Fn { .. }, id) = path.res
             {
-                // FIXME(min_generic_const_args): this branch is dead once new const path lowering
+                // FIXME(mgca): this branch is dead once new const path lowering
                 // (for single-segment paths) is no longer gated
                 err.help(format!("`{}` is a function item, not a type", tcx.item_name(id)));
                 err.help("function item types cannot be named directly");
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 a0f848f07c4..dd6c40bfbb8 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -44,18 +44,18 @@ use rustc_middle::ty::{
 };
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS;
+use rustc_session::parse::feature_err;
 use rustc_span::edit_distance::find_best_match_for_name;
-use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw};
+use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym};
 use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::wf::object_region_bounds;
 use rustc_trait_selection::traits::{self, ObligationCtxt};
 use rustc_type_ir::Upcast;
 use tracing::{debug, instrument};
 
+use self::errors::assoc_kind_str;
 use crate::check::check_abi_fn_ptr;
-use crate::errors::{
-    AmbiguousLifetimeBound, BadReturnTypeNotation, InvalidBaseType, NoVariantNamed,
-};
+use crate::errors::{AmbiguousLifetimeBound, BadReturnTypeNotation, NoVariantNamed};
 use crate::hir_ty_lowering::errors::{GenericsArgsErrExtend, prohibit_assoc_item_constraint};
 use crate::hir_ty_lowering::generics::{check_generic_arg_count, lower_generic_args};
 use crate::middle::resolve_bound_vars as rbv;
@@ -152,7 +152,7 @@ pub trait HirTyLowerer<'tcx> {
         assoc_name: Ident,
     ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]>;
 
-    /// Lower an associated type to a projection.
+    /// Lower an associated type/const (from a trait) to a projection.
     ///
     /// This method has to be defined by the concrete lowering context because
     /// dealing with higher-ranked trait references depends on its capabilities:
@@ -164,13 +164,14 @@ pub trait HirTyLowerer<'tcx> {
     ///
     /// The canonical example of this is associated type `T::P` where `T` is a type
     /// param constrained by `T: for<'a> Trait<'a>` and where `Trait` defines `P`.
-    fn lower_assoc_ty(
+    fn lower_assoc_shared(
         &self,
         span: Span,
         item_def_id: DefId,
         item_segment: &hir::PathSegment<'tcx>,
         poly_trait_ref: ty::PolyTraitRef<'tcx>,
-    ) -> Ty<'tcx>;
+        kind: ty::AssocKind,
+    ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed>;
 
     fn lower_fn_sig(
         &self,
@@ -245,6 +246,42 @@ pub enum FeedConstTy<'a, 'tcx> {
     No,
 }
 
+#[derive(Debug, Clone, Copy)]
+enum LowerAssocMode {
+    Type { permit_variants: bool },
+    Const,
+}
+
+impl LowerAssocMode {
+    fn kind(self) -> ty::AssocKind {
+        match self {
+            LowerAssocMode::Type { .. } => ty::AssocKind::Type,
+            LowerAssocMode::Const => ty::AssocKind::Const,
+        }
+    }
+
+    fn def_kind(self) -> DefKind {
+        match self {
+            LowerAssocMode::Type { .. } => DefKind::AssocTy,
+            LowerAssocMode::Const => DefKind::AssocConst,
+        }
+    }
+
+    fn permit_variants(self) -> bool {
+        match self {
+            LowerAssocMode::Type { permit_variants } => permit_variants,
+            // FIXME(mgca): Support paths like `Option::<T>::None` or `Option::<T>::Some` which resolve to const ctors/fn items respectively
+            LowerAssocMode::Const => false,
+        }
+    }
+}
+
+#[derive(Debug, Clone, Copy)]
+enum LoweredAssoc<'tcx> {
+    Term(DefId, GenericArgsRef<'tcx>),
+    Variant { adt: Ty<'tcx>, variant_did: DefId },
+}
+
 /// New-typed boolean indicating whether explicit late-bound lifetimes
 /// are present in a set of generic arguments.
 ///
@@ -630,7 +667,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         (args, arg_count)
     }
 
-    #[instrument(level = "debug", skip_all)]
+    #[instrument(level = "debug", skip(self))]
     pub fn lower_generic_args_of_assoc_item(
         &self,
         span: Span,
@@ -638,7 +675,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         item_segment: &hir::PathSegment<'tcx>,
         parent_args: GenericArgsRef<'tcx>,
     ) -> GenericArgsRef<'tcx> {
-        debug!(?span, ?item_def_id, ?item_segment);
         let (args, _) =
             self.lower_generic_args_of_path(span, item_def_id, parent_args, item_segment, None);
         if let Some(c) = item_segment.args().constraints.first() {
@@ -1118,7 +1154,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     // NOTE: When this function starts resolving `Trait::AssocTy` successfully
     // it should also start reporting the `BARE_TRAIT_OBJECTS` lint.
     #[instrument(level = "debug", skip_all, ret)]
-    pub fn lower_assoc_path(
+    pub fn lower_assoc_path_ty(
         &self,
         hir_ref_id: HirId,
         span: Span,
@@ -1127,6 +1163,72 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         assoc_segment: &'tcx hir::PathSegment<'tcx>,
         permit_variants: bool,
     ) -> Result<(Ty<'tcx>, DefKind, DefId), ErrorGuaranteed> {
+        let tcx = self.tcx();
+        match self.lower_assoc_path_shared(
+            hir_ref_id,
+            span,
+            qself_ty,
+            qself,
+            assoc_segment,
+            LowerAssocMode::Type { permit_variants },
+        )? {
+            LoweredAssoc::Term(def_id, args) => {
+                let alias_ty = ty::AliasTy::new_from_args(tcx, def_id, args);
+                let ty = Ty::new_alias(tcx, alias_ty.kind(tcx), alias_ty);
+                Ok((ty, tcx.def_kind(def_id), def_id))
+            }
+            LoweredAssoc::Variant { adt, variant_did } => Ok((adt, DefKind::Variant, variant_did)),
+        }
+    }
+
+    #[instrument(level = "debug", skip_all, ret)]
+    fn lower_assoc_path_const(
+        &self,
+        hir_ref_id: HirId,
+        span: Span,
+        qself_ty: Ty<'tcx>,
+        qself: &'tcx hir::Ty<'tcx>,
+        assoc_segment: &'tcx hir::PathSegment<'tcx>,
+    ) -> Result<Const<'tcx>, ErrorGuaranteed> {
+        let tcx = self.tcx();
+        let (def_id, args) = match self.lower_assoc_path_shared(
+            hir_ref_id,
+            span,
+            qself_ty,
+            qself,
+            assoc_segment,
+            LowerAssocMode::Const,
+        )? {
+            LoweredAssoc::Term(def_id, args) => {
+                if !tcx.associated_item(def_id).is_type_const_capable(tcx) {
+                    let mut err = tcx.dcx().struct_span_err(
+                        span,
+                        "use of trait associated const without `#[type_const]`",
+                    );
+                    err.note("the declaration in the trait must be marked with `#[type_const]`");
+                    return Err(err.emit());
+                }
+                (def_id, args)
+            }
+            // FIXME(mgca): implement support for this once ready to support all adt ctor expressions,
+            // not just const ctors
+            LoweredAssoc::Variant { .. } => {
+                span_bug!(span, "unexpected variant res for type associated const path")
+            }
+        };
+        Ok(Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(def_id, args)))
+    }
+
+    #[instrument(level = "debug", skip_all, ret)]
+    fn lower_assoc_path_shared(
+        &self,
+        hir_ref_id: HirId,
+        span: Span,
+        qself_ty: Ty<'tcx>,
+        qself: &'tcx hir::Ty<'tcx>,
+        assoc_segment: &'tcx hir::PathSegment<'tcx>,
+        mode: LowerAssocMode,
+    ) -> Result<LoweredAssoc<'tcx>, ErrorGuaranteed> {
         debug!(%qself_ty, ?assoc_segment.ident);
         let tcx = self.tcx();
 
@@ -1141,13 +1243,16 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     .iter()
                     .find(|vd| tcx.hygienic_eq(assoc_ident, vd.ident(tcx), adt_def.did()));
                 if let Some(variant_def) = variant_def {
-                    if permit_variants {
+                    if mode.permit_variants() {
                         tcx.check_stability(variant_def.def_id, Some(hir_ref_id), span, None);
                         let _ = self.prohibit_generic_args(
                             slice::from_ref(assoc_segment).iter(),
                             GenericsArgsErrExtend::EnumVariant { qself, assoc_segment, adt_def },
                         );
-                        return Ok((qself_ty, DefKind::Variant, variant_def.def_id));
+                        return Ok(LoweredAssoc::Variant {
+                            adt: qself_ty,
+                            variant_did: variant_def.def_id,
+                        });
                     } else {
                         variant_resolution = Some(variant_def.def_id);
                     }
@@ -1155,15 +1260,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             }
 
             // FIXME(inherent_associated_types, #106719): Support self types other than ADTs.
-            if let Some((ty, did)) = self.probe_inherent_assoc_ty(
-                assoc_ident,
+            if let Some((did, args)) = self.probe_inherent_assoc_shared(
                 assoc_segment,
                 adt_def.did(),
                 qself_ty,
                 hir_ref_id,
                 span,
+                mode.kind(),
             )? {
-                return Ok((ty, DefKind::AssocTy, did));
+                return Ok(LoweredAssoc::Term(did, args));
             }
         }
 
@@ -1192,7 +1297,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         )
                     },
                     AssocItemQSelf::SelfTyAlias,
-                    ty::AssocKind::Type,
+                    mode.kind(),
                     assoc_ident,
                     span,
                     None,
@@ -1204,14 +1309,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             ) => self.probe_single_ty_param_bound_for_assoc_item(
                 param_did.expect_local(),
                 qself.span,
-                ty::AssocKind::Type,
+                mode.kind(),
                 assoc_ident,
                 span,
             )?,
             _ => {
+                let kind_str = assoc_kind_str(mode.kind());
                 let reported = if variant_resolution.is_some() {
                     // Variant in type position
-                    let msg = format!("expected type, found variant `{assoc_ident}`");
+                    let msg = format!("expected {kind_str}, found variant `{assoc_ident}`");
                     self.dcx().span_err(span, msg)
                 } else if qself_ty.is_enum() {
                     let mut err = self.dcx().create_err(NoVariantNamed {
@@ -1310,11 +1416,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         self.probe_traits_that_match_assoc_ty(qself_ty, assoc_ident);
 
                     // Don't print `ty::Error` to the user.
-                    self.report_ambiguous_assoc_ty(
+                    self.report_ambiguous_assoc(
                         span,
                         &[qself_ty.to_string()],
                         &traits,
                         assoc_ident.name,
+                        mode.kind(),
                     )
                 };
                 return Err(reported);
@@ -1322,10 +1429,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         };
 
         let trait_did = bound.def_id();
-        let assoc_ty = self
-            .probe_assoc_item(assoc_ident, ty::AssocKind::Type, hir_ref_id, span, trait_did)
-            .expect("failed to find associated type");
-        let ty = self.lower_assoc_ty(span, assoc_ty.def_id, assoc_segment, bound);
+        let assoc_item = self
+            .probe_assoc_item(assoc_ident, mode.kind(), hir_ref_id, span, trait_did)
+            .expect("failed to find associated item");
+        let (def_id, args) =
+            self.lower_assoc_shared(span, assoc_item.def_id, assoc_segment, bound, mode.kind())?;
+        let result = LoweredAssoc::Term(def_id, args);
 
         if let Some(variant_def_id) = variant_resolution {
             tcx.node_span_lint(AMBIGUOUS_ASSOCIATED_ITEMS, hir_ref_id, span, |lint| {
@@ -1341,7 +1450,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 };
 
                 could_refer_to(DefKind::Variant, variant_def_id, "");
-                could_refer_to(DefKind::AssocTy, assoc_ty.def_id, " also");
+                could_refer_to(mode.def_kind(), assoc_item.def_id, " also");
 
                 lint.span_suggestion(
                     span,
@@ -1351,36 +1460,51 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 );
             });
         }
-        Ok((ty, DefKind::AssocTy, assoc_ty.def_id))
+        Ok(result)
     }
 
-    fn probe_inherent_assoc_ty(
+    fn probe_inherent_assoc_shared(
         &self,
-        name: Ident,
         segment: &hir::PathSegment<'tcx>,
         adt_did: DefId,
         self_ty: Ty<'tcx>,
         block: HirId,
         span: Span,
-    ) -> Result<Option<(Ty<'tcx>, DefId)>, ErrorGuaranteed> {
+        kind: ty::AssocKind,
+    ) -> Result<Option<(DefId, GenericArgsRef<'tcx>)>, ErrorGuaranteed> {
         let tcx = self.tcx();
 
-        // Don't attempt to look up inherent associated types when the feature is not enabled.
-        // Theoretically it'd be fine to do so since we feature-gate their definition site.
-        // However, due to current limitations of the implementation (caused by us performing
-        // selection during HIR ty lowering instead of in the trait solver), IATs can lead to cycle
-        // errors (#108491) which mask the feature-gate error, needlessly confusing users
-        // who use IATs by accident (#113265).
         if !tcx.features().inherent_associated_types() {
-            return Ok(None);
+            match kind {
+                // Don't attempt to look up inherent associated types when the feature is not enabled.
+                // Theoretically it'd be fine to do so since we feature-gate their definition site.
+                // However, due to current limitations of the implementation (caused by us performing
+                // selection during HIR ty lowering instead of in the trait solver), IATs can lead to cycle
+                // errors (#108491) which mask the feature-gate error, needlessly confusing users
+                // who use IATs by accident (#113265).
+                ty::AssocKind::Type => return Ok(None),
+                ty::AssocKind::Const => {
+                    // We also gate the mgca codepath for type-level uses of inherent consts
+                    // with the inherent_associated_types feature gate since it relies on the
+                    // same machinery and has similar rough edges.
+                    return Err(feature_err(
+                        &tcx.sess,
+                        sym::inherent_associated_types,
+                        span,
+                        "inherent associated types are unstable",
+                    )
+                    .emit());
+                }
+                ty::AssocKind::Fn => unreachable!(),
+            }
         }
 
+        let name = segment.ident;
         let candidates: Vec<_> = tcx
             .inherent_impls(adt_did)
             .iter()
             .filter_map(|&impl_| {
-                let (item, scope) =
-                    self.probe_assoc_item_unchecked(name, ty::AssocKind::Type, block, impl_)?;
+                let (item, scope) = self.probe_assoc_item_unchecked(name, kind, block, impl_)?;
                 Some((impl_, (item.def_id, scope)))
             })
             .collect();
@@ -1395,13 +1519,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
         // In contexts that have no inference context, just make a new one.
         // We do need a local variable to store it, though.
-        let infcx_;
         let infcx = match self.infcx() {
             Some(infcx) => infcx,
             None => {
                 assert!(!self_ty.has_infer());
-                infcx_ = tcx.infer_ctxt().ignoring_regions().build(TypingMode::non_body_analysis());
-                &infcx_
+                &tcx.infer_ctxt().ignoring_regions().build(TypingMode::non_body_analysis())
             }
         };
 
@@ -1420,8 +1542,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             &mut universes,
             self_ty,
             |self_ty| {
-                self.select_inherent_assoc_type_candidates(
-                    infcx, name, span, self_ty, param_env, candidates,
+                self.select_inherent_assoc_candidates(
+                    infcx, name, span, self_ty, param_env, candidates, kind,
                 )
             },
         )?;
@@ -1438,13 +1560,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 .chain(args.into_iter().skip(parent_args.len())),
         );
 
-        let ty =
-            Ty::new_alias(tcx, ty::Inherent, ty::AliasTy::new_from_args(tcx, assoc_item, args));
-
-        Ok(Some((ty, assoc_item)))
+        Ok(Some((assoc_item, args)))
     }
 
-    fn select_inherent_assoc_type_candidates(
+    fn select_inherent_assoc_candidates(
         &self,
         infcx: &InferCtxt<'tcx>,
         name: Ident,
@@ -1452,6 +1571,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         self_ty: Ty<'tcx>,
         param_env: ParamEnv<'tcx>,
         candidates: Vec<(DefId, (DefId, DefId))>,
+        kind: ty::AssocKind,
     ) -> Result<(DefId, (DefId, DefId)), ErrorGuaranteed> {
         let tcx = self.tcx();
         let mut fulfillment_errors = Vec::new();
@@ -1496,17 +1616,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             .collect();
 
         match &applicable_candidates[..] {
-            &[] => Err(self.complain_about_inherent_assoc_ty_not_found(
+            &[] => Err(self.complain_about_inherent_assoc_not_found(
                 name,
                 self_ty,
                 candidates,
                 fulfillment_errors,
                 span,
+                kind,
             )),
 
             &[applicable_candidate] => Ok(applicable_candidate),
 
-            &[_, ..] => Err(self.complain_about_ambiguous_inherent_assoc_ty(
+            &[_, ..] => Err(self.complain_about_ambiguous_inherent_assoc(
                 name,
                 applicable_candidates.into_iter().map(|(_, (candidate, _))| candidate).collect(),
                 span,
@@ -1638,7 +1759,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
     /// Lower a qualified path to a type.
     #[instrument(level = "debug", skip_all)]
-    fn lower_qpath(
+    fn lower_qpath_ty(
         &self,
         span: Span,
         opt_self_ty: Option<Ty<'tcx>>,
@@ -1646,13 +1767,64 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         trait_segment: &hir::PathSegment<'tcx>,
         item_segment: &hir::PathSegment<'tcx>,
     ) -> Ty<'tcx> {
+        match self.lower_qpath_shared(
+            span,
+            opt_self_ty,
+            item_def_id,
+            trait_segment,
+            item_segment,
+            ty::AssocKind::Type,
+        ) {
+            Ok((item_def_id, item_args)) => {
+                Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
+            }
+            Err(guar) => Ty::new_error(self.tcx(), guar),
+        }
+    }
+
+    /// Lower a qualified path to a const.
+    #[instrument(level = "debug", skip_all)]
+    fn lower_qpath_const(
+        &self,
+        span: Span,
+        opt_self_ty: Option<Ty<'tcx>>,
+        item_def_id: DefId,
+        trait_segment: &hir::PathSegment<'tcx>,
+        item_segment: &hir::PathSegment<'tcx>,
+    ) -> Const<'tcx> {
+        match self.lower_qpath_shared(
+            span,
+            opt_self_ty,
+            item_def_id,
+            trait_segment,
+            item_segment,
+            ty::AssocKind::Const,
+        ) {
+            Ok((item_def_id, item_args)) => {
+                let uv = ty::UnevaluatedConst::new(item_def_id, item_args);
+                Const::new_unevaluated(self.tcx(), uv)
+            }
+            Err(guar) => Const::new_error(self.tcx(), guar),
+        }
+    }
+
+    #[instrument(level = "debug", skip_all)]
+    fn lower_qpath_shared(
+        &self,
+        span: Span,
+        opt_self_ty: Option<Ty<'tcx>>,
+        item_def_id: DefId,
+        trait_segment: &hir::PathSegment<'tcx>,
+        item_segment: &hir::PathSegment<'tcx>,
+        kind: ty::AssocKind,
+    ) -> Result<(DefId, GenericArgsRef<'tcx>), ErrorGuaranteed> {
         let tcx = self.tcx();
 
         let trait_def_id = tcx.parent(item_def_id);
         debug!(?trait_def_id);
 
         let Some(self_ty) = opt_self_ty else {
-            return self.error_missing_qpath_self_ty(trait_def_id, span, item_segment);
+            return Err(self.error_missing_qpath_self_ty(trait_def_id, span, item_segment, kind));
         };
         debug!(?self_ty);
 
@@ -1663,7 +1835,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         let item_args =
             self.lower_generic_args_of_assoc_item(span, item_def_id, item_segment, trait_ref.args);
 
-        Ty::new_projection_from_args(tcx, item_def_id, item_args)
+        Ok((item_def_id, item_args))
     }
 
     fn error_missing_qpath_self_ty(
@@ -1671,7 +1843,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         trait_def_id: DefId,
         span: Span,
         item_segment: &hir::PathSegment<'tcx>,
-    ) -> Ty<'tcx> {
+        kind: ty::AssocKind,
+    ) -> ErrorGuaranteed {
         let tcx = self.tcx();
         let path_str = tcx.def_path_str(trait_def_id);
 
@@ -1707,9 +1880,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // FIXME: also look at `tcx.generics_of(self.item_def_id()).params` any that
         // references the trait. Relevant for the first case in
         // `src/test/ui/associated-types/associated-types-in-ambiguous-context.rs`
-        let reported =
-            self.report_ambiguous_assoc_ty(span, &type_names, &[path_str], item_segment.ident.name);
-        Ty::new_error(tcx, reported)
+        self.report_ambiguous_assoc(span, &type_names, &[path_str], item_segment.ident.name, kind)
     }
 
     pub fn prohibit_generic_args<'a>(
@@ -2013,7 +2184,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     path.segments[..path.segments.len() - 2].iter(),
                     GenericsArgsErrExtend::None,
                 );
-                self.lower_qpath(
+                self.lower_qpath_ty(
                     span,
                     opt_self_ty,
                     def_id,
@@ -2167,11 +2338,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 let opt_self_ty = maybe_qself.as_ref().map(|qself| self.lower_ty(qself));
                 self.lower_const_path_resolved(opt_self_ty, path, hir_id)
             }
-            hir::ConstArgKind::Path(qpath) => ty::Const::new_error_with_message(
-                tcx,
-                qpath.span(),
-                format!("Const::lower_const_arg: invalid qpath {qpath:?}"),
-            ),
+            hir::ConstArgKind::Path(hir::QPath::TypeRelative(qself, segment)) => {
+                debug!(?qself, ?segment);
+                let ty = self.lower_ty(qself);
+                self.lower_assoc_path_const(hir_id, const_arg.span(), ty, qself, segment)
+                    .unwrap_or_else(|guar| Const::new_error(tcx, guar))
+            }
+            hir::ConstArgKind::Path(qpath @ hir::QPath::LangItem(..)) => {
+                ty::Const::new_error_with_message(
+                    tcx,
+                    qpath.span(),
+                    format!("Const::lower_const_arg: invalid qpath {qpath:?}"),
+                )
+            }
             hir::ConstArgKind::Anon(anon) => self.lower_anon_const(anon),
             hir::ConstArgKind::Infer(span, ()) => self.ct_infer(None, span),
         }
@@ -2207,6 +2386,20 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 );
                 ty::Const::new_unevaluated(tcx, ty::UnevaluatedConst::new(did, args))
             }
+            Res::Def(DefKind::AssocConst, did) => {
+                debug_assert!(path.segments.len() >= 2);
+                let _ = self.prohibit_generic_args(
+                    path.segments[..path.segments.len() - 2].iter(),
+                    GenericsArgsErrExtend::None,
+                );
+                self.lower_qpath_const(
+                    span,
+                    opt_self_ty,
+                    did,
+                    &path.segments[path.segments.len() - 2],
+                    path.segments.last().unwrap(),
+                )
+            }
             Res::Def(DefKind::Static { .. }, _) => {
                 span_bug!(span, "use of bare `static` ConstArgKind::Path's not yet supported")
             }
@@ -2223,7 +2416,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
 
             // Exhaustive match to be clear about what exactly we're considering to be
             // an invalid Res for a const path.
-            Res::Def(
+            res @ (Res::Def(
                 DefKind::Mod
                 | DefKind::Enum
                 | DefKind::Variant
@@ -2237,7 +2430,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 | DefKind::Union
                 | DefKind::Trait
                 | DefKind::ForeignTy
-                | DefKind::AssocConst
                 | DefKind::TyParam
                 | DefKind::Macro(_)
                 | DefKind::LifetimeParam
@@ -2260,12 +2452,15 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             | Res::Local(_)
             | Res::ToolMod
             | Res::NonMacroAttr(_)
-            | Res::Err => Const::new_error_with_message(tcx, span, "invalid Res for const path"),
+            | Res::Err) => Const::new_error_with_message(
+                tcx,
+                span,
+                format!("invalid Res {res:?} for const path"),
+            ),
         }
     }
 
-    /// Literals and const generic parameters are eagerly converted to a constant, everything else
-    /// becomes `Unevaluated`.
+    /// Literals are eagerly converted to a constant, everything else becomes `Unevaluated`.
     #[instrument(skip(self), level = "debug")]
     fn lower_anon_const(&self, anon: &AnonConst) -> Const<'tcx> {
         let tcx = self.tcx();
@@ -2464,7 +2659,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             hir::TyKind::Path(hir::QPath::TypeRelative(qself, segment)) => {
                 debug!(?qself, ?segment);
                 let ty = self.lower_ty(qself);
-                self.lower_assoc_path(hir_ty.hir_id, hir_ty.span, ty, qself, segment, false)
+                self.lower_assoc_path_ty(hir_ty.hir_id, hir_ty.span, ty, qself, segment, false)
                     .map(|(ty, _, _)| ty)
                     .unwrap_or_else(|guar| Ty::new_error(tcx, guar))
             }
@@ -2495,28 +2690,26 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 let ty_span = ty.span;
                 let ty = self.lower_ty(ty);
                 let pat_ty = match pat.kind {
-                    hir::TyPatKind::Range(start, end, include_end) => {
-                        let ty = match ty.kind() {
-                            ty::Int(_) | ty::Uint(_) | ty::Char => ty,
-                            _ => Ty::new_error(
-                                tcx,
-                                self.dcx().emit_err(InvalidBaseType {
-                                    ty,
-                                    pat: "range",
+                    hir::TyPatKind::Range(start, end) => {
+                        let (ty, start, end) = match ty.kind() {
+                            // Keep this list of types in sync with the list of types that
+                            // the `RangePattern` trait is implemented for.
+                            ty::Int(_) | ty::Uint(_) | ty::Char => {
+                                let start = self.lower_const_arg(start, FeedConstTy::No);
+                                let end = self.lower_const_arg(end, FeedConstTy::No);
+                                (ty, start, end)
+                            }
+                            _ => {
+                                let guar = self.dcx().span_delayed_bug(
                                     ty_span,
-                                    pat_span: pat.span,
-                                }),
-                            ),
-                        };
-                        let start = start.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
-                        let end = end.map(|expr| self.lower_const_arg(expr, FeedConstTy::No));
-
-                        let include_end = match include_end {
-                            hir::RangeEnd::Included => true,
-                            hir::RangeEnd::Excluded => false,
+                                    "invalid base type for range pattern",
+                                );
+                                let errc = ty::Const::new_error(tcx, guar);
+                                (Ty::new_error(tcx, guar), errc, errc)
+                            }
                         };
 
-                        let pat = tcx.mk_pat(ty::PatternKind::Range { start, end, include_end });
+                        let pat = tcx.mk_pat(ty::PatternKind::Range { start, end });
                         Ty::new_pat(tcx, ty, pat)
                     }
                     hir::TyPatKind::Err(e) => Ty::new_error(tcx, e),
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index cf18bab950a..50b0e32b95e 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -212,7 +212,10 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
     tcx.par_hir_body_owners(|item_def_id| {
         let def_kind = tcx.def_kind(item_def_id);
         match def_kind {
-            DefKind::Static { .. } => tcx.ensure_ok().eval_static_initializer(item_def_id),
+            DefKind::Static { .. } => {
+                tcx.ensure_ok().eval_static_initializer(item_def_id);
+                check::maybe_check_static_with_link_section(tcx, item_def_id);
+            }
             DefKind::Const if tcx.generics_of(item_def_id).is_empty() => {
                 let instance = ty::Instance::new(item_def_id.into(), ty::GenericArgs::empty());
                 let cid = GlobalId { instance, promoted: None };
@@ -223,12 +226,9 @@ pub fn check_crate(tcx: TyCtxt<'_>) {
         }
     });
 
-    // FIXME: Remove this when we implement creating `DefId`s
-    // for anon constants during their parents' typeck.
-    // Typeck all body owners in parallel will produce queries
-    // cycle errors because it may typeck on anon constants directly.
     tcx.par_hir_body_owners(|item_def_id| {
         let def_kind = tcx.def_kind(item_def_id);
+        // Skip `AnonConst`s because we feed their `type_of`.
         if !matches!(def_kind, DefKind::AnonConst) {
             tcx.ensure_ok().typeck(item_def_id);
         }
diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs
index e954d2b9ea4..8475903c68f 100644
--- a/compiler/rustc_hir_analysis/src/variance/constraints.rs
+++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs
@@ -252,13 +252,9 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
 
             ty::Pat(typ, pat) => {
                 match *pat {
-                    ty::PatternKind::Range { start, end, include_end: _ } => {
-                        if let Some(start) = start {
-                            self.add_constraints_from_const(current, start, variance);
-                        }
-                        if let Some(end) = end {
-                            self.add_constraints_from_const(current, end, variance);
-                        }
+                    ty::PatternKind::Range { start, end } => {
+                        self.add_constraints_from_const(current, start, variance);
+                        self.add_constraints_from_const(current, end, variance);
                     }
                 }
                 self.add_constraints_from_ty(current, typ, variance);
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index e06398cf3c4..1f6fb3a329a 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -1869,17 +1869,10 @@ impl<'a> State<'a> {
         // Pat isn't normalized, but the beauty of it
         // is that it doesn't matter
         match pat.kind {
-            TyPatKind::Range(begin, end, end_kind) => {
-                if let Some(expr) = begin {
-                    self.print_const_arg(expr);
-                }
-                match end_kind {
-                    RangeEnd::Included => self.word("..."),
-                    RangeEnd::Excluded => self.word(".."),
-                }
-                if let Some(expr) = end {
-                    self.print_const_arg(expr);
-                }
+            TyPatKind::Range(begin, end) => {
+                self.print_const_arg(begin);
+                self.word("..=");
+                self.print_const_arg(end);
             }
             TyPatKind::Err(_) => {
                 self.popen();
@@ -2386,6 +2379,7 @@ impl<'a> State<'a> {
     }
 
     fn print_where_predicate(&mut self, predicate: &hir::WherePredicate<'_>) {
+        self.print_attrs_as_outer(self.attrs(predicate.hir_id));
         match *predicate.kind {
             hir::WherePredicateKind::BoundPredicate(hir::WhereBoundPredicate {
                 bound_generic_params,
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index ed80bc3e7be..872861d6289 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -171,10 +171,13 @@ hir_typeck_pass_to_variadic_function = can't pass `{$ty}` to variadic function
     .suggestion = cast the value to `{$cast_ty}`
     .teach_help = certain types, like `{$ty}`, must be casted before passing them to a variadic function, because of arcane ABI rules dictated by the C standard
 
-hir_typeck_ptr_cast_add_auto_to_object = adding {$traits_len ->
-    [1] an auto trait {$traits}
+hir_typeck_ptr_cast_add_auto_to_object = cannot add {$traits_len ->
+    [1] auto trait {$traits}
     *[other] auto traits {$traits}
-} to a trait object in a pointer cast may cause UB later on
+} to dyn bound via pointer cast
+    .note = this could allow UB elsewhere
+    .help = use `transmute` if you're sure this is sound
+    .label = unsupported cast
 
 hir_typeck_remove_semi_for_coerce = you might have meant to return the `match` expression
 hir_typeck_remove_semi_for_coerce_expr = this could be implicitly returned but it is a statement, not a tail expression
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index ea4ec345ad0..70b49fea34f 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -940,23 +940,19 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                             .collect::<Vec<_>>();
 
                         if !added.is_empty() {
-                            tcx.emit_node_span_lint(
-                                lint::builtin::PTR_CAST_ADD_AUTO_TO_OBJECT,
-                                self.expr.hir_id,
-                                self.span,
-                                errors::PtrCastAddAutoToObject {
-                                    traits_len: added.len(),
-                                    traits: {
-                                        let mut traits: Vec<_> = added
-                                            .into_iter()
-                                            .map(|trait_did| tcx.def_path_str(trait_did))
-                                            .collect();
-
-                                        traits.sort();
-                                        traits.into()
-                                    },
+                            tcx.dcx().emit_err(errors::PtrCastAddAutoToObject {
+                                span: self.span,
+                                traits_len: added.len(),
+                                traits: {
+                                    let mut traits: Vec<_> = added
+                                        .into_iter()
+                                        .map(|trait_did| tcx.def_path_str(trait_did))
+                                        .collect();
+
+                                    traits.sort();
+                                    traits.into()
                                 },
-                            )
+                            });
                         }
 
                         Ok(CastKind::PtrPtrCast)
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index a5108e7a032..67419fdf1c3 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -51,15 +51,13 @@ use rustc_infer::traits::{
     PredicateObligations,
 };
 use rustc_middle::span_bug;
-use rustc_middle::traits::BuiltinImplSource;
 use rustc_middle::ty::adjustment::{
     Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability, PointerCoercion,
 };
 use rustc_middle::ty::error::TypeError;
 use rustc_middle::ty::visit::TypeVisitableExt;
 use rustc_middle::ty::{self, GenericArgsRef, Ty, TyCtxt};
-use rustc_session::parse::feature_err;
-use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Span, sym};
+use rustc_span::{BytePos, DUMMY_SP, DesugaringKind, Span};
 use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 use rustc_trait_selection::traits::{
@@ -610,8 +608,6 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             ty::TraitRef::new(self.tcx, coerce_unsized_did, [coerce_source, coerce_target])
         )];
 
-        let mut has_unsized_tuple_coercion = false;
-
         // Keep resolving `CoerceUnsized` and `Unsize` predicates to avoid
         // emitting a coercion in cases like `Foo<$1>` -> `Foo<$2>`, where
         // inference might unify those two inner type variables later.
@@ -690,31 +686,10 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                     // be silent, as it causes a type mismatch later.
                 }
 
-                Ok(Some(impl_source)) => {
-                    // Some builtin coercions are still unstable so we detect
-                    // these here and emit a feature error if coercion doesn't fail
-                    // due to another reason.
-                    match impl_source {
-                        traits::ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => {
-                            has_unsized_tuple_coercion = true;
-                        }
-                        _ => {}
-                    }
-                    queue.extend(impl_source.nested_obligations())
-                }
+                Ok(Some(impl_source)) => queue.extend(impl_source.nested_obligations()),
             }
         }
 
-        if has_unsized_tuple_coercion && !self.tcx.features().unsized_tuple_coercion() {
-            feature_err(
-                &self.tcx.sess,
-                sym::unsized_tuple_coercion,
-                self.cause.span,
-                "unsized tuple coercion is not stable enough for use and is subject to change",
-            )
-            .emit();
-        }
-
         Ok(coercion)
     }
 
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 85131f6195f..aa917ee07ff 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -1265,7 +1265,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 } else {
                     CallableKind::Function
                 };
-                maybe_emit_help(def_id, path.segments[0].ident, args, callable_kind);
+                maybe_emit_help(def_id, path.segments.last().unwrap().ident, args, callable_kind);
             }
             hir::ExprKind::MethodCall(method, _receiver, args, _span) => {
                 let Some(def_id) =
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 20688a5b949..b73cd26927a 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -373,9 +373,14 @@ pub(crate) struct LossyProvenanceInt2Ptr<'tcx> {
     pub sugg: LossyProvenanceInt2PtrSuggestion,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(hir_typeck_ptr_cast_add_auto_to_object)]
+#[derive(Diagnostic)]
+#[diag(hir_typeck_ptr_cast_add_auto_to_object, code = E0804)]
+#[note]
+#[help]
 pub(crate) struct PtrCastAddAutoToObject {
+    #[primary_span]
+    #[label]
+    pub span: Span,
     pub traits_len: usize,
     pub traits: DiagSymbolList<String>,
 }
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index dec1779d92c..2a89a03e0aa 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1806,7 +1806,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         crate::GatherLocalsVisitor::new(&fcx).visit_body(body);
 
         let ty = fcx.check_expr_with_expectation(body.value, expected);
-        fcx.require_type_is_sized(ty, body.value.span, ObligationCauseCode::ConstSized);
+        fcx.require_type_is_sized(ty, body.value.span, ObligationCauseCode::SizedConstOrStatic);
         fcx.write_ty(block.hir_id, ty);
         ty
     }
@@ -3069,7 +3069,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             "ban_nonexisting_field: field={:?}, base={:?}, expr={:?}, base_ty={:?}",
             ident, base, expr, base_ty
         );
-        let mut err = self.no_such_field_err(ident, base_ty, base.hir_id);
+        let mut err = self.no_such_field_err(ident, base_ty, expr);
 
         match *base_ty.peel_refs().kind() {
             ty::Array(_, len) => {
@@ -3282,18 +3282,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         );
     }
 
-    fn no_such_field_err(&self, field: Ident, expr_t: Ty<'tcx>, id: HirId) -> Diag<'_> {
+    fn no_such_field_err(
+        &self,
+        field: Ident,
+        base_ty: Ty<'tcx>,
+        expr: &hir::Expr<'tcx>,
+    ) -> Diag<'_> {
         let span = field.span;
-        debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, expr_t);
+        debug!("no_such_field_err(span: {:?}, field: {:?}, expr_t: {:?})", span, field, base_ty);
 
-        let mut err = self.dcx().create_err(NoFieldOnType { span, ty: expr_t, field });
-        if expr_t.references_error() {
+        let mut err = self.dcx().create_err(NoFieldOnType { span, ty: base_ty, field });
+        if base_ty.references_error() {
             err.downgrade_to_delayed_bug();
         }
 
+        if let Some(within_macro_span) = span.within_macro(expr.span, self.tcx.sess.source_map()) {
+            err.span_label(within_macro_span, "due to this macro variable");
+        }
+
         // try to add a suggestion in case the field is a nested field of a field of the Adt
-        let mod_id = self.tcx.parent_module(id).to_def_id();
-        let (ty, unwrap) = if let ty::Adt(def, args) = expr_t.kind()
+        let mod_id = self.tcx.parent_module(expr.hir_id).to_def_id();
+        let (ty, unwrap) = if let ty::Adt(def, args) = base_ty.kind()
             && (self.tcx.is_diagnostic_item(sym::Result, def.did())
                 || self.tcx.is_diagnostic_item(sym::Option, def.did()))
             && let Some(arg) = args.get(0)
@@ -3301,10 +3310,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         {
             (ty, "unwrap().")
         } else {
-            (expr_t, "")
+            (base_ty, "")
         };
         for (found_fields, args) in
-            self.get_field_candidates_considering_privacy_for_diag(span, ty, mod_id, id)
+            self.get_field_candidates_considering_privacy_for_diag(span, ty, mod_id, expr.hir_id)
         {
             let field_names = found_fields.iter().map(|field| field.name).collect::<Vec<_>>();
             let mut candidate_fields: Vec<_> = found_fields
@@ -3317,7 +3326,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         args,
                         vec![],
                         mod_id,
-                        id,
+                        expr.hir_id,
                     )
                 })
                 .map(|mut field_path| {
@@ -3328,7 +3337,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             candidate_fields.sort();
 
             let len = candidate_fields.len();
-            if len > 0 {
+            // Don't suggest `.field` if the base expr is from a different
+            // syntax context than the field.
+            if len > 0 && expr.span.eq_ctxt(field.span) {
                 err.span_suggestions(
                     field.span.shrink_to_lo(),
                     format!(
@@ -3963,7 +3974,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 _ => (),
             };
 
-            self.no_such_field_err(field, container, expr.hir_id).emit();
+            self.no_such_field_err(field, container, expr).emit();
 
             break;
         }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 054e3bcb67c..c46a42c5de1 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -669,12 +669,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         if !errors.is_empty() {
             self.adjust_fulfillment_errors_for_expr_obligation(&mut errors);
-            let errors_causecode = errors
-                .iter()
-                .map(|e| (e.obligation.cause.span, e.root_obligation.cause.code().clone()))
-                .collect::<Vec<_>>();
             self.err_ctxt().report_fulfillment_errors(errors);
-            self.collect_unused_stmts_for_coerce_return_ty(errors_causecode);
         }
     }
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index e60a4bb47b5..db947b6744d 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -3,9 +3,7 @@ use std::{fmt, iter, mem};
 use itertools::Itertools;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::codes::*;
-use rustc_errors::{
-    Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey, a_or_an, listify, pluralize,
-};
+use rustc_errors::{Applicability, Diag, ErrorGuaranteed, MultiSpan, a_or_an, listify, pluralize};
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
@@ -2174,7 +2172,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 let result = self
                     .lowerer()
-                    .lower_assoc_path(hir_id, path_span, ty.raw, qself, segment, true);
+                    .lower_assoc_path_ty(hir_id, path_span, ty.raw, qself, segment, true);
                 let ty = result
                     .map(|(ty, _, _)| ty)
                     .unwrap_or_else(|guar| Ty::new_error(self.tcx(), guar));
@@ -2193,62 +2191,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    pub(super) fn collect_unused_stmts_for_coerce_return_ty(
-        &self,
-        errors_causecode: Vec<(Span, ObligationCauseCode<'tcx>)>,
-    ) {
-        for (span, code) in errors_causecode {
-            self.dcx().try_steal_modify_and_emit_err(span, StashKey::MaybeForgetReturn, |err| {
-                if let Some(fn_sig) = self.body_fn_sig()
-                    && let ObligationCauseCode::WhereClauseInExpr(_, _, binding_hir_id, ..) = code
-                    && !fn_sig.output().is_unit()
-                {
-                    let mut block_num = 0;
-                    let mut found_semi = false;
-                    for (hir_id, node) in self.tcx.hir_parent_iter(binding_hir_id) {
-                        // Don't proceed into parent bodies
-                        if hir_id.owner != binding_hir_id.owner {
-                            break;
-                        }
-                        match node {
-                            hir::Node::Stmt(stmt) => {
-                                if let hir::StmtKind::Semi(expr) = stmt.kind {
-                                    let expr_ty = self.typeck_results.borrow().expr_ty(expr);
-                                    let return_ty = fn_sig.output();
-                                    if !matches!(expr.kind, hir::ExprKind::Ret(..))
-                                        && self.may_coerce(expr_ty, return_ty)
-                                    {
-                                        found_semi = true;
-                                    }
-                                }
-                            }
-                            hir::Node::Block(_block) => {
-                                if found_semi {
-                                    block_num += 1;
-                                }
-                            }
-                            hir::Node::Item(item) => {
-                                if let hir::ItemKind::Fn { .. } = item.kind {
-                                    break;
-                                }
-                            }
-                            _ => {}
-                        }
-                    }
-                    if block_num > 1 && found_semi {
-                        err.span_suggestion_verbose(
-                            // use the span of the *whole* expr
-                            self.tcx.hir().span(binding_hir_id).shrink_to_lo(),
-                            "you might have meant to return this to infer its type parameters",
-                            "return ",
-                            Applicability::MaybeIncorrect,
-                        );
-                    }
-                }
-            });
-        }
-    }
-
     /// Given a vector of fulfillment errors, try to adjust the spans of the
     /// errors to more accurately point at the cause of the failure.
     ///
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
index 42236ac6d80..e14f1528d2c 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/mod.rs
@@ -17,7 +17,7 @@ use rustc_infer::infer;
 use rustc_infer::traits::Obligation;
 use rustc_middle::ty::{self, Const, Ty, TyCtxt, TypeVisitableExt};
 use rustc_session::Session;
-use rustc_span::{self, DUMMY_SP, Ident, Span, sym};
+use rustc_span::{self, DUMMY_SP, ErrorGuaranteed, Ident, Span, sym};
 use rustc_trait_selection::error_reporting::TypeErrCtxt;
 use rustc_trait_selection::error_reporting::infer::sub_relations::SubRelations;
 use rustc_trait_selection::traits::{ObligationCause, ObligationCauseCode, ObligationCtxt};
@@ -308,15 +308,17 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
         ))
     }
 
-    fn lower_assoc_ty(
+    fn lower_assoc_shared(
         &self,
         span: Span,
         item_def_id: DefId,
-        item_segment: &hir::PathSegment<'tcx>,
+        item_segment: &rustc_hir::PathSegment<'tcx>,
         poly_trait_ref: ty::PolyTraitRef<'tcx>,
-    ) -> Ty<'tcx> {
+        _kind: ty::AssocKind,
+    ) -> Result<(DefId, ty::GenericArgsRef<'tcx>), ErrorGuaranteed> {
         let trait_ref = self.instantiate_binder_with_fresh_vars(
             span,
+            // FIXME(mgca): this should be assoc const if that is the `kind`
             infer::BoundRegionConversionTime::AssocTypeProjection(item_def_id),
             poly_trait_ref,
         );
@@ -328,7 +330,7 @@ impl<'tcx> HirTyLowerer<'tcx> for FnCtxt<'_, 'tcx> {
             trait_ref.args,
         );
 
-        Ty::new_projection_from_args(self.tcx(), item_def_id, item_args)
+        Ok((item_def_id, item_args))
     }
 
     fn probe_adt(&self, span: Span, ty: Ty<'tcx>) -> Option<ty::AdtDef<'tcx>> {
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 18218a7a0a6..cb1e89fb9e5 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -158,7 +158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             self.typeck_results.borrow_mut().used_trait_imports.insert(import_id);
         }
 
-        let (span, sugg_span, source, item_name, args) = match self.tcx.hir_node(call_id) {
+        let (span, expr_span, source, item_name, args) = match self.tcx.hir_node(call_id) {
             hir::Node::Expr(&hir::Expr {
                 kind: hir::ExprKind::MethodCall(segment, rcvr, args, _),
                 span,
@@ -194,6 +194,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             node => unreachable!("{node:?}"),
         };
 
+        // Try to get the span of the identifier within the expression's syntax context
+        // (if that's different).
+        let within_macro_span = span.within_macro(expr_span, self.tcx.sess.source_map());
+
         // Avoid suggestions when we don't know what's going on.
         if let Err(guar) = rcvr_ty.error_reported() {
             return guar;
@@ -207,10 +211,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 call_id,
                 source,
                 args,
-                sugg_span,
+                expr_span,
                 &mut no_match_data,
                 expected,
                 trait_missing_method,
+                within_macro_span,
             ),
 
             MethodError::Ambiguity(mut sources) => {
@@ -221,6 +226,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     "multiple applicable items in scope"
                 );
                 err.span_label(item_name.span, format!("multiple `{item_name}` found"));
+                if let Some(within_macro_span) = within_macro_span {
+                    err.span_label(within_macro_span, "due to this macro variable");
+                }
 
                 self.note_candidates_on_method_error(
                     rcvr_ty,
@@ -230,7 +238,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     span,
                     &mut err,
                     &mut sources,
-                    Some(sugg_span),
+                    Some(expr_span),
                 );
                 err.emit()
             }
@@ -252,6 +260,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .span_if_local(def_id)
                     .unwrap_or_else(|| self.tcx.def_span(def_id));
                 err.span_label(sp, format!("private {kind} defined here"));
+                if let Some(within_macro_span) = within_macro_span {
+                    err.span_label(within_macro_span, "due to this macro variable");
+                }
                 self.suggest_valid_traits(&mut err, item_name, out_of_scope_traits, true);
                 err.emit()
             }
@@ -268,6 +279,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if !needs_mut {
                     err.span_label(bound_span, "this has a `Sized` requirement");
                 }
+                if let Some(within_macro_span) = within_macro_span {
+                    err.span_label(within_macro_span, "due to this macro variable");
+                }
                 if !candidates.is_empty() {
                     let help = format!(
                         "{an}other candidate{s} {were} found in the following trait{s}",
@@ -581,6 +595,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         no_match_data: &mut NoMatchData<'tcx>,
         expected: Expectation<'tcx>,
         trait_missing_method: bool,
+        within_macro_span: Option<Span>,
     ) -> ErrorGuaranteed {
         let mode = no_match_data.mode;
         let tcx = self.tcx;
@@ -721,6 +736,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         if tcx.sess.source_map().is_multiline(sugg_span) {
             err.span_label(sugg_span.with_hi(span.lo()), "");
         }
+        if let Some(within_macro_span) = within_macro_span {
+            err.span_label(within_macro_span, "due to this macro variable");
+        }
 
         if short_ty_str.len() < ty_str.len() && ty_str.len() > 10 {
             ty_str = short_ty_str;
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 553215ca0af..e47385d0899 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -2,14 +2,14 @@ use std::any::Any;
 use std::ffi::OsString;
 use std::io::{self, BufWriter, Write};
 use std::path::{Path, PathBuf};
-use std::sync::{Arc, LazyLock};
+use std::sync::{Arc, LazyLock, OnceLock};
 use std::{env, fs, iter};
 
 use rustc_ast as ast;
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_data_structures::parallel;
 use rustc_data_structures::steal::Steal;
-use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, OnceLock, WorkerLocal};
+use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, WorkerLocal};
 use rustc_expand::base::{ExtCtxt, LintStoreExpand};
 use rustc_feature::Features;
 use rustc_fs_util::try_canonicalize;
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 5c5b3b350dd..7018774e5c6 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -599,6 +599,11 @@ fn register_builtins(store: &mut LintStore) {
         "converted into hard error, \
          see <https://github.com/rust-lang/rust/issues/73333> for more information",
     );
+    store.register_removed(
+        "ptr_cast_add_auto_to_object",
+        "converted into hard error, see issue #127323 \
+         <https://github.com/rust-lang/rust/issues/127323> for more information",
+    );
 }
 
 fn register_internals(store: &mut LintStore) {
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index cb83d405cc3..fcadbfc3c4a 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1,7 +1,7 @@
 use std::iter;
 use std::ops::ControlFlow;
 
-use rustc_abi::{BackendRepr, ExternAbi, TagEncoding, VariantIdx, Variants, WrappingRange};
+use rustc_abi::{BackendRepr, TagEncoding, VariantIdx, Variants, WrappingRange};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::DiagMessage;
 use rustc_hir::intravisit::VisitorExt;
@@ -882,27 +882,13 @@ fn ty_is_known_nonnull<'tcx>(
                 || Option::unwrap_or_default(
                     try {
                         match **pat {
-                            ty::PatternKind::Range { start, end, include_end } => {
-                                match (start, end) {
-                                    (Some(start), None) => {
-                                        start.try_to_value()?.try_to_bits(tcx, typing_env)? > 0
-                                    }
-                                    (Some(start), Some(end)) => {
-                                        let start =
-                                            start.try_to_value()?.try_to_bits(tcx, typing_env)?;
-                                        let end =
-                                            end.try_to_value()?.try_to_bits(tcx, typing_env)?;
-
-                                        if include_end {
-                                            // This also works for negative numbers, as we just need
-                                            // to ensure we aren't wrapping over zero.
-                                            start > 0 && end >= start
-                                        } else {
-                                            start > 0 && end > start
-                                        }
-                                    }
-                                    _ => false,
-                                }
+                            ty::PatternKind::Range { start, end } => {
+                                let start = start.try_to_value()?.try_to_bits(tcx, typing_env)?;
+                                let end = end.try_to_value()?.try_to_bits(tcx, typing_env)?;
+
+                                // This also works for negative numbers, as we just need
+                                // to ensure we aren't wrapping over zero.
+                                start > 0 && end >= start
                             }
                         }
                     },
@@ -1349,7 +1335,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
 
             ty::FnPtr(sig_tys, hdr) => {
                 let sig = sig_tys.with(hdr);
-                if self.is_internal_abi(sig.abi()) {
+                if sig.abi().is_rustic_abi() {
                     return FfiUnsafe {
                         ty,
                         reason: fluent::lint_improper_ctypes_fnptr_reason,
@@ -1552,13 +1538,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         self.check_type_for_ffi_and_report_errors(span, ty, true, false);
     }
 
-    fn is_internal_abi(&self, abi: ExternAbi) -> bool {
-        matches!(
-            abi,
-            ExternAbi::Rust | ExternAbi::RustCall | ExternAbi::RustCold | ExternAbi::RustIntrinsic
-        )
-    }
-
     /// Find any fn-ptr types with external ABIs in `ty`.
     ///
     /// For example, `Option<extern "C" fn()>` returns `extern "C" fn()`
@@ -1567,17 +1546,16 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
         hir_ty: &hir::Ty<'tcx>,
         ty: Ty<'tcx>,
     ) -> Vec<(Ty<'tcx>, Span)> {
-        struct FnPtrFinder<'a, 'b, 'tcx> {
-            visitor: &'a ImproperCTypesVisitor<'b, 'tcx>,
+        struct FnPtrFinder<'tcx> {
             spans: Vec<Span>,
             tys: Vec<Ty<'tcx>>,
         }
 
-        impl<'a, 'b, 'tcx> hir::intravisit::Visitor<'_> for FnPtrFinder<'a, 'b, 'tcx> {
+        impl<'tcx> hir::intravisit::Visitor<'_> for FnPtrFinder<'tcx> {
             fn visit_ty(&mut self, ty: &'_ hir::Ty<'_, AmbigArg>) {
                 debug!(?ty);
                 if let hir::TyKind::BareFn(hir::BareFnTy { abi, .. }) = ty.kind
-                    && !self.visitor.is_internal_abi(*abi)
+                    && !abi.is_rustic_abi()
                 {
                     self.spans.push(ty.span);
                 }
@@ -1586,12 +1564,12 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             }
         }
 
-        impl<'a, 'b, 'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for FnPtrFinder<'a, 'b, 'tcx> {
+        impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for FnPtrFinder<'tcx> {
             type Result = ();
 
             fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result {
                 if let ty::FnPtr(_, hdr) = ty.kind()
-                    && !self.visitor.is_internal_abi(hdr.abi)
+                    && !hdr.abi.is_rustic_abi()
                 {
                     self.tys.push(ty);
                 }
@@ -1600,7 +1578,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             }
         }
 
-        let mut visitor = FnPtrFinder { visitor: self, spans: Vec::new(), tys: Vec::new() };
+        let mut visitor = FnPtrFinder { spans: Vec::new(), tys: Vec::new() };
         ty.visit_with(&mut visitor);
         visitor.visit_ty_unambig(hir_ty);
 
@@ -1615,13 +1593,13 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDeclarations {
 
         match it.kind {
             hir::ForeignItemKind::Fn(sig, _, _) => {
-                if vis.is_internal_abi(abi) {
+                if abi.is_rustic_abi() {
                     vis.check_fn(it.owner_id.def_id, sig.decl)
                 } else {
                     vis.check_foreign_fn(it.owner_id.def_id, sig.decl);
                 }
             }
-            hir::ForeignItemKind::Static(ty, _, _) if !vis.is_internal_abi(abi) => {
+            hir::ForeignItemKind::Static(ty, _, _) if !abi.is_rustic_abi() => {
                 vis.check_foreign_static(it.owner_id, ty.span);
             }
             hir::ForeignItemKind::Static(..) | hir::ForeignItemKind::Type => (),
@@ -1775,7 +1753,7 @@ impl<'tcx> LateLintPass<'tcx> for ImproperCTypesDefinitions {
         };
 
         let mut vis = ImproperCTypesVisitor { cx, mode: CItemKind::Definition };
-        if vis.is_internal_abi(abi) {
+        if abi.is_rustic_abi() {
             vis.check_fn(id, decl);
         } else {
             vis.check_foreign_fn(id, decl);
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 97850a2afc1..10b85be2cfb 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -80,7 +80,6 @@ declare_lint_pass! {
         PRIVATE_BOUNDS,
         PRIVATE_INTERFACES,
         PROC_MACRO_DERIVE_RESOLUTION_FALLBACK,
-        PTR_CAST_ADD_AUTO_TO_OBJECT,
         PTR_TO_INTEGER_TRANSMUTE_IN_CONSTS,
         PUB_USE_OF_PRIVATE_EXTERN_CRATE,
         REDUNDANT_IMPORTS,
@@ -3782,7 +3781,7 @@ declare_lint! {
     Warn,
     "use of unsupported calling convention for function pointer",
     @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorDontReportInDeps,
+        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
         reference: "issue #130260 <https://github.com/rust-lang/rust/issues/130260>",
     };
 }
@@ -4828,58 +4827,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `ptr_cast_add_auto_to_object` lint detects casts of raw pointers to trait
-    /// objects, which add auto traits.
-    ///
-    /// ### Example
-    ///
-    /// ```rust,edition2021,compile_fail
-    /// let ptr: *const dyn core::any::Any = &();
-    /// _ = ptr as *const dyn core::any::Any + Send;
-    /// ```
-    ///
-    /// {{produces}}
-    ///
-    /// ### Explanation
-    ///
-    /// Adding an auto trait can make the vtable invalid, potentially causing
-    /// UB in safe code afterwards. For example:
-    ///
-    /// ```ignore (causes a warning)
-    /// #![feature(arbitrary_self_types)]
-    ///
-    /// trait Trait {
-    ///     fn f(self: *const Self)
-    ///     where
-    ///         Self: Send;
-    /// }
-    ///
-    /// impl Trait for *const () {
-    ///     fn f(self: *const Self) {
-    ///         unreachable!()
-    ///     }
-    /// }
-    ///
-    /// fn main() {
-    ///     let unsend: *const () = &();
-    ///     let unsend: *const dyn Trait = &unsend;
-    ///     let send_bad: *const (dyn Trait + Send) = unsend as _;
-    ///     send_bad.f(); // this crashes, since vtable for `*const ()` does not have an entry for `f`
-    /// }
-    /// ```
-    ///
-    /// Generally you must ensure that vtable is right for the pointer's type,
-    /// before passing the pointer to safe code.
-    pub PTR_CAST_ADD_AUTO_TO_OBJECT,
-    Warn,
-    "detects `as` casts from pointers to `dyn Trait` to pointers to `dyn Trait + Auto`",
-    @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
-        reference: "issue #127323 <https://github.com/rust-lang/rust/issues/127323>",
-    };
-}
-
-declare_lint! {
     /// The `out_of_scope_macro_calls` lint detects `macro_rules` called when they are not in scope,
     /// above their definition, which may happen in key-value attributes.
     ///
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 6e607baebb5..bc3d4d6f83a 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -484,7 +484,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
 
   if (ArgsCstrBuff != nullptr) {
 #if LLVM_VERSION_GE(20, 0)
-    int buffer_offset = 0;
+    size_t buffer_offset = 0;
     assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0');
     auto Arg0 = std::string(ArgsCstrBuff);
     buffer_offset = Arg0.size() + 1;
@@ -502,7 +502,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
     Options.MCOptions.Argv0 = Arg0;
     Options.MCOptions.CommandlineArgs = CommandlineArgs;
 #else
-    int buffer_offset = 0;
+    size_t buffer_offset = 0;
     assert(ArgsCstrBuff[ArgsCstrBuffLen - 1] == '\0');
 
     const size_t arg0_len = std::strlen(ArgsCstrBuff);
@@ -511,13 +511,13 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
     arg0[arg0_len] = '\0';
     buffer_offset += arg0_len + 1;
 
-    const int num_cmd_arg_strings = std::count(
+    const size_t num_cmd_arg_strings = std::count(
         &ArgsCstrBuff[buffer_offset], &ArgsCstrBuff[ArgsCstrBuffLen], '\0');
 
     std::string *cmd_arg_strings = new std::string[num_cmd_arg_strings];
-    for (int i = 0; i < num_cmd_arg_strings; ++i) {
+    for (size_t i = 0; i < num_cmd_arg_strings; ++i) {
       assert(buffer_offset < ArgsCstrBuffLen);
-      const int len = std::strlen(ArgsCstrBuff + buffer_offset);
+      const size_t len = std::strlen(ArgsCstrBuff + buffer_offset);
       cmd_arg_strings[i] = std::string(&ArgsCstrBuff[buffer_offset], len);
       buffer_offset += len + 1;
     }
diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl
index df0a25712cc..20f66fae5c0 100644
--- a/compiler/rustc_metadata/messages.ftl
+++ b/compiler/rustc_metadata/messages.ftl
@@ -244,6 +244,9 @@ metadata_prev_alloc_error_handler =
 metadata_prev_global_alloc =
     previous global allocator defined here
 
+metadata_raw_dylib_elf_unstable =
+    link kind `raw-dylib` is unstable on ELF platforms
+
 metadata_raw_dylib_no_nul =
     link name must not contain NUL characters if link kind is `raw-dylib`
 
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index e2d043f47c0..b96921a63f3 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -17,7 +17,7 @@ use rustc_session::search_paths::PathKind;
 use rustc_session::utils::NativeLibKind;
 use rustc_span::def_id::{DefId, LOCAL_CRATE};
 use rustc_span::{Symbol, sym};
-use rustc_target::spec::LinkSelfContainedComponents;
+use rustc_target::spec::{BinaryFormat, LinkSelfContainedComponents};
 
 use crate::{errors, fluent_generated};
 
@@ -263,9 +263,26 @@ impl<'tcx> Collector<'tcx> {
                                 NativeLibKind::Framework { as_needed: None }
                             }
                             "raw-dylib" => {
-                                if !sess.target.is_like_windows {
+                                if sess.target.is_like_windows {
+                                    // raw-dylib is stable and working on Windows
+                                } else if sess.target.binary_format == BinaryFormat::Elf
+                                    && features.raw_dylib_elf()
+                                {
+                                    // raw-dylib is unstable on ELF, but the user opted in
+                                } else if sess.target.binary_format == BinaryFormat::Elf
+                                    && sess.is_nightly_build()
+                                {
+                                    feature_err(
+                                        sess,
+                                        sym::raw_dylib_elf,
+                                        span,
+                                        fluent_generated::metadata_raw_dylib_elf_unstable,
+                                    )
+                                    .emit();
+                                } else {
                                     sess.dcx().emit_err(errors::RawDylibOnlyWindows { span });
                                 }
+
                                 NativeLibKind::RawDylib
                             }
                             "link-arg" => {
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index e8d9d17872f..6ffbebfffd5 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -2,7 +2,7 @@
 
 use std::iter::TrustedLen;
 use std::path::Path;
-use std::sync::Arc;
+use std::sync::{Arc, OnceLock};
 use std::{io, iter, mem};
 
 pub(super) use cstore_impl::provide;
@@ -11,7 +11,7 @@ use rustc_ast as ast;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::owned_slice::OwnedSlice;
-use rustc_data_structures::sync::{Lock, OnceLock};
+use rustc_data_structures::sync::Lock;
 use rustc_data_structures::unhash::UnhashMap;
 use rustc_expand::base::{SyntaxExtension, SyntaxExtensionKind};
 use rustc_expand::proc_macro::{AttrProcMacro, BangProcMacro, DeriveProcMacro};
diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs
index 171542d1279..d0dbf64dc59 100644
--- a/compiler/rustc_middle/src/mir/basic_blocks.rs
+++ b/compiler/rustc_middle/src/mir/basic_blocks.rs
@@ -1,8 +1,9 @@
+use std::sync::OnceLock;
+
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::graph;
 use rustc_data_structures::graph::dominators::{Dominators, dominators};
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
-use rustc_data_structures::sync::OnceLock;
 use rustc_index::{IndexSlice, IndexVec};
 use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation.rs b/compiler/rustc_middle/src/mir/interpret/allocation.rs
index 95bc9b71fe0..ba65a711815 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation.rs
@@ -222,7 +222,7 @@ impl AllocError {
 }
 
 /// The information that makes up a memory access: offset and size.
-#[derive(Copy, Clone, PartialEq)]
+#[derive(Copy, Clone)]
 pub struct AllocRange {
     pub start: Size,
     pub size: Size,
@@ -470,7 +470,7 @@ impl<Prov: Provenance, Extra, Bytes: AllocBytes> Allocation<Prov, Extra, Bytes>
             // Find the provenance.
             let (offset, _prov) = self
                 .provenance
-                .range_get_ptrs(range, cx)
+                .range_ptrs_get(range, cx)
                 .first()
                 .copied()
                 .expect("there must be provenance somewhere here");
diff --git a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
index 82fb5f33b4c..c9525df1f79 100644
--- a/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
+++ b/compiler/rustc_middle/src/mir/interpret/allocation/provenance_map.rs
@@ -67,7 +67,7 @@ impl ProvenanceMap {
 }
 
 impl<Prov: Provenance> ProvenanceMap<Prov> {
-    fn adjusted_range(range: AllocRange, cx: &impl HasDataLayout) -> Range<Size> {
+    fn adjusted_range_ptrs(range: AllocRange, cx: &impl HasDataLayout) -> Range<Size> {
         // We have to go back `pointer_size - 1` bytes, as that one would still overlap with
         // the beginning of this range.
         let adjusted_start = Size::from_bytes(
@@ -79,26 +79,21 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
     /// Returns all ptr-sized provenance in the given range.
     /// If the range has length 0, returns provenance that crosses the edge between `start-1` and
     /// `start`.
-    pub(super) fn range_get_ptrs(
+    pub(super) fn range_ptrs_get(
         &self,
         range: AllocRange,
         cx: &impl HasDataLayout,
     ) -> &[(Size, Prov)] {
-        self.ptrs.range(Self::adjusted_range(range, cx))
+        self.ptrs.range(Self::adjusted_range_ptrs(range, cx))
     }
 
-    /// `pm.range_get_ptrs_is_empty(r, cx)` == `pm.range_get_ptrs(r, cx).is_empty()`, but is
-    /// faster.
-    pub(super) fn range_get_ptrs_is_empty(
-        &self,
-        range: AllocRange,
-        cx: &impl HasDataLayout,
-    ) -> bool {
-        self.ptrs.range_is_empty(Self::adjusted_range(range, cx))
+    /// `pm.range_ptrs_is_empty(r, cx)` == `pm.range_ptrs_get(r, cx).is_empty()`, but is faster.
+    pub(super) fn range_ptrs_is_empty(&self, range: AllocRange, cx: &impl HasDataLayout) -> bool {
+        self.ptrs.range_is_empty(Self::adjusted_range_ptrs(range, cx))
     }
 
     /// Returns all byte-wise provenance in the given range.
-    fn range_get_bytes(&self, range: AllocRange) -> &[(Size, Prov)] {
+    fn range_bytes_get(&self, range: AllocRange) -> &[(Size, Prov)] {
         if let Some(bytes) = self.bytes.as_ref() {
             bytes.range(range.start..range.end())
         } else {
@@ -106,9 +101,14 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
         }
     }
 
+    /// Same as `range_bytes_get(range).is_empty()`, but faster.
+    fn range_bytes_is_empty(&self, range: AllocRange) -> bool {
+        self.bytes.as_ref().is_none_or(|bytes| bytes.range_is_empty(range.start..range.end()))
+    }
+
     /// Get the provenance of a single byte.
     pub fn get(&self, offset: Size, cx: &impl HasDataLayout) -> Option<Prov> {
-        let prov = self.range_get_ptrs(alloc_range(offset, Size::from_bytes(1)), cx);
+        let prov = self.range_ptrs_get(alloc_range(offset, Size::from_bytes(1)), cx);
         debug_assert!(prov.len() <= 1);
         if let Some(entry) = prov.first() {
             // If it overlaps with this byte, it is on this byte.
@@ -132,7 +132,7 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
     /// limit access to provenance outside of the `Allocation` abstraction.
     ///
     pub fn range_empty(&self, range: AllocRange, cx: &impl HasDataLayout) -> bool {
-        self.range_get_ptrs_is_empty(range, cx) && self.range_get_bytes(range).is_empty()
+        self.range_ptrs_is_empty(range, cx) && self.range_bytes_is_empty(range)
     }
 
     /// Yields all the provenances stored in this map.
@@ -164,14 +164,14 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
         // provenance that overlaps with the given range.
         let (first, last) = {
             // Find all provenance overlapping the given range.
-            if self.range_get_ptrs_is_empty(range, cx) {
+            if self.range_ptrs_is_empty(range, cx) {
                 // No provenance in this range, we are done. This is the common case.
                 return Ok(());
             }
 
             // This redoes some of the work of `range_get_ptrs_is_empty`, but this path is much
             // colder than the early return above, so it's worth it.
-            let provenance = self.range_get_ptrs(range, cx);
+            let provenance = self.range_ptrs_get(range, cx);
             (
                 provenance.first().unwrap().0,
                 provenance.last().unwrap().0 + cx.data_layout().pointer_size,
@@ -284,8 +284,8 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
         // This includes the existing bytewise provenance in the range, and ptr provenance
         // that overlaps with the begin/end of the range.
         let mut dest_bytes_box = None;
-        let begin_overlap = self.range_get_ptrs(alloc_range(src.start, Size::ZERO), cx).first();
-        let end_overlap = self.range_get_ptrs(alloc_range(src.end(), Size::ZERO), cx).first();
+        let begin_overlap = self.range_ptrs_get(alloc_range(src.start, Size::ZERO), cx).first();
+        let end_overlap = self.range_ptrs_get(alloc_range(src.end(), Size::ZERO), cx).first();
         if !Prov::OFFSET_IS_ADDR {
             // There can't be any bytewise provenance, and we cannot split up the begin/end overlap.
             if let Some(entry) = begin_overlap {
@@ -308,10 +308,10 @@ impl<Prov: Provenance> ProvenanceMap<Prov> {
             } else {
                 trace!("no start overlapping entry");
             }
+
             // Then the main part, bytewise provenance from `self.bytes`.
-            if let Some(all_bytes) = self.bytes.as_ref() {
-                bytes.extend(all_bytes.range(src.start..src.end()));
-            }
+            bytes.extend(self.range_bytes_get(src));
+
             // And finally possibly parts of a pointer at the end.
             if let Some(entry) = end_overlap {
                 trace!("end overlapping entry: {entry:?}");
diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs
index 5950ac295af..9308570d89d 100644
--- a/compiler/rustc_middle/src/mir/traversal.rs
+++ b/compiler/rustc_middle/src/mir/traversal.rs
@@ -23,19 +23,13 @@ pub struct Preorder<'a, 'tcx> {
     body: &'a Body<'tcx>,
     visited: DenseBitSet<BasicBlock>,
     worklist: Vec<BasicBlock>,
-    root_is_start_block: bool,
 }
 
 impl<'a, 'tcx> Preorder<'a, 'tcx> {
     pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> Preorder<'a, 'tcx> {
         let worklist = vec![root];
 
-        Preorder {
-            body,
-            visited: DenseBitSet::new_empty(body.basic_blocks.len()),
-            worklist,
-            root_is_start_block: root == START_BLOCK,
-        }
+        Preorder { body, visited: DenseBitSet::new_empty(body.basic_blocks.len()), worklist }
     }
 }
 
@@ -71,15 +65,11 @@ impl<'a, 'tcx> Iterator for Preorder<'a, 'tcx> {
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        // All the blocks, minus the number of blocks we've visited.
-        let upper = self.body.basic_blocks.len() - self.visited.count();
+        // The worklist might be only things already visited.
+        let lower = 0;
 
-        let lower = if self.root_is_start_block {
-            // We will visit all remaining blocks exactly once.
-            upper
-        } else {
-            self.worklist.len()
-        };
+        // This is extremely loose, but it's not worth a popcnt loop to do better.
+        let upper = self.body.basic_blocks.len();
 
         (lower, Some(upper))
     }
@@ -108,7 +98,6 @@ pub struct Postorder<'a, 'tcx> {
     basic_blocks: &'a IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
     visited: DenseBitSet<BasicBlock>,
     visit_stack: Vec<(BasicBlock, Successors<'a>)>,
-    root_is_start_block: bool,
     /// A non-empty `extra` allows for a precise calculation of the successors.
     extra: Option<(TyCtxt<'tcx>, Instance<'tcx>)>,
 }
@@ -123,7 +112,6 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
             basic_blocks,
             visited: DenseBitSet::new_empty(basic_blocks.len()),
             visit_stack: Vec::new(),
-            root_is_start_block: root == START_BLOCK,
             extra,
         };
 
@@ -211,16 +199,13 @@ impl<'tcx> Iterator for Postorder<'_, 'tcx> {
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
-        // All the blocks, minus the number of blocks we've visited.
-        let upper = self.basic_blocks.len() - self.visited.count();
-
-        let lower = if self.root_is_start_block {
-            // We will visit all remaining blocks exactly once.
-            upper
-        } else {
-            self.visit_stack.len()
-        };
+        // These bounds are not at all tight, but that's fine.
+        // It's not worth a popcnt loop in `DenseBitSet` to improve the upper,
+        // and in mono-reachable we can't be precise anyway.
+        // Leaning on amortized growth is fine.
 
+        let lower = self.visit_stack.len();
+        let upper = self.basic_blocks.len();
         (lower, Some(upper))
     }
 }
diff --git a/compiler/rustc_middle/src/query/keys.rs b/compiler/rustc_middle/src/query/keys.rs
index 1489d57aba6..98314b5abfd 100644
--- a/compiler/rustc_middle/src/query/keys.rs
+++ b/compiler/rustc_middle/src/query/keys.rs
@@ -508,6 +508,14 @@ impl<'tcx, T: Clone> Key for CanonicalQueryInput<'tcx, T> {
     }
 }
 
+impl<'tcx, T: Clone> Key for (CanonicalQueryInput<'tcx, T>, bool) {
+    type Cache<V> = DefaultCache<Self, V>;
+
+    fn default_span(&self, _tcx: TyCtxt<'_>) -> Span {
+        DUMMY_SP
+    }
+}
+
 impl Key for (Symbol, u32, u32) {
     type Cache<V> = DefaultCache<Self, V>;
 
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 1302027aabb..4ad4427594c 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -2262,22 +2262,13 @@ rustc_queries! {
         desc { "normalizing `{}`", goal.value }
     }
 
-    query implied_outlives_bounds_compat(
-        goal: CanonicalImpliedOutlivesBoundsGoal<'tcx>
-    ) -> Result<
-        &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
-        NoSolution,
-    > {
-        desc { "computing implied outlives bounds for `{}`", goal.canonical.value.value.ty }
-    }
-
     query implied_outlives_bounds(
-        goal: CanonicalImpliedOutlivesBoundsGoal<'tcx>
+        key: (CanonicalImpliedOutlivesBoundsGoal<'tcx>, bool)
     ) -> Result<
         &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
         NoSolution,
     > {
-        desc { "computing implied outlives bounds v2 for `{}`", goal.canonical.value.value.ty }
+        desc { "computing implied outlives bounds for `{}` (hack disabled = {:?})", key.0.canonical.value.value.ty, key.1 }
     }
 
     /// Do not call this query directly:
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index e5592de81cd..72f31cec008 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -19,7 +19,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BindingMode, ByRef, HirId, MatchSource, RangeEnd};
 use rustc_index::{IndexVec, newtype_index};
-use rustc_macros::{HashStable, TypeVisitable};
+use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeVisitable};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{ErrorGuaranteed, Span, Symbol};
 use rustc_target::asm::InlineAsmRegOrRegClass;
@@ -49,10 +49,13 @@ macro_rules! thir_with_elements {
             }
         )*
 
+        // Note: Making `Thir` implement `Clone` is useful for external tools that need access to
+        // THIR bodies even after the `Steal` query result has been stolen.
+        // One such tool is https://github.com/rust-corpus/qrates/.
         /// A container for a THIR body.
         ///
         /// This can be indexed directly by any THIR index (e.g. [`ExprId`]).
-        #[derive(Debug, HashStable)]
+        #[derive(Debug, HashStable, Clone)]
         pub struct Thir<'tcx> {
             pub body_type: BodyTy<'tcx>,
             $(
@@ -90,7 +93,7 @@ thir_with_elements! {
     params: ParamId => Param<'tcx> => "p{}",
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Debug, HashStable, Clone)]
 pub enum BodyTy<'tcx> {
     Const(Ty<'tcx>),
     Fn(FnSig<'tcx>),
@@ -98,7 +101,7 @@ pub enum BodyTy<'tcx> {
 }
 
 /// Description of a type-checked function parameter.
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct Param<'tcx> {
     /// The pattern that appears in the parameter list, or None for implicit parameters.
     pub pat: Option<Box<Pat<'tcx>>>,
@@ -118,7 +121,7 @@ pub enum LintLevel {
     Explicit(HirId),
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct Block {
     /// Whether the block itself has a label. Used by `label: {}`
     /// and `try` blocks.
@@ -138,7 +141,7 @@ pub struct Block {
 
 type UserTy<'tcx> = Option<Box<CanonicalUserType<'tcx>>>;
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct AdtExpr<'tcx> {
     /// The ADT we're constructing.
     pub adt_def: AdtDef<'tcx>,
@@ -155,7 +158,7 @@ pub struct AdtExpr<'tcx> {
     pub base: AdtExprBase<'tcx>,
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub enum AdtExprBase<'tcx> {
     /// A struct expression where all the fields are explicitly enumerated: `Foo { a, b }`.
     None,
@@ -168,7 +171,7 @@ pub enum AdtExprBase<'tcx> {
     DefaultFields(Box<[Ty<'tcx>]>),
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct ClosureExpr<'tcx> {
     pub closure_id: LocalDefId,
     pub args: UpvarArgs<'tcx>,
@@ -177,7 +180,7 @@ pub struct ClosureExpr<'tcx> {
     pub fake_reads: Vec<(ExprId, FakeReadCause, HirId)>,
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct InlineAsmExpr<'tcx> {
     pub asm_macro: AsmMacro,
     pub template: &'tcx [InlineAsmTemplatePiece],
@@ -195,12 +198,12 @@ pub enum BlockSafety {
     ExplicitUnsafe(HirId),
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct Stmt<'tcx> {
     pub kind: StmtKind<'tcx>,
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub enum StmtKind<'tcx> {
     /// An expression with a trailing semicolon.
     Expr {
@@ -240,11 +243,11 @@ pub enum StmtKind<'tcx> {
     },
 }
 
-#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, HashStable)]
+#[derive(Clone, Debug, Copy, PartialEq, Eq, Hash, HashStable, TyEncodable, TyDecodable)]
 pub struct LocalVarId(pub HirId);
 
 /// A THIR expression.
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct Expr<'tcx> {
     /// kind of expression
     pub kind: ExprKind<'tcx>,
@@ -271,7 +274,7 @@ pub struct TempLifetime {
     pub backwards_incompatible: Option<region::Scope>,
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub enum ExprKind<'tcx> {
     /// `Scope`s are used to explicitly mark destruction scopes,
     /// and to track the `HirId` of the expressions within the scope.
@@ -548,20 +551,20 @@ pub enum ExprKind<'tcx> {
 /// Represents the association of a field identifier and an expression.
 ///
 /// This is used in struct constructors.
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct FieldExpr {
     pub name: FieldIdx,
     pub expr: ExprId,
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct FruInfo<'tcx> {
     pub base: ExprId,
     pub field_types: Box<[Ty<'tcx>]>,
 }
 
 /// A `match` arm.
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub struct Arm<'tcx> {
     pub pattern: Box<Pat<'tcx>>,
     pub guard: Option<ExprId>,
@@ -579,7 +582,7 @@ pub enum LogicalOp {
     Or,
 }
 
-#[derive(Debug, HashStable)]
+#[derive(Clone, Debug, HashStable)]
 pub enum InlineAsmOperand<'tcx> {
     In {
         reg: InlineAsmRegOrRegClass,
@@ -616,13 +619,13 @@ pub enum InlineAsmOperand<'tcx> {
     },
 }
 
-#[derive(Debug, HashStable, TypeVisitable)]
+#[derive(Clone, Debug, HashStable, TypeVisitable)]
 pub struct FieldPat<'tcx> {
     pub field: FieldIdx,
     pub pattern: Pat<'tcx>,
 }
 
-#[derive(Debug, HashStable, TypeVisitable)]
+#[derive(Clone, Debug, HashStable, TypeVisitable)]
 pub struct Pat<'tcx> {
     pub ty: Ty<'tcx>,
     pub span: Span,
@@ -729,7 +732,7 @@ impl<'tcx> Pat<'tcx> {
     }
 }
 
-#[derive(Debug, HashStable, TypeVisitable)]
+#[derive(Clone, Debug, HashStable, TypeVisitable)]
 pub struct Ascription<'tcx> {
     pub annotation: CanonicalUserTypeAnnotation<'tcx>,
     /// Variance to use when relating the `user_ty` to the **type of the value being
@@ -753,7 +756,7 @@ pub struct Ascription<'tcx> {
     pub variance: ty::Variance,
 }
 
-#[derive(Debug, HashStable, TypeVisitable)]
+#[derive(Clone, Debug, HashStable, TypeVisitable)]
 pub enum PatKind<'tcx> {
     /// A wildcard pattern: `_`.
     Wild,
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index d033ecc75db..53f233f20eb 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -266,7 +266,7 @@ pub enum ObligationCauseCode<'tcx> {
     },
 
     /// Constant expressions must be sized.
-    ConstSized,
+    SizedConstOrStatic,
 
     /// `static` items must have `Sync` type.
     SharedStatic,
@@ -397,9 +397,9 @@ pub enum ObligationCauseCode<'tcx> {
 
     RustCall,
 
-    /// Obligations to prove that a `std::ops::Drop` impl is not stronger than
+    /// Obligations to prove that a `Drop` or negative auto trait impl is not stronger than
     /// the ADT it's being implemented for.
-    DropImpl,
+    AlwaysApplicableImpl,
 
     /// Requirement for a `const N: Ty` to implement `Ty: ConstParamTy`
     ConstParam(Ty<'tcx>),
diff --git a/compiler/rustc_middle/src/ty/assoc.rs b/compiler/rustc_middle/src/ty/assoc.rs
index 6309dd2e490..ce4c08aa485 100644
--- a/compiler/rustc_middle/src/ty/assoc.rs
+++ b/compiler/rustc_middle/src/ty/assoc.rs
@@ -3,7 +3,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Namespace};
 use rustc_hir::def_id::DefId;
 use rustc_macros::{Decodable, Encodable, HashStable};
-use rustc_span::{Ident, Symbol};
+use rustc_span::{Ident, Symbol, sym};
 
 use super::{TyCtxt, Visibility};
 use crate::ty;
@@ -108,6 +108,24 @@ impl AssocItem {
     pub fn is_impl_trait_in_trait(&self) -> bool {
         self.opt_rpitit_info.is_some()
     }
+
+    /// Returns true if:
+    /// - This trait associated item has the `#[type_const]` attribute,
+    /// - If it is in a trait impl, the item from the original trait has this attribute, or
+    /// - It is an inherent assoc const.
+    pub fn is_type_const_capable(&self, tcx: TyCtxt<'_>) -> bool {
+        if self.kind != ty::AssocKind::Const {
+            return false;
+        }
+
+        let def_id = match (self.container, self.trait_item_def_id) {
+            (AssocItemContainer::Trait, _) => self.def_id,
+            (AssocItemContainer::Impl, Some(trait_item_did)) => trait_item_did,
+            // Inherent impl but this attr is only applied to trait assoc items.
+            (AssocItemContainer::Impl, None) => return true,
+        };
+        tcx.has_attr(def_id, sym::type_const)
+    }
 }
 
 #[derive(Copy, Clone, PartialEq, Debug, HashStable, Eq, Hash, Encodable, Decodable)]
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index d0aa2b8cbda..4013f7b2c85 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1327,6 +1327,11 @@ pub struct TyCtxt<'tcx> {
     gcx: &'tcx GlobalCtxt<'tcx>,
 }
 
+// Explicitly implement `DynSync` and `DynSend` for `TyCtxt` to short circuit trait resolution. Its
+// field are asserted to implement these traits below, so this is trivially safe, and it greatly
+// speeds-up compilation of this crate and its dependents.
+unsafe impl DynSend for TyCtxt<'_> {}
+unsafe impl DynSync for TyCtxt<'_> {}
 fn _assert_tcx_fields() {
     sync::assert_dyn_sync::<&'_ GlobalCtxt<'_>>();
     sync::assert_dyn_send::<&'_ GlobalCtxt<'_>>();
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index ec0498b168c..0b8f0e8cd41 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -220,13 +220,9 @@ impl FlagComputation {
             &ty::Pat(ty, pat) => {
                 self.add_ty(ty);
                 match *pat {
-                    ty::PatternKind::Range { start, end, include_end: _ } => {
-                        if let Some(start) = start {
-                            self.add_const(start)
-                        }
-                        if let Some(end) = end {
-                            self.add_const(end)
-                        }
+                    ty::PatternKind::Range { start, end } => {
+                        self.add_const(start);
+                        self.add_const(end);
                     }
                 }
             }
diff --git a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
index 505c7278176..953ad62be0a 100644
--- a/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
+++ b/compiler/rustc_middle/src/ty/inhabitedness/inhabited_predicate.rs
@@ -236,6 +236,11 @@ impl<'tcx> InhabitedPredicate<'tcx> {
         self.instantiate_opt(tcx, args).unwrap_or(self)
     }
 
+    /// Same as [`Self::instantiate`], but if there is no generics to
+    /// instantiate, returns `None`. This is useful because it lets us avoid
+    /// allocating a recursive copy of everything when the result is unchanged.
+    ///
+    /// Only used to implement `instantiate` itself.
     fn instantiate_opt(self, tcx: TyCtxt<'tcx>, args: ty::GenericArgsRef<'tcx>) -> Option<Self> {
         match self {
             Self::ConstIsZero(c) => {
@@ -260,7 +265,10 @@ impl<'tcx> InhabitedPredicate<'tcx> {
                 Some(InhabitedPredicate::True) => Some(InhabitedPredicate::True),
                 Some(a) => Some(a.or(tcx, b.instantiate_opt(tcx, args).unwrap_or(b))),
             },
-            _ => None,
+            Self::True | Self::False | Self::NotInModule(_) => None,
+            Self::OpaqueType(_) => {
+                bug!("unexpected OpaqueType in InhabitedPredicate");
+            }
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/pattern.rs b/compiler/rustc_middle/src/ty/pattern.rs
index e604aedd05e..4cad1ab2099 100644
--- a/compiler/rustc_middle/src/ty/pattern.rs
+++ b/compiler/rustc_middle/src/ty/pattern.rs
@@ -26,18 +26,30 @@ impl<'tcx> fmt::Debug for Pattern<'tcx> {
 impl<'tcx> fmt::Debug for PatternKind<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
-            PatternKind::Range { start, end, include_end } => {
-                if let Some(start) = start {
-                    write!(f, "{start}")?;
+            PatternKind::Range { start, end } => {
+                write!(f, "{start}")?;
+
+                if let Some(c) = end.try_to_value() {
+                    let end = c.valtree.unwrap_leaf();
+                    let size = end.size();
+                    let max = match c.ty.kind() {
+                        ty::Int(_) => {
+                            Some(ty::ScalarInt::truncate_from_int(size.signed_int_max(), size))
+                        }
+                        ty::Uint(_) => {
+                            Some(ty::ScalarInt::truncate_from_uint(size.unsigned_int_max(), size))
+                        }
+                        ty::Char => Some(ty::ScalarInt::truncate_from_uint(char::MAX, size)),
+                        _ => None,
+                    };
+                    if let Some((max, _)) = max
+                        && end == max
+                    {
+                        return write!(f, "..");
+                    }
                 }
-                write!(f, "..")?;
-                if include_end {
-                    write!(f, "=")?;
-                }
-                if let Some(end) = end {
-                    write!(f, "{end}")?;
-                }
-                Ok(())
+
+                write!(f, "..={end}")
             }
         }
     }
@@ -46,5 +58,5 @@ impl<'tcx> fmt::Debug for PatternKind<'tcx> {
 #[derive(Clone, PartialEq, Eq, Hash)]
 #[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
 pub enum PatternKind<'tcx> {
-    Range { start: Option<ty::Const<'tcx>>, end: Option<ty::Const<'tcx>>, include_end: bool },
+    Range { start: ty::Const<'tcx>, end: ty::Const<'tcx> },
 }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index c77b37a302b..34d85534d0a 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -133,6 +133,20 @@ pub macro with_no_queries($e:expr) {{
     ))
 }}
 
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+pub enum WrapBinderMode {
+    ForAll,
+    Unsafe,
+}
+impl WrapBinderMode {
+    pub fn start_str(self) -> &'static str {
+        match self {
+            WrapBinderMode::ForAll => "for<",
+            WrapBinderMode::Unsafe => "unsafe<",
+        }
+    }
+}
+
 /// The "region highlights" are used to control region printing during
 /// specific error messages. When a "region highlight" is enabled, it
 /// gives an alternate way to print specific regions. For now, we
@@ -219,7 +233,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         self.print_def_path(def_id, args)
     }
 
-    fn in_binder<T>(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), PrintError>
+    fn print_in_binder<T>(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), PrintError>
     where
         T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
     {
@@ -229,6 +243,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
     fn wrap_binder<T, F: FnOnce(&T, &mut Self) -> Result<(), fmt::Error>>(
         &mut self,
         value: &ty::Binder<'tcx, T>,
+        _mode: WrapBinderMode,
         f: F,
     ) -> Result<(), PrintError>
     where
@@ -703,8 +718,9 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             }
             ty::FnPtr(ref sig_tys, hdr) => p!(print(sig_tys.with(hdr))),
             ty::UnsafeBinder(ref bound_ty) => {
-                // FIXME(unsafe_binders): Make this print `unsafe<>` rather than `for<>`.
-                self.wrap_binder(bound_ty, |ty, cx| cx.pretty_print_type(*ty))?;
+                self.wrap_binder(bound_ty, WrapBinderMode::Unsafe, |ty, cx| {
+                    cx.pretty_print_type(*ty)
+                })?;
             }
             ty::Infer(infer_ty) => {
                 if self.should_print_verbose() {
@@ -1067,29 +1083,33 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
             };
 
             if let Some(return_ty) = entry.return_ty {
-                self.wrap_binder(&bound_args_and_self_ty, |(args, _), cx| {
-                    define_scoped_cx!(cx);
-                    p!(write("{}", tcx.item_name(trait_def_id)));
-                    p!("(");
-
-                    for (idx, ty) in args.iter().enumerate() {
-                        if idx > 0 {
-                            p!(", ");
+                self.wrap_binder(
+                    &bound_args_and_self_ty,
+                    WrapBinderMode::ForAll,
+                    |(args, _), cx| {
+                        define_scoped_cx!(cx);
+                        p!(write("{}", tcx.item_name(trait_def_id)));
+                        p!("(");
+
+                        for (idx, ty) in args.iter().enumerate() {
+                            if idx > 0 {
+                                p!(", ");
+                            }
+                            p!(print(ty));
                         }
-                        p!(print(ty));
-                    }
 
-                    p!(")");
-                    if let Some(ty) = return_ty.skip_binder().as_type() {
-                        if !ty.is_unit() {
-                            p!(" -> ", print(return_ty));
+                        p!(")");
+                        if let Some(ty) = return_ty.skip_binder().as_type() {
+                            if !ty.is_unit() {
+                                p!(" -> ", print(return_ty));
+                            }
                         }
-                    }
-                    p!(write("{}", if paren_needed { ")" } else { "" }));
+                        p!(write("{}", if paren_needed { ")" } else { "" }));
 
-                    first = false;
-                    Ok(())
-                })?;
+                        first = false;
+                        Ok(())
+                    },
+                )?;
             } else {
                 // Otherwise, render this like a regular trait.
                 traits.insert(
@@ -1110,7 +1130,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         for (trait_pred, assoc_items) in traits {
             write!(self, "{}", if first { "" } else { " + " })?;
 
-            self.wrap_binder(&trait_pred, |trait_pred, cx| {
+            self.wrap_binder(&trait_pred, WrapBinderMode::ForAll, |trait_pred, cx| {
                 define_scoped_cx!(cx);
 
                 if trait_pred.polarity == ty::PredicatePolarity::Negative {
@@ -1302,7 +1322,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         let mut first = true;
 
         if let Some(bound_principal) = predicates.principal() {
-            self.wrap_binder(&bound_principal, |principal, cx| {
+            self.wrap_binder(&bound_principal, WrapBinderMode::ForAll, |principal, cx| {
                 define_scoped_cx!(cx);
                 p!(print_def_path(principal.def_id, &[]));
 
@@ -1927,7 +1947,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
         let kind = closure.kind_ty().to_opt_closure_kind().unwrap_or(ty::ClosureKind::Fn);
 
         write!(self, "impl ")?;
-        self.wrap_binder(&sig, |sig, cx| {
+        self.wrap_binder(&sig, WrapBinderMode::ForAll, |sig, cx| {
             define_scoped_cx!(cx);
 
             p!(write("{kind}("));
@@ -2367,22 +2387,23 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> {
         Ok(())
     }
 
-    fn in_binder<T>(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), PrintError>
+    fn print_in_binder<T>(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), PrintError>
     where
         T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
     {
-        self.pretty_in_binder(value)
+        self.pretty_print_in_binder(value)
     }
 
     fn wrap_binder<T, C: FnOnce(&T, &mut Self) -> Result<(), PrintError>>(
         &mut self,
         value: &ty::Binder<'tcx, T>,
+        mode: WrapBinderMode,
         f: C,
     ) -> Result<(), PrintError>
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
-        self.pretty_wrap_binder(value, f)
+        self.pretty_wrap_binder(value, mode, f)
     }
 
     fn typed_value(
@@ -2632,6 +2653,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
     pub fn name_all_regions<T>(
         &mut self,
         value: &ty::Binder<'tcx, T>,
+        mode: WrapBinderMode,
     ) -> Result<(T, UnordMap<ty::BoundRegion, ty::Region<'tcx>>), fmt::Error>
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
@@ -2705,9 +2727,13 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
         // anyways.
         let (new_value, map) = if self.should_print_verbose() {
             for var in value.bound_vars().iter() {
-                start_or_continue(self, "for<", ", ");
+                start_or_continue(self, mode.start_str(), ", ");
                 write!(self, "{var:?}")?;
             }
+            // Unconditionally render `unsafe<>`.
+            if value.bound_vars().is_empty() && mode == WrapBinderMode::Unsafe {
+                start_or_continue(self, mode.start_str(), "");
+            }
             start_or_continue(self, "", "> ");
             (value.clone().skip_binder(), UnordMap::default())
         } else {
@@ -2772,8 +2798,9 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
                     }
                 };
 
-                if !trim_path {
-                    start_or_continue(self, "for<", ", ");
+                // Unconditionally render `unsafe<>`.
+                if !trim_path || mode == WrapBinderMode::Unsafe {
+                    start_or_continue(self, mode.start_str(), ", ");
                     do_continue(self, name);
                 }
                 ty::Region::new_bound(tcx, ty::INNERMOST, ty::BoundRegion { var: br.var, kind })
@@ -2786,9 +2813,12 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
             };
             let new_value = value.clone().skip_binder().fold_with(&mut folder);
             let region_map = folder.region_map;
-            if !trim_path {
-                start_or_continue(self, "", "> ");
+
+            if mode == WrapBinderMode::Unsafe && region_map.is_empty() {
+                start_or_continue(self, mode.start_str(), "");
             }
+            start_or_continue(self, "", "> ");
+
             (new_value, region_map)
         };
 
@@ -2797,12 +2827,15 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
         Ok((new_value, map))
     }
 
-    pub fn pretty_in_binder<T>(&mut self, value: &ty::Binder<'tcx, T>) -> Result<(), fmt::Error>
+    pub fn pretty_print_in_binder<T>(
+        &mut self,
+        value: &ty::Binder<'tcx, T>,
+    ) -> Result<(), fmt::Error>
     where
         T: Print<'tcx, Self> + TypeFoldable<TyCtxt<'tcx>>,
     {
         let old_region_index = self.region_index;
-        let (new_value, _) = self.name_all_regions(value)?;
+        let (new_value, _) = self.name_all_regions(value, WrapBinderMode::ForAll)?;
         new_value.print(self)?;
         self.region_index = old_region_index;
         self.binder_depth -= 1;
@@ -2812,13 +2845,14 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
     pub fn pretty_wrap_binder<T, C: FnOnce(&T, &mut Self) -> Result<(), fmt::Error>>(
         &mut self,
         value: &ty::Binder<'tcx, T>,
+        mode: WrapBinderMode,
         f: C,
     ) -> Result<(), fmt::Error>
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
         let old_region_index = self.region_index;
-        let (new_value, _) = self.name_all_regions(value)?;
+        let (new_value, _) = self.name_all_regions(value, mode)?;
         f(&new_value, self)?;
         self.region_index = old_region_index;
         self.binder_depth -= 1;
@@ -2877,7 +2911,7 @@ where
     T: Print<'tcx, P> + TypeFoldable<TyCtxt<'tcx>>,
 {
     fn print(&self, cx: &mut P) -> Result<(), PrintError> {
-        cx.in_binder(self)
+        cx.print_in_binder(self)
     }
 }
 
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 839c1c346a4..b1dfcb80bde 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -51,22 +51,12 @@ impl<'tcx> Relate<TyCtxt<'tcx>> for ty::Pattern<'tcx> {
     ) -> RelateResult<'tcx, Self> {
         match (&*a, &*b) {
             (
-                &ty::PatternKind::Range { start: start_a, end: end_a, include_end: inc_a },
-                &ty::PatternKind::Range { start: start_b, end: end_b, include_end: inc_b },
+                &ty::PatternKind::Range { start: start_a, end: end_a },
+                &ty::PatternKind::Range { start: start_b, end: end_b },
             ) => {
-                // FIXME(pattern_types): make equal patterns equal (`0..=` is the same as `..=`).
-                let mut relate_opt_const = |a, b| match (a, b) {
-                    (None, None) => Ok(None),
-                    (Some(a), Some(b)) => relation.relate(a, b).map(Some),
-                    // FIXME(pattern_types): report a better error
-                    _ => Err(TypeError::Mismatch),
-                };
-                let start = relate_opt_const(start_a, start_b)?;
-                let end = relate_opt_const(end_a, end_b)?;
-                if inc_a != inc_b {
-                    todo!()
-                }
-                Ok(relation.cx().mk_pat(ty::PatternKind::Range { start, end, include_end: inc_a }))
+                let start = relation.relate(start_a, start_b)?;
+                let end = relation.relate(end_a, end_b)?;
+                Ok(relation.cx().mk_pat(ty::PatternKind::Range { start, end }))
             }
         }
     }
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index db9e9fbc643..6c62c04f42e 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -284,6 +284,7 @@ TrivialTypeTraversalImpls! {
     rustc_hir::def_id::LocalDefId,
     rustc_hir::HirId,
     rustc_hir::MatchSource,
+    rustc_hir::RangeEnd,
     rustc_span::Ident,
     rustc_span::Span,
     rustc_span::Symbol,
diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs
index 3e8a3d1a289..a23316ae6fc 100644
--- a/compiler/rustc_middle/src/ty/walk.rs
+++ b/compiler/rustc_middle/src/ty/walk.rs
@@ -137,9 +137,9 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
 
             ty::Pat(ty, pat) => {
                 match *pat {
-                    ty::PatternKind::Range { start, end, include_end: _ } => {
-                        stack.extend(end.map(Into::into));
-                        stack.extend(start.map(Into::into));
+                    ty::PatternKind::Range { start, end } => {
+                        stack.push(end.into());
+                        stack.push(start.into());
                     }
                 }
                 stack.push(ty.into());
diff --git a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
index 10b43390eb2..c6f3e22e95f 100644
--- a/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/match_pair.rs
@@ -6,27 +6,25 @@ use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 
 use crate::builder::Builder;
 use crate::builder::expr::as_place::{PlaceBase, PlaceBuilder};
-use crate::builder::matches::{FlatPat, MatchPairTree, TestCase};
+use crate::builder::matches::{FlatPat, MatchPairTree, PatternExtraData, TestCase};
 
 impl<'a, 'tcx> Builder<'a, 'tcx> {
-    /// Builds and returns [`MatchPairTree`] subtrees, one for each pattern in
+    /// Builds and pushes [`MatchPairTree`] subtrees, one for each pattern in
     /// `subpatterns`, representing the fields of a [`PatKind::Variant`] or
     /// [`PatKind::Leaf`].
     ///
     /// Used internally by [`MatchPairTree::for_pattern`].
     fn field_match_pairs(
         &mut self,
+        match_pairs: &mut Vec<MatchPairTree<'tcx>>,
+        extra_data: &mut PatternExtraData<'tcx>,
         place: PlaceBuilder<'tcx>,
         subpatterns: &[FieldPat<'tcx>],
-    ) -> Vec<MatchPairTree<'tcx>> {
-        subpatterns
-            .iter()
-            .map(|fieldpat| {
-                let place =
-                    place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty));
-                MatchPairTree::for_pattern(place, &fieldpat.pattern, self)
-            })
-            .collect()
+    ) {
+        for fieldpat in subpatterns {
+            let place = place.clone_project(PlaceElem::Field(fieldpat.field, fieldpat.pattern.ty));
+            MatchPairTree::for_pattern(place, &fieldpat.pattern, self, match_pairs, extra_data);
+        }
     }
 
     /// Builds [`MatchPairTree`] subtrees for the prefix/middle/suffix parts of an
@@ -36,6 +34,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     fn prefix_slice_suffix(
         &mut self,
         match_pairs: &mut Vec<MatchPairTree<'tcx>>,
+        extra_data: &mut PatternExtraData<'tcx>,
         place: &PlaceBuilder<'tcx>,
         prefix: &[Pat<'tcx>],
         opt_slice: &Option<Box<Pat<'tcx>>>,
@@ -56,11 +55,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             ((prefix.len() + suffix.len()).try_into().unwrap(), false)
         };
 
-        match_pairs.extend(prefix.iter().enumerate().map(|(idx, subpattern)| {
+        for (idx, subpattern) in prefix.iter().enumerate() {
             let elem =
                 ProjectionElem::ConstantIndex { offset: idx as u64, min_length, from_end: false };
-            MatchPairTree::for_pattern(place.clone_project(elem), subpattern, self)
-        }));
+            let place = place.clone_project(elem);
+            MatchPairTree::for_pattern(place, subpattern, self, match_pairs, extra_data)
+        }
 
         if let Some(subslice_pat) = opt_slice {
             let suffix_len = suffix.len() as u64;
@@ -69,10 +69,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 to: if exact_size { min_length - suffix_len } else { suffix_len },
                 from_end: !exact_size,
             });
-            match_pairs.push(MatchPairTree::for_pattern(subslice, subslice_pat, self));
+            MatchPairTree::for_pattern(subslice, subslice_pat, self, match_pairs, extra_data);
         }
 
-        match_pairs.extend(suffix.iter().rev().enumerate().map(|(idx, subpattern)| {
+        for (idx, subpattern) in suffix.iter().rev().enumerate() {
             let end_offset = (idx + 1) as u64;
             let elem = ProjectionElem::ConstantIndex {
                 offset: if exact_size { min_length - end_offset } else { end_offset },
@@ -80,19 +80,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 from_end: !exact_size,
             };
             let place = place.clone_project(elem);
-            MatchPairTree::for_pattern(place, subpattern, self)
-        }));
+            MatchPairTree::for_pattern(place, subpattern, self, match_pairs, extra_data)
+        }
     }
 }
 
 impl<'tcx> MatchPairTree<'tcx> {
     /// Recursively builds a match pair tree for the given pattern and its
     /// subpatterns.
-    pub(in crate::builder) fn for_pattern(
+    pub(super) fn for_pattern(
         mut place_builder: PlaceBuilder<'tcx>,
         pattern: &Pat<'tcx>,
         cx: &mut Builder<'_, 'tcx>,
-    ) -> MatchPairTree<'tcx> {
+        match_pairs: &mut Vec<Self>, // Newly-created nodes are added to this vector
+        extra_data: &mut PatternExtraData<'tcx>, // Bindings/ascriptions are added here
+    ) {
         // Force the place type to the pattern's type.
         // FIXME(oli-obk): can we use this to simplify slice/array pattern hacks?
         if let Some(resolved) = place_builder.resolve_upvar(cx) {
@@ -113,64 +115,102 @@ impl<'tcx> MatchPairTree<'tcx> {
             place_builder = place_builder.project(ProjectionElem::OpaqueCast(pattern.ty));
         }
 
+        // Place can be none if the pattern refers to a non-captured place in a closure.
         let place = place_builder.try_to_place(cx);
-        let default_irrefutable = || TestCase::Irrefutable { binding: None, ascription: None };
         let mut subpairs = Vec::new();
         let test_case = match pattern.kind {
-            PatKind::Wild | PatKind::Error(_) => default_irrefutable(),
+            PatKind::Wild | PatKind::Error(_) => None,
 
-            PatKind::Or { ref pats } => TestCase::Or {
+            PatKind::Or { ref pats } => Some(TestCase::Or {
                 pats: pats.iter().map(|pat| FlatPat::new(place_builder.clone(), pat, cx)).collect(),
-            },
+            }),
 
             PatKind::Range(ref range) => {
                 if range.is_full_range(cx.tcx) == Some(true) {
-                    default_irrefutable()
+                    None
                 } else {
-                    TestCase::Range(Arc::clone(range))
+                    Some(TestCase::Range(Arc::clone(range)))
                 }
             }
 
-            PatKind::Constant { value } => TestCase::Constant { value },
+            PatKind::Constant { value } => Some(TestCase::Constant { value }),
 
             PatKind::AscribeUserType {
                 ascription: Ascription { ref annotation, variance },
                 ref subpattern,
                 ..
             } => {
+                MatchPairTree::for_pattern(
+                    place_builder,
+                    subpattern,
+                    cx,
+                    &mut subpairs,
+                    extra_data,
+                );
+
                 // Apply the type ascription to the value at `match_pair.place`
-                let ascription = place.map(|source| super::Ascription {
-                    annotation: annotation.clone(),
-                    source,
-                    variance,
-                });
-
-                subpairs.push(MatchPairTree::for_pattern(place_builder, subpattern, cx));
-                TestCase::Irrefutable { ascription, binding: None }
+                if let Some(source) = place {
+                    let annotation = annotation.clone();
+                    extra_data.ascriptions.push(super::Ascription { source, annotation, variance });
+                }
+
+                None
             }
 
             PatKind::Binding { mode, var, ref subpattern, .. } => {
-                let binding = place.map(|source| super::Binding {
-                    span: pattern.span,
-                    source,
-                    var_id: var,
-                    binding_mode: mode,
-                });
+                // In order to please the borrow checker, when lowering a pattern
+                // like `x @ subpat` we must establish any bindings in `subpat`
+                // before establishing the binding for `x`.
+                //
+                // For example (from #69971):
+                //
+                // ```ignore (illustrative)
+                // struct NonCopyStruct {
+                //     copy_field: u32,
+                // }
+                //
+                // fn foo1(x: NonCopyStruct) {
+                //     let y @ NonCopyStruct { copy_field: z } = x;
+                //     // the above should turn into
+                //     let z = x.copy_field;
+                //     let y = x;
+                // }
+                // ```
 
+                // First, recurse into the subpattern, if any.
                 if let Some(subpattern) = subpattern.as_ref() {
                     // this is the `x @ P` case; have to keep matching against `P` now
-                    subpairs.push(MatchPairTree::for_pattern(place_builder, subpattern, cx));
+                    MatchPairTree::for_pattern(
+                        place_builder,
+                        subpattern,
+                        cx,
+                        &mut subpairs,
+                        extra_data,
+                    );
                 }
-                TestCase::Irrefutable { ascription: None, binding }
+
+                // Then push this binding, after any bindings in the subpattern.
+                if let Some(source) = place {
+                    extra_data.bindings.push(super::Binding {
+                        span: pattern.span,
+                        source,
+                        var_id: var,
+                        binding_mode: mode,
+                    });
+                }
+
+                None
             }
 
             PatKind::ExpandedConstant { subpattern: ref pattern, def_id: _, is_inline: false } => {
-                subpairs.push(MatchPairTree::for_pattern(place_builder, pattern, cx));
-                default_irrefutable()
+                MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data);
+                None
             }
             PatKind::ExpandedConstant { subpattern: ref pattern, def_id, is_inline: true } => {
+                MatchPairTree::for_pattern(place_builder, pattern, cx, &mut subpairs, extra_data);
+
                 // Apply a type ascription for the inline constant to the value at `match_pair.place`
-                let ascription = place.map(|source| {
+                if let Some(source) = place {
                     let span = pattern.span;
                     let parent_id = cx.tcx.typeck_root_def_id(cx.def_id.to_def_id());
                     let args = ty::InlineConstArgs::new(
@@ -189,33 +229,47 @@ impl<'tcx> MatchPairTree<'tcx> {
                         span,
                         user_ty: Box::new(user_ty),
                     };
-                    super::Ascription { annotation, source, variance: ty::Contravariant }
-                });
+                    let variance = ty::Contravariant;
+                    extra_data.ascriptions.push(super::Ascription { annotation, source, variance });
+                }
 
-                subpairs.push(MatchPairTree::for_pattern(place_builder, pattern, cx));
-                TestCase::Irrefutable { ascription, binding: None }
+                None
             }
 
             PatKind::Array { ref prefix, ref slice, ref suffix } => {
-                cx.prefix_slice_suffix(&mut subpairs, &place_builder, prefix, slice, suffix);
-                default_irrefutable()
+                cx.prefix_slice_suffix(
+                    &mut subpairs,
+                    extra_data,
+                    &place_builder,
+                    prefix,
+                    slice,
+                    suffix,
+                );
+                None
             }
             PatKind::Slice { ref prefix, ref slice, ref suffix } => {
-                cx.prefix_slice_suffix(&mut subpairs, &place_builder, prefix, slice, suffix);
+                cx.prefix_slice_suffix(
+                    &mut subpairs,
+                    extra_data,
+                    &place_builder,
+                    prefix,
+                    slice,
+                    suffix,
+                );
 
                 if prefix.is_empty() && slice.is_some() && suffix.is_empty() {
-                    default_irrefutable()
+                    None
                 } else {
-                    TestCase::Slice {
+                    Some(TestCase::Slice {
                         len: prefix.len() + suffix.len(),
                         variable_length: slice.is_some(),
-                    }
+                    })
                 }
             }
 
             PatKind::Variant { adt_def, variant_index, args, ref subpatterns } => {
                 let downcast_place = place_builder.downcast(adt_def, variant_index); // `(x as Variant)`
-                subpairs = cx.field_match_pairs(downcast_place, subpatterns);
+                cx.field_match_pairs(&mut subpairs, extra_data, downcast_place, subpatterns);
 
                 let irrefutable = adt_def.variants().iter_enumerated().all(|(i, v)| {
                     i == variant_index
@@ -225,21 +279,23 @@ impl<'tcx> MatchPairTree<'tcx> {
                             .apply_ignore_module(cx.tcx, cx.infcx.typing_env(cx.param_env))
                 }) && (adt_def.did().is_local()
                     || !adt_def.is_variant_list_non_exhaustive());
-                if irrefutable {
-                    default_irrefutable()
-                } else {
-                    TestCase::Variant { adt_def, variant_index }
-                }
+                if irrefutable { None } else { Some(TestCase::Variant { adt_def, variant_index }) }
             }
 
             PatKind::Leaf { ref subpatterns } => {
-                subpairs = cx.field_match_pairs(place_builder, subpatterns);
-                default_irrefutable()
+                cx.field_match_pairs(&mut subpairs, extra_data, place_builder, subpatterns);
+                None
             }
 
             PatKind::Deref { ref subpattern } => {
-                subpairs.push(MatchPairTree::for_pattern(place_builder.deref(), subpattern, cx));
-                default_irrefutable()
+                MatchPairTree::for_pattern(
+                    place_builder.deref(),
+                    subpattern,
+                    cx,
+                    &mut subpairs,
+                    extra_data,
+                );
+                None
             }
 
             PatKind::DerefPattern { ref subpattern, mutability } => {
@@ -249,23 +305,32 @@ impl<'tcx> MatchPairTree<'tcx> {
                     Ty::new_ref(cx.tcx, cx.tcx.lifetimes.re_erased, subpattern.ty, mutability),
                     pattern.span,
                 );
-                subpairs.push(MatchPairTree::for_pattern(
+                MatchPairTree::for_pattern(
                     PlaceBuilder::from(temp).deref(),
                     subpattern,
                     cx,
-                ));
-                TestCase::Deref { temp, mutability }
+                    &mut subpairs,
+                    extra_data,
+                );
+                Some(TestCase::Deref { temp, mutability })
             }
 
-            PatKind::Never => TestCase::Never,
+            PatKind::Never => Some(TestCase::Never),
         };
 
-        MatchPairTree {
-            place,
-            test_case,
-            subpairs,
-            pattern_ty: pattern.ty,
-            pattern_span: pattern.span,
+        if let Some(test_case) = test_case {
+            // This pattern is refutable, so push a new match-pair node.
+            match_pairs.push(MatchPairTree {
+                place: place.expect("refutable patterns should always have a place to inspect"),
+                test_case,
+                subpairs,
+                pattern_ty: pattern.ty,
+                pattern_span: pattern.span,
+            })
+        } else {
+            // This pattern is irrefutable, so it doesn't need its own match-pair node.
+            // Just push its refutable subpatterns instead, if any.
+            match_pairs.extend(subpairs);
         }
     }
 }
diff --git a/compiler/rustc_mir_build/src/builder/matches/mod.rs b/compiler/rustc_mir_build/src/builder/matches/mod.rs
index d05d5b151ff..b05052a3455 100644
--- a/compiler/rustc_mir_build/src/builder/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/mod.rs
@@ -26,7 +26,6 @@ use crate::builder::{
 
 // helper functions, broken out by category:
 mod match_pair;
-mod simplify;
 mod test;
 mod util;
 
@@ -987,18 +986,16 @@ impl<'tcx> PatternExtraData<'tcx> {
 }
 
 /// A pattern in a form suitable for lowering the match tree, with all irrefutable
-/// patterns simplified away, and or-patterns sorted to the end.
+/// patterns simplified away.
 ///
-/// Here, "flat" indicates that the pattern's match pairs have been recursively
-/// simplified by [`Builder::simplify_match_pairs`]. They are not necessarily
-/// flat in an absolute sense.
+/// Here, "flat" indicates that irrefutable nodes in the pattern tree have been
+/// recursively replaced with their refutable subpatterns. They are not
+/// necessarily flat in an absolute sense.
 ///
 /// Will typically be incorporated into a [`Candidate`].
 #[derive(Debug, Clone)]
 struct FlatPat<'tcx> {
     /// To match the pattern, all of these must be satisfied...
-    // Invariant: all the match pairs are recursively simplified.
-    // Invariant: or-patterns must be sorted to the end.
     match_pairs: Vec<MatchPairTree<'tcx>>,
 
     extra_data: PatternExtraData<'tcx>,
@@ -1008,17 +1005,15 @@ impl<'tcx> FlatPat<'tcx> {
     /// Creates a `FlatPat` containing a simplified [`MatchPairTree`] list/forest
     /// for the given pattern.
     fn new(place: PlaceBuilder<'tcx>, pattern: &Pat<'tcx>, cx: &mut Builder<'_, 'tcx>) -> Self {
-        // First, recursively build a tree of match pairs for the given pattern.
-        let mut match_pairs = vec![MatchPairTree::for_pattern(place, pattern, cx)];
+        // Recursively build a tree of match pairs for the given pattern.
+        let mut match_pairs = vec![];
         let mut extra_data = PatternExtraData {
             span: pattern.span,
             bindings: Vec::new(),
             ascriptions: Vec::new(),
             is_never: pattern.is_never_pattern(),
         };
-        // Recursively remove irrefutable match pairs, while recording their
-        // bindings/ascriptions, and sort or-patterns after other match pairs.
-        cx.simplify_match_pairs(&mut match_pairs, &mut extra_data);
+        MatchPairTree::for_pattern(place, pattern, cx, &mut match_pairs, &mut extra_data);
 
         Self { match_pairs, extra_data }
     }
@@ -1055,7 +1050,6 @@ struct Candidate<'tcx> {
     ///   (see [`Builder::test_remaining_match_pairs_after_or`]).
     ///
     /// Invariants:
-    /// - All [`TestCase::Irrefutable`] patterns have been removed by simplification.
     /// - All or-patterns ([`TestCase::Or`]) have been sorted to the end.
     match_pairs: Vec<MatchPairTree<'tcx>>,
 
@@ -1126,7 +1120,7 @@ impl<'tcx> Candidate<'tcx> {
 
     /// Incorporates an already-simplified [`FlatPat`] into a new candidate.
     fn from_flat_pat(flat_pat: FlatPat<'tcx>, has_guard: bool) -> Self {
-        Candidate {
+        let mut this = Candidate {
             match_pairs: flat_pat.match_pairs,
             extra_data: flat_pat.extra_data,
             has_guard,
@@ -1135,7 +1129,14 @@ impl<'tcx> Candidate<'tcx> {
             otherwise_block: None,
             pre_binding_block: None,
             false_edge_start_block: None,
-        }
+        };
+        this.sort_match_pairs();
+        this
+    }
+
+    /// Restores the invariant that or-patterns must be sorted to the end.
+    fn sort_match_pairs(&mut self) {
+        self.match_pairs.sort_by_key(|pair| matches!(pair.test_case, TestCase::Or { .. }));
     }
 
     /// Returns whether the first match pair of this candidate is an or-pattern.
@@ -1227,17 +1228,11 @@ struct Ascription<'tcx> {
 /// - [`Builder::pick_test_for_match_pair`] (to choose a test)
 /// - [`Builder::sort_candidate`] (to see how the test interacts with a match pair)
 ///
-/// Two variants are unlike the others and deserve special mention:
-///
-/// - [`Self::Irrefutable`] is only used temporarily when building a [`MatchPairTree`].
-///   They are then flattened away by [`Builder::simplify_match_pairs`], with any
-///   bindings/ascriptions incorporated into the enclosing [`FlatPat`].
-/// - [`Self::Or`] are not tested directly like the other variants. Instead they
-///   participate in or-pattern expansion, where they are transformed into subcandidates.
-///   - See [`Builder::expand_and_match_or_candidates`].
+/// Note that or-patterns are not tested directly like the other variants.
+/// Instead they participate in or-pattern expansion, where they are transformed into
+/// subcandidates. See [`Builder::expand_and_match_or_candidates`].
 #[derive(Debug, Clone)]
 enum TestCase<'tcx> {
-    Irrefutable { binding: Option<Binding<'tcx>>, ascription: Option<Ascription<'tcx>> },
     Variant { adt_def: ty::AdtDef<'tcx>, variant_index: VariantIdx },
     Constant { value: mir::Const<'tcx> },
     Range(Arc<PatRange<'tcx>>),
@@ -1261,19 +1256,9 @@ impl<'tcx> TestCase<'tcx> {
 #[derive(Debug, Clone)]
 pub(crate) struct MatchPairTree<'tcx> {
     /// This place...
-    ///
-    /// ---
-    /// This can be `None` if it referred to a non-captured place in a closure.
-    ///
-    /// Invariant: Can only be `None` when `test_case` is `Irrefutable`.
-    /// Therefore this must be `Some(_)` after simplification.
-    place: Option<Place<'tcx>>,
+    place: Place<'tcx>,
 
     /// ... must pass this test...
-    ///
-    /// ---
-    /// Invariant: after creation and simplification in [`FlatPat::new`],
-    /// this must not be [`TestCase::Irrefutable`].
     test_case: TestCase<'tcx>,
 
     /// ... and these subpairs must match.
@@ -2091,11 +2076,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         // Extract the match-pair from the highest priority candidate
         let match_pair = &candidates[0].match_pairs[0];
         let test = self.pick_test_for_match_pair(match_pair);
-        // Unwrap is ok after simplification.
-        let match_place = match_pair.place.unwrap();
         debug!(?test, ?match_pair);
 
-        (match_place, test)
+        (match_pair.place, test)
     }
 
     /// Given a test, we partition the input candidates into several buckets.
diff --git a/compiler/rustc_mir_build/src/builder/matches/simplify.rs b/compiler/rustc_mir_build/src/builder/matches/simplify.rs
deleted file mode 100644
index 15c860151dc..00000000000
--- a/compiler/rustc_mir_build/src/builder/matches/simplify.rs
+++ /dev/null
@@ -1,71 +0,0 @@
-//! Simplifying Candidates
-//!
-//! *Simplifying* a match pair `place @ pattern` means breaking it down
-//! into bindings or other, simpler match pairs. For example:
-//!
-//! - `place @ (P1, P2)` can be simplified to `[place.0 @ P1, place.1 @ P2]`
-//! - `place @ x` can be simplified to `[]` by binding `x` to `place`
-//!
-//! The `simplify_match_pairs` routine just repeatedly applies these
-//! sort of simplifications until there is nothing left to
-//! simplify. Match pairs cannot be simplified if they require some
-//! sort of test: for example, testing which variant an enum is, or
-//! testing a value against a constant.
-
-use std::mem;
-
-use tracing::{debug, instrument};
-
-use crate::builder::Builder;
-use crate::builder::matches::{MatchPairTree, PatternExtraData, TestCase};
-
-impl<'a, 'tcx> Builder<'a, 'tcx> {
-    /// Simplify a list of match pairs so they all require a test. Stores relevant bindings and
-    /// ascriptions in `extra_data`.
-    #[instrument(skip(self), level = "debug")]
-    pub(super) fn simplify_match_pairs(
-        &mut self,
-        match_pairs: &mut Vec<MatchPairTree<'tcx>>,
-        extra_data: &mut PatternExtraData<'tcx>,
-    ) {
-        // In order to please the borrow checker, in a pattern like `x @ pat` we must lower the
-        // bindings in `pat` before `x`. E.g. (#69971):
-        //
-        // struct NonCopyStruct {
-        //     copy_field: u32,
-        // }
-        //
-        // fn foo1(x: NonCopyStruct) {
-        //     let y @ NonCopyStruct { copy_field: z } = x;
-        //     // the above should turn into
-        //     let z = x.copy_field;
-        //     let y = x;
-        // }
-        //
-        // We therefore lower bindings from left-to-right, except we lower the `x` in `x @ pat`
-        // after any bindings in `pat`. This doesn't work for or-patterns: the current structure of
-        // match lowering forces us to lower bindings inside or-patterns last.
-        for mut match_pair in mem::take(match_pairs) {
-            self.simplify_match_pairs(&mut match_pair.subpairs, extra_data);
-            if let TestCase::Irrefutable { binding, ascription } = match_pair.test_case {
-                if let Some(binding) = binding {
-                    extra_data.bindings.push(binding);
-                }
-                if let Some(ascription) = ascription {
-                    extra_data.ascriptions.push(ascription);
-                }
-                // Simplifiable pattern; we replace it with its already simplified subpairs.
-                match_pairs.append(&mut match_pair.subpairs);
-            } else {
-                // Unsimplifiable pattern; we keep it.
-                match_pairs.push(match_pair);
-            }
-        }
-
-        // Move or-patterns to the end, because they can result in us
-        // creating additional candidates, so we want to test them as
-        // late as possible.
-        match_pairs.sort_by_key(|pair| matches!(pair.test_case, TestCase::Or { .. }));
-        debug!(simplified = ?match_pairs, "simplify_match_pairs");
-    }
-}
diff --git a/compiler/rustc_mir_build/src/builder/matches/test.rs b/compiler/rustc_mir_build/src/builder/matches/test.rs
index a7a028bff97..e5d61bc9e55 100644
--- a/compiler/rustc_mir_build/src/builder/matches/test.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/test.rs
@@ -55,12 +55,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             // Or-patterns are not tested directly; instead they are expanded into subcandidates,
             // which are then distinguished by testing whatever non-or patterns they contain.
             TestCase::Or { .. } => bug!("or-patterns should have already been handled"),
-
-            TestCase::Irrefutable { .. } => span_bug!(
-                match_pair.pattern_span,
-                "simplifiable pattern found: {:?}",
-                match_pair.pattern_span
-            ),
         };
 
         Test { span: match_pair.pattern_span, kind }
@@ -546,11 +540,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         // than one, but it'd be very unusual to have two sides that
         // both require tests; you'd expect one side to be simplified
         // away.)
-        let (match_pair_index, match_pair) = candidate
-            .match_pairs
-            .iter()
-            .enumerate()
-            .find(|&(_, mp)| mp.place == Some(test_place))?;
+        let (match_pair_index, match_pair) =
+            candidate.match_pairs.iter().enumerate().find(|&(_, mp)| mp.place == test_place)?;
 
         // If true, the match pair is completely entailed by its corresponding test
         // branch, so it can be removed. If false, the match pair is _compatible_
@@ -593,7 +584,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     candidate
                         .match_pairs
                         .iter()
-                        .any(|mp| mp.place == Some(test_place) && is_covering_range(&mp.test_case))
+                        .any(|mp| mp.place == test_place && is_covering_range(&mp.test_case))
                 };
                 if sorted_candidates
                     .get(&TestBranch::Failure)
@@ -769,7 +760,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             let match_pair = candidate.match_pairs.remove(match_pair_index);
             candidate.match_pairs.extend(match_pair.subpairs);
             // Move or-patterns to the end.
-            candidate.match_pairs.sort_by_key(|pair| matches!(pair.test_case, TestCase::Or { .. }));
+            candidate.sort_match_pairs();
         }
 
         ret
diff --git a/compiler/rustc_mir_build/src/builder/matches/util.rs b/compiler/rustc_mir_build/src/builder/matches/util.rs
index 589e350a03f..ed3b652e4ef 100644
--- a/compiler/rustc_mir_build/src/builder/matches/util.rs
+++ b/compiler/rustc_mir_build/src/builder/matches/util.rs
@@ -173,14 +173,10 @@ impl<'a, 'b, 'tcx> FakeBorrowCollector<'a, 'b, 'tcx> {
             // }
             // ```
             // Hence we fake borrow using a deep borrow.
-            if let Some(place) = match_pair.place {
-                self.fake_borrow(place, FakeBorrowKind::Deep);
-            }
+            self.fake_borrow(match_pair.place, FakeBorrowKind::Deep);
         } else {
             // Insert a Shallow borrow of any place that is switched on.
-            if let Some(place) = match_pair.place {
-                self.fake_borrow(place, FakeBorrowKind::Shallow);
-            }
+            self.fake_borrow(match_pair.place, FakeBorrowKind::Shallow);
 
             for subpair in &match_pair.subpairs {
                 self.visit_match_pair(subpair);
diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs
index 55694cacd92..bc335cee147 100644
--- a/compiler/rustc_mir_transform/src/add_call_guards.rs
+++ b/compiler/rustc_mir_transform/src/add_call_guards.rs
@@ -40,6 +40,16 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards {
         let mut new_blocks = Vec::new();
 
         let cur_len = body.basic_blocks.len();
+        let mut new_block = |source_info: SourceInfo, is_cleanup: bool, target: BasicBlock| {
+            let block = BasicBlockData {
+                statements: vec![],
+                is_cleanup,
+                terminator: Some(Terminator { source_info, kind: TerminatorKind::Goto { target } }),
+            };
+            let idx = cur_len + new_blocks.len();
+            new_blocks.push(block);
+            BasicBlock::new(idx)
+        };
 
         for block in body.basic_blocks_mut() {
             match block.terminator {
@@ -47,25 +57,34 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards {
                     kind: TerminatorKind::Call { target: Some(ref mut destination), unwind, .. },
                     source_info,
                 }) if pred_count[*destination] > 1
-                    && (matches!(
-                        unwind,
-                        UnwindAction::Cleanup(_) | UnwindAction::Terminate(_)
-                    ) || self == &AllCallEdges) =>
+                    && (generates_invoke(unwind) || self == &AllCallEdges) =>
                 {
                     // It's a critical edge, break it
-                    let call_guard = BasicBlockData {
-                        statements: vec![],
-                        is_cleanup: block.is_cleanup,
-                        terminator: Some(Terminator {
-                            source_info,
-                            kind: TerminatorKind::Goto { target: *destination },
-                        }),
-                    };
-
-                    // Get the index it will be when inserted into the MIR
-                    let idx = cur_len + new_blocks.len();
-                    new_blocks.push(call_guard);
-                    *destination = BasicBlock::new(idx);
+                    *destination = new_block(source_info, block.is_cleanup, *destination);
+                }
+                Some(Terminator {
+                    kind:
+                        TerminatorKind::InlineAsm {
+                            asm_macro: InlineAsmMacro::Asm,
+                            ref mut targets,
+                            ref operands,
+                            unwind,
+                            ..
+                        },
+                    source_info,
+                }) if self == &CriticalCallEdges => {
+                    let has_outputs = operands.iter().any(|op| {
+                        matches!(op, InlineAsmOperand::InOut { .. } | InlineAsmOperand::Out { .. })
+                    });
+                    let has_labels =
+                        operands.iter().any(|op| matches!(op, InlineAsmOperand::Label { .. }));
+                    if has_outputs && (has_labels || generates_invoke(unwind)) {
+                        for target in targets.iter_mut() {
+                            if pred_count[*target] > 1 {
+                                *target = new_block(source_info, block.is_cleanup, *target);
+                            }
+                        }
+                    }
                 }
                 _ => {}
             }
@@ -80,3 +99,11 @@ impl<'tcx> crate::MirPass<'tcx> for AddCallGuards {
         true
     }
 }
+
+/// Returns true if this unwind action is code generated as an invoke as opposed to a call.
+fn generates_invoke(unwind: UnwindAction) -> bool {
+    match unwind {
+        UnwindAction::Continue | UnwindAction::Unreachable => false,
+        UnwindAction::Cleanup(_) | UnwindAction::Terminate(_) => true,
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
index 049f13ce96d..a0db8bdb7ed 100644
--- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
+++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
@@ -80,35 +80,6 @@ impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
         // `f` passes. Note that function arguments are the only situation in which this problem can
         // arise: every other use of `move` in MIR doesn't actually write to the value it moves
         // from.
-        //
-        // Anyway, right now this situation doesn't actually arise in practice. Instead, the MIR for
-        // that function looks like this:
-        //
-        //      fn f(_1: BigStruct) -> () {
-        //          let mut _0: ();
-        //          let mut _2: BigStruct;
-        //          bb0: {
-        //              _2 = move _1;
-        //              _0 = g(move _2) -> bb1;
-        //          }
-        //          ...
-        //      }
-        //
-        // Because of that extra move that MIR construction inserts, `x` (i.e. `_1`) can *in
-        // practice* safely be marked `readonly`.
-        //
-        // To handle the possibility that other optimizations (for example, destination propagation)
-        // might someday generate MIR like the first example above, we panic upon seeing an argument
-        // to *our* function that is directly moved into *another* function as an argument. Having
-        // eliminated that problematic case, we can safely treat moves as copies in this analysis.
-        //
-        // In the future, if MIR optimizations cause arguments of a caller to be directly moved into
-        // the argument of a callee, we can just add that argument to `mutated_args` instead of
-        // panicking.
-        //
-        // Note that, because the problematic MIR is never actually generated, we can't add a test
-        // case for this.
-
         if let TerminatorKind::Call { ref args, .. } = terminator.kind {
             for arg in args {
                 if let Operand::Move(place) = arg.node {
diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
index 7b3553e7afd..abbff1c48dd 100644
--- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
+++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
@@ -53,11 +53,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
 
         // Rust calls cannot themselves create foreign unwinds.
         // We assume this is true for intrinsics as well.
-        if let ExternAbi::RustIntrinsic
-        | ExternAbi::Rust
-        | ExternAbi::RustCall
-        | ExternAbi::RustCold = sig.abi()
-        {
+        if sig.abi().is_rustic_abi() {
             continue;
         };
 
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 5981b5031c6..0183ba19475 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -606,14 +606,14 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
         ty::EarlyBinder::bind(callee_body.clone()),
     ) else {
         debug!("failed to normalize callee body");
-        return Err("implementation limitation");
+        return Err("implementation limitation -- could not normalize callee body");
     };
 
     // Normally, this shouldn't be required, but trait normalization failure can create a
     // validation ICE.
     if !validate_types(tcx, inliner.typing_env(), &callee_body, &caller_body).is_empty() {
         debug!("failed to validate callee body");
-        return Err("implementation limitation");
+        return Err("implementation limitation -- callee body failed validation");
     }
 
     // Check call signature compatibility.
@@ -622,17 +622,9 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
     let output_type = callee_body.return_ty();
     if !util::sub_types(tcx, inliner.typing_env(), output_type, destination_ty) {
         trace!(?output_type, ?destination_ty);
-        debug!("failed to normalize return type");
-        return Err("implementation limitation");
+        return Err("implementation limitation -- return type mismatch");
     }
     if callsite.fn_sig.abi() == ExternAbi::RustCall {
-        // FIXME: Don't inline user-written `extern "rust-call"` functions,
-        // since this is generally perf-negative on rustc, and we hope that
-        // LLVM will inline these functions instead.
-        if callee_body.spread_arg.is_some() {
-            return Err("user-written rust-call functions");
-        }
-
         let (self_arg, arg_tuple) = match &args[..] {
             [arg_tuple] => (None, arg_tuple),
             [self_arg, arg_tuple] => (Some(self_arg), arg_tuple),
@@ -642,12 +634,17 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
         let self_arg_ty = self_arg.map(|self_arg| self_arg.node.ty(&caller_body.local_decls, tcx));
 
         let arg_tuple_ty = arg_tuple.node.ty(&caller_body.local_decls, tcx);
-        let ty::Tuple(arg_tuple_tys) = *arg_tuple_ty.kind() else {
-            bug!("Closure arguments are not passed as a tuple");
+        let arg_tys = if callee_body.spread_arg.is_some() {
+            std::slice::from_ref(&arg_tuple_ty)
+        } else {
+            let ty::Tuple(arg_tuple_tys) = *arg_tuple_ty.kind() else {
+                bug!("Closure arguments are not passed as a tuple");
+            };
+            arg_tuple_tys.as_slice()
         };
 
         for (arg_ty, input) in
-            self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter())
+            self_arg_ty.into_iter().chain(arg_tys.iter().copied()).zip(callee_body.args_iter())
         {
             let input_type = callee_body.local_decls[input].ty;
             if !util::sub_types(tcx, inliner.typing_env(), input_type, arg_ty) {
@@ -663,7 +660,7 @@ fn try_inlining<'tcx, I: Inliner<'tcx>>(
             if !util::sub_types(tcx, inliner.typing_env(), input_type, arg_ty) {
                 trace!(?arg_ty, ?input_type);
                 debug!("failed to normalize argument type");
-                return Err("implementation limitation");
+                return Err("implementation limitation -- arg mismatch");
             }
         }
     }
@@ -693,13 +690,13 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>(
             // won't cause cycles on this.
             if !inliner.tcx().is_mir_available(callee_def_id) {
                 debug!("item MIR unavailable");
-                return Err("implementation limitation");
+                return Err("implementation limitation -- MIR unavailable");
             }
         }
         // These have no own callable MIR.
         InstanceKind::Intrinsic(_) | InstanceKind::Virtual(..) => {
             debug!("instance without MIR (intrinsic / virtual)");
-            return Err("implementation limitation");
+            return Err("implementation limitation -- cannot inline intrinsic");
         }
 
         // FIXME(#127030): `ConstParamHasTy` has bad interactions with
@@ -709,7 +706,7 @@ fn check_mir_is_available<'tcx, I: Inliner<'tcx>>(
         // substituted.
         InstanceKind::DropGlue(_, Some(ty)) if ty.has_type_flags(TypeFlags::HAS_CT_PARAM) => {
             debug!("still needs substitution");
-            return Err("implementation limitation");
+            return Err("implementation limitation -- HACK for dropping polymorphic type");
         }
 
         // This cannot result in an immediate cycle since the callee MIR is a shim, which does
@@ -1060,8 +1057,7 @@ fn make_call_args<'tcx, I: Inliner<'tcx>>(
 
         closure_ref_arg.chain(tuple_tmp_args).collect()
     } else {
-        // FIXME(edition_2024): switch back to a normal method call.
-        <_>::into_iter(args)
+        args.into_iter()
             .map(|a| create_temp_if_necessary(inliner, a.node, callsite, caller_body, return_block))
             .collect()
     }
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 04c9375b831..5df12ac4d8b 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -513,6 +513,24 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
         body.tainted_by_errors = Some(error_reported);
     }
 
+    // Also taint the body if it's within a top-level item that is not well formed.
+    //
+    // We do this check here and not during `mir_promoted` because that may result
+    // in borrowck cycles if WF requires looking into an opaque hidden type.
+    let root = tcx.typeck_root_def_id(def.to_def_id());
+    match tcx.def_kind(root) {
+        DefKind::Fn
+        | DefKind::AssocFn
+        | DefKind::Static { .. }
+        | DefKind::Const
+        | DefKind::AssocConst => {
+            if let Err(guar) = tcx.check_well_formed(root.expect_local()) {
+                body.tainted_by_errors = Some(guar);
+            }
+        }
+        _ => {}
+    }
+
     run_analysis_to_runtime_passes(tcx, &mut body);
 
     tcx.alloc_steal_mir(body)
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 08df0dedc6b..67fca1d7c29 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -209,7 +209,7 @@ use std::path::PathBuf;
 
 use rustc_attr_parsing::InlineAttr;
 use rustc_data_structures::fx::FxIndexMap;
-use rustc_data_structures::sync::{LRef, MTLock, par_for_each_in};
+use rustc_data_structures::sync::{MTLock, par_for_each_in};
 use rustc_data_structures::unord::{UnordMap, UnordSet};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
@@ -357,7 +357,7 @@ impl<'tcx> Extend<Spanned<MonoItem<'tcx>>> for MonoItems<'tcx> {
 fn collect_items_rec<'tcx>(
     tcx: TyCtxt<'tcx>,
     starting_item: Spanned<MonoItem<'tcx>>,
-    state: LRef<'_, SharedState<'tcx>>,
+    state: &SharedState<'tcx>,
     recursion_depths: &mut DefIdMap<usize>,
     recursion_limit: Limit,
     mode: CollectionMode,
@@ -1671,30 +1671,26 @@ pub(crate) fn collect_crate_mono_items<'tcx>(
 
     debug!("building mono item graph, beginning at roots");
 
-    let mut state = SharedState {
+    let state = SharedState {
         visited: MTLock::new(UnordSet::default()),
         mentioned: MTLock::new(UnordSet::default()),
         usage_map: MTLock::new(UsageMap::new()),
     };
     let recursion_limit = tcx.recursion_limit();
 
-    {
-        let state: LRef<'_, _> = &mut state;
-
-        tcx.sess.time("monomorphization_collector_graph_walk", || {
-            par_for_each_in(roots, |root| {
-                let mut recursion_depths = DefIdMap::default();
-                collect_items_rec(
-                    tcx,
-                    dummy_spanned(root),
-                    state,
-                    &mut recursion_depths,
-                    recursion_limit,
-                    CollectionMode::UsedItems,
-                );
-            });
+    tcx.sess.time("monomorphization_collector_graph_walk", || {
+        par_for_each_in(roots, |root| {
+            let mut recursion_depths = DefIdMap::default();
+            collect_items_rec(
+                tcx,
+                dummy_spanned(root),
+                &state,
+                &mut recursion_depths,
+                recursion_limit,
+                CollectionMode::UsedItems,
+            );
         });
-    }
+    });
 
     // The set of MonoItems was created in an inherently indeterministic order because
     // of parallelism. We sort it here to ensure that the output is deterministic.
diff --git a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
index 9f26da7d5c6..06d6c3ab805 100644
--- a/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
+++ b/compiler/rustc_monomorphize/src/mono_checks/abi_check.rs
@@ -1,6 +1,6 @@
 //! This module ensures that if a function's ABI requires a particular target feature,
 //! that target feature is enabled both on the callee and all callers.
-use rustc_abi::{BackendRepr, ExternAbi, RegKind};
+use rustc_abi::{BackendRepr, RegKind};
 use rustc_hir::CRATE_HIR_ID;
 use rustc_middle::mir::{self, traversal};
 use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt};
@@ -115,8 +115,8 @@ fn check_call_site_abi<'tcx>(
     span: Span,
     caller: InstanceKind<'tcx>,
 ) {
-    if callee.fn_sig(tcx).abi() == ExternAbi::Rust {
-        // "Rust" ABI never passes arguments in vector registers.
+    if callee.fn_sig(tcx).abi().is_rustic_abi() {
+        // we directly handle the soundness of Rust ABIs
         return;
     }
     let typing_env = ty::TypingEnv::fully_monomorphized();
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 1b18142c242..12a55664641 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -786,13 +786,6 @@ where
                     )
                 }
 
-                //  `(A, B, T)` -> `(A, B, U)` where `T: Unsize<U>`
-                (ty::Tuple(a_tys), ty::Tuple(b_tys))
-                    if a_tys.len() == b_tys.len() && !a_tys.is_empty() =>
-                {
-                    result_to_single(ecx.consider_builtin_tuple_unsize(goal, a_tys, b_tys))
-                }
-
                 _ => vec![],
             }
         })
@@ -1084,48 +1077,6 @@ where
             .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
     }
 
-    /// We generate the following builtin impl for tuples of all sizes.
-    ///
-    /// This impl is still unstable and we emit a feature error when it
-    /// when it is used by a coercion.
-    /// ```ignore (builtin impl example)
-    /// impl<T: ?Sized, U: ?Sized, V: ?Sized> Unsize<(T, V)> for (T, U)
-    /// where
-    ///     U: Unsize<V>,
-    /// {}
-    /// ```
-    fn consider_builtin_tuple_unsize(
-        &mut self,
-        goal: Goal<I, (I::Ty, I::Ty)>,
-        a_tys: I::Tys,
-        b_tys: I::Tys,
-    ) -> Result<Candidate<I>, NoSolution> {
-        let cx = self.cx();
-        let Goal { predicate: (_a_ty, b_ty), .. } = goal;
-
-        let (&a_last_ty, a_rest_tys) = a_tys.split_last().unwrap();
-        let b_last_ty = b_tys.last().unwrap();
-
-        // Instantiate just the tail field of B., and require that they're equal.
-        let unsized_a_ty = Ty::new_tup_from_iter(cx, a_rest_tys.iter().copied().chain([b_last_ty]));
-        self.eq(goal.param_env, unsized_a_ty, b_ty)?;
-
-        // Similar to ADTs, require that we can unsize the tail.
-        self.add_goal(
-            GoalSource::ImplWhereBound,
-            goal.with(
-                cx,
-                ty::TraitRef::new(
-                    cx,
-                    cx.require_lang_item(TraitSolverLangItem::Unsize),
-                    [a_last_ty, b_last_ty],
-                ),
-            ),
-        );
-        self.probe_builtin_trait_candidate(BuiltinImplSource::TupleUnsizing)
-            .enter(|ecx| ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes))
-    }
-
     // Return `Some` if there is an impl (built-in or user provided) that may
     // hold for the self type of the goal, which for coherence and soundness
     // purposes must disqualify the built-in auto impl assembled by considering
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 792e2cc26ef..1d17290e1c7 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -384,17 +384,17 @@ impl<'psess, 'src> Lexer<'psess, 'src> {
                 rustc_lexer::TokenKind::Colon => token::Colon,
                 rustc_lexer::TokenKind::Dollar => token::Dollar,
                 rustc_lexer::TokenKind::Eq => token::Eq,
-                rustc_lexer::TokenKind::Bang => token::Not,
+                rustc_lexer::TokenKind::Bang => token::Bang,
                 rustc_lexer::TokenKind::Lt => token::Lt,
                 rustc_lexer::TokenKind::Gt => token::Gt,
-                rustc_lexer::TokenKind::Minus => token::BinOp(token::Minus),
-                rustc_lexer::TokenKind::And => token::BinOp(token::And),
-                rustc_lexer::TokenKind::Or => token::BinOp(token::Or),
-                rustc_lexer::TokenKind::Plus => token::BinOp(token::Plus),
-                rustc_lexer::TokenKind::Star => token::BinOp(token::Star),
-                rustc_lexer::TokenKind::Slash => token::BinOp(token::Slash),
-                rustc_lexer::TokenKind::Caret => token::BinOp(token::Caret),
-                rustc_lexer::TokenKind::Percent => token::BinOp(token::Percent),
+                rustc_lexer::TokenKind::Minus => token::Minus,
+                rustc_lexer::TokenKind::And => token::And,
+                rustc_lexer::TokenKind::Or => token::Or,
+                rustc_lexer::TokenKind::Plus => token::Plus,
+                rustc_lexer::TokenKind::Star => token::Star,
+                rustc_lexer::TokenKind::Slash => token::Slash,
+                rustc_lexer::TokenKind::Caret => token::Caret,
+                rustc_lexer::TokenKind::Percent => token::Percent,
 
                 rustc_lexer::TokenKind::Unknown | rustc_lexer::TokenKind::InvalidIdent => {
                     // Don't emit diagnostics for sequences of the same invalid token
diff --git a/compiler/rustc_parse/src/lexer/unicode_chars.rs b/compiler/rustc_parse/src/lexer/unicode_chars.rs
index 648a352efd9..ff03b42484b 100644
--- a/compiler/rustc_parse/src/lexer/unicode_chars.rs
+++ b/compiler/rustc_parse/src/lexer/unicode_chars.rs
@@ -308,11 +308,11 @@ pub(super) static UNICODE_ARRAY: &[(char, &str, &str)] = &[
 const ASCII_ARRAY: &[(&str, &str, Option<token::TokenKind>)] = &[
     (" ", "Space", None),
     ("_", "Underscore", Some(token::Ident(kw::Underscore, token::IdentIsRaw::No))),
-    ("-", "Minus/Hyphen", Some(token::BinOp(token::Minus))),
+    ("-", "Minus/Hyphen", Some(token::Minus)),
     (",", "Comma", Some(token::Comma)),
     (";", "Semicolon", Some(token::Semi)),
     (":", "Colon", Some(token::Colon)),
-    ("!", "Exclamation Mark", Some(token::Not)),
+    ("!", "Exclamation Mark", Some(token::Bang)),
     ("?", "Question Mark", Some(token::Question)),
     (".", "Period", Some(token::Dot)),
     ("(", "Left Parenthesis", Some(token::OpenDelim(Delimiter::Parenthesis))),
@@ -321,11 +321,11 @@ const ASCII_ARRAY: &[(&str, &str, Option<token::TokenKind>)] = &[
     ("]", "Right Square Bracket", Some(token::CloseDelim(Delimiter::Bracket))),
     ("{", "Left Curly Brace", Some(token::OpenDelim(Delimiter::Brace))),
     ("}", "Right Curly Brace", Some(token::CloseDelim(Delimiter::Brace))),
-    ("*", "Asterisk", Some(token::BinOp(token::Star))),
-    ("/", "Slash", Some(token::BinOp(token::Slash))),
+    ("*", "Asterisk", Some(token::Star)),
+    ("/", "Slash", Some(token::Slash)),
     ("\\", "Backslash", None),
-    ("&", "Ampersand", Some(token::BinOp(token::And))),
-    ("+", "Plus Sign", Some(token::BinOp(token::Plus))),
+    ("&", "Ampersand", Some(token::And)),
+    ("+", "Plus Sign", Some(token::Plus)),
     ("<", "Less-Than Sign", Some(token::Lt)),
     ("=", "Equals Sign", Some(token::Eq)),
     ("==", "Double Equals Sign", Some(token::EqEq)),
diff --git a/compiler/rustc_parse/src/parser/attr.rs b/compiler/rustc_parse/src/parser/attr.rs
index 98fdd35190d..066b570c23f 100644
--- a/compiler/rustc_parse/src/parser/attr.rs
+++ b/compiler/rustc_parse/src/parser/attr.rs
@@ -130,7 +130,7 @@ impl<'a> Parser<'a> {
             assert!(this.eat(exp!(Pound)), "parse_attribute called in non-attribute position");
 
             let style =
-                if this.eat(exp!(Not)) { ast::AttrStyle::Inner } else { ast::AttrStyle::Outer };
+                if this.eat(exp!(Bang)) { ast::AttrStyle::Inner } else { ast::AttrStyle::Outer };
 
             this.expect(exp!(OpenBracket))?;
             let item = this.parse_attr_item(ForceCollect::No)?;
@@ -312,7 +312,7 @@ impl<'a> Parser<'a> {
         loop {
             let start_pos = self.num_bump_calls;
             // Only try to parse if it is an inner attribute (has `!`).
-            let attr = if self.check(exp!(Pound)) && self.look_ahead(1, |t| t == &token::Not) {
+            let attr = if self.check(exp!(Pound)) && self.look_ahead(1, |t| t == &token::Bang) {
                 Some(self.parse_attribute(InnerAttrPolicy::Permitted)?)
             } else if let token::DocComment(comment_kind, attr_style, data) = self.token.kind {
                 if attr_style == ast::AttrStyle::Inner {
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 02bcb1fbf70..94db43bb59f 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -1167,7 +1167,7 @@ impl<'a> Parser<'a> {
         let mut number_of_gt = 0;
         while self.look_ahead(position, |t| {
             trace!("check_trailing_angle_brackets: t={:?}", t);
-            if *t == token::BinOp(token::BinOpToken::Shr) {
+            if *t == token::Shr {
                 number_of_shr += 1;
                 true
             } else if *t == token::Gt {
@@ -1222,7 +1222,7 @@ impl<'a> Parser<'a> {
                     let span = lo.to(self.prev_token.span);
                     // Detect trailing `>` like in `x.collect::Vec<_>>()`.
                     let mut trailing_span = self.prev_token.span.shrink_to_hi();
-                    while self.token == token::BinOp(token::Shr) || self.token == token::Gt {
+                    while self.token == token::Shr || self.token == token::Gt {
                         trailing_span = trailing_span.to(self.token.span);
                         self.bump();
                     }
@@ -1468,8 +1468,7 @@ impl<'a> Parser<'a> {
                         let snapshot = self.create_snapshot_for_diagnostic();
                         self.bump();
                         // So far we have parsed `foo<bar<`, consume the rest of the type args.
-                        let modifiers =
-                            [(token::Lt, 1), (token::Gt, -1), (token::BinOp(token::Shr), -2)];
+                        let modifiers = [(token::Lt, 1), (token::Gt, -1), (token::Shr, -2)];
                         self.consume_tts(1, &modifiers);
 
                         if !&[token::OpenDelim(Delimiter::Parenthesis), token::PathSep]
@@ -1962,7 +1961,7 @@ impl<'a> Parser<'a> {
         &mut self,
         await_sp: Span,
     ) -> PResult<'a, P<Expr>> {
-        let (hi, expr, is_question) = if self.token == token::Not {
+        let (hi, expr, is_question) = if self.token == token::Bang {
             // Handle `await!(<expr>)`.
             self.recover_await_macro()?
         } else {
@@ -1974,7 +1973,7 @@ impl<'a> Parser<'a> {
     }
 
     fn recover_await_macro(&mut self) -> PResult<'a, (Span, P<Expr>, bool)> {
-        self.expect(exp!(Not))?;
+        self.expect(exp!(Bang))?;
         self.expect(exp!(OpenParen))?;
         let expr = self.parse_expr()?;
         self.expect(exp!(CloseParen))?;
@@ -2034,7 +2033,7 @@ impl<'a> Parser<'a> {
 
     pub(super) fn try_macro_suggestion(&mut self) -> PResult<'a, P<Expr>> {
         let is_try = self.token.is_keyword(kw::Try);
-        let is_questionmark = self.look_ahead(1, |t| t == &token::Not); //check for !
+        let is_questionmark = self.look_ahead(1, |t| t == &token::Bang); //check for !
         let is_open = self.look_ahead(2, |t| t == &token::OpenDelim(Delimiter::Parenthesis)); //check for (
 
         if is_try && is_questionmark && is_open {
@@ -2613,8 +2612,7 @@ impl<'a> Parser<'a> {
             || self.token == TokenKind::Dot;
         // This will be true when a trait object type `Foo +` or a path which was a `const fn` with
         // type params has been parsed.
-        let was_op =
-            matches!(self.prev_token.kind, token::BinOp(token::Plus | token::Shr) | token::Gt);
+        let was_op = matches!(self.prev_token.kind, token::Plus | token::Shr | token::Gt);
         if !is_op_or_dot && !was_op {
             // We perform these checks and early return to avoid taking a snapshot unnecessarily.
             return Err(err);
@@ -2992,8 +2990,7 @@ impl<'a> Parser<'a> {
 
     pub(super) fn recover_vcs_conflict_marker(&mut self) {
         // <<<<<<<
-        let Some(start) = self.conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt)
-        else {
+        let Some(start) = self.conflict_marker(&TokenKind::Shl, &TokenKind::Lt) else {
             return;
         };
         let mut spans = Vec::with_capacity(3);
@@ -3008,15 +3005,13 @@ impl<'a> Parser<'a> {
             if self.token == TokenKind::Eof {
                 break;
             }
-            if let Some(span) = self.conflict_marker(&TokenKind::OrOr, &TokenKind::BinOp(token::Or))
-            {
+            if let Some(span) = self.conflict_marker(&TokenKind::OrOr, &TokenKind::Or) {
                 middlediff3 = Some(span);
             }
             if let Some(span) = self.conflict_marker(&TokenKind::EqEq, &TokenKind::Eq) {
                 middle = Some(span);
             }
-            if let Some(span) = self.conflict_marker(&TokenKind::BinOp(token::Shr), &TokenKind::Gt)
-            {
+            if let Some(span) = self.conflict_marker(&TokenKind::Shr, &TokenKind::Gt) {
                 spans.push(span);
                 end = Some(span);
                 break;
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index ef29ac2719d..0a08c6faeb4 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -239,8 +239,8 @@ impl<'a> Parser<'a> {
                 self.bump();
             }
 
-            if self.prev_token == token::BinOp(token::Plus)
-                && self.token == token::BinOp(token::Plus)
+            if self.prev_token == token::Plus
+                && self.token == token::Plus
                 && self.prev_token.span.between(self.token.span).is_empty()
             {
                 let op_span = self.prev_token.span.to(self.token.span);
@@ -250,8 +250,8 @@ impl<'a> Parser<'a> {
                 continue;
             }
 
-            if self.prev_token == token::BinOp(token::Minus)
-                && self.token == token::BinOp(token::Minus)
+            if self.prev_token == token::Minus
+                && self.token == token::Minus
                 && self.prev_token.span.between(self.token.span).is_empty()
                 && !self.look_ahead(1, |tok| tok.can_begin_expr())
             {
@@ -505,23 +505,23 @@ impl<'a> Parser<'a> {
         // Note: when adding new unary operators, don't forget to adjust TokenKind::can_begin_expr()
         match this.token.uninterpolate().kind {
             // `!expr`
-            token::Not => make_it!(this, attrs, |this, _| this.parse_expr_unary(lo, UnOp::Not)),
+            token::Bang => make_it!(this, attrs, |this, _| this.parse_expr_unary(lo, UnOp::Not)),
             // `~expr`
             token::Tilde => make_it!(this, attrs, |this, _| this.recover_tilde_expr(lo)),
             // `-expr`
-            token::BinOp(token::Minus) => {
+            token::Minus => {
                 make_it!(this, attrs, |this, _| this.parse_expr_unary(lo, UnOp::Neg))
             }
             // `*expr`
-            token::BinOp(token::Star) => {
+            token::Star => {
                 make_it!(this, attrs, |this, _| this.parse_expr_unary(lo, UnOp::Deref))
             }
             // `&expr` and `&&expr`
-            token::BinOp(token::And) | token::AndAnd => {
+            token::And | token::AndAnd => {
                 make_it!(this, attrs, |this, _| this.parse_expr_borrow(lo))
             }
             // `+lit`
-            token::BinOp(token::Plus) if this.look_ahead(1, |tok| tok.is_numeric_lit()) => {
+            token::Plus if this.look_ahead(1, |tok| tok.is_numeric_lit()) => {
                 let mut err = errors::LeadingPlusNotSupported {
                     span: lo,
                     remove_plus: None,
@@ -541,9 +541,7 @@ impl<'a> Parser<'a> {
                 this.parse_expr_prefix(attrs)
             }
             // Recover from `++x`:
-            token::BinOp(token::Plus)
-                if this.look_ahead(1, |t| *t == token::BinOp(token::Plus)) =>
-            {
+            token::Plus if this.look_ahead(1, |t| *t == token::Plus) => {
                 let starts_stmt = this.prev_token == token::Semi
                     || this.prev_token == token::CloseDelim(Delimiter::Brace);
                 let pre_span = this.token.span.to(this.look_ahead(1, |t| t.span));
@@ -567,7 +565,11 @@ impl<'a> Parser<'a> {
     fn parse_expr_prefix_common(&mut self, lo: Span) -> PResult<'a, (Span, P<Expr>)> {
         self.bump();
         let attrs = self.parse_outer_attributes()?;
-        let expr = self.parse_expr_prefix(attrs)?;
+        let expr = if self.token.is_range_separator() {
+            self.parse_expr_prefix_range(attrs)
+        } else {
+            self.parse_expr_prefix(attrs)
+        }?;
         let span = self.interpolated_or_expr_span(&expr);
         Ok((lo.to(span), expr))
     }
@@ -723,14 +725,12 @@ impl<'a> Parser<'a> {
                                     suggestion,
                                 })
                             }
-                            token::BinOp(token::Shl) => {
-                                self.dcx().emit_err(errors::ShiftInterpretedAsGeneric {
-                                    shift: self.token.span,
-                                    r#type: path,
-                                    args: args_span,
-                                    suggestion,
-                                })
-                            }
+                            token::Shl => self.dcx().emit_err(errors::ShiftInterpretedAsGeneric {
+                                shift: self.token.span,
+                                r#type: path,
+                                args: args_span,
+                                suggestion,
+                            }),
                             _ => {
                                 // We can end up here even without `<` being the next token, for
                                 // example because `parse_ty_no_plus` returns `Err` on keywords,
@@ -1574,7 +1574,7 @@ impl<'a> Parser<'a> {
         };
 
         // `!`, as an operator, is prefix, so we know this isn't that.
-        let (span, kind) = if self.eat(exp!(Not)) {
+        let (span, kind) = if self.eat(exp!(Bang)) {
             // MACRO INVOCATION expression
             if qself.is_some() {
                 self.dcx().emit_err(errors::MacroInvocationWithQualifiedPath(path.span));
@@ -2595,7 +2595,7 @@ impl<'a> Parser<'a> {
                 missing_let: None,
                 comparison: None,
             };
-            if self.prev_token == token::BinOp(token::Or) {
+            if self.prev_token == token::Or {
                 // This was part of a closure, the that part of the parser recover.
                 return Err(self.dcx().create_err(err));
             } else {
diff --git a/compiler/rustc_parse/src/parser/generics.rs b/compiler/rustc_parse/src/parser/generics.rs
index 11f0e579de5..c3f71dd8b30 100644
--- a/compiler/rustc_parse/src/parser/generics.rs
+++ b/compiler/rustc_parse/src/parser/generics.rs
@@ -367,34 +367,47 @@ impl<'a> Parser<'a> {
 
         loop {
             let where_sp = where_lo.to(self.prev_token.span);
+            let attrs = self.parse_outer_attributes()?;
             let pred_lo = self.token.span;
-            let kind = if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) {
-                let lifetime = self.expect_lifetime();
-                // Bounds starting with a colon are mandatory, but possibly empty.
-                self.expect(exp!(Colon))?;
-                let bounds = self.parse_lt_param_bounds();
-                ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate {
-                    lifetime,
-                    bounds,
-                })
-            } else if self.check_type() {
-                match self.parse_ty_where_predicate_kind_or_recover_tuple_struct_body(
-                    struct_, pred_lo, where_sp,
-                )? {
-                    PredicateKindOrStructBody::PredicateKind(kind) => kind,
-                    PredicateKindOrStructBody::StructBody(body) => {
-                        tuple_struct_body = Some(body);
-                        break;
-                    }
+            let predicate = self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
+                for attr in &attrs {
+                    self.psess.gated_spans.gate(sym::where_clause_attrs, attr.span);
                 }
-            } else {
-                break;
-            };
-            where_clause.predicates.push(ast::WherePredicate {
-                kind,
-                id: DUMMY_NODE_ID,
-                span: pred_lo.to(self.prev_token.span),
-            });
+                let kind = if this.check_lifetime() && this.look_ahead(1, |t| !t.is_like_plus()) {
+                    let lifetime = this.expect_lifetime();
+                    // Bounds starting with a colon are mandatory, but possibly empty.
+                    this.expect(exp!(Colon))?;
+                    let bounds = this.parse_lt_param_bounds();
+                    Some(ast::WherePredicateKind::RegionPredicate(ast::WhereRegionPredicate {
+                        lifetime,
+                        bounds,
+                    }))
+                } else if this.check_type() {
+                    match this.parse_ty_where_predicate_kind_or_recover_tuple_struct_body(
+                        struct_, pred_lo, where_sp,
+                    )? {
+                        PredicateKindOrStructBody::PredicateKind(kind) => Some(kind),
+                        PredicateKindOrStructBody::StructBody(body) => {
+                            tuple_struct_body = Some(body);
+                            None
+                        }
+                    }
+                } else {
+                    None
+                };
+                let predicate = kind.map(|kind| ast::WherePredicate {
+                    attrs,
+                    kind,
+                    id: DUMMY_NODE_ID,
+                    span: pred_lo.to(this.prev_token.span),
+                    is_placeholder: false,
+                });
+                Ok((predicate, Trailing::No, UsePreAttrPos::No))
+            })?;
+            match predicate {
+                Some(predicate) => where_clause.predicates.push(predicate),
+                None => break,
+            }
 
             let prev_token = self.prev_token.span;
             let ate_comma = self.eat(exp!(Comma));
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 5765a5b5315..c3b1956ad2e 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -382,7 +382,7 @@ impl<'a> Parser<'a> {
 
     /// Are we sure this could not possibly be a macro invocation?
     fn isnt_macro_invocation(&mut self) -> bool {
-        self.check_ident() && self.look_ahead(1, |t| *t != token::Not && *t != token::PathSep)
+        self.check_ident() && self.look_ahead(1, |t| *t != token::Bang && *t != token::PathSep)
     }
 
     /// Recover on encountering a struct, enum, or method definition where the user
@@ -480,7 +480,7 @@ impl<'a> Parser<'a> {
     /// Parses an item macro, e.g., `item!();`.
     fn parse_item_macro(&mut self, vis: &Visibility) -> PResult<'a, MacCall> {
         let path = self.parse_path(PathStyle::Mod)?; // `foo::bar`
-        self.expect(exp!(Not))?; // `!`
+        self.expect(exp!(Bang))?; // `!`
         match self.parse_delim_args() {
             // `( .. )` or `[ .. ]` (followed by `;`), or `{ .. }`.
             Ok(args) => {
@@ -540,7 +540,7 @@ impl<'a> Parser<'a> {
 
     fn parse_polarity(&mut self) -> ast::ImplPolarity {
         // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type.
-        if self.check(exp!(Not)) && self.look_ahead(1, |t| t.can_begin_type()) {
+        if self.check(exp!(Bang)) && self.look_ahead(1, |t| t.can_begin_type()) {
             self.bump(); // `!`
             ast::ImplPolarity::Negative(self.prev_token.span)
         } else {
@@ -1293,7 +1293,7 @@ impl<'a> Parser<'a> {
                 if token.is_keyword(kw::Move) {
                     return true;
                 }
-                matches!(token.kind, token::BinOp(token::Or) | token::OrOr)
+                matches!(token.kind, token::Or | token::OrOr)
             })
         } else {
             // `$qual static`
@@ -1579,7 +1579,7 @@ impl<'a> Parser<'a> {
             }
             let ident = this.parse_field_ident("enum", vlo)?;
 
-            if this.token == token::Not {
+            if this.token == token::Bang {
                 if let Err(err) = this.unexpected() {
                     err.with_note(fluent::parse_macro_expands_to_enum_variant).emit();
                 }
@@ -1814,7 +1814,7 @@ impl<'a> Parser<'a> {
             let attrs = p.parse_outer_attributes()?;
             p.collect_tokens(None, attrs, ForceCollect::No, |p, attrs| {
                 let mut snapshot = None;
-                if p.is_vcs_conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) {
+                if p.is_vcs_conflict_marker(&TokenKind::Shl, &TokenKind::Lt) {
                     // Account for `<<<<<<<` diff markers. We can't proactively error here because
                     // that can be a valid type start, so we snapshot and reparse only we've
                     // encountered another parse error.
@@ -2034,7 +2034,7 @@ impl<'a> Parser<'a> {
         attrs: AttrVec,
     ) -> PResult<'a, FieldDef> {
         let name = self.parse_field_ident(adt_ty, lo)?;
-        if self.token == token::Not {
+        if self.token == token::Bang {
             if let Err(mut err) = self.unexpected() {
                 // Encounter the macro invocation
                 err.subdiagnostic(MacroExpandsToAdtField { adt_ty });
@@ -2184,7 +2184,7 @@ impl<'a> Parser<'a> {
         if self.check_keyword(exp!(MacroRules)) {
             let macro_rules_span = self.token.span;
 
-            if self.look_ahead(1, |t| *t == token::Not) && self.look_ahead(2, |t| t.is_ident()) {
+            if self.look_ahead(1, |t| *t == token::Bang) && self.look_ahead(2, |t| t.is_ident()) {
                 return IsMacroRulesItem::Yes { has_bang: true };
             } else if self.look_ahead(1, |t| (t.is_ident())) {
                 // macro_rules foo
@@ -2209,11 +2209,11 @@ impl<'a> Parser<'a> {
         self.expect_keyword(exp!(MacroRules))?; // `macro_rules`
 
         if has_bang {
-            self.expect(exp!(Not))?; // `!`
+            self.expect(exp!(Bang))?; // `!`
         }
         let ident = self.parse_ident()?;
 
-        if self.eat(exp!(Not)) {
+        if self.eat(exp!(Bang)) {
             // Handle macro_rules! foo!
             let span = self.prev_token.span;
             self.dcx().emit_err(errors::MacroNameRemoveBang { span });
@@ -2954,14 +2954,27 @@ impl<'a> Parser<'a> {
             }
             _ => unreachable!(),
         };
+        // is lifetime `n` tokens ahead?
+        let is_lifetime = |this: &Self, n| this.look_ahead(n, |t| t.is_lifetime());
         // Is `self` `n` tokens ahead?
         let is_isolated_self = |this: &Self, n| {
             this.is_keyword_ahead(n, &[kw::SelfLower])
                 && this.look_ahead(n + 1, |t| t != &token::PathSep)
         };
+        // Is `pin const self` `n` tokens ahead?
+        let is_isolated_pin_const_self = |this: &Self, n| {
+            this.look_ahead(n, |token| token.is_ident_named(sym::pin))
+                && this.is_keyword_ahead(n + 1, &[kw::Const])
+                && is_isolated_self(this, n + 2)
+        };
         // Is `mut self` `n` tokens ahead?
         let is_isolated_mut_self =
             |this: &Self, n| this.is_keyword_ahead(n, &[kw::Mut]) && is_isolated_self(this, n + 1);
+        // Is `pin mut self` `n` tokens ahead?
+        let is_isolated_pin_mut_self = |this: &Self, n| {
+            this.look_ahead(n, |token| token.is_ident_named(sym::pin))
+                && is_isolated_mut_self(this, n + 1)
+        };
         // Parse `self` or `self: TYPE`. We already know the current token is `self`.
         let parse_self_possibly_typed = |this: &mut Self, m| {
             let eself_ident = expect_self_ident(this);
@@ -3011,27 +3024,36 @@ impl<'a> Parser<'a> {
         // else is parsed as a normal function parameter list, so some lookahead is required.
         let eself_lo = self.token.span;
         let (eself, eself_ident, eself_hi) = match self.token.uninterpolate().kind {
-            token::BinOp(token::And) => {
-                let eself = if is_isolated_self(self, 1) {
-                    // `&self`
-                    self.bump();
-                    SelfKind::Region(None, Mutability::Not)
-                } else if is_isolated_mut_self(self, 1) {
-                    // `&mut self`
-                    self.bump();
-                    self.bump();
-                    SelfKind::Region(None, Mutability::Mut)
-                } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_self(self, 2) {
-                    // `&'lt self`
-                    self.bump();
-                    let lt = self.expect_lifetime();
-                    SelfKind::Region(Some(lt), Mutability::Not)
-                } else if self.look_ahead(1, |t| t.is_lifetime()) && is_isolated_mut_self(self, 2) {
-                    // `&'lt mut self`
-                    self.bump();
-                    let lt = self.expect_lifetime();
-                    self.bump();
-                    SelfKind::Region(Some(lt), Mutability::Mut)
+            token::And => {
+                let has_lifetime = is_lifetime(self, 1);
+                let skip_lifetime_count = has_lifetime as usize;
+                let eself = if is_isolated_self(self, skip_lifetime_count + 1) {
+                    // `&{'lt} self`
+                    self.bump(); // &
+                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
+                    SelfKind::Region(lifetime, Mutability::Not)
+                } else if is_isolated_mut_self(self, skip_lifetime_count + 1) {
+                    // `&{'lt} mut self`
+                    self.bump(); // &
+                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
+                    self.bump(); // mut
+                    SelfKind::Region(lifetime, Mutability::Mut)
+                } else if is_isolated_pin_const_self(self, skip_lifetime_count + 1) {
+                    // `&{'lt} pin const self`
+                    self.bump(); // &
+                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
+                    self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
+                    self.bump(); // pin
+                    self.bump(); // const
+                    SelfKind::Pinned(lifetime, Mutability::Not)
+                } else if is_isolated_pin_mut_self(self, skip_lifetime_count + 1) {
+                    // `&{'lt} pin mut self`
+                    self.bump(); // &
+                    let lifetime = has_lifetime.then(|| self.expect_lifetime());
+                    self.psess.gated_spans.gate(sym::pin_ergonomics, self.token.span);
+                    self.bump(); // pin
+                    self.bump(); // mut
+                    SelfKind::Pinned(lifetime, Mutability::Mut)
                 } else {
                     // `&not_self`
                     return Ok(None);
@@ -3041,12 +3063,12 @@ impl<'a> Parser<'a> {
                 (eself, self_ident, hi)
             }
             // `*self`
-            token::BinOp(token::Star) if is_isolated_self(self, 1) => {
+            token::Star if is_isolated_self(self, 1) => {
                 self.bump();
                 recover_self_ptr(self)?
             }
             // `*mut self` and `*const self`
-            token::BinOp(token::Star)
+            token::Star
                 if self.look_ahead(1, |t| t.is_mutability()) && is_isolated_self(self, 2) =>
             {
                 self.bump();
@@ -3077,7 +3099,7 @@ impl<'a> Parser<'a> {
                 }
                 _ => 0,
             },
-            token::BinOp(token::And) | token::AndAnd => 1,
+            token::And | token::AndAnd => 1,
             _ if self.token.is_keyword(kw::Mut) => 1,
             _ => 0,
         };
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 00282ef8679..7dabc28c645 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -813,9 +813,9 @@ impl<'a> Parser<'a> {
         self.is_keyword_ahead(0, &[kw::Const])
             && self.look_ahead(1, |t| match &t.kind {
                 // async closures do not work with const closures, so we do not parse that here.
-                token::Ident(kw::Move | kw::Static, IdentIsRaw::No)
-                | token::OrOr
-                | token::BinOp(token::Or) => true,
+                token::Ident(kw::Move | kw::Static, IdentIsRaw::No) | token::OrOr | token::Or => {
+                    true
+                }
                 _ => false,
             })
     }
@@ -1651,7 +1651,7 @@ impl<'a> Parser<'a> {
     /// `::{` or `::*`
     fn is_import_coupler(&mut self) -> bool {
         self.check_path_sep_and_look_ahead(|t| {
-            matches!(t.kind, token::OpenDelim(Delimiter::Brace) | token::BinOp(token::Star))
+            matches!(t.kind, token::OpenDelim(Delimiter::Brace) | token::Star)
         })
     }
 
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 40f2e228b24..ec14c5718da 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -3,7 +3,7 @@ use std::ops::Bound;
 use rustc_ast::mut_visit::{self, MutVisitor};
 use rustc_ast::ptr::P;
 use rustc_ast::token::NtPatKind::*;
-use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, MetaVarKind, Token};
+use rustc_ast::token::{self, Delimiter, IdentIsRaw, MetaVarKind, Token};
 use rustc_ast::util::parser::ExprPrecedence;
 use rustc_ast::visit::{self, Visitor};
 use rustc_ast::{
@@ -358,7 +358,7 @@ impl<'a> Parser<'a> {
             )
         });
         match (is_end_ahead, &self.token.kind) {
-            (true, token::BinOp(token::Or) | token::OrOr) => {
+            (true, token::Or | token::OrOr) => {
                 // A `|` or possibly `||` token shouldn't be here. Ban it.
                 self.dcx().emit_err(TrailingVertNotAllowed {
                     span: self.token.span,
@@ -432,7 +432,11 @@ impl<'a> Parser<'a> {
         // `[` is included for indexing operations,
         // `[]` is excluded as `a[]` isn't an expression and should be recovered as `a, []` (cf. `tests/ui/parser/pat-lt-bracket-7.rs`),
         // `as` is included for type casts
-        let has_trailing_operator = matches!(self.token.kind, token::BinOp(op) if op != BinOpToken::Or)
+        let has_trailing_operator = matches!(
+                self.token.kind,
+                token::Plus | token::Minus | token::Star | token::Slash | token::Percent
+                | token::Caret | token::And | token::Shl | token::Shr // excludes `Or`
+            )
             || self.token == token::Question
             || (self.token == token::OpenDelim(Delimiter::Bracket)
                 && self.look_ahead(1, |t| *t != token::CloseDelim(Delimiter::Bracket))) // excludes `[]`
@@ -763,7 +767,7 @@ impl<'a> Parser<'a> {
             self.recover_dotdotdot_rest_pat(lo)
         } else if let Some(form) = self.parse_range_end() {
             self.parse_pat_range_to(form)? // `..=X`, `...X`, or `..X`.
-        } else if self.eat(exp!(Not)) {
+        } else if self.eat(exp!(Bang)) {
             // Parse `!`
             self.psess.gated_spans.gate(sym::never_patterns, self.prev_token.span);
             PatKind::Never
@@ -819,7 +823,7 @@ impl<'a> Parser<'a> {
             };
             let span = lo.to(self.prev_token.span);
 
-            if qself.is_none() && self.check(exp!(Not)) {
+            if qself.is_none() && self.check(exp!(Bang)) {
                 self.parse_pat_mac_invoc(path)?
             } else if let Some(form) = self.parse_range_end() {
                 let begin = self.mk_expr(span, ExprKind::Path(qself, path));
@@ -1255,7 +1259,7 @@ impl<'a> Parser<'a> {
             || self.look_ahead(dist, |t| {
                 t.is_path_start() // e.g. `MY_CONST`;
                 || *t == token::Dot // e.g. `.5` for recovery;
-                || matches!(t.kind, token::Literal(..) | token::BinOp(token::Minus))
+                || matches!(t.kind, token::Literal(..) | token::Minus)
                 || t.is_bool_lit()
                 || t.is_whole_expr()
                 || t.is_lifetime() // recover `'a` instead of `'a'`
@@ -1331,7 +1335,7 @@ impl<'a> Parser<'a> {
             | token::OpenDelim(Delimiter::Brace) // A struct pattern.
             | token::DotDotDot | token::DotDotEq | token::DotDot // A range pattern.
             | token::PathSep // A tuple / struct variant pattern.
-            | token::Not)) // A macro expanding to a pattern.
+            | token::Bang)) // A macro expanding to a pattern.
     }
 
     /// Parses `ident` or `ident @ pat`.
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 8091dfa2a4a..9c6830c3672 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -305,10 +305,7 @@ impl<'a> Parser<'a> {
         let is_args_start = |token: &Token| {
             matches!(
                 token.kind,
-                token::Lt
-                    | token::BinOp(token::Shl)
-                    | token::OpenDelim(Delimiter::Parenthesis)
-                    | token::LArrow
+                token::Lt | token::Shl | token::OpenDelim(Delimiter::Parenthesis) | token::LArrow
             )
         };
         let check_args_start = |this: &mut Self| {
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index a2699b077fc..3a9dc5ce798 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -176,7 +176,7 @@ impl<'a> Parser<'a> {
         let stmt = self.collect_tokens(None, attrs, ForceCollect::No, |this, attrs| {
             let path = this.parse_path(PathStyle::Expr)?;
 
-            if this.eat(exp!(Not)) {
+            if this.eat(exp!(Bang)) {
                 let stmt_mac = this.parse_stmt_mac(lo, attrs, path)?;
                 return Ok((
                     stmt_mac,
@@ -442,7 +442,16 @@ impl<'a> Parser<'a> {
     /// Parses the RHS of a local variable declaration (e.g., `= 14;`).
     fn parse_initializer(&mut self, eq_optional: bool) -> PResult<'a, Option<P<Expr>>> {
         let eq_consumed = match self.token.kind {
-            token::BinOpEq(..) => {
+            token::PlusEq
+            | token::MinusEq
+            | token::StarEq
+            | token::SlashEq
+            | token::PercentEq
+            | token::CaretEq
+            | token::AndEq
+            | token::OrEq
+            | token::ShlEq
+            | token::ShrEq => {
                 // Recover `let x <op>= 1` as `let x = 1` We must not use `+ BytePos(1)` here
                 // because `<op>` can be a multi-byte lookalike that was recovered, e.g. `➖=` (the
                 // `➖` is a U+2796 Heavy Minus Sign Unicode Character) that was recovered as a
@@ -688,7 +697,7 @@ impl<'a> Parser<'a> {
             if self.token == token::Eof {
                 break;
             }
-            if self.is_vcs_conflict_marker(&TokenKind::BinOp(token::Shl), &TokenKind::Lt) {
+            if self.is_vcs_conflict_marker(&TokenKind::Shl, &TokenKind::Lt) {
                 // Account for `<<<<<<<` diff markers. We can't proactively error here because
                 // that can be a valid path start, so we snapshot and reparse only we've
                 // encountered another parse error.
diff --git a/compiler/rustc_parse/src/parser/tests.rs b/compiler/rustc_parse/src/parser/tests.rs
index 8b8c81a77a0..471966d086d 100644
--- a/compiler/rustc_parse/src/parser/tests.rs
+++ b/compiler/rustc_parse/src/parser/tests.rs
@@ -2291,7 +2291,7 @@ fn string_to_tts_macro() {
                     Token { kind: token::Ident(name_macro_rules, IdentIsRaw::No), .. },
                     _,
                 ),
-                TokenTree::Token(Token { kind: token::Not, .. }, _),
+                TokenTree::Token(Token { kind: token::Bang, .. }, _),
                 TokenTree::Token(Token { kind: token::Ident(name_zip, IdentIsRaw::No), .. }, _),
                 TokenTree::Delimited(.., macro_delim, macro_tts),
             ] if name_macro_rules == &kw::MacroRules && name_zip.as_str() == "zip" => {
diff --git a/compiler/rustc_parse/src/parser/token_type.rs b/compiler/rustc_parse/src/parser/token_type.rs
index 40631d9154d..110546d0ba6 100644
--- a/compiler/rustc_parse/src/parser/token_type.rs
+++ b/compiler/rustc_parse/src/parser/token_type.rs
@@ -25,7 +25,7 @@ pub enum TokenType {
     Gt,
     AndAnd,
     OrOr,
-    Not,
+    Bang,
     Tilde,
 
     // BinOps
@@ -172,7 +172,7 @@ impl TokenType {
             Gt,
             AndAnd,
             OrOr,
-            Not,
+            Bang,
             Tilde,
 
             Plus,
@@ -366,7 +366,7 @@ impl TokenType {
             TokenType::Gt => "`>`",
             TokenType::AndAnd => "`&&`",
             TokenType::OrOr => "`||`",
-            TokenType::Not => "`!`",
+            TokenType::Bang => "`!`",
             TokenType::Tilde => "`~`",
 
             TokenType::Plus => "`+`",
@@ -445,12 +445,6 @@ macro_rules! exp {
             token_type: $crate::parser::token_type::TokenType::$tok
         }
     };
-    (@binop, $op:ident) => {
-        $crate::parser::token_type::ExpTokenPair {
-            tok: &rustc_ast::token::BinOp(rustc_ast::token::BinOpToken::$op),
-            token_type: $crate::parser::token_type::TokenType::$op,
-        }
-    };
     (@open, $delim:ident, $token_type:ident) => {
         $crate::parser::token_type::ExpTokenPair {
             tok: &rustc_ast::token::OpenDelim(rustc_ast::token::Delimiter::$delim),
@@ -485,8 +479,13 @@ macro_rules! exp {
     (Gt)             => { exp!(@tok, Gt) };
     (AndAnd)         => { exp!(@tok, AndAnd) };
     (OrOr)           => { exp!(@tok, OrOr) };
-    (Not)            => { exp!(@tok, Not) };
+    (Bang)           => { exp!(@tok, Bang) };
     (Tilde)          => { exp!(@tok, Tilde) };
+    (Plus)           => { exp!(@tok, Plus) };
+    (Minus)          => { exp!(@tok, Minus) };
+    (Star)           => { exp!(@tok, Star) };
+    (And)            => { exp!(@tok, And) };
+    (Or)             => { exp!(@tok, Or) };
     (At)             => { exp!(@tok, At) };
     (Dot)            => { exp!(@tok, Dot) };
     (DotDot)         => { exp!(@tok, DotDot) };
@@ -502,12 +501,6 @@ macro_rules! exp {
     (Question)       => { exp!(@tok, Question) };
     (Eof)            => { exp!(@tok, Eof) };
 
-    (Plus)           => { exp!(@binop, Plus) };
-    (Minus)          => { exp!(@binop, Minus) };
-    (Star)           => { exp!(@binop, Star) };
-    (And)            => { exp!(@binop, And) };
-    (Or)             => { exp!(@binop, Or) };
-
     (OpenParen)      => { exp!(@open,  Parenthesis, OpenParen) };
     (OpenBrace)      => { exp!(@open,  Brace,       OpenBrace) };
     (OpenBracket)    => { exp!(@open,  Bracket,     OpenBracket) };
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 18af0a1c79a..b45ebae079c 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -1,5 +1,5 @@
 use rustc_ast::ptr::P;
-use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, MetaVarKind, Token, TokenKind};
+use rustc_ast::token::{self, Delimiter, IdentIsRaw, MetaVarKind, Token, TokenKind};
 use rustc_ast::util::case::Case;
 use rustc_ast::{
     self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, DUMMY_NODE_ID, FnRetTy,
@@ -86,7 +86,7 @@ enum AllowCVariadic {
 /// Types can also be of the form `IDENT(u8, u8) -> u8`, however this assumes
 /// that `IDENT` is not the ident of a fn trait.
 fn can_continue_type_after_non_fn_ident(t: &Token) -> bool {
-    t == &token::PathSep || t == &token::Lt || t == &token::BinOp(token::Shl)
+    t == &token::PathSep || t == &token::Lt || t == &token::Shl
 }
 
 fn can_begin_dyn_bound_in_edition_2015(t: &Token) -> bool {
@@ -260,7 +260,7 @@ impl<'a> Parser<'a> {
         let mut impl_dyn_multi = false;
         let kind = if self.check(exp!(OpenParen)) {
             self.parse_ty_tuple_or_parens(lo, allow_plus)?
-        } else if self.eat(exp!(Not)) {
+        } else if self.eat(exp!(Bang)) {
             // Never type `!`
             TyKind::Never
         } else if self.eat(exp!(Star)) {
@@ -399,7 +399,7 @@ impl<'a> Parser<'a> {
         let mut trailing_plus = false;
         let (ts, trailing) = self.parse_paren_comma_seq(|p| {
             let ty = p.parse_ty()?;
-            trailing_plus = p.prev_token == TokenKind::BinOp(token::Plus);
+            trailing_plus = p.prev_token == TokenKind::Plus;
             Ok(ty)
         })?;
 
@@ -735,7 +735,7 @@ impl<'a> Parser<'a> {
         // Always parse bounds greedily for better error recovery.
         let bounds = self.parse_generic_bounds()?;
 
-        *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::BinOp(token::Plus);
+        *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::Plus;
 
         Ok(TyKind::ImplTrait(ast::DUMMY_NODE_ID, bounds))
     }
@@ -747,11 +747,7 @@ impl<'a> Parser<'a> {
         self.expect_lt()?;
         let (args, _, _) = self.parse_seq_to_before_tokens(
             &[exp!(Gt)],
-            &[
-                &TokenKind::Ge,
-                &TokenKind::BinOp(BinOpToken::Shr),
-                &TokenKind::BinOpEq(BinOpToken::Shr),
-            ],
+            &[&TokenKind::Ge, &TokenKind::Shr, &TokenKind::Shr],
             SeqSep::trailing_allowed(exp!(Comma)),
             |self_| {
                 if self_.check_keyword(exp!(SelfUpper)) {
@@ -781,7 +777,7 @@ impl<'a> Parser<'a> {
         self.check_keyword(exp!(Dyn))
             && (self.token.uninterpolated_span().at_least_rust_2018()
                 || self.look_ahead(1, |t| {
-                    (can_begin_dyn_bound_in_edition_2015(t) || *t == TokenKind::BinOp(token::Star))
+                    (can_begin_dyn_bound_in_edition_2015(t) || *t == TokenKind::Star)
                         && !can_continue_type_after_non_fn_ident(t)
                 }))
     }
@@ -803,7 +799,7 @@ impl<'a> Parser<'a> {
 
         // Always parse bounds greedily for better error recovery.
         let bounds = self.parse_generic_bounds()?;
-        *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::BinOp(token::Plus);
+        *impl_dyn_multi = bounds.len() > 1 || self.prev_token == TokenKind::Plus;
         Ok(TyKind::TraitObject(bounds, syntax))
     }
 
@@ -821,7 +817,7 @@ impl<'a> Parser<'a> {
     ) -> PResult<'a, TyKind> {
         // Simple path
         let path = self.parse_path_inner(PathStyle::Type, ty_generics)?;
-        if self.eat(exp!(Not)) {
+        if self.eat(exp!(Bang)) {
             // Macro invocation in type position
             Ok(TyKind::MacCall(P(MacCall { path, args: self.parse_delim_args()? })))
         } else if allow_plus == AllowPlus::Yes && self.check_plus() {
@@ -874,7 +870,7 @@ impl<'a> Parser<'a> {
     fn can_begin_bound(&mut self) -> bool {
         self.check_path()
             || self.check_lifetime()
-            || self.check(exp!(Not))
+            || self.check(exp!(Bang))
             || self.check(exp!(Question))
             || self.check(exp!(Tilde))
             || self.check_keyword(exp!(For))
@@ -1025,7 +1021,7 @@ impl<'a> Parser<'a> {
 
         let polarity = if self.eat(exp!(Question)) {
             BoundPolarity::Maybe(self.prev_token.span)
-        } else if self.eat(exp!(Not)) {
+        } else if self.eat(exp!(Bang)) {
             self.psess.gated_spans.gate(sym::negative_bounds, self.prev_token.span);
             BoundPolarity::Negative(self.prev_token.span)
         } else {
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index b65430c3480..ed498d9d344 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -779,6 +779,10 @@ passes_unstable_attr_for_already_stable_feature =
     .item = the stability attribute annotates this item
     .help = consider removing the attribute
 
+passes_unsupported_attributes_in_where =
+    most attributes are not supported in `where` clauses
+    .help = only `#[cfg]` and `#[cfg_attr]` are supported
+
 passes_unused =
     unused attribute
     .suggestion = remove this attribute
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 5ada289cc20..91916b8f5fc 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -14,6 +14,7 @@ use rustc_attr_parsing::{AttributeKind, ReprAttr, find_attr};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::{Applicability, DiagCtxtHandle, IntoDiagArg, MultiSpan, StashKey};
 use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, BuiltinAttribute};
+use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalModDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{
@@ -257,6 +258,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                         [sym::coroutine, ..] => {
                             self.check_coroutine(attr, target);
                         }
+                        [sym::type_const, ..] => {
+                            self.check_type_const(hir_id,attr, target);
+                        }
                         [sym::linkage, ..] => self.check_linkage(attr, span, target),
                         [sym::rustc_pub_transparent, ..] => self.check_rustc_pub_transparent(attr.span(), span, attrs),
                         [
@@ -919,7 +923,8 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             | Target::Arm
             | Target::ForeignMod
             | Target::Closure
-            | Target::Impl => Some(target.name()),
+            | Target::Impl
+            | Target::WherePredicate => Some(target.name()),
             Target::ExternCrate
             | Target::Use
             | Target::Static
@@ -2518,6 +2523,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
+    fn check_type_const(&self, hir_id: HirId, attr: &Attribute, target: Target) {
+        let tcx = self.tcx;
+        if target == Target::AssocConst
+            && let parent = tcx.parent(hir_id.expect_owner().to_def_id())
+            && self.tcx.def_kind(parent) == DefKind::Trait
+        {
+            return;
+        } else {
+            self.dcx()
+                .struct_span_err(
+                    attr.span(),
+                    "`#[type_const]` must only be applied to trait associated constants",
+                )
+                .emit();
+        }
+    }
+
     fn check_linkage(&self, attr: &Attribute, span: Span, target: Target) {
         match target {
             Target::Fn
@@ -2614,6 +2636,32 @@ impl<'tcx> Visitor<'tcx> for CheckAttrVisitor<'tcx> {
         intravisit::walk_item(self, item)
     }
 
+    fn visit_where_predicate(&mut self, where_predicate: &'tcx hir::WherePredicate<'tcx>) {
+        // FIXME(where_clause_attrs): Currently, as the following check shows,
+        // only `#[cfg]` and `#[cfg_attr]` are allowed, but it should be removed
+        // if we allow more attributes (e.g., tool attributes and `allow/deny/warn`)
+        // in where clauses. After that, only `self.check_attributes` should be enough.
+        const ATTRS_ALLOWED: &[Symbol] = &[sym::cfg, sym::cfg_attr];
+        let spans = self
+            .tcx
+            .hir()
+            .attrs(where_predicate.hir_id)
+            .iter()
+            .filter(|attr| !ATTRS_ALLOWED.iter().any(|&sym| attr.has_name(sym)))
+            .map(|attr| attr.span())
+            .collect::<Vec<_>>();
+        if !spans.is_empty() {
+            self.tcx.dcx().emit_err(errors::UnsupportedAttributesInWhere { span: spans.into() });
+        }
+        self.check_attributes(
+            where_predicate.hir_id,
+            where_predicate.span,
+            Target::WherePredicate,
+            None,
+        );
+        intravisit::walk_where_predicate(self, where_predicate)
+    }
+
     fn visit_generic_param(&mut self, generic_param: &'tcx hir::GenericParam<'tcx>) {
         let target = Target::from_generic_param(generic_param);
         self.check_attributes(generic_param.hir_id, generic_param.span, target, None);
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 9bb9b2353dc..b8359c27e53 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -1909,3 +1909,11 @@ pub(crate) struct RustcConstStableIndirectPairing {
     #[primary_span]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(passes_unsupported_attributes_in_where)]
+#[help]
+pub(crate) struct UnsupportedAttributesInWhere {
+    #[primary_span]
+    pub span: MultiSpan,
+}
diff --git a/compiler/rustc_query_system/src/query/caches.rs b/compiler/rustc_query_system/src/query/caches.rs
index e11123dff26..3b47e7eba0f 100644
--- a/compiler/rustc_query_system/src/query/caches.rs
+++ b/compiler/rustc_query_system/src/query/caches.rs
@@ -1,9 +1,9 @@
 use std::fmt::Debug;
 use std::hash::Hash;
+use std::sync::OnceLock;
 
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sharded::{self, Sharded};
-use rustc_data_structures::sync::OnceLock;
 pub use rustc_data_structures::vec_cache::VecCache;
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_index::Idx;
diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs
index a8c2aa98cd0..37b305d0a8b 100644
--- a/compiler/rustc_query_system/src/query/job.rs
+++ b/compiler/rustc_query_system/src/query/job.rs
@@ -477,8 +477,8 @@ fn remove_cycle(
 /// Detects query cycles by using depth first search over all active query jobs.
 /// If a query cycle is found it will break the cycle by finding an edge which
 /// uses a query latch and then resuming that waiter.
-/// There may be multiple cycles involved in a deadlock, so this searches
-/// all active queries for cycles before finally resuming all the waiters at once.
+/// There may be multiple cycles involved in a deadlock, but we only search
+/// one cycle at a call and resume one waiter at once. See `FIXME` below.
 pub fn break_query_cycles(query_map: QueryMap, registry: &rayon_core::Registry) {
     let mut wakelist = Vec::new();
     let mut jobs: Vec<QueryJobId> = query_map.keys().cloned().collect();
@@ -488,6 +488,19 @@ pub fn break_query_cycles(query_map: QueryMap, registry: &rayon_core::Registry)
     while jobs.len() > 0 {
         if remove_cycle(&query_map, &mut jobs, &mut wakelist) {
             found_cycle = true;
+
+            // FIXME(#137731): Resume all the waiters at once may cause deadlocks,
+            // so we resume one waiter at a call for now. It's still unclear whether
+            // it's due to possible issues in rustc-rayon or instead in the handling
+            // of query cycles.
+            // This seem to only appear when multiple query cycles errors
+            // are involved, so this reduction in parallelism, while suboptimal, is not
+            // universal and only the deadlock handler will encounter these cases.
+            // The workaround shows loss of potential gains, but there still are big
+            // improvements in the common case, and no regressions compared to the
+            // single-threaded case. More investigation is still needed, and once fixed,
+            // we can wake up all the waiters up.
+            break;
         }
     }
 
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 87f7eda391d..42fe01b1c84 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -1529,6 +1529,14 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for BuildReducedGraphVisitor<'a, 'ra, 'tcx> {
         visit::walk_variant(self, variant);
     }
 
+    fn visit_where_predicate(&mut self, p: &'a ast::WherePredicate) {
+        if p.is_placeholder {
+            self.visit_invoc(p.id);
+        } else {
+            visit::walk_where_predicate(self, p);
+        }
+    }
+
     fn visit_crate(&mut self, krate: &'a ast::Crate) {
         if krate.is_placeholder {
             self.visit_invoc_in_module(krate.id);
diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs
index 9d78c71b76a..95d637b6b22 100644
--- a/compiler/rustc_resolve/src/def_collector.rs
+++ b/compiler/rustc_resolve/src/def_collector.rs
@@ -285,6 +285,14 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> {
         });
     }
 
+    fn visit_where_predicate(&mut self, pred: &'a WherePredicate) {
+        if pred.is_placeholder {
+            self.visit_macro_invoc(pred.id)
+        } else {
+            visit::walk_where_predicate(self, pred)
+        }
+    }
+
     fn visit_variant_data(&mut self, data: &'a VariantData) {
         // The assumption here is that non-`cfg` macro expansion cannot change field indices.
         // It currently holds because only inert attributes are accepted on fields,
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index f119ed55e7d..92f5fba1f9b 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -78,6 +78,7 @@ struct IsNeverPattern;
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 enum AnonConstKind {
     EnumDiscriminant,
+    FieldDefaultValue,
     InlineConst,
     ConstArg(IsRepeatExpr),
 }
@@ -623,7 +624,7 @@ pub(crate) struct UnnecessaryQualification<'ra> {
     pub removal_span: Span,
 }
 
-#[derive(Default)]
+#[derive(Default, Debug)]
 struct DiagMetadata<'ast> {
     /// The current trait's associated items' ident, used for diagnostic suggestions.
     current_trait_assoc_items: Option<&'ast [P<AssocItem>]>,
@@ -1202,7 +1203,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
                 if let TyKind::Path(None, ref path) = ty.kind
                     // We cannot disambiguate multi-segment paths right now as that requires type
                     // checking.
-                    && path.is_potential_trivial_const_arg()
+                    && path.is_potential_trivial_const_arg(false)
                 {
                     let mut check_ns = |ns| {
                         self.maybe_resolve_ident_in_lexical_scope(path.segments[0].ident, ns)
@@ -1406,7 +1407,7 @@ impl<'ra: 'ast, 'ast, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'r
         visit_opt!(self, visit_ident, ident);
         try_visit!(self.visit_ty(ty));
         if let Some(v) = &default {
-            self.resolve_anon_const(v, AnonConstKind::ConstArg(IsRepeatExpr::No));
+            self.resolve_anon_const(v, AnonConstKind::FieldDefaultValue);
         }
     }
 }
@@ -3146,6 +3147,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 PathSource::Trait(AliasPossibility::No),
                 Finalize::new(trait_ref.ref_id, trait_ref.path.span),
                 RecordPartialRes::Yes,
+                None,
             );
             self.diag_metadata.currently_processing_impl_trait = None;
             if let Some(def_id) = res.expect_full_res().opt_def_id() {
@@ -4072,6 +4074,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             source,
             Finalize::new(id, path.span),
             RecordPartialRes::Yes,
+            None,
         );
     }
 
@@ -4083,14 +4086,21 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
         source: PathSource<'ast>,
         finalize: Finalize,
         record_partial_res: RecordPartialRes,
+        parent_qself: Option<&QSelf>,
     ) -> PartialRes {
         let ns = source.namespace();
 
         let Finalize { node_id, path_span, .. } = finalize;
         let report_errors = |this: &mut Self, res: Option<Res>| {
             if this.should_report_errs() {
-                let (err, candidates) =
-                    this.smart_resolve_report_errors(path, None, path_span, source, res);
+                let (err, candidates) = this.smart_resolve_report_errors(
+                    path,
+                    None,
+                    path_span,
+                    source,
+                    res,
+                    parent_qself,
+                );
 
                 let def_id = this.parent_scope.module.nearest_parent_mod();
                 let instead = res.is_some();
@@ -4159,6 +4169,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                     path_span,
                     PathSource::Type,
                     None,
+                    parent_qself,
                 );
 
                 // There are two different error messages user might receive at
@@ -4436,6 +4447,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 PathSource::Trait(AliasPossibility::No),
                 Finalize::new(finalize.node_id, qself.path_span),
                 RecordPartialRes::No,
+                Some(&qself),
             );
 
             if trait_res.expect_full_res() == Res::Err {
@@ -4460,6 +4472,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 PathSource::TraitItem(ns),
                 Finalize::with_root_span(finalize.node_id, finalize.path_span, qself.path_span),
                 RecordPartialRes::No,
+                Some(&qself),
             );
 
             // The remaining segments (the `C` in our example) will
@@ -4630,11 +4643,12 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             constant, anon_const_kind
         );
 
-        self.resolve_anon_const_manual(
-            constant.value.is_potential_trivial_const_arg(),
-            anon_const_kind,
-            |this| this.resolve_expr(&constant.value, None),
-        )
+        let is_trivial_const_arg = constant
+            .value
+            .is_potential_trivial_const_arg(self.r.tcx.features().min_generic_const_args());
+        self.resolve_anon_const_manual(is_trivial_const_arg, anon_const_kind, |this| {
+            this.resolve_expr(&constant.value, None)
+        })
     }
 
     /// There are a few places that we need to resolve an anon const but we did not parse an
@@ -4658,6 +4672,7 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
             AnonConstKind::EnumDiscriminant => {
                 ConstantHasGenerics::No(NoConstantGenericsReason::IsEnumDiscriminant)
             }
+            AnonConstKind::FieldDefaultValue => ConstantHasGenerics::Yes,
             AnonConstKind::InlineConst => ConstantHasGenerics::Yes,
             AnonConstKind::ConstArg(_) => {
                 if self.r.tcx.features().generic_const_exprs() || is_trivial_const_arg {
@@ -4794,8 +4809,11 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                     // Constant arguments need to be treated as AnonConst since
                     // that is how they will be later lowered to HIR.
                     if const_args.contains(&idx) {
+                        let is_trivial_const_arg = argument.is_potential_trivial_const_arg(
+                            self.r.tcx.features().min_generic_const_args(),
+                        );
                         self.resolve_anon_const_manual(
-                            argument.is_potential_trivial_const_arg(),
+                            is_trivial_const_arg,
                             AnonConstKind::ConstArg(IsRepeatExpr::No),
                             |this| this.resolve_expr(argument, None),
                         );
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index 0e14e7671b1..67024f988a4 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -35,7 +35,7 @@ use super::NoConstantGenericsReason;
 use crate::diagnostics::{ImportSuggestion, LabelSuggestion, TypoSuggestion};
 use crate::late::{
     AliasPossibility, LateResolutionVisitor, LifetimeBinderKind, LifetimeRes, LifetimeRibKind,
-    LifetimeUseSet, RibKind,
+    LifetimeUseSet, QSelf, RibKind,
 };
 use crate::ty::fast_reject::SimplifiedType;
 use crate::{
@@ -421,6 +421,7 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         span: Span,
         source: PathSource<'_>,
         res: Option<Res>,
+        qself: Option<&QSelf>,
     ) -> (Diag<'tcx>, Vec<ImportSuggestion>) {
         debug!(?res, ?source);
         let base_error = self.make_base_error(path, span, source, res);
@@ -429,6 +430,14 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         let mut err = self.r.dcx().struct_span_err(base_error.span, base_error.msg.clone());
         err.code(code);
 
+        // Try to get the span of the identifier within the path's syntax context
+        // (if that's different).
+        if let Some(within_macro_span) =
+            base_error.span.within_macro(span, self.r.tcx.sess.source_map())
+        {
+            err.span_label(within_macro_span, "due to this macro variable");
+        }
+
         self.detect_missing_binding_available_from_pattern(&mut err, path, following_seg);
         self.suggest_at_operator_in_slice_pat_with_range(&mut err, path);
         self.suggest_swapping_misplaced_self_ty_and_trait(&mut err, source, res, base_error.span);
@@ -453,6 +462,15 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
 
         self.suggest_self_or_self_ref(&mut err, path, span);
         self.detect_assoc_type_constraint_meant_as_path(&mut err, &base_error);
+        self.detect_rtn_with_fully_qualified_path(
+            &mut err,
+            path,
+            following_seg,
+            span,
+            source,
+            res,
+            qself,
+        );
         if self.suggest_self_ty(&mut err, source, path, span)
             || self.suggest_self_value(&mut err, source, path, span)
         {
@@ -501,6 +519,33 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
         (err, candidates)
     }
 
+    fn detect_rtn_with_fully_qualified_path(
+        &self,
+        err: &mut Diag<'_>,
+        path: &[Segment],
+        following_seg: Option<&Segment>,
+        span: Span,
+        source: PathSource<'_>,
+        res: Option<Res>,
+        qself: Option<&QSelf>,
+    ) {
+        if let Some(Res::Def(DefKind::AssocFn, _)) = res
+            && let PathSource::TraitItem(TypeNS) = source
+            && let None = following_seg
+            && let Some(qself) = qself
+            && let TyKind::Path(None, ty_path) = &qself.ty.kind
+            && ty_path.segments.len() == 1
+            && self.diag_metadata.current_where_predicate.is_some()
+        {
+            err.span_suggestion_verbose(
+                span,
+                "you might have meant to use the return type notation syntax",
+                format!("{}::{}(..)", ty_path.segments[0].ident, path[path.len() - 1].ident),
+                Applicability::MaybeIncorrect,
+            );
+        }
+    }
+
     fn detect_assoc_type_constraint_meant_as_path(
         &self,
         err: &mut Diag<'_>,
@@ -3515,12 +3560,6 @@ impl<'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> {
                         }
                     }
                 }
-
-                // Record as using the suggested resolution.
-                let (_, (_, res)) = in_scope_lifetimes[0];
-                for &lt in &lifetime_refs {
-                    self.r.lifetimes_res_map.insert(lt.id, res);
-                }
             }
             _ => {
                 let lifetime_spans: Vec<_> =
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 36adb113d05..7af221c9607 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -42,6 +42,32 @@ mod cfg;
 mod native_libs;
 pub mod sigpipe;
 
+pub const PRINT_KINDS: &[(&str, PrintKind)] = &[
+    // tidy-alphabetical-start
+    ("all-target-specs-json", PrintKind::AllTargetSpecs),
+    ("calling-conventions", PrintKind::CallingConventions),
+    ("cfg", PrintKind::Cfg),
+    ("check-cfg", PrintKind::CheckCfg),
+    ("code-models", PrintKind::CodeModels),
+    ("crate-name", PrintKind::CrateName),
+    ("deployment-target", PrintKind::DeploymentTarget),
+    ("file-names", PrintKind::FileNames),
+    ("host-tuple", PrintKind::HostTuple),
+    ("link-args", PrintKind::LinkArgs),
+    ("native-static-libs", PrintKind::NativeStaticLibs),
+    ("relocation-models", PrintKind::RelocationModels),
+    ("split-debuginfo", PrintKind::SplitDebuginfo),
+    ("stack-protector-strategies", PrintKind::StackProtectorStrategies),
+    ("sysroot", PrintKind::Sysroot),
+    ("target-cpus", PrintKind::TargetCPUs),
+    ("target-features", PrintKind::TargetFeatures),
+    ("target-libdir", PrintKind::TargetLibdir),
+    ("target-list", PrintKind::TargetList),
+    ("target-spec-json", PrintKind::TargetSpec),
+    ("tls-models", PrintKind::TlsModels),
+    // tidy-alphabetical-end
+];
+
 /// The different settings that the `-C strip` flag can have.
 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
 pub enum Strip {
@@ -1501,6 +1527,13 @@ The default is {DEFAULT_EDITION} and the latest stable edition is {LATEST_STABLE
     )
 });
 
+static PRINT_KINDS_STRING: LazyLock<String> = LazyLock::new(|| {
+    format!(
+        "[{}]",
+        PRINT_KINDS.iter().map(|(name, _)| format!("{name}")).collect::<Vec<_>>().join("|")
+    )
+});
+
 /// Returns all rustc command line options, including metadata for
 /// each option, such as whether the option is stable.
 pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
@@ -1561,10 +1594,7 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
             "",
             "print",
             "Compiler information to print on stdout",
-            "[crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|\
-             target-list|target-cpus|target-features|relocation-models|code-models|\
-             tls-models|target-spec-json|all-target-specs-json|native-static-libs|\
-             stack-protector-strategies|link-args|deployment-target]",
+            &PRINT_KINDS_STRING,
         ),
         opt(Stable, FlagMulti, "g", "", "Equivalent to -C debuginfo=2", ""),
         opt(Stable, FlagMulti, "O", "", "Equivalent to -C opt-level=3", ""),
@@ -1991,32 +2021,6 @@ fn collect_print_requests(
         cg.target_feature = String::new();
     }
 
-    const PRINT_KINDS: &[(&str, PrintKind)] = &[
-        // tidy-alphabetical-start
-        ("all-target-specs-json", PrintKind::AllTargetSpecs),
-        ("calling-conventions", PrintKind::CallingConventions),
-        ("cfg", PrintKind::Cfg),
-        ("check-cfg", PrintKind::CheckCfg),
-        ("code-models", PrintKind::CodeModels),
-        ("crate-name", PrintKind::CrateName),
-        ("deployment-target", PrintKind::DeploymentTarget),
-        ("file-names", PrintKind::FileNames),
-        ("host-tuple", PrintKind::HostTuple),
-        ("link-args", PrintKind::LinkArgs),
-        ("native-static-libs", PrintKind::NativeStaticLibs),
-        ("relocation-models", PrintKind::RelocationModels),
-        ("split-debuginfo", PrintKind::SplitDebuginfo),
-        ("stack-protector-strategies", PrintKind::StackProtectorStrategies),
-        ("sysroot", PrintKind::Sysroot),
-        ("target-cpus", PrintKind::TargetCPUs),
-        ("target-features", PrintKind::TargetFeatures),
-        ("target-libdir", PrintKind::TargetLibdir),
-        ("target-list", PrintKind::TargetList),
-        ("target-spec-json", PrintKind::TargetSpec),
-        ("tls-models", PrintKind::TlsModels),
-        // tidy-alphabetical-end
-    ];
-
     // We disallow reusing the same path in multiple prints, such as `--print
     // cfg=output.txt --print link-args=output.txt`, because outputs are printed
     // by disparate pieces of the compiler, and keeping track of which files
@@ -2875,14 +2879,6 @@ impl PpMode {
             | StableMir => true,
         }
     }
-    pub fn needs_hir(&self) -> bool {
-        use PpMode::*;
-        match *self {
-            Source(_) | AstTree | AstTreeExpanded => false,
-
-            Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG | StableMir => true,
-        }
-    }
 
     pub fn needs_analysis(&self) -> bool {
         use PpMode::*;
diff --git a/compiler/rustc_session/src/utils.rs b/compiler/rustc_session/src/utils.rs
index 9182789cf02..fcede379b89 100644
--- a/compiler/rustc_session/src/utils.rs
+++ b/compiler/rustc_session/src/utils.rs
@@ -34,6 +34,7 @@ pub enum NativeLibKind {
         as_needed: Option<bool>,
     },
     /// Dynamic library (e.g. `foo.dll` on Windows) without a corresponding import library.
+    /// On Linux, it refers to a generated shared library stub.
     RawDylib,
     /// A macOS-specific kind of dynamic libraries.
     Framework {
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index 50cf605ba2a..bb2b2dea2f3 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -88,10 +88,9 @@ impl RustcInternal for Pattern {
     type T<'tcx> = rustc_ty::Pattern<'tcx>;
     fn internal<'tcx>(&self, tables: &mut Tables<'_>, tcx: TyCtxt<'tcx>) -> Self::T<'tcx> {
         tcx.mk_pat(match self {
-            Pattern::Range { start, end, include_end } => rustc_ty::PatternKind::Range {
-                start: start.as_ref().map(|c| c.internal(tables, tcx)),
-                end: end.as_ref().map(|c| c.internal(tables, tcx)),
-                include_end: *include_end,
+            Pattern::Range { start, end, include_end: _ } => rustc_ty::PatternKind::Range {
+                start: start.as_ref().unwrap().internal(tables, tcx),
+                end: end.as_ref().unwrap().internal(tables, tcx),
             },
         })
     }
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index a0faf20c79a..aa0eac628dd 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -405,10 +405,11 @@ impl<'tcx> Stable<'tcx> for ty::Pattern<'tcx> {
 
     fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
         match **self {
-            ty::PatternKind::Range { start, end, include_end } => stable_mir::ty::Pattern::Range {
-                start: start.stable(tables),
-                end: end.stable(tables),
-                include_end,
+            ty::PatternKind::Range { start, end } => stable_mir::ty::Pattern::Range {
+                // FIXME(SMIR): update data structures to not have an Option here anymore
+                start: Some(start.stable(tables)),
+                end: Some(end.stable(tables)),
+                include_end: true,
             },
         }
     }
diff --git a/compiler/rustc_span/src/analyze_source_file.rs b/compiler/rustc_span/src/analyze_source_file.rs
index 141d261b5f0..6384fa06c21 100644
--- a/compiler/rustc_span/src/analyze_source_file.rs
+++ b/compiler/rustc_span/src/analyze_source_file.rs
@@ -83,17 +83,17 @@ cfg_match! {
 
                 // For character in the chunk, see if its byte value is < 0, which
                 // indicates that it's part of a UTF-8 char.
-                let multibyte_test = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)) };
+                let multibyte_test = _mm_cmplt_epi8(chunk, _mm_set1_epi8(0));
                 // Create a bit mask from the comparison results.
-                let multibyte_mask = unsafe { _mm_movemask_epi8(multibyte_test) };
+                let multibyte_mask = _mm_movemask_epi8(multibyte_test);
 
                 // If the bit mask is all zero, we only have ASCII chars here:
                 if multibyte_mask == 0 {
                     assert!(intra_chunk_offset == 0);
 
                     // Check for newlines in the chunk
-                    let newlines_test = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)) };
-                    let mut newlines_mask = unsafe { _mm_movemask_epi8(newlines_test) };
+                    let newlines_test = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8));
+                    let mut newlines_mask = _mm_movemask_epi8(newlines_test);
 
                     let output_offset = RelativeBytePos::from_usize(chunk_index * CHUNK_SIZE + 1);
 
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 84e89ff4b7d..64982b858c6 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -1173,6 +1173,8 @@ pub enum DesugaringKind {
     BoundModifier,
     /// Calls to contract checks (`#[requires]` to precond, `#[ensures]` to postcond)
     Contract,
+    /// A pattern type range start/end
+    PatTyRange,
 }
 
 impl DesugaringKind {
@@ -1190,6 +1192,7 @@ impl DesugaringKind {
             DesugaringKind::WhileLoop => "`while` loop",
             DesugaringKind::BoundModifier => "trait bound modifier",
             DesugaringKind::Contract => "contract check",
+            DesugaringKind::PatTyRange => "pattern type",
         }
     }
 }
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index bca9323a50d..798e186a94b 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -1057,6 +1057,37 @@ impl Span {
         }
     }
 
+    /// Returns the `Span` within the syntax context of "within". This is useful when
+    /// "self" is an expansion from a macro variable, since this can be used for
+    /// providing extra macro expansion context for certain errors.
+    ///
+    /// ```text
+    /// macro_rules! m {
+    ///     ($ident:ident) => { ($ident,) }
+    /// }
+    ///
+    /// m!(outer_ident);
+    /// ```
+    ///
+    /// If "self" is the span of the outer_ident, and "within" is the span of the `($ident,)`
+    /// expr, then this will return the span of the `$ident` macro variable.
+    pub fn within_macro(self, within: Span, sm: &SourceMap) -> Option<Span> {
+        match Span::prepare_to_combine(self, within) {
+            // Only return something if it doesn't overlap with the original span,
+            // and the span isn't "imported" (i.e. from unavailable sources).
+            // FIXME: This does limit the usefulness of the error when the macro is
+            // from a foreign crate; we could also take into account `-Zmacro-backtrace`,
+            // which doesn't redact this span (but that would mean passing in even more
+            // args to this function, lol).
+            Ok((self_, _, parent))
+                if self_.hi < self.lo() || self.hi() < self_.lo && !sm.is_imported(within) =>
+            {
+                Some(Span::new(self_.lo, self_.hi, self_.ctxt, parent))
+            }
+            _ => None,
+        }
+    }
+
     pub fn from_inner(self, inner: InnerSpan) -> Span {
         let span = self.data();
         Span::new(
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 2a709b07255..573c65a772c 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -308,6 +308,9 @@ symbols! {
         RangeFull,
         RangeInclusive,
         RangeInclusiveCopy,
+        RangeMax,
+        RangeMin,
+        RangeSub,
         RangeTo,
         RangeToInclusive,
         Rc,
@@ -1522,6 +1525,7 @@ symbols! {
         pattern_complexity_limit,
         pattern_parentheses,
         pattern_type,
+        pattern_type_range_trait,
         pattern_types,
         permissions_from_mode,
         phantom_data,
@@ -1625,6 +1629,7 @@ symbols! {
         quote,
         range_inclusive_new,
         raw_dylib,
+        raw_dylib_elf,
         raw_eq,
         raw_identifiers,
         raw_ref_op,
@@ -2083,6 +2088,7 @@ symbols! {
         type_ascribe,
         type_ascription,
         type_changing_struct_update,
+        type_const,
         type_id,
         type_ir_inherent,
         type_length_limit,
@@ -2234,6 +2240,7 @@ symbols! {
         wasm_abi,
         wasm_import_module,
         wasm_target_feature,
+        where_clause_attrs,
         while_let,
         windows,
         windows_subsystem,
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 4fafd1ac350..bc3923e4b4d 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -169,7 +169,7 @@ impl<'tcx> SymbolMangler<'tcx> {
         Ok(())
     }
 
-    fn in_binder<T>(
+    fn wrap_binder<T>(
         &mut self,
         value: &ty::Binder<'tcx, T>,
         print_value: impl FnOnce(&mut Self, &T) -> Result<(), PrintError>,
@@ -413,12 +413,8 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             }
 
             ty::Pat(ty, pat) => match *pat {
-                ty::PatternKind::Range { start, end, include_end } => {
-                    let consts = [
-                        start.unwrap_or(self.tcx.consts.unit),
-                        end.unwrap_or(self.tcx.consts.unit),
-                        ty::Const::from_bool(self.tcx, include_end),
-                    ];
+                ty::PatternKind::Range { start, end } => {
+                    let consts = [start, end];
                     // HACK: Represent as tuple until we have something better.
                     // HACK: constants are used in arrays, even if the types don't match.
                     self.push("T");
@@ -471,7 +467,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             ty::FnPtr(sig_tys, hdr) => {
                 let sig = sig_tys.with(hdr);
                 self.push("F");
-                self.in_binder(&sig, |cx, sig| {
+                self.wrap_binder(&sig, |cx, sig| {
                     if sig.safety.is_unsafe() {
                         cx.push("U");
                     }
@@ -554,7 +550,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
         // [<Trait> [{<Projection>}]] [{<Auto>}]
         // Since any predicates after the first one shouldn't change the binders,
         // just put them all in the binders of the first.
-        self.in_binder(&predicates[0], |cx, _| {
+        self.wrap_binder(&predicates[0], |cx, _| {
             for predicate in predicates.iter() {
                 // It would be nice to be able to validate bound vars here, but
                 // projections can actually include bound vars from super traits
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index cc8162a2f27..72202129f5b 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -43,7 +43,7 @@ use std::str::FromStr;
 use std::{fmt, io};
 
 use rustc_abi::{Endian, ExternAbi, Integer, Size, TargetDataLayout, TargetDataLayoutErrors};
-use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
 use rustc_fs_util::try_canonicalize;
 use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
@@ -3535,6 +3535,59 @@ impl Target {
             s => s.clone(),
         }
     }
+
+    pub fn object_architecture(
+        &self,
+        unstable_target_features: &FxIndexSet<Symbol>,
+    ) -> Option<(object::Architecture, Option<object::SubArchitecture>)> {
+        use object::Architecture;
+        Some(match self.arch.as_ref() {
+            "arm" => (Architecture::Arm, None),
+            "aarch64" => (
+                if self.pointer_width == 32 {
+                    Architecture::Aarch64_Ilp32
+                } else {
+                    Architecture::Aarch64
+                },
+                None,
+            ),
+            "x86" => (Architecture::I386, None),
+            "s390x" => (Architecture::S390x, None),
+            "mips" | "mips32r6" => (Architecture::Mips, None),
+            "mips64" | "mips64r6" => (Architecture::Mips64, None),
+            "x86_64" => (
+                if self.pointer_width == 32 {
+                    Architecture::X86_64_X32
+                } else {
+                    Architecture::X86_64
+                },
+                None,
+            ),
+            "powerpc" => (Architecture::PowerPc, None),
+            "powerpc64" => (Architecture::PowerPc64, None),
+            "riscv32" => (Architecture::Riscv32, None),
+            "riscv64" => (Architecture::Riscv64, None),
+            "sparc" => {
+                if unstable_target_features.contains(&sym::v8plus) {
+                    // Target uses V8+, aka EM_SPARC32PLUS, aka 64-bit V9 but in 32-bit mode
+                    (Architecture::Sparc32Plus, None)
+                } else {
+                    // Target uses V7 or V8, aka EM_SPARC
+                    (Architecture::Sparc, None)
+                }
+            }
+            "sparc64" => (Architecture::Sparc64, None),
+            "avr" => (Architecture::Avr, None),
+            "msp430" => (Architecture::Msp430, None),
+            "hexagon" => (Architecture::Hexagon, None),
+            "bpf" => (Architecture::Bpf, None),
+            "loongarch64" => (Architecture::LoongArch64, None),
+            "csky" => (Architecture::Csky, None),
+            "arm64ec" => (Architecture::Aarch64, Some(object::SubArchitecture::Arm64EC)),
+            // Unsupported architecture.
+            _ => return None,
+        })
+    }
 }
 
 /// Either a target tuple string or a path to a JSON file.
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs
index dd98f34d323..cffdaa90727 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_espidf.rs
@@ -20,7 +20,7 @@ pub(crate) fn target() -> Target {
             vendor: "espressif".into(),
 
             executables: true,
-            cpu: "esp32-s2".into(),
+            cpu: "esp32s2".into(),
             linker: Some("xtensa-esp32s2-elf-gcc".into()),
 
             // See https://github.com/espressif/rust-esp32-example/issues/3#issuecomment-861054477
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs
index 29bcf12cbaf..7bf5834ab0a 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s2_none_elf.rs
@@ -16,7 +16,7 @@ pub(crate) fn target() -> Target {
 
         options: TargetOptions {
             vendor: "espressif".into(),
-            cpu: "esp32-s2".into(),
+            cpu: "esp32s2".into(),
             linker: Some("xtensa-esp32s2-elf-gcc".into()),
             max_atomic_width: Some(32),
             features: "+forced-atomics".into(),
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs
index dd6e7b6c3e8..2e4afc00541 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_espidf.rs
@@ -20,7 +20,7 @@ pub(crate) fn target() -> Target {
             vendor: "espressif".into(),
 
             executables: true,
-            cpu: "esp32-s3".into(),
+            cpu: "esp32s3".into(),
             linker: Some("xtensa-esp32s3-elf-gcc".into()),
 
             // The esp32s3 only supports native 32bit atomics.
diff --git a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs
index ddc909f387e..d506888d8ee 100644
--- a/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/xtensa_esp32s3_none_elf.rs
@@ -16,7 +16,7 @@ pub(crate) fn target() -> Target {
 
         options: TargetOptions {
             vendor: "espressif".into(),
-            cpu: "esp32-s3".into(),
+            cpu: "esp32s3".into(),
             linker: Some("xtensa-esp32s3-elf-gcc".into()),
             max_atomic_width: Some(32),
             atomic_cas: true,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index 847bd06bb01..42d37418fb8 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -65,7 +65,9 @@ use rustc_middle::bug;
 use rustc_middle::dep_graph::DepContext;
 use rustc_middle::traits::PatternOriginExpr;
 use rustc_middle::ty::error::{ExpectedFound, TypeError, TypeErrorToStringExt};
-use rustc_middle::ty::print::{PrintError, PrintTraitRefExt as _, with_forced_trimmed_paths};
+use rustc_middle::ty::print::{
+    PrintError, PrintTraitRefExt as _, WrapBinderMode, with_forced_trimmed_paths,
+};
 use rustc_middle::ty::{
     self, List, ParamEnv, Region, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable,
     TypeVisitableExt,
@@ -835,7 +837,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         let get_lifetimes = |sig| {
             use rustc_hir::def::Namespace;
             let (sig, reg) = ty::print::FmtPrinter::new(self.tcx, Namespace::TypeNS)
-                .name_all_regions(sig)
+                .name_all_regions(sig, WrapBinderMode::ForAll)
                 .unwrap();
             let lts: Vec<String> =
                 reg.into_items().map(|(_, kind)| kind.to_string()).into_sorted_stable_ord();
diff --git a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
index f15f1b78b52..d673e5672a0 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/ambiguity.rs
@@ -1,8 +1,6 @@
 use std::ops::ControlFlow;
 
-use rustc_errors::{
-    Applicability, Diag, E0283, E0284, E0790, MultiSpan, StashKey, struct_span_code_err,
-};
+use rustc_errors::{Applicability, Diag, E0283, E0284, E0790, MultiSpan, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::LangItem;
 use rustc_hir::def::{DefKind, Res};
@@ -197,7 +195,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 // be ignoring the fact that we don't KNOW the type works
                 // out. Though even that would probably be harmless, given that
                 // we're only talking about builtin traits, which are known to be
-                // inhabited. We used to check for `self.tcx.sess.has_errors()` to
+                // inhabited. We used to check for `self.tainted_by_errors()` to
                 // avoid inundating the user with unnecessary errors, but we now
                 // check upstream for type errors and don't add the obligations to
                 // begin with in those cases.
@@ -211,7 +209,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                                 TypeAnnotationNeeded::E0282,
                                 false,
                             );
-                            return err.stash(span, StashKey::MaybeForgetReturn).unwrap();
+                            return err.emit();
                         }
                         Some(e) => return e,
                     }
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 d270b4cf96b..e2bdd52ba7c 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
@@ -829,7 +829,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                 && let ty::Closure(closure_def_id, _) | ty::CoroutineClosure(closure_def_id, _) =
                     *typeck_results.node_type(arg_hir_id).kind()
             {
-                // Otherwise, extract the closure kind from the obligation.
+                // Otherwise, extract the closure kind from the obligation,
+                // but only if we actually have an argument to deduce the
+                // closure type from...
                 let mut err = self.report_closure_error(
                     &obligation,
                     closure_def_id,
@@ -844,63 +846,72 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
 
         let self_ty = trait_pred.self_ty().skip_binder();
 
-        if let Some(expected_kind) = self.tcx.fn_trait_kind_from_def_id(trait_pred.def_id()) {
-            let (closure_def_id, found_args, by_ref_captures) = match *self_ty.kind() {
-                ty::Closure(def_id, args) => {
-                    (def_id, args.as_closure().sig().map_bound(|sig| sig.inputs()[0]), None)
-                }
-                ty::CoroutineClosure(def_id, args) => (
-                    def_id,
-                    args.as_coroutine_closure()
-                        .coroutine_closure_sig()
-                        .map_bound(|sig| sig.tupled_inputs_ty),
-                    Some(args.as_coroutine_closure().coroutine_captures_by_ref_ty()),
-                ),
-                _ => return None,
+        let (expected_kind, trait_prefix) =
+            if let Some(expected_kind) = self.tcx.fn_trait_kind_from_def_id(trait_pred.def_id()) {
+                (expected_kind, "")
+            } else if let Some(expected_kind) =
+                self.tcx.async_fn_trait_kind_from_def_id(trait_pred.def_id())
+            {
+                (expected_kind, "Async")
+            } else {
+                return None;
             };
 
-            let expected_args =
-                trait_pred.map_bound(|trait_pred| trait_pred.trait_ref.args.type_at(1));
-
-            // Verify that the arguments are compatible. If the signature is
-            // mismatched, then we have a totally different error to report.
-            if self.enter_forall(found_args, |found_args| {
-                self.enter_forall(expected_args, |expected_args| {
-                    !self.can_eq(obligation.param_env, expected_args, found_args)
-                })
-            }) {
-                return None;
+        let (closure_def_id, found_args, by_ref_captures) = match *self_ty.kind() {
+            ty::Closure(def_id, args) => {
+                (def_id, args.as_closure().sig().map_bound(|sig| sig.inputs()[0]), None)
             }
+            ty::CoroutineClosure(def_id, args) => (
+                def_id,
+                args.as_coroutine_closure()
+                    .coroutine_closure_sig()
+                    .map_bound(|sig| sig.tupled_inputs_ty),
+                Some(args.as_coroutine_closure().coroutine_captures_by_ref_ty()),
+            ),
+            _ => return None,
+        };
 
-            if let Some(found_kind) = self.closure_kind(self_ty)
-                && !found_kind.extends(expected_kind)
-            {
-                let mut err = self.report_closure_error(
-                    &obligation,
-                    closure_def_id,
-                    found_kind,
-                    expected_kind,
-                    "",
-                );
-                self.note_obligation_cause(&mut err, &obligation);
-                return Some(err.emit());
-            }
+        let expected_args = trait_pred.map_bound(|trait_pred| trait_pred.trait_ref.args.type_at(1));
 
-            // If the closure has captures, then perhaps the reason that the trait
-            // is unimplemented is because async closures don't implement `Fn`/`FnMut`
-            // if they have captures.
-            if let Some(by_ref_captures) = by_ref_captures
-                && let ty::FnPtr(sig_tys, _) = by_ref_captures.kind()
-                && !sig_tys.skip_binder().output().is_unit()
-            {
-                let mut err = self.dcx().create_err(AsyncClosureNotFn {
-                    span: self.tcx.def_span(closure_def_id),
-                    kind: expected_kind.as_str(),
-                });
-                self.note_obligation_cause(&mut err, &obligation);
-                return Some(err.emit());
-            }
+        // Verify that the arguments are compatible. If the signature is
+        // mismatched, then we have a totally different error to report.
+        if self.enter_forall(found_args, |found_args| {
+            self.enter_forall(expected_args, |expected_args| {
+                !self.can_eq(obligation.param_env, expected_args, found_args)
+            })
+        }) {
+            return None;
+        }
+
+        if let Some(found_kind) = self.closure_kind(self_ty)
+            && !found_kind.extends(expected_kind)
+        {
+            let mut err = self.report_closure_error(
+                &obligation,
+                closure_def_id,
+                found_kind,
+                expected_kind,
+                trait_prefix,
+            );
+            self.note_obligation_cause(&mut err, &obligation);
+            return Some(err.emit());
         }
+
+        // If the closure has captures, then perhaps the reason that the trait
+        // is unimplemented is because async closures don't implement `Fn`/`FnMut`
+        // if they have captures.
+        if let Some(by_ref_captures) = by_ref_captures
+            && let ty::FnPtr(sig_tys, _) = by_ref_captures.kind()
+            && !sig_tys.skip_binder().output().is_unit()
+        {
+            let mut err = self.dcx().create_err(AsyncClosureNotFn {
+                span: self.tcx.def_span(closure_def_id),
+                kind: expected_kind.as_str(),
+            });
+            self.note_obligation_cause(&mut err, &obligation);
+            return Some(err.emit());
+        }
+
         None
     }
 
@@ -3250,7 +3261,9 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         obligation: &PredicateObligation<'tcx>,
         span: Span,
     ) -> Result<Diag<'a>, ErrorGuaranteed> {
-        if !self.tcx.features().generic_const_exprs() {
+        if !self.tcx.features().generic_const_exprs()
+            && !self.tcx.features().min_generic_const_args()
+        {
             let guar = self
                 .dcx()
                 .struct_span_err(span, "constant expression depends on a generic parameter")
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 b85c18c5312..ad46a15a5ac 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/traits/suggestions.rs
@@ -2695,7 +2695,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             | ObligationCauseCode::LetElse
             | ObligationCauseCode::BinOp { .. }
             | ObligationCauseCode::AscribeUserTypeProvePredicate(..)
-            | ObligationCauseCode::DropImpl
+            | ObligationCauseCode::AlwaysApplicableImpl
             | ObligationCauseCode::ConstParam(_)
             | ObligationCauseCode::ReferenceOutlivesReferent(..)
             | ObligationCauseCode::ObjectTypeBound(..) => {}
@@ -3126,8 +3126,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     Applicability::MachineApplicable,
                 );
             }
-            ObligationCauseCode::ConstSized => {
-                err.note("constant expressions must have a statically known size");
+            ObligationCauseCode::SizedConstOrStatic => {
+                err.note("statics and constants must have a statically known size");
             }
             ObligationCauseCode::InlineAsmSized => {
                 err.note("all inline asm arguments must have a statically known size");
@@ -3191,7 +3191,10 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     false
                 };
 
-                if !is_upvar_tys_infer_tuple {
+                let is_builtin_async_fn_trait =
+                    tcx.async_fn_trait_kind_from_def_id(data.parent_trait_pred.def_id()).is_some();
+
+                if !is_upvar_tys_infer_tuple && !is_builtin_async_fn_trait {
                     let ty_str = tcx.short_string(ty, err.long_ty_path());
                     let msg = format!("required because it appears within the type `{ty_str}`");
                     match ty.kind() {
diff --git a/compiler/rustc_trait_selection/src/regions.rs b/compiler/rustc_trait_selection/src/regions.rs
index 55171754618..068e90b00b8 100644
--- a/compiler/rustc_trait_selection/src/regions.rs
+++ b/compiler/rustc_trait_selection/src/regions.rs
@@ -17,13 +17,7 @@ impl<'tcx> OutlivesEnvironment<'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         assumed_wf_tys: impl IntoIterator<Item = Ty<'tcx>>,
     ) -> Self {
-        Self::new_with_implied_bounds_compat(
-            infcx,
-            body_id,
-            param_env,
-            assumed_wf_tys,
-            !infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat,
-        )
+        Self::new_with_implied_bounds_compat(infcx, body_id, param_env, assumed_wf_tys, false)
     }
 
     fn new_with_implied_bounds_compat(
@@ -31,7 +25,7 @@ impl<'tcx> OutlivesEnvironment<'tcx> {
         body_id: LocalDefId,
         param_env: ty::ParamEnv<'tcx>,
         assumed_wf_tys: impl IntoIterator<Item = Ty<'tcx>>,
-        implied_bounds_compat: bool,
+        disable_implied_bounds_hack: bool,
     ) -> Self {
         let mut bounds = vec![];
 
@@ -59,11 +53,11 @@ impl<'tcx> OutlivesEnvironment<'tcx> {
         OutlivesEnvironment::from_normalized_bounds(
             param_env,
             bounds,
-            infcx.implied_bounds_tys_with_compat(
+            infcx.implied_bounds_tys(
                 body_id,
                 param_env,
                 assumed_wf_tys,
-                implied_bounds_compat,
+                disable_implied_bounds_hack,
             ),
         )
     }
diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
index bdee6ca2afe..75f53b063d1 100644
--- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
+++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs
@@ -85,6 +85,12 @@ pub fn is_const_evaluatable<'tcx>(
             }
             _ => bug!("unexpected constkind in `is_const_evalautable: {unexpanded_ct:?}`"),
         }
+    } else if tcx.features().min_generic_const_args() {
+        // This is a sanity check to make sure that non-generics consts are checked to
+        // be evaluatable in case they aren't cchecked elsewhere. This will NOT error
+        // if the const uses generics, as desired.
+        crate::traits::evaluate_const(infcx, unexpanded_ct, param_env);
+        Ok(())
     } else {
         let uv = match unexpanded_ct.kind() {
             ty::ConstKind::Unevaluated(uv) => uv,
diff --git a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
index 18932695807..68983ef80fa 100644
--- a/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/outlives_bounds.rs
@@ -36,7 +36,7 @@ fn implied_outlives_bounds<'a, 'tcx>(
     param_env: ty::ParamEnv<'tcx>,
     body_id: LocalDefId,
     ty: Ty<'tcx>,
-    compat: bool,
+    disable_implied_bounds_hack: bool,
 ) -> Vec<OutlivesBound<'tcx>> {
     let ty = infcx.resolve_vars_if_possible(ty);
     let ty = OpportunisticRegionResolver::new(infcx).fold_ty(ty);
@@ -52,11 +52,8 @@ fn implied_outlives_bounds<'a, 'tcx>(
     let mut canonical_var_values = OriginalQueryValues::default();
     let input = ImpliedOutlivesBounds { ty };
     let canonical = infcx.canonicalize_query(param_env.and(input), &mut canonical_var_values);
-    let implied_bounds_result = if compat {
-        infcx.tcx.implied_outlives_bounds_compat(canonical)
-    } else {
-        infcx.tcx.implied_outlives_bounds(canonical)
-    };
+    let implied_bounds_result =
+        infcx.tcx.implied_outlives_bounds((canonical, disable_implied_bounds_hack));
     let Ok(canonical_result) = implied_bounds_result else {
         return vec![];
     };
@@ -110,14 +107,15 @@ fn implied_outlives_bounds<'a, 'tcx>(
 impl<'tcx> InferCtxt<'tcx> {
     /// Do *NOT* call this directly. You probably want to construct a `OutlivesEnvironment`
     /// instead if you're interested in the implied bounds for a given signature.
-    fn implied_bounds_tys_with_compat<Tys: IntoIterator<Item = Ty<'tcx>>>(
+    fn implied_bounds_tys<Tys: IntoIterator<Item = Ty<'tcx>>>(
         &self,
         body_id: LocalDefId,
         param_env: ParamEnv<'tcx>,
         tys: Tys,
-        compat: bool,
+        disable_implied_bounds_hack: bool,
     ) -> impl Iterator<Item = OutlivesBound<'tcx>> {
-        tys.into_iter()
-            .flat_map(move |ty| implied_outlives_bounds(self, param_env, body_id, ty, compat))
+        tys.into_iter().flat_map(move |ty| {
+            implied_outlives_bounds(self, param_env, body_id, ty, disable_implied_bounds_hack)
+        })
     }
 }
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index de5aaa5bd97..4d9cf6620d6 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1232,8 +1232,7 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                 // why we special case object types.
                 false
             }
-            ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _)
-            | ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => {
+            ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) => {
                 // These traits have no associated types.
                 selcx.tcx().dcx().span_delayed_bug(
                     obligation.cause.span,
@@ -1325,8 +1324,7 @@ fn confirm_select_candidate<'cx, 'tcx>(
         }
         ImplSource::Builtin(BuiltinImplSource::Object { .. }, _)
         | ImplSource::Param(..)
-        | ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _)
-        | ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => {
+        | ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) => {
             // we don't create Select candidates with this kind of resolution
             span_bug!(
                 obligation.cause.span,
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
index ec0b7903396..f98529860ff 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/implied_outlives_bounds.rs
@@ -1,15 +1,16 @@
+use std::ops::ControlFlow;
+
+use rustc_infer::infer::RegionObligation;
 use rustc_infer::infer::canonical::CanonicalQueryInput;
-use rustc_infer::infer::resolve::OpportunisticRegionResolver;
 use rustc_infer::traits::query::OutlivesBound;
 use rustc_infer::traits::query::type_op::ImpliedOutlivesBounds;
 use rustc_middle::infer::canonical::CanonicalQueryResponse;
 use rustc_middle::traits::ObligationCause;
-use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeFolder, TypeVisitableExt};
+use rustc_middle::ty::{self, ParamEnvAnd, Ty, TyCtxt, TypeVisitable, TypeVisitor};
 use rustc_span::def_id::CRATE_DEF_ID;
-use rustc_span::{DUMMY_SP, Span};
+use rustc_span::{DUMMY_SP, Span, sym};
 use rustc_type_ir::outlives::{Component, push_outlives_components};
 use smallvec::{SmallVec, smallvec};
-use tracing::debug;
 
 use crate::traits::query::NoSolution;
 use crate::traits::{ObligationCtxt, wf};
@@ -35,11 +36,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> {
         tcx: TyCtxt<'tcx>,
         canonicalized: CanonicalQueryInput<'tcx, ParamEnvAnd<'tcx, Self>>,
     ) -> Result<CanonicalQueryResponse<'tcx, Self::QueryResponse>, NoSolution> {
-        if tcx.sess.opts.unstable_opts.no_implied_bounds_compat {
-            tcx.implied_outlives_bounds(canonicalized)
-        } else {
-            tcx.implied_outlives_bounds_compat(canonicalized)
-        }
+        tcx.implied_outlives_bounds((canonicalized, false))
     }
 
     fn perform_locally_with_next_solver(
@@ -47,11 +44,7 @@ impl<'tcx> super::QueryTypeOp<'tcx> for ImpliedOutlivesBounds<'tcx> {
         key: ParamEnvAnd<'tcx, Self>,
         span: Span,
     ) -> Result<Self::QueryResponse, NoSolution> {
-        if ocx.infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat {
-            compute_implied_outlives_bounds_inner(ocx, key.param_env, key.value.ty, span)
-        } else {
-            compute_implied_outlives_bounds_compat_inner(ocx, key.param_env, key.value.ty, span)
-        }
+        compute_implied_outlives_bounds_inner(ocx, key.param_env, key.value.ty, span, false)
     }
 }
 
@@ -60,18 +53,15 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
     param_env: ty::ParamEnv<'tcx>,
     ty: Ty<'tcx>,
     span: Span,
+    disable_implied_bounds_hack: bool,
 ) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> {
-    let normalize_op = |ty| -> Result<_, NoSolution> {
+    let normalize_ty = |ty| -> Result<_, NoSolution> {
         // We must normalize the type so we can compute the right outlives components.
         // for example, if we have some constrained param type like `T: Trait<Out = U>`,
         // and we know that `&'a T::Out` is WF, then we want to imply `U: 'a`.
         let ty = ocx
             .deeply_normalize(&ObligationCause::dummy_with_span(span), param_env, ty)
             .map_err(|_| NoSolution)?;
-        if !ocx.select_all_or_error().is_empty() {
-            return Err(NoSolution);
-        }
-        let ty = OpportunisticRegionResolver::new(&ocx.infcx).fold_ty(ty);
         Ok(ty)
     };
 
@@ -81,7 +71,7 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
     // guaranteed to be a subset of the original type, so we need to store the
     // WF args we've computed in a set.
     let mut checked_wf_args = rustc_data_structures::fx::FxHashSet::default();
-    let mut wf_args = vec![ty.into(), normalize_op(ty)?.into()];
+    let mut wf_args = vec![ty.into(), normalize_ty(ty)?.into()];
 
     let mut outlives_bounds: Vec<OutlivesBound<'tcx>> = vec![];
 
@@ -96,8 +86,14 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
                 .into_iter()
                 .flatten()
         {
-            assert!(!obligation.has_escaping_bound_vars());
-            let Some(pred) = obligation.predicate.kind().no_bound_vars() else {
+            let pred = ocx
+                .deeply_normalize(
+                    &ObligationCause::dummy_with_span(span),
+                    param_env,
+                    obligation.predicate,
+                )
+                .map_err(|_| NoSolution)?;
+            let Some(pred) = pred.kind().no_bound_vars() else {
                 continue;
             };
             match pred {
@@ -130,7 +126,6 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
                     ty_a,
                     r_b,
                 ))) => {
-                    let ty_a = normalize_op(ty_a)?;
                     let mut components = smallvec![];
                     push_outlives_components(ocx.infcx.tcx, ty_a, &mut components);
                     outlives_bounds.extend(implied_bounds_from_components(r_b, components))
@@ -139,141 +134,48 @@ pub fn compute_implied_outlives_bounds_inner<'tcx>(
         }
     }
 
-    Ok(outlives_bounds)
-}
-
-pub fn compute_implied_outlives_bounds_compat_inner<'tcx>(
-    ocx: &ObligationCtxt<'_, 'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-    ty: Ty<'tcx>,
-    span: Span,
-) -> Result<Vec<OutlivesBound<'tcx>>, NoSolution> {
-    let tcx = ocx.infcx.tcx;
-
-    // Sometimes when we ask what it takes for T: WF, we get back that
-    // U: WF is required; in that case, we push U onto this stack and
-    // process it next. Because the resulting predicates aren't always
-    // guaranteed to be a subset of the original type, so we need to store the
-    // WF args we've computed in a set.
-    let mut checked_wf_args = rustc_data_structures::fx::FxHashSet::default();
-    let mut wf_args = vec![ty.into()];
-
-    let mut outlives_bounds: Vec<ty::OutlivesPredicate<'tcx, ty::GenericArg<'tcx>>> = vec![];
-
-    while let Some(arg) = wf_args.pop() {
-        if !checked_wf_args.insert(arg) {
-            continue;
+    // If we detect `bevy_ecs::*::ParamSet` in the WF args list (and `disable_implied_bounds_hack`
+    // or `-Zno-implied-bounds-compat` are not set), then use the registered outlives obligations
+    // as implied bounds.
+    if !disable_implied_bounds_hack
+        && !ocx.infcx.tcx.sess.opts.unstable_opts.no_implied_bounds_compat
+        && ty.visit_with(&mut ContainsBevyParamSet { tcx: ocx.infcx.tcx }).is_break()
+    {
+        for RegionObligation { sup_type, sub_region, .. } in
+            ocx.infcx.take_registered_region_obligations()
+        {
+            let mut components = smallvec![];
+            push_outlives_components(ocx.infcx.tcx, sup_type, &mut components);
+            outlives_bounds.extend(implied_bounds_from_components(sub_region, components));
         }
+    }
 
-        // Compute the obligations for `arg` to be well-formed. If `arg` is
-        // an unresolved inference variable, just instantiated an empty set
-        // -- because the return type here is going to be things we *add*
-        // to the environment, it's always ok for this set to be smaller
-        // than the ultimate set. (Note: normally there won't be
-        // unresolved inference variables here anyway, but there might be
-        // during typeck under some circumstances.)
-        //
-        // FIXME(@lcnr): It's not really "always fine", having fewer implied
-        // bounds can be backward incompatible, e.g. #101951 was caused by
-        // us not dealing with inference vars in `TypeOutlives` predicates.
-        let obligations =
-            wf::obligations(ocx.infcx, param_env, CRATE_DEF_ID, 0, arg, span).unwrap_or_default();
+    Ok(outlives_bounds)
+}
 
-        for obligation in obligations {
-            debug!(?obligation);
-            assert!(!obligation.has_escaping_bound_vars());
+struct ContainsBevyParamSet<'tcx> {
+    tcx: TyCtxt<'tcx>,
+}
 
-            // While these predicates should all be implied by other parts of
-            // the program, they are still relevant as they may constrain
-            // inference variables, which is necessary to add the correct
-            // implied bounds in some cases, mostly when dealing with projections.
-            //
-            // Another important point here: we only register `Projection`
-            // predicates, since otherwise we might register outlives
-            // predicates containing inference variables, and we don't
-            // learn anything new from those.
-            if obligation.predicate.has_non_region_infer() {
-                match obligation.predicate.kind().skip_binder() {
-                    ty::PredicateKind::Clause(ty::ClauseKind::Projection(..))
-                    | ty::PredicateKind::AliasRelate(..) => {
-                        ocx.register_obligation(obligation.clone());
-                    }
-                    _ => {}
-                }
-            }
+impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsBevyParamSet<'tcx> {
+    type Result = ControlFlow<()>;
 
-            let pred = match obligation.predicate.kind().no_bound_vars() {
-                None => continue,
-                Some(pred) => pred,
-            };
-            match pred {
-                // FIXME(const_generics): Make sure that `<'a, 'b, const N: &'a &'b u32>` is sound
-                // if we ever support that
-                ty::PredicateKind::Clause(ty::ClauseKind::Trait(..))
-                | ty::PredicateKind::Clause(ty::ClauseKind::HostEffect(..))
-                | ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(..))
-                | ty::PredicateKind::Subtype(..)
-                | ty::PredicateKind::Coerce(..)
-                | ty::PredicateKind::Clause(ty::ClauseKind::Projection(..))
-                | ty::PredicateKind::DynCompatible(..)
-                | ty::PredicateKind::Clause(ty::ClauseKind::ConstEvaluatable(..))
-                | ty::PredicateKind::ConstEquate(..)
-                | ty::PredicateKind::Ambiguous
-                | ty::PredicateKind::NormalizesTo(..)
-                | ty::PredicateKind::AliasRelate(..) => {}
-
-                // We need to search through *all* WellFormed predicates
-                ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
-                    wf_args.push(arg);
+    fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
+        // We only care to match `ParamSet<T>` or `&ParamSet<T>`.
+        match t.kind() {
+            ty::Adt(def, _) => {
+                if self.tcx.item_name(def.did()) == sym::ParamSet
+                    && self.tcx.crate_name(def.did().krate) == sym::bevy_ecs
+                {
+                    return ControlFlow::Break(());
                 }
-
-                // We need to register region relationships
-                ty::PredicateKind::Clause(ty::ClauseKind::RegionOutlives(
-                    ty::OutlivesPredicate(r_a, r_b),
-                )) => outlives_bounds.push(ty::OutlivesPredicate(r_a.into(), r_b)),
-
-                ty::PredicateKind::Clause(ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(
-                    ty_a,
-                    r_b,
-                ))) => outlives_bounds.push(ty::OutlivesPredicate(ty_a.into(), r_b)),
             }
+            ty::Ref(_, ty, _) => ty.visit_with(self)?,
+            _ => {}
         }
-    }
 
-    // This call to `select_all_or_error` is necessary to constrain inference variables, which we
-    // use further down when computing the implied bounds.
-    match ocx.select_all_or_error().as_slice() {
-        [] => (),
-        _ => return Err(NoSolution),
+        ControlFlow::Continue(())
     }
-
-    // We lazily compute the outlives components as
-    // `select_all_or_error` constrains inference variables.
-    let mut implied_bounds = Vec::new();
-    for ty::OutlivesPredicate(a, r_b) in outlives_bounds {
-        match a.unpack() {
-            ty::GenericArgKind::Lifetime(r_a) => {
-                implied_bounds.push(OutlivesBound::RegionSubRegion(r_b, r_a))
-            }
-            ty::GenericArgKind::Type(ty_a) => {
-                let mut ty_a = ocx.infcx.resolve_vars_if_possible(ty_a);
-                // Need to manually normalize in the new solver as `wf::obligations` does not.
-                if ocx.infcx.next_trait_solver() {
-                    ty_a = ocx
-                        .deeply_normalize(&ObligationCause::dummy_with_span(span), param_env, ty_a)
-                        .map_err(|_| NoSolution)?;
-                }
-                let mut components = smallvec![];
-                push_outlives_components(tcx, ty_a, &mut components);
-                implied_bounds.extend(implied_bounds_from_components(r_b, components))
-            }
-            ty::GenericArgKind::Const(_) => {
-                unreachable!("consts do not participate in outlives bounds")
-            }
-        }
-    }
-
-    Ok(implied_bounds)
 }
 
 /// When we have an implied bound that `T: 'a`, we can further break
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 11b6b826efe..a8d8003ead6 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -1017,13 +1017,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 }
             }
 
-            // `(.., T)` -> `(.., U)`
-            (&ty::Tuple(tys_a), &ty::Tuple(tys_b)) => {
-                if tys_a.len() == tys_b.len() {
-                    candidates.vec.push(BuiltinUnsizeCandidate);
-                }
-            }
-
             _ => {}
         };
     }
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index a58317dd56d..6db97fc321a 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -7,7 +7,6 @@
 //! [rustc dev guide]:
 //! https://rustc-dev-guide.rust-lang.org/traits/resolution.html#confirmation
 
-use std::iter;
 use std::ops::ControlFlow;
 
 use rustc_ast::Mutability;
@@ -410,7 +409,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         let predicate = obligation.predicate.skip_binder();
 
         let mut assume = predicate.trait_ref.args.const_at(2);
-        // FIXME(min_generic_const_exprs): We should shallowly normalize this.
+        // FIXME(mgca): We should shallowly normalize this.
         if self.tcx().features().generic_const_exprs() {
             assume = crate::traits::evaluate_const(self.infcx, assume, obligation.param_env)
         }
@@ -984,8 +983,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 return Err(SelectionError::Unimplemented);
             }
         } else {
-            nested.push(obligation.with(
+            nested.push(Obligation::new(
                 self.tcx(),
+                obligation.derived_cause(ObligationCauseCode::BuiltinDerived),
+                obligation.param_env,
                 ty::TraitRef::new(
                     self.tcx(),
                     self.tcx().require_lang_item(
@@ -1315,34 +1316,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 ImplSource::Builtin(BuiltinImplSource::Misc, nested)
             }
 
-            // `(.., T)` -> `(.., U)`
-            (&ty::Tuple(tys_a), &ty::Tuple(tys_b)) => {
-                assert_eq!(tys_a.len(), tys_b.len());
-
-                // The last field of the tuple has to exist.
-                let (&a_last, a_mid) = tys_a.split_last().ok_or(Unimplemented)?;
-                let &b_last = tys_b.last().unwrap();
-
-                // Check that the source tuple with the target's
-                // last element is equal to the target.
-                let new_tuple =
-                    Ty::new_tup_from_iter(tcx, a_mid.iter().copied().chain(iter::once(b_last)));
-                let InferOk { mut obligations, .. } = self
-                    .infcx
-                    .at(&obligation.cause, obligation.param_env)
-                    .eq(DefineOpaqueTypes::Yes, target, new_tuple)
-                    .map_err(|_| Unimplemented)?;
-
-                // Add a nested `T: Unsize<U>` predicate.
-                let last_unsize_obligation = obligation.with(
-                    tcx,
-                    ty::TraitRef::new(tcx, obligation.predicate.def_id(), [a_last, b_last]),
-                );
-                obligations.push(last_unsize_obligation);
-
-                ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, obligations)
-            }
-
             _ => bug!("source: {source}, target: {target}"),
         })
     }
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 18906a6a8ce..54b6c22b2d8 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -708,7 +708,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
             ty::Pat(subty, pat) => {
                 self.require_sized(subty, ObligationCauseCode::Misc);
                 match *pat {
-                    ty::PatternKind::Range { start, end, include_end: _ } => {
+                    ty::PatternKind::Range { start, end } => {
                         let mut check = |c| {
                             let cause = self.cause(ObligationCauseCode::Misc);
                             self.out.push(traits::Obligation::with_depth(
@@ -738,12 +738,8 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
                                 }
                             }
                         };
-                        if let Some(start) = start {
-                            check(start)
-                        }
-                        if let Some(end) = end {
-                            check(end)
-                        }
+                        check(start);
+                        check(end);
                     }
                 }
             }
diff --git a/compiler/rustc_traits/src/implied_outlives_bounds.rs b/compiler/rustc_traits/src/implied_outlives_bounds.rs
index 5f75e242a50..6fb483e6dac 100644
--- a/compiler/rustc_traits/src/implied_outlives_bounds.rs
+++ b/compiler/rustc_traits/src/implied_outlives_bounds.rs
@@ -10,38 +10,28 @@ use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::DUMMY_SP;
 use rustc_trait_selection::infer::InferCtxtBuilderExt;
-use rustc_trait_selection::traits::query::type_op::implied_outlives_bounds::{
-    compute_implied_outlives_bounds_compat_inner, compute_implied_outlives_bounds_inner,
-};
+use rustc_trait_selection::traits::query::type_op::implied_outlives_bounds::compute_implied_outlives_bounds_inner;
 use rustc_trait_selection::traits::query::{CanonicalImpliedOutlivesBoundsGoal, NoSolution};
 
 pub(crate) fn provide(p: &mut Providers) {
-    *p = Providers { implied_outlives_bounds_compat, ..*p };
     *p = Providers { implied_outlives_bounds, ..*p };
 }
 
-fn implied_outlives_bounds_compat<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    goal: CanonicalImpliedOutlivesBoundsGoal<'tcx>,
-) -> Result<
-    &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
-    NoSolution,
-> {
-    tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| {
-        let (param_env, ImpliedOutlivesBounds { ty }) = key.into_parts();
-        compute_implied_outlives_bounds_compat_inner(ocx, param_env, ty, DUMMY_SP)
-    })
-}
-
 fn implied_outlives_bounds<'tcx>(
     tcx: TyCtxt<'tcx>,
-    goal: CanonicalImpliedOutlivesBoundsGoal<'tcx>,
+    (goal, disable_implied_bounds_hack): (CanonicalImpliedOutlivesBoundsGoal<'tcx>, bool),
 ) -> Result<
     &'tcx Canonical<'tcx, canonical::QueryResponse<'tcx, Vec<OutlivesBound<'tcx>>>>,
     NoSolution,
 > {
     tcx.infer_ctxt().enter_canonical_trait_query(&goal, |ocx, key| {
         let (param_env, ImpliedOutlivesBounds { ty }) = key.into_parts();
-        compute_implied_outlives_bounds_inner(ocx, param_env, ty, DUMMY_SP)
+        compute_implied_outlives_bounds_inner(
+            ocx,
+            param_env,
+            ty,
+            DUMMY_SP,
+            disable_implied_bounds_hack,
+        )
     })
 }
diff --git a/compiler/rustc_ty_utils/messages.ftl b/compiler/rustc_ty_utils/messages.ftl
index ae795ef2214..de2c3b63997 100644
--- a/compiler/rustc_ty_utils/messages.ftl
+++ b/compiler/rustc_ty_utils/messages.ftl
@@ -42,8 +42,6 @@ ty_utils_logical_op_not_supported = unsupported operation in generic constants,
 
 ty_utils_loop_not_supported = loops and loop control flow are not supported in generic constants
 
-ty_utils_multiple_array_fields_simd_type = monomorphising SIMD type `{$ty}` with more than one array field
-
 ty_utils_needs_drop_overflow = overflow while checking whether `{$query_ty}` requires drop
 
 ty_utils_never_to_any_not_supported = coercing the `never` type is not supported in generic constants
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index e317768ff60..a726ebae6fe 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -436,10 +436,7 @@ fn fn_abi_sanity_check<'tcx>(
     ) {
         let tcx = cx.tcx();
 
-        if spec_abi == ExternAbi::Rust
-            || spec_abi == ExternAbi::RustCall
-            || spec_abi == ExternAbi::RustCold
-        {
+        if spec_abi.is_rustic_abi() {
             if arg.layout.is_zst() {
                 // Casting closures to function pointers depends on ZST closure types being
                 // omitted entirely in the calling convention.
@@ -687,7 +684,7 @@ fn fn_abi_adjust_for_abi<'tcx>(
 
     let tcx = cx.tcx();
 
-    if abi == ExternAbi::Rust || abi == ExternAbi::RustCall || abi == ExternAbi::RustIntrinsic {
+    if abi.is_rustic_abi() {
         fn_abi.adjust_for_rust_abi(cx, abi);
 
         // Look up the deduced parameter attributes for this function, if we have its def ID and
diff --git a/compiler/rustc_ty_utils/src/errors.rs b/compiler/rustc_ty_utils/src/errors.rs
index 5497d7d0bd2..8877bb45ceb 100644
--- a/compiler/rustc_ty_utils/src/errors.rs
+++ b/compiler/rustc_ty_utils/src/errors.rs
@@ -83,12 +83,6 @@ pub(crate) struct ZeroLengthSimdType<'tcx> {
 }
 
 #[derive(Diagnostic)]
-#[diag(ty_utils_multiple_array_fields_simd_type)]
-pub(crate) struct MultipleArrayFieldsSimdType<'tcx> {
-    pub ty: Ty<'tcx>,
-}
-
-#[derive(Diagnostic)]
 #[diag(ty_utils_oversized_simd_type)]
 pub(crate) struct OversizedSimdType<'tcx> {
     pub ty: Ty<'tcx>,
diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs
index d059d6dcd13..6dc5a9c4a47 100644
--- a/compiler/rustc_ty_utils/src/instance.rs
+++ b/compiler/rustc_ty_utils/src/instance.rs
@@ -381,8 +381,7 @@ fn resolve_associated_item<'tcx>(
             }
         }
         traits::ImplSource::Param(..)
-        | traits::ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _)
-        | traits::ImplSource::Builtin(BuiltinImplSource::TupleUnsizing, _) => None,
+        | traits::ImplSource::Builtin(BuiltinImplSource::TraitUpcasting { .. }, _) => None,
     })
 }
 
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 1a82d171307..a53f0538c58 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -28,9 +28,7 @@ use rustc_span::{Symbol, sym};
 use tracing::{debug, instrument, trace};
 use {rustc_abi as abi, rustc_hir as hir};
 
-use crate::errors::{
-    MultipleArrayFieldsSimdType, NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType,
-};
+use crate::errors::{NonPrimitiveSimdType, OversizedSimdType, ZeroLengthSimdType};
 
 mod invariant;
 
@@ -207,24 +205,17 @@ fn layout_of_uncached<'tcx>(
             let layout = cx.layout_of(ty)?.layout;
             let mut layout = LayoutData::clone(&layout.0);
             match *pat {
-                ty::PatternKind::Range { start, end, include_end } => {
+                ty::PatternKind::Range { start, end } => {
                     if let BackendRepr::Scalar(scalar) | BackendRepr::ScalarPair(scalar, _) =
                         &mut layout.backend_repr
                     {
-                        if let Some(start) = start {
-                            scalar.valid_range_mut().start = extract_const_value(cx, ty, start)?
-                                .try_to_bits(tcx, cx.typing_env)
-                                .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
-                        }
-                        if let Some(end) = end {
-                            let mut end = extract_const_value(cx, ty, end)?
-                                .try_to_bits(tcx, cx.typing_env)
-                                .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
-                            if !include_end {
-                                end = end.wrapping_sub(1);
-                            }
-                            scalar.valid_range_mut().end = end;
-                        }
+                        scalar.valid_range_mut().start = extract_const_value(cx, ty, start)?
+                            .try_to_bits(tcx, cx.typing_env)
+                            .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
+
+                        scalar.valid_range_mut().end = extract_const_value(cx, ty, end)?
+                            .try_to_bits(tcx, cx.typing_env)
+                            .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
 
                         let niche = Niche {
                             offset: Size::ZERO,
@@ -450,71 +441,26 @@ fn layout_of_uncached<'tcx>(
 
         // SIMD vector types.
         ty::Adt(def, args) if def.repr().simd() => {
-            if !def.is_struct() {
-                // Should have yielded E0517 by now.
-                let guar = tcx
-                    .dcx()
-                    .delayed_bug("#[repr(simd)] was applied to an ADT that is not a struct");
-                return Err(error(cx, LayoutError::ReferencesError(guar)));
-            }
-
-            let fields = &def.non_enum_variant().fields;
-
-            // Supported SIMD vectors are homogeneous ADTs with at least one field:
+            // Supported SIMD vectors are ADTs with a single array field:
             //
-            // * #[repr(simd)] struct S(T, T, T, T);
-            // * #[repr(simd)] struct S { x: T, y: T, z: T, w: T }
             // * #[repr(simd)] struct S([T; 4])
             //
             // where T is a primitive scalar (integer/float/pointer).
-
-            // SIMD vectors with zero fields are not supported.
-            // (should be caught by typeck)
-            if fields.is_empty() {
-                tcx.dcx().emit_fatal(ZeroLengthSimdType { ty })
-            }
-
-            // Type of the first ADT field:
-            let f0_ty = fields[FieldIdx::ZERO].ty(tcx, args);
-
-            // Heterogeneous SIMD vectors are not supported:
-            // (should be caught by typeck)
-            for fi in fields {
-                if fi.ty(tcx, args) != f0_ty {
-                    let guar = tcx.dcx().delayed_bug(
-                        "#[repr(simd)] was applied to an ADT with heterogeneous field type",
-                    );
-                    return Err(error(cx, LayoutError::ReferencesError(guar)));
-                }
-            }
-
-            // The element type and number of elements of the SIMD vector
-            // are obtained from:
-            //
-            // * the element type and length of the single array field, if
-            // the first field is of array type, or
-            //
-            // * the homogeneous field type and the number of fields.
-            let (e_ty, e_len, is_array) = if let ty::Array(e_ty, _) = f0_ty.kind() {
-                // First ADT field is an array:
-
-                // SIMD vectors with multiple array fields are not supported:
-                // Can't be caught by typeck with a generic simd type.
-                if def.non_enum_variant().fields.len() != 1 {
-                    tcx.dcx().emit_fatal(MultipleArrayFieldsSimdType { ty });
-                }
-
-                // Extract the number of elements from the layout of the array field:
-                let FieldsShape::Array { count, .. } = cx.layout_of(f0_ty)?.layout.fields() else {
-                    return Err(error(cx, LayoutError::Unknown(ty)));
-                };
-
-                (*e_ty, *count, true)
-            } else {
-                // First ADT field is not an array:
-                (f0_ty, def.non_enum_variant().fields.len() as _, false)
+            let Some(ty::Array(e_ty, e_len)) = def
+                .is_struct()
+                .then(|| &def.variant(FIRST_VARIANT).fields)
+                .filter(|fields| fields.len() == 1)
+                .map(|fields| *fields[FieldIdx::ZERO].ty(tcx, args).kind())
+            else {
+                // Invalid SIMD types should have been caught by typeck by now.
+                let guar = tcx.dcx().delayed_bug("#[repr(simd)] was applied to an invalid ADT");
+                return Err(error(cx, LayoutError::ReferencesError(guar)));
             };
 
+            let e_len = extract_const_value(cx, ty, e_len)?
+                .try_to_target_usize(tcx)
+                .ok_or_else(|| error(cx, LayoutError::Unknown(ty)))?;
+
             // SIMD vectors of zero length are not supported.
             // Additionally, lengths are capped at 2^16 as a fixed maximum backends must
             // support.
@@ -559,16 +505,12 @@ fn layout_of_uncached<'tcx>(
             };
             let size = size.align_to(align.abi);
 
-            // Compute the placement of the vector fields:
-            let fields = if is_array {
-                FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() }
-            } else {
-                FieldsShape::Array { stride: e_ly.size, count: e_len }
-            };
-
             tcx.mk_layout(LayoutData {
                 variants: Variants::Single { index: FIRST_VARIANT },
-                fields,
+                fields: FieldsShape::Arbitrary {
+                    offsets: [Size::ZERO].into(),
+                    memory_index: [0].into(),
+                },
                 backend_repr: abi,
                 largest_niche: e_ly.largest_niche,
                 uninhabited: false,
diff --git a/compiler/rustc_type_ir/src/solve/mod.rs b/compiler/rustc_type_ir/src/solve/mod.rs
index b93668b5111..6f37db1cb85 100644
--- a/compiler/rustc_type_ir/src/solve/mod.rs
+++ b/compiler/rustc_type_ir/src/solve/mod.rs
@@ -189,11 +189,6 @@ pub enum BuiltinImplSource {
     ///
     /// The index is only used for winnowing.
     TraitUpcasting(usize),
-    /// Unsizing a tuple like `(A, B, ..., X)` to `(A, B, ..., Y)` if `X` unsizes to `Y`.
-    ///
-    /// This can be removed when `feature(tuple_unsizing)` is stabilized, since we only
-    /// use it to detect when unsizing tuples in hir typeck.
-    TupleUnsizing,
 }
 
 #[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
diff --git a/compiler/stable_mir/src/lib.rs b/compiler/stable_mir/src/lib.rs
index 8df36e23c4a..70d42dfbfcb 100644
--- a/compiler/stable_mir/src/lib.rs
+++ b/compiler/stable_mir/src/lib.rs
@@ -129,13 +129,21 @@ crate_def_with_ty! {
 }
 
 impl CrateItem {
-    /// This will return the body of an item.
-    ///
-    /// This will panic if no body is available.
-    pub fn body(&self) -> mir::Body {
+    /// This will return the body of an item or panic if it's not available.
+    pub fn expect_body(&self) -> mir::Body {
         with(|cx| cx.mir_body(self.0))
     }
 
+    /// Return the body of an item if available.
+    pub fn body(&self) -> Option<mir::Body> {
+        with(|cx| cx.has_body(self.0).then(|| cx.mir_body(self.0)))
+    }
+
+    /// Check if a body is available for this item.
+    pub fn has_body(&self) -> bool {
+        with(|cx| cx.has_body(self.0))
+    }
+
     pub fn span(&self) -> Span {
         with(|cx| cx.span_of_an_item(self.0))
     }
@@ -156,8 +164,11 @@ impl CrateItem {
         with(|cx| cx.is_foreign_item(self.0))
     }
 
+    /// Emit MIR for this item body.
     pub fn emit_mir<W: io::Write>(&self, w: &mut W) -> io::Result<()> {
-        self.body().dump(w, &self.name())
+        self.body()
+            .ok_or_else(|| io::Error::other(format!("No body found for `{}`", self.name())))?
+            .dump(w, &self.name())
     }
 }
 
diff --git a/config.example.toml b/config.example.toml
index 2e26c024865..ac5e491b4b5 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -189,6 +189,17 @@
 # The default stage to use for the `bench` subcommand
 #bench-stage = 2
 
+# A descriptive string to be appended to version output (e.g., `rustc --version`),
+# which is also used in places like debuginfo `DW_AT_producer`. This may be useful for
+# supplementary build information, like distro-specific package versions.
+#
+# The Rust compiler will differentiate between versions of itself, including
+# based on this string, which means that if you wish to be compatible with
+# upstream Rust you need to set this to "". However, note that if you set this to "" but
+# are not actually compatible -- for example if you've backported patches that change
+# behavior -- this may lead to miscompilations or other bugs.
+#description = ""
+
 # Build triple for the pre-compiled snapshot compiler. If `rustc` is set, this must match its host
 # triple (see `rustc --version --verbose`; cross-compiling the rust build system itself is NOT
 # supported). If `rustc` is unset, this must be a platform with pre-compiled host tools
@@ -615,17 +626,6 @@
 # If using tarball sources, default value is "auto-detect", otherwise, it's "dev".
 #channel = if "is a tarball source" { "auto-detect" } else { "dev" }
 
-# A descriptive string to be appended to `rustc --version` output, which is
-# also used in places like debuginfo `DW_AT_producer`. This may be useful for
-# supplementary build information, like distro-specific package versions.
-#
-# The Rust compiler will differentiate between versions of itself, including
-# based on this string, which means that if you wish to be compatible with
-# upstream Rust you need to set this to "". However, note that if you are not
-# actually compatible -- for example if you've backported patches that change
-# behavior -- this may lead to miscompilations or other bugs.
-#description = ""
-
 # The root location of the musl installation directory. The library directory
 # will also need to contain libunwind.a for an unwinding implementation. Note
 # that this option only makes sense for musl targets that produce statically
diff --git a/library/Cargo.lock b/library/Cargo.lock
index de9685742f5..31656414121 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -61,9 +61,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.148"
+version = "0.1.151"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "26137996631d90d2727b905b480fdcf8c4479fdbce7afd7f8e3796d689b33cc2"
+checksum = "abc30f1766d387c35f2405e586d3e7a88230dc728ff78cd1d0bc59ae0b63154b"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
@@ -151,9 +151,9 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.169"
+version = "0.2.170"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
+checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828"
 dependencies = [
  "rustc-std-workspace-core",
 ]
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index 9e80f3579e8..4cb83501256 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -12,7 +12,7 @@ edition = "2021"
 
 [dependencies]
 core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.148", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "=0.1.151", features = ['rustc-dep-of-std'] }
 
 [dev-dependencies]
 rand = { version = "0.9.0", default-features = false, features = ["alloc"] }
diff --git a/library/alloc/benches/slice.rs b/library/alloc/benches/slice.rs
index c6b46e6a2a1..27b0e6fac0a 100644
--- a/library/alloc/benches/slice.rs
+++ b/library/alloc/benches/slice.rs
@@ -1,4 +1,4 @@
-use std::{mem, ptr};
+use std::ptr;
 
 use rand::Rng;
 use rand::distr::{Alphanumeric, SampleString, StandardUniform};
@@ -234,7 +234,7 @@ macro_rules! sort {
         fn $name(b: &mut Bencher) {
             let v = $gen($len);
             b.iter(|| v.clone().$f());
-            b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
+            b.bytes = $len * size_of_val(&$gen(1)[0]) as u64;
         }
     };
 }
@@ -246,7 +246,7 @@ macro_rules! sort_strings {
             let v = $gen($len);
             let v = v.iter().map(|s| &**s).collect::<Vec<&str>>();
             b.iter(|| v.clone().$f());
-            b.bytes = $len * mem::size_of::<&str>() as u64;
+            b.bytes = $len * size_of::<&str>() as u64;
         }
     };
 }
@@ -268,7 +268,7 @@ macro_rules! sort_expensive {
                 });
                 black_box(count);
             });
-            b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
+            b.bytes = $len * size_of_val(&$gen(1)[0]) as u64;
         }
     };
 }
@@ -279,7 +279,7 @@ macro_rules! sort_lexicographic {
         fn $name(b: &mut Bencher) {
             let v = $gen($len);
             b.iter(|| v.clone().$f(|x| x.to_string()));
-            b.bytes = $len * mem::size_of_val(&$gen(1)[0]) as u64;
+            b.bytes = $len * size_of_val(&$gen(1)[0]) as u64;
         }
     };
 }
@@ -322,7 +322,7 @@ macro_rules! reverse {
         fn $name(b: &mut Bencher) {
             // odd length and offset by 1 to be as unaligned as possible
             let n = 0xFFFFF;
-            let mut v: Vec<_> = (0..1 + (n / mem::size_of::<$ty>() as u64)).map($f).collect();
+            let mut v: Vec<_> = (0..1 + (n / size_of::<$ty>() as u64)).map($f).collect();
             b.iter(|| black_box(&mut v[1..]).reverse());
             b.bytes = n;
         }
@@ -346,7 +346,7 @@ macro_rules! rotate {
     ($name:ident, $gen:expr, $len:expr, $mid:expr) => {
         #[bench]
         fn $name(b: &mut Bencher) {
-            let size = mem::size_of_val(&$gen(1)[0]);
+            let size = size_of_val(&$gen(1)[0]);
             let mut v = $gen($len * 8 / size);
             b.iter(|| black_box(&mut v).rotate_left(($mid * 8 + size - 1) / size));
             b.bytes = (v.len() * size) as u64;
diff --git a/library/alloc/benches/vec.rs b/library/alloc/benches/vec.rs
index a725ad6894b..1dab71fa1f4 100644
--- a/library/alloc/benches/vec.rs
+++ b/library/alloc/benches/vec.rs
@@ -669,7 +669,7 @@ fn random_sorted_fill(mut seed: u32, buf: &mut [u32]) {
 // This algorithm was used for Vecs prior to Rust 1.52.
 fn bench_dedup_slice_truncate(b: &mut Bencher, sz: usize) {
     let mut template = vec![0u32; sz];
-    b.bytes = std::mem::size_of_val(template.as_slice()) as u64;
+    b.bytes = size_of_val(template.as_slice()) as u64;
     random_sorted_fill(0x43, &mut template);
 
     let mut vec = template.clone();
@@ -691,7 +691,7 @@ fn bench_dedup_slice_truncate(b: &mut Bencher, sz: usize) {
 // Measures performance of Vec::dedup on random data.
 fn bench_vec_dedup_random(b: &mut Bencher, sz: usize) {
     let mut template = vec![0u32; sz];
-    b.bytes = std::mem::size_of_val(template.as_slice()) as u64;
+    b.bytes = size_of_val(template.as_slice()) as u64;
     random_sorted_fill(0x43, &mut template);
 
     let mut vec = template.clone();
@@ -708,7 +708,7 @@ fn bench_vec_dedup_random(b: &mut Bencher, sz: usize) {
 // Measures performance of Vec::dedup when there is no items removed
 fn bench_vec_dedup_none(b: &mut Bencher, sz: usize) {
     let mut template = vec![0u32; sz];
-    b.bytes = std::mem::size_of_val(template.as_slice()) as u64;
+    b.bytes = size_of_val(template.as_slice()) as u64;
     template.chunks_exact_mut(2).for_each(|w| {
         w[0] = black_box(0);
         w[1] = black_box(5);
@@ -729,7 +729,7 @@ fn bench_vec_dedup_none(b: &mut Bencher, sz: usize) {
 // Measures performance of Vec::dedup when there is all items removed
 fn bench_vec_dedup_all(b: &mut Bencher, sz: usize) {
     let mut template = vec![0u32; sz];
-    b.bytes = std::mem::size_of_val(template.as_slice()) as u64;
+    b.bytes = size_of_val(template.as_slice()) as u64;
     template.iter_mut().for_each(|w| {
         *w = black_box(0);
     });
diff --git a/library/alloc/src/boxed.rs b/library/alloc/src/boxed.rs
index c3f5806e1aa..9b19ab74edf 100644
--- a/library/alloc/src/boxed.rs
+++ b/library/alloc/src/boxed.rs
@@ -937,8 +937,6 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
     /// # Examples
     ///
     /// ```
-    /// #![feature(box_uninit_write)]
-    ///
     /// let big_box = Box::<[usize; 1024]>::new_uninit();
     ///
     /// let mut array = [0; 1024];
@@ -954,7 +952,7 @@ impl<T, A: Allocator> Box<mem::MaybeUninit<T>, A> {
     ///     assert_eq!(*x, i);
     /// }
     /// ```
-    #[unstable(feature = "box_uninit_write", issue = "129397")]
+    #[stable(feature = "box_uninit_write", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub fn write(mut boxed: Self, value: T) -> Box<T, A> {
         unsafe {
diff --git a/library/alloc/src/boxed/convert.rs b/library/alloc/src/boxed/convert.rs
index 255cefb1e78..80626580202 100644
--- a/library/alloc/src/boxed/convert.rs
+++ b/library/alloc/src/boxed/convert.rs
@@ -529,7 +529,6 @@ impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
     /// ```
     /// use std::error::Error;
     /// use std::fmt;
-    /// use std::mem;
     ///
     /// #[derive(Debug)]
     /// struct AnError;
@@ -543,9 +542,9 @@ impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
     /// impl Error for AnError {}
     ///
     /// let an_error = AnError;
-    /// assert!(0 == mem::size_of_val(&an_error));
+    /// assert!(0 == size_of_val(&an_error));
     /// let a_boxed_error = Box::<dyn Error>::from(an_error);
-    /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
+    /// assert!(size_of::<Box<dyn Error>>() == size_of_val(&a_boxed_error))
     /// ```
     fn from(err: E) -> Box<dyn Error + 'a> {
         Box::new(err)
@@ -563,7 +562,6 @@ impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync +
     /// ```
     /// use std::error::Error;
     /// use std::fmt;
-    /// use std::mem;
     ///
     /// #[derive(Debug)]
     /// struct AnError;
@@ -581,10 +579,10 @@ impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync +
     /// unsafe impl Sync for AnError {}
     ///
     /// let an_error = AnError;
-    /// assert!(0 == mem::size_of_val(&an_error));
+    /// assert!(0 == size_of_val(&an_error));
     /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(an_error);
     /// assert!(
-    ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
+    ///     size_of::<Box<dyn Error + Send + Sync>>() == size_of_val(&a_boxed_error))
     /// ```
     fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> {
         Box::new(err)
@@ -600,12 +598,11 @@ impl<'a> From<String> for Box<dyn Error + Send + Sync + 'a> {
     ///
     /// ```
     /// use std::error::Error;
-    /// use std::mem;
     ///
     /// let a_string_error = "a string error".to_string();
     /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_string_error);
     /// assert!(
-    ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
+    ///     size_of::<Box<dyn Error + Send + Sync>>() == size_of_val(&a_boxed_error))
     /// ```
     #[inline]
     fn from(err: String) -> Box<dyn Error + Send + Sync + 'a> {
@@ -644,11 +641,10 @@ impl<'a> From<String> for Box<dyn Error + 'a> {
     ///
     /// ```
     /// use std::error::Error;
-    /// use std::mem;
     ///
     /// let a_string_error = "a string error".to_string();
     /// let a_boxed_error = Box::<dyn Error>::from(a_string_error);
-    /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
+    /// assert!(size_of::<Box<dyn Error>>() == size_of_val(&a_boxed_error))
     /// ```
     fn from(str_err: String) -> Box<dyn Error + 'a> {
         let err1: Box<dyn Error + Send + Sync> = From::from(str_err);
@@ -668,12 +664,11 @@ impl<'a> From<&str> for Box<dyn Error + Send + Sync + 'a> {
     ///
     /// ```
     /// use std::error::Error;
-    /// use std::mem;
     ///
     /// let a_str_error = "a str error";
     /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_str_error);
     /// assert!(
-    ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
+    ///     size_of::<Box<dyn Error + Send + Sync>>() == size_of_val(&a_boxed_error))
     /// ```
     #[inline]
     fn from(err: &str) -> Box<dyn Error + Send + Sync + 'a> {
@@ -692,11 +687,10 @@ impl<'a> From<&str> for Box<dyn Error + 'a> {
     ///
     /// ```
     /// use std::error::Error;
-    /// use std::mem;
     ///
     /// let a_str_error = "a str error";
     /// let a_boxed_error = Box::<dyn Error>::from(a_str_error);
-    /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
+    /// assert!(size_of::<Box<dyn Error>>() == size_of_val(&a_boxed_error))
     /// ```
     fn from(err: &str) -> Box<dyn Error + 'a> {
         From::from(String::from(err))
@@ -712,13 +706,12 @@ impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
     ///
     /// ```
     /// use std::error::Error;
-    /// use std::mem;
     /// use std::borrow::Cow;
     ///
     /// let a_cow_str_error = Cow::from("a str error");
     /// let a_boxed_error = Box::<dyn Error + Send + Sync>::from(a_cow_str_error);
     /// assert!(
-    ///     mem::size_of::<Box<dyn Error + Send + Sync>>() == mem::size_of_val(&a_boxed_error))
+    ///     size_of::<Box<dyn Error + Send + Sync>>() == size_of_val(&a_boxed_error))
     /// ```
     fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> {
         From::from(String::from(err))
@@ -734,12 +727,11 @@ impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + 'a> {
     ///
     /// ```
     /// use std::error::Error;
-    /// use std::mem;
     /// use std::borrow::Cow;
     ///
     /// let a_cow_str_error = Cow::from("a str error");
     /// let a_boxed_error = Box::<dyn Error>::from(a_cow_str_error);
-    /// assert!(mem::size_of::<Box<dyn Error>>() == mem::size_of_val(&a_boxed_error))
+    /// assert!(size_of::<Box<dyn Error>>() == size_of_val(&a_boxed_error))
     /// ```
     fn from(err: Cow<'b, str>) -> Box<dyn Error + 'a> {
         From::from(String::from(err))
diff --git a/library/alloc/src/boxed/thin.rs b/library/alloc/src/boxed/thin.rs
index 78e5aec09b1..21425b9846e 100644
--- a/library/alloc/src/boxed/thin.rs
+++ b/library/alloc/src/boxed/thin.rs
@@ -9,9 +9,8 @@ use core::intrinsics::const_allocate;
 use core::marker::PhantomData;
 #[cfg(not(no_global_oom_handling))]
 use core::marker::Unsize;
-use core::mem;
 #[cfg(not(no_global_oom_handling))]
-use core::mem::SizedTypeProperties;
+use core::mem::{self, SizedTypeProperties};
 use core::ops::{Deref, DerefMut};
 use core::ptr::{self, NonNull, Pointee};
 
@@ -30,7 +29,6 @@ use crate::alloc::{self, Layout, LayoutError};
 /// let five = ThinBox::new(5);
 /// let thin_slice = ThinBox::<[i32]>::new_unsize([1, 2, 3, 4]);
 ///
-/// use std::mem::{size_of, size_of_val};
 /// let size_of_ptr = size_of::<*const ()>();
 /// assert_eq!(size_of_ptr, size_of_val(&five));
 /// assert_eq!(size_of_ptr, size_of_val(&thin_slice));
@@ -114,7 +112,7 @@ impl<Dyn: ?Sized> ThinBox<Dyn> {
     where
         T: Unsize<Dyn>,
     {
-        if mem::size_of::<T>() == 0 {
+        if size_of::<T>() == 0 {
             let ptr = WithOpaqueHeader::new_unsize_zst::<Dyn, T>(value);
             ThinBox { ptr, _marker: PhantomData }
         } else {
@@ -283,9 +281,7 @@ impl<H> WithHeader<H> {
             let ptr = if layout.size() == 0 {
                 // Some paranoia checking, mostly so that the ThinBox tests are
                 // more able to catch issues.
-                debug_assert!(
-                    value_offset == 0 && mem::size_of::<T>() == 0 && mem::size_of::<H>() == 0
-                );
+                debug_assert!(value_offset == 0 && size_of::<T>() == 0 && size_of::<H>() == 0);
                 layout.dangling()
             } else {
                 let ptr = alloc::alloc(layout);
@@ -315,7 +311,7 @@ impl<H> WithHeader<H> {
         Dyn: Pointee<Metadata = H> + ?Sized,
         T: Unsize<Dyn>,
     {
-        assert!(mem::size_of::<T>() == 0);
+        assert!(size_of::<T>() == 0);
 
         const fn max(a: usize, b: usize) -> usize {
             if a > b { a } else { b }
@@ -329,18 +325,16 @@ impl<H> WithHeader<H> {
             // FIXME: just call `WithHeader::alloc_layout` with size reset to 0.
             // Currently that's blocked on `Layout::extend` not being `const fn`.
 
-            let alloc_align =
-                max(mem::align_of::<T>(), mem::align_of::<<Dyn as Pointee>::Metadata>());
+            let alloc_align = max(align_of::<T>(), align_of::<<Dyn as Pointee>::Metadata>());
 
-            let alloc_size =
-                max(mem::align_of::<T>(), mem::size_of::<<Dyn as Pointee>::Metadata>());
+            let alloc_size = max(align_of::<T>(), size_of::<<Dyn as Pointee>::Metadata>());
 
             unsafe {
                 // SAFETY: align is power of two because it is the maximum of two alignments.
                 let alloc: *mut u8 = const_allocate(alloc_size, alloc_align);
 
                 let metadata_offset =
-                    alloc_size.checked_sub(mem::size_of::<<Dyn as Pointee>::Metadata>()).unwrap();
+                    alloc_size.checked_sub(size_of::<<Dyn as Pointee>::Metadata>()).unwrap();
                 // SAFETY: adding offset within the allocation.
                 let metadata_ptr: *mut <Dyn as Pointee>::Metadata =
                     alloc.add(metadata_offset).cast();
@@ -421,7 +415,7 @@ impl<H> WithHeader<H> {
     }
 
     const fn header_size() -> usize {
-        mem::size_of::<H>()
+        size_of::<H>()
     }
 
     fn alloc_layout(value_layout: Layout) -> Result<(Layout, usize), LayoutError> {
diff --git a/library/alloc/src/collections/btree/node/tests.rs b/library/alloc/src/collections/btree/node/tests.rs
index ecd009f11c7..7d1a2ea4809 100644
--- a/library/alloc/src/collections/btree/node/tests.rs
+++ b/library/alloc/src/collections/btree/node/tests.rs
@@ -92,8 +92,8 @@ fn test_partial_eq() {
 #[cfg(target_arch = "x86_64")]
 #[cfg_attr(any(miri, randomized_layouts), ignore)] // We'd like to run Miri with layout randomization
 fn test_sizes() {
-    assert_eq!(core::mem::size_of::<LeafNode<(), ()>>(), 16);
-    assert_eq!(core::mem::size_of::<LeafNode<i64, i64>>(), 16 + CAPACITY * 2 * 8);
-    assert_eq!(core::mem::size_of::<InternalNode<(), ()>>(), 16 + (CAPACITY + 1) * 8);
-    assert_eq!(core::mem::size_of::<InternalNode<i64, i64>>(), 16 + (CAPACITY * 3 + 1) * 8);
+    assert_eq!(size_of::<LeafNode<(), ()>>(), 16);
+    assert_eq!(size_of::<LeafNode<i64, i64>>(), 16 + CAPACITY * 2 * 8);
+    assert_eq!(size_of::<InternalNode<(), ()>>(), 16 + (CAPACITY + 1) * 8);
+    assert_eq!(size_of::<InternalNode<i64, i64>>(), 16 + (CAPACITY * 3 + 1) * 8);
 }
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 2e9dd985715..cb93100f56c 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -102,7 +102,6 @@
 #![feature(assert_matches)]
 #![feature(async_fn_traits)]
 #![feature(async_iterator)]
-#![feature(box_uninit_write)]
 #![feature(bstr)]
 #![feature(bstr_internals)]
 #![feature(char_max_len)]
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index b80d1fc7889..70f32fbaab4 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -480,7 +480,7 @@ impl<A: Allocator> RawVecInner<A> {
 
         // Allocators currently return a `NonNull<[u8]>` whose length
         // matches the size requested. If that ever changes, the capacity
-        // here should change to `ptr.len() / mem::size_of::<T>()`.
+        // here should change to `ptr.len() / size_of::<T>()`.
         Ok(Self {
             ptr: Unique::from(ptr.cast()),
             cap: unsafe { Cap::new_unchecked(capacity) },
@@ -627,7 +627,7 @@ impl<A: Allocator> RawVecInner<A> {
     unsafe fn set_ptr_and_cap(&mut self, ptr: NonNull<[u8]>, cap: usize) {
         // Allocators currently return a `NonNull<[u8]>` whose length matches
         // the size requested. If that ever changes, the capacity here should
-        // change to `ptr.len() / mem::size_of::<T>()`.
+        // change to `ptr.len() / size_of::<T>()`.
         self.ptr = Unique::from(ptr.cast());
         self.cap = unsafe { Cap::new_unchecked(cap) };
     }
diff --git a/library/alloc/src/raw_vec/tests.rs b/library/alloc/src/raw_vec/tests.rs
index d78ded104fb..700fa922739 100644
--- a/library/alloc/src/raw_vec/tests.rs
+++ b/library/alloc/src/raw_vec/tests.rs
@@ -1,4 +1,3 @@
-use core::mem::size_of;
 use std::cell::Cell;
 
 use super::*;
@@ -93,7 +92,7 @@ fn zst_sanity<T>(v: &RawVec<T>) {
 fn zst() {
     let cap_err = Err(crate::collections::TryReserveErrorKind::CapacityOverflow.into());
 
-    assert_eq!(std::mem::size_of::<ZST>(), 0);
+    assert_eq!(size_of::<ZST>(), 0);
 
     // All these different ways of creating the RawVec produce the same thing.
 
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index dcd95ddf00f..8baf9685062 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -16,7 +16,7 @@ use core::borrow::{Borrow, BorrowMut};
 #[cfg(not(no_global_oom_handling))]
 use core::cmp::Ordering::{self, Less};
 #[cfg(not(no_global_oom_handling))]
-use core::mem::{self, MaybeUninit};
+use core::mem::MaybeUninit;
 #[cfg(not(no_global_oom_handling))]
 use core::ptr;
 #[unstable(feature = "array_chunks", issue = "74985")]
@@ -446,7 +446,7 @@ impl<T> [T] {
         // Avoids binary-size usage in cases where the alignment doesn't work out to make this
         // beneficial or on 32-bit platforms.
         let is_using_u32_as_idx_type_helpful =
-            const { mem::size_of::<(K, u32)>() < mem::size_of::<(K, usize)>() };
+            const { size_of::<(K, u32)>() < size_of::<(K, usize)>() };
 
         // It's possible to instantiate this for u8 and u16 but, doing so is very wasteful in terms
         // of compile-times and binary-size, the peak saved heap memory for u16 is (u8 + u16) -> 4
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index f10ef1fca13..2c034786549 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -119,8 +119,6 @@ use crate::vec::{self, Vec};
 /// the same `char`s:
 ///
 /// ```
-/// use std::mem;
-///
 /// // `s` is ASCII which represents each `char` as one byte
 /// let s = "hello";
 /// assert_eq!(s.len(), 5);
@@ -128,7 +126,7 @@ use crate::vec::{self, Vec};
 /// // A `char` array with the same contents would be longer because
 /// // every `char` is four bytes
 /// let s = ['h', 'e', 'l', 'l', 'o'];
-/// let size: usize = s.into_iter().map(|c| mem::size_of_val(&c)).sum();
+/// let size: usize = s.into_iter().map(|c| size_of_val(&c)).sum();
 /// assert_eq!(size, 20);
 ///
 /// // However, for non-ASCII strings, the difference will be smaller
@@ -137,7 +135,7 @@ use crate::vec::{self, Vec};
 /// assert_eq!(s.len(), 20);
 ///
 /// let s = ['💖', '💖', '💖', '💖', '💖'];
-/// let size: usize = s.into_iter().map(|c| mem::size_of_val(&c)).sum();
+/// let size: usize = s.into_iter().map(|c| size_of_val(&c)).sum();
 /// assert_eq!(size, 20);
 /// ```
 ///
@@ -1134,7 +1132,6 @@ impl String {
     /// # Examples
     ///
     /// ```
-    /// #![feature(string_extend_from_within)]
     /// let mut string = String::from("abcde");
     ///
     /// string.extend_from_within(2..);
@@ -1147,7 +1144,7 @@ impl String {
     /// assert_eq!(string, "abcdecdeabecde");
     /// ```
     #[cfg(not(no_global_oom_handling))]
-    #[unstable(feature = "string_extend_from_within", issue = "103806")]
+    #[stable(feature = "string_extend_from_within", since = "CURRENT_RUSTC_VERSION")]
     pub fn extend_from_within<R>(&mut self, src: R)
     where
         R: RangeBounds<usize>,
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index dba1449347a..1956dda5388 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -2274,7 +2274,7 @@ impl<T: ?Sized + CloneToUninit, A: Allocator + Clone> Arc<T, A> {
     #[inline]
     #[stable(feature = "arc_unique", since = "1.4.0")]
     pub fn make_mut(this: &mut Self) -> &mut T {
-        let size_of_val = mem::size_of_val::<T>(&**this);
+        let size_of_val = size_of_val::<T>(&**this);
 
         // Note that we hold both a strong reference and a weak reference.
         // Thus, releasing our strong reference only will not, by itself, cause
@@ -3544,7 +3544,7 @@ impl<T> Default for Arc<[T]> {
     /// This may or may not share an allocation with other Arcs.
     #[inline]
     fn default() -> Self {
-        if mem::align_of::<T>() <= MAX_STATIC_INNER_SLICE_ALIGNMENT {
+        if align_of::<T>() <= MAX_STATIC_INNER_SLICE_ALIGNMENT {
             // We take a reference to the whole struct instead of the ArcInner<[u8; 1]> inside it so
             // we don't shrink the range of bytes the ptr is allowed to access under Stacked Borrows.
             // (Miri complains on 32-bit targets with Arc<[Align16]> otherwise.)
diff --git a/library/alloc/src/vec/in_place_collect.rs b/library/alloc/src/vec/in_place_collect.rs
index dffd85f13aa..b98a118048f 100644
--- a/library/alloc/src/vec/in_place_collect.rs
+++ b/library/alloc/src/vec/in_place_collect.rs
@@ -171,7 +171,7 @@ const fn in_place_collectible<DEST, SRC>(
 ) -> bool {
     // Require matching alignments because an alignment-changing realloc is inefficient on many
     // system allocators and better implementations would require the unstable Allocator trait.
-    if const { SRC::IS_ZST || DEST::IS_ZST || mem::align_of::<SRC>() != mem::align_of::<DEST>() } {
+    if const { SRC::IS_ZST || DEST::IS_ZST || align_of::<SRC>() != align_of::<DEST>() } {
         return false;
     }
 
@@ -181,7 +181,7 @@ const fn in_place_collectible<DEST, SRC>(
             // e.g.
             // - 1 x [u8; 4] -> 4x u8, via flatten
             // - 4 x u8 -> 1x [u8; 4], via array_chunks
-            mem::size_of::<SRC>() * step_merge.get() >= mem::size_of::<DEST>() * step_expand.get()
+            size_of::<SRC>() * step_merge.get() >= size_of::<DEST>() * step_expand.get()
         }
         // Fall back to other from_iter impls if an overflow occurred in the step merge/expansion
         // tracking.
@@ -190,7 +190,7 @@ const fn in_place_collectible<DEST, SRC>(
 }
 
 const fn needs_realloc<SRC, DEST>(src_cap: usize, dst_cap: usize) -> bool {
-    if const { mem::align_of::<SRC>() != mem::align_of::<DEST>() } {
+    if const { align_of::<SRC>() != align_of::<DEST>() } {
         // FIXME(const-hack): use unreachable! once that works in const
         panic!("in_place_collectible() prevents this");
     }
@@ -199,8 +199,8 @@ const fn needs_realloc<SRC, DEST>(src_cap: usize, dst_cap: usize) -> bool {
     // the caller will have calculated a `dst_cap` that is an integer multiple of
     // `src_cap` without remainder.
     if const {
-        let src_sz = mem::size_of::<SRC>();
-        let dest_sz = mem::size_of::<DEST>();
+        let src_sz = size_of::<SRC>();
+        let dest_sz = size_of::<DEST>();
         dest_sz != 0 && src_sz % dest_sz == 0
     } {
         return false;
@@ -208,7 +208,7 @@ const fn needs_realloc<SRC, DEST>(src_cap: usize, dst_cap: usize) -> bool {
 
     // type layouts don't guarantee a fit, so do a runtime check to see if
     // the allocations happen to match
-    src_cap > 0 && src_cap * mem::size_of::<SRC>() != dst_cap * mem::size_of::<DEST>()
+    src_cap > 0 && src_cap * size_of::<SRC>() != dst_cap * size_of::<DEST>()
 }
 
 /// This provides a shorthand for the source type since local type aliases aren't a thing.
@@ -262,7 +262,7 @@ where
             inner.buf.cast::<T>(),
             inner.end as *const T,
             // SAFETY: the multiplication can not overflow, since `inner.cap * size_of::<I::SRC>()` is the size of the allocation.
-            inner.cap.unchecked_mul(mem::size_of::<I::Src>()) / mem::size_of::<T>(),
+            inner.cap.unchecked_mul(size_of::<I::Src>()) / size_of::<T>(),
         )
     };
 
@@ -310,14 +310,14 @@ where
         debug_assert_ne!(dst_cap, 0);
         unsafe {
             // The old allocation exists, therefore it must have a valid layout.
-            let src_align = mem::align_of::<I::Src>();
-            let src_size = mem::size_of::<I::Src>().unchecked_mul(src_cap);
+            let src_align = align_of::<I::Src>();
+            let src_size = size_of::<I::Src>().unchecked_mul(src_cap);
             let old_layout = Layout::from_size_align_unchecked(src_size, src_align);
 
             // The allocation must be equal or smaller for in-place iteration to be possible
             // therefore the new layout must be ≤ the old one and therefore valid.
-            let dst_align = mem::align_of::<T>();
-            let dst_size = mem::size_of::<T>().unchecked_mul(dst_cap);
+            let dst_align = align_of::<T>();
+            let dst_size = size_of::<T>().unchecked_mul(dst_cap);
             let new_layout = Layout::from_size_align_unchecked(dst_size, dst_align);
 
             let result = alloc.shrink(dst_buf.cast(), old_layout, new_layout);
@@ -325,7 +325,7 @@ where
             dst_buf = reallocated.cast::<T>();
         }
     } else {
-        debug_assert_eq!(src_cap * mem::size_of::<I::Src>(), dst_cap * mem::size_of::<T>());
+        debug_assert_eq!(src_cap * size_of::<I::Src>(), dst_cap * size_of::<T>());
     }
 
     mem::forget(dst_guard);
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 701144cc3af..49878f2b6fa 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -293,7 +293,7 @@ mod spec_extend;
 /// on an empty Vec, it will not allocate memory. Similarly, if you store zero-sized
 /// types inside a `Vec`, it will not allocate space for them. *Note that in this case
 /// the `Vec` might not report a [`capacity`] of 0*. `Vec` will allocate if and only
-/// if <code>[mem::size_of::\<T>]\() * [capacity]\() > 0</code>. In general, `Vec`'s allocation
+/// if <code>[size_of::\<T>]\() * [capacity]\() > 0</code>. In general, `Vec`'s allocation
 /// details are very subtle --- if you intend to allocate memory using a `Vec`
 /// and use it for something else (either to pass to unsafe code, or to build your
 /// own memory-backed collection), be sure to deallocate this memory by using
@@ -393,7 +393,7 @@ mod spec_extend;
 /// [capacity]: Vec::capacity
 /// [`capacity`]: Vec::capacity
 /// [`Vec::capacity`]: Vec::capacity
-/// [mem::size_of::\<T>]: core::mem::size_of
+/// [size_of::\<T>]: size_of
 /// [len]: Vec::len
 /// [`len`]: Vec::len
 /// [`push`]: Vec::push
@@ -1573,7 +1573,7 @@ impl<T, A: Allocator> Vec<T, A> {
     pub const fn as_slice(&self) -> &[T] {
         // SAFETY: `slice::from_raw_parts` requires pointee is a contiguous, aligned buffer of size
         // `len` containing properly-initialized `T`s. Data must not be mutated for the returned
-        // lifetime. Further, `len * mem::size_of::<T>` <= `ISIZE::MAX`, and allocation does not
+        // lifetime. Further, `len * size_of::<T>` <= `isize::MAX`, and allocation does not
         // "wrap" through overflowing memory addresses.
         //
         // * Vec API guarantees that self.buf:
@@ -1605,7 +1605,7 @@ impl<T, A: Allocator> Vec<T, A> {
     pub const fn as_mut_slice(&mut self) -> &mut [T] {
         // SAFETY: `slice::from_raw_parts_mut` requires pointee is a contiguous, aligned buffer of
         // size `len` containing properly-initialized `T`s. Data must not be accessed through any
-        // other pointer for the returned lifetime. Further, `len * mem::size_of::<T>` <=
+        // other pointer for the returned lifetime. Further, `len * size_of::<T>` <=
         // `ISIZE::MAX` and allocation does not "wrap" through overflowing memory addresses.
         //
         // * Vec API guarantees that self.buf:
@@ -2693,7 +2693,7 @@ impl<T, A: Allocator> Vec<T, A> {
         let len = self.len;
 
         // SAFETY: The maximum capacity of `Vec<T>` is `isize::MAX` bytes, so the maximum value can
-        // be returned is `usize::checked_div(mem::size_of::<T>()).unwrap_or(usize::MAX)`, which
+        // be returned is `usize::checked_div(size_of::<T>()).unwrap_or(usize::MAX)`, which
         // matches the definition of `T::MAX_SLICE_LEN`.
         unsafe { intrinsics::assume(len <= T::MAX_SLICE_LEN) };
 
diff --git a/library/alloc/tests/arc.rs b/library/alloc/tests/arc.rs
index a259c0131ec..0baa50f439b 100644
--- a/library/alloc/tests/arc.rs
+++ b/library/alloc/tests/arc.rs
@@ -1,7 +1,6 @@
 use std::any::Any;
 use std::cell::{Cell, RefCell};
 use std::iter::TrustedLen;
-use std::mem;
 use std::sync::{Arc, Weak};
 
 #[test]
@@ -129,7 +128,7 @@ fn shared_from_iter_trustedlen_normal() {
         let vec = iter.clone().collect::<Vec<_>>();
         let rc = iter.collect::<Rc<[_]>>();
         assert_eq!(&*vec, &*rc);
-        assert_eq!(mem::size_of::<Box<u16>>() * SHARED_ITER_MAX as usize, mem::size_of_val(&*rc));
+        assert_eq!(size_of::<Box<u16>>() * SHARED_ITER_MAX as usize, size_of_val(&*rc));
 
         // Clone a bit and let these get dropped.
         {
@@ -145,7 +144,7 @@ fn shared_from_iter_trustedlen_normal() {
         let vec = iter.clone().collect::<Vec<_>>();
         let rc = iter.collect::<Rc<[_]>>();
         assert_eq!(&*vec, &*rc);
-        assert_eq!(0, mem::size_of_val(&*rc));
+        assert_eq!(0, size_of_val(&*rc));
         {
             let _rc_2 = rc.clone();
             let _rc_3 = rc.clone();
diff --git a/library/alloc/tests/rc.rs b/library/alloc/tests/rc.rs
index 451765d7242..9d82a7621a2 100644
--- a/library/alloc/tests/rc.rs
+++ b/library/alloc/tests/rc.rs
@@ -1,7 +1,6 @@
 use std::any::Any;
 use std::cell::{Cell, RefCell};
 use std::iter::TrustedLen;
-use std::mem;
 use std::rc::{Rc, Weak};
 
 #[test]
@@ -125,7 +124,7 @@ fn shared_from_iter_trustedlen_normal() {
         let vec = iter.clone().collect::<Vec<_>>();
         let rc = iter.collect::<Rc<[_]>>();
         assert_eq!(&*vec, &*rc);
-        assert_eq!(mem::size_of::<Box<u16>>() * SHARED_ITER_MAX as usize, mem::size_of_val(&*rc));
+        assert_eq!(size_of::<Box<u16>>() * SHARED_ITER_MAX as usize, size_of_val(&*rc));
 
         // Clone a bit and let these get dropped.
         {
@@ -141,7 +140,7 @@ fn shared_from_iter_trustedlen_normal() {
         let vec = iter.clone().collect::<Vec<_>>();
         let rc = iter.collect::<Rc<[_]>>();
         assert_eq!(&*vec, &*rc);
-        assert_eq!(0, mem::size_of_val(&*rc));
+        assert_eq!(0, size_of_val(&*rc));
         {
             let _rc_2 = rc.clone();
             let _rc_3 = rc.clone();
diff --git a/library/alloc/tests/slice.rs b/library/alloc/tests/slice.rs
index f990a41b679..2516563187f 100644
--- a/library/alloc/tests/slice.rs
+++ b/library/alloc/tests/slice.rs
@@ -1,7 +1,7 @@
 use std::cmp::Ordering::{Equal, Greater, Less};
 use std::convert::identity;
 use std::rc::Rc;
-use std::{fmt, mem, panic};
+use std::{fmt, panic};
 
 fn square(n: usize) -> usize {
     n * n
@@ -73,7 +73,7 @@ fn test_len_divzero() {
     let v0: &[Z] = &[];
     let v1: &[Z] = &[[]];
     let v2: &[Z] = &[[], []];
-    assert_eq!(mem::size_of::<Z>(), 0);
+    assert_eq!(size_of::<Z>(), 0);
     assert_eq!(v0.len(), 0);
     assert_eq!(v1.len(), 1);
     assert_eq!(v2.len(), 2);
diff --git a/library/alloc/tests/sort/known_good_stable_sort.rs b/library/alloc/tests/sort/known_good_stable_sort.rs
index f8615435fc2..2df89146253 100644
--- a/library/alloc/tests/sort/known_good_stable_sort.rs
+++ b/library/alloc/tests/sort/known_good_stable_sort.rs
@@ -5,7 +5,7 @@
 // Based on https://github.com/voultapher/tiny-sort-rs.
 
 use alloc::alloc::{Layout, alloc, dealloc};
-use std::{mem, ptr};
+use std::ptr;
 
 /// Sort `v` preserving initial order of equal elements.
 ///
@@ -26,7 +26,7 @@ pub fn sort<T: Ord>(v: &mut [T]) {
 
 #[inline(always)]
 fn stable_sort<T, F: FnMut(&T, &T) -> bool>(v: &mut [T], mut is_less: F) {
-    if mem::size_of::<T>() == 0 {
+    if size_of::<T>() == 0 {
         return;
     }
 
@@ -166,7 +166,7 @@ struct BufGuard<T> {
 impl<T> BufGuard<T> {
     // SAFETY: The caller has to ensure that len is not 0 and that T is not a ZST.
     unsafe fn new(len: usize) -> Self {
-        debug_assert!(len > 0 && mem::size_of::<T>() > 0);
+        debug_assert!(len > 0 && size_of::<T>() > 0);
 
         // SAFETY: See function safety description.
         let layout = unsafe { unwrap_unchecked(Layout::array::<T>(len).ok()) };
diff --git a/library/alloc/tests/thin_box.rs b/library/alloc/tests/thin_box.rs
index e008b0cc357..4c46b614127 100644
--- a/library/alloc/tests/thin_box.rs
+++ b/library/alloc/tests/thin_box.rs
@@ -1,5 +1,4 @@
 use core::fmt::Debug;
-use core::mem::size_of;
 use std::boxed::ThinBox;
 
 #[test]
@@ -52,7 +51,7 @@ fn verify_aligned<T>(ptr: *const T) {
         ptr.is_aligned() && !ptr.is_null(),
         "misaligned ThinBox data; valid pointers to `{ty}` should be aligned to {align}: {ptr:p}",
         ty = core::any::type_name::<T>(),
-        align = core::mem::align_of::<T>(),
+        align = align_of::<T>(),
     );
 }
 
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index fe1db56414e..f430d979fa8 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -11,14 +11,14 @@ use std::borrow::Cow;
 use std::cell::Cell;
 use std::collections::TryReserveErrorKind::*;
 use std::fmt::Debug;
+use std::hint;
 use std::iter::InPlaceIterable;
-use std::mem::{size_of, swap};
+use std::mem::swap;
 use std::ops::Bound::*;
 use std::panic::{AssertUnwindSafe, catch_unwind};
 use std::rc::Rc;
 use std::sync::atomic::{AtomicU32, Ordering};
 use std::vec::{Drain, IntoIter};
-use std::{hint, mem};
 
 struct DropCounter<'a> {
     count: &'a mut u32,
@@ -1134,7 +1134,7 @@ fn test_into_iter_zst() {
     impl Drop for AlignedZstWithDrop {
         fn drop(&mut self) {
             let addr = self as *mut _ as usize;
-            assert!(hint::black_box(addr) % mem::align_of::<u64>() == 0);
+            assert!(hint::black_box(addr) % align_of::<u64>() == 0);
         }
     }
 
diff --git a/library/core/Cargo.toml b/library/core/Cargo.toml
index 1538ecc6b92..edde8153aa1 100644
--- a/library/core/Cargo.toml
+++ b/library/core/Cargo.toml
@@ -32,6 +32,8 @@ check-cfg = [
     'cfg(bootstrap)',
     'cfg(no_fp_fmt_parse)',
     'cfg(stdarch_intel_sde)',
+    # #[cfg(bootstrap)]
+    'cfg(target_feature, values("vector-enhancements-1"))',
     # core use #[path] imports to portable-simd `core_simd` crate
     # and to stdarch `core_arch` crate which messes-up with Cargo list
     # of declared features, we therefor expect any feature cfg
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index 17f4d68867e..1595a3af883 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -17,7 +17,7 @@ use crate::{assert_unsafe_precondition, fmt, mem};
 // * https://github.com/rust-lang/rust/pull/72189
 // * https://github.com/rust-lang/rust/pull/79827
 const fn size_align<T>() -> (usize, usize) {
-    (mem::size_of::<T>(), mem::align_of::<T>())
+    (size_of::<T>(), align_of::<T>())
 }
 
 /// Layout of a block of memory.
@@ -182,7 +182,7 @@ impl Layout {
     #[must_use]
     #[inline]
     pub const fn for_value<T: ?Sized>(t: &T) -> Self {
-        let (size, align) = (mem::size_of_val(t), mem::align_of_val(t));
+        let (size, align) = (size_of_val(t), align_of_val(t));
         // SAFETY: see rationale in `new` for why this is using the unsafe variant
         unsafe { Layout::from_size_align_unchecked(size, align) }
     }
diff --git a/library/core/src/bstr.rs b/library/core/src/bstr.rs
index 74e07f3d242..ae84fd8adb6 100644
--- a/library/core/src/bstr.rs
+++ b/library/core/src/bstr.rs
@@ -151,7 +151,9 @@ impl fmt::Display for ByteStr {
         };
         let nchars: usize = self
             .utf8_chunks()
-            .map(|chunk| chunk.valid().len() + if chunk.invalid().is_empty() { 0 } else { 1 })
+            .map(|chunk| {
+                chunk.valid().chars().count() + if chunk.invalid().is_empty() { 0 } else { 1 }
+            })
             .sum();
         let padding = f.width().unwrap_or(0).saturating_sub(nchars);
         let fill = f.fill();
diff --git a/library/core/src/char/convert.rs b/library/core/src/char/convert.rs
index 73ab4f1e52a..ac808038f89 100644
--- a/library/core/src/char/convert.rs
+++ b/library/core/src/char/convert.rs
@@ -40,11 +40,9 @@ impl From<char> for u32 {
     /// # Examples
     ///
     /// ```
-    /// use std::mem;
-    ///
     /// let c = 'c';
     /// let u = u32::from(c);
-    /// assert!(4 == mem::size_of_val(&u))
+    /// assert!(4 == size_of_val(&u))
     /// ```
     #[inline]
     fn from(c: char) -> Self {
@@ -59,11 +57,9 @@ impl From<char> for u64 {
     /// # Examples
     ///
     /// ```
-    /// use std::mem;
-    ///
     /// let c = '👤';
     /// let u = u64::from(c);
-    /// assert!(8 == mem::size_of_val(&u))
+    /// assert!(8 == size_of_val(&u))
     /// ```
     #[inline]
     fn from(c: char) -> Self {
@@ -80,11 +76,9 @@ impl From<char> for u128 {
     /// # Examples
     ///
     /// ```
-    /// use std::mem;
-    ///
     /// let c = '⚙';
     /// let u = u128::from(c);
-    /// assert!(16 == mem::size_of_val(&u))
+    /// assert!(16 == size_of_val(&u))
     /// ```
     #[inline]
     fn from(c: char) -> Self {
@@ -167,11 +161,9 @@ impl From<u8> for char {
     /// # Examples
     ///
     /// ```
-    /// use std::mem;
-    ///
     /// let u = 32 as u8;
     /// let c = char::from(u);
-    /// assert!(4 == mem::size_of_val(&c))
+    /// assert!(4 == size_of_val(&c))
     /// ```
     #[inline]
     fn from(i: u8) -> Self {
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index 00300328b64..9d64348289c 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -244,8 +244,8 @@ pub unsafe trait CloneToUninit {
     ///
     /// Behavior is undefined if any of the following conditions are violated:
     ///
-    /// * `dst` must be [valid] for writes for `std::mem::size_of_val(self)` bytes.
-    /// * `dst` must be properly aligned to `std::mem::align_of_val(self)`.
+    /// * `dst` must be [valid] for writes for `size_of_val(self)` bytes.
+    /// * `dst` must be properly aligned to `align_of_val(self)`.
     ///
     /// [valid]: crate::ptr#safety
     /// [pointer metadata]: crate::ptr::metadata()
diff --git a/library/core/src/convert/mod.rs b/library/core/src/convert/mod.rs
index e468f4f0f7e..43fd54f881d 100644
--- a/library/core/src/convert/mod.rs
+++ b/library/core/src/convert/mod.rs
@@ -778,7 +778,6 @@ impl<T> From<T> for T {
 ///
 /// [#64715]: https://github.com/rust-lang/rust/issues/64715
 #[stable(feature = "convert_infallible", since = "1.34.0")]
-#[allow(unused_attributes)] // FIXME(#58633): do a principled fix instead.
 #[rustc_reservation_impl = "permitting this impl would forbid us from adding \
                             `impl<T> From<!> for T` later; see rust-lang/rust#64715 for details"]
 impl<T> From<!> for T {
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 764e7fff33e..3f60bb067d6 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -1693,49 +1693,41 @@ impl<'a> Formatter<'a> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn pad(&mut self, s: &str) -> Result {
-        // Make sure there's a fast path up front
+        // Make sure there's a fast path up front.
         if self.options.width.is_none() && self.options.precision.is_none() {
             return self.buf.write_str(s);
         }
-        // The `precision` field can be interpreted as a `max-width` for the
+
+        // The `precision` field can be interpreted as a maximum width for the
         // string being formatted.
-        let s = if let Some(max) = self.options.precision {
-            // If our string is longer that the precision, then we must have
-            // truncation. However other flags like `fill`, `width` and `align`
-            // must act as always.
-            if let Some((i, _)) = s.char_indices().nth(max) {
-                // LLVM here can't prove that `..i` won't panic `&s[..i]`, but
-                // we know that it can't panic. Use `get` + `unwrap_or` to avoid
-                // `unsafe` and otherwise don't emit any panic-related code
-                // here.
-                s.get(..i).unwrap_or(s)
-            } else {
-                &s
-            }
+        let (s, char_count) = if let Some(max_char_count) = self.options.precision {
+            let mut iter = s.char_indices();
+            let remaining = match iter.advance_by(max_char_count) {
+                Ok(()) => 0,
+                Err(remaining) => remaining.get(),
+            };
+            // SAFETY: The offset of `.char_indices()` is guaranteed to be
+            // in-bounds and between character boundaries.
+            let truncated = unsafe { s.get_unchecked(..iter.offset()) };
+            (truncated, max_char_count - remaining)
         } else {
-            &s
+            // Use the optimized char counting algorithm for the full string.
+            (s, s.chars().count())
         };
-        // The `width` field is more of a `min-width` parameter at this point.
-        match self.options.width {
-            // If we're under the maximum length, and there's no minimum length
-            // requirements, then we can just emit the string
-            None => self.buf.write_str(s),
-            Some(width) => {
-                let chars_count = s.chars().count();
-                // If we're under the maximum width, check if we're over the minimum
-                // width, if so it's as easy as just emitting the string.
-                if chars_count >= width {
-                    self.buf.write_str(s)
-                }
-                // If we're under both the maximum and the minimum width, then fill
-                // up the minimum width with the specified string + some alignment.
-                else {
-                    let align = Alignment::Left;
-                    let post_padding = self.padding(width - chars_count, align)?;
-                    self.buf.write_str(s)?;
-                    post_padding.write(self)
-                }
-            }
+
+        // The `width` field is more of a minimum width parameter at this point.
+        if let Some(width) = self.options.width
+            && char_count < width
+        {
+            // If we're under the minimum width, then fill up the minimum width
+            // with the specified string + some alignment.
+            let post_padding = self.padding(width - char_count, Alignment::Left)?;
+            self.buf.write_str(s)?;
+            post_padding.write(self)
+        } else {
+            // If we're over the minimum width or there is no minimum width, we
+            // can just emit the string.
+            self.buf.write_str(s)
         }
     }
 
diff --git a/library/core/src/hash/mod.rs b/library/core/src/hash/mod.rs
index 7a6630c82d0..f7b874b26bb 100644
--- a/library/core/src/hash/mod.rs
+++ b/library/core/src/hash/mod.rs
@@ -801,7 +801,7 @@ impl<H> Eq for BuildHasherDefault<H> {}
 
 mod impls {
     use super::*;
-    use crate::{mem, slice};
+    use crate::slice;
 
     macro_rules! impl_write {
         ($(($ty:ident, $meth:ident),)*) => {$(
@@ -814,7 +814,7 @@ mod impls {
 
                 #[inline]
                 fn hash_slice<H: Hasher>(data: &[$ty], state: &mut H) {
-                    let newlen = mem::size_of_val(data);
+                    let newlen = size_of_val(data);
                     let ptr = data.as_ptr() as *const u8;
                     // SAFETY: `ptr` is valid and aligned, as this macro is only used
                     // for numeric primitives which have no padding. The new slice only
diff --git a/library/core/src/hash/sip.rs b/library/core/src/hash/sip.rs
index 6ea3241c593..780e522c48e 100644
--- a/library/core/src/hash/sip.rs
+++ b/library/core/src/hash/sip.rs
@@ -3,7 +3,7 @@
 #![allow(deprecated)] // the types in this module are deprecated
 
 use crate::marker::PhantomData;
-use crate::{cmp, mem, ptr};
+use crate::{cmp, ptr};
 
 /// An implementation of SipHash 1-3.
 ///
@@ -99,12 +99,12 @@ macro_rules! compress {
 /// `$i..$i+size_of::<$int_ty>()`, so that must be in-bounds.
 macro_rules! load_int_le {
     ($buf:expr, $i:expr, $int_ty:ident) => {{
-        debug_assert!($i + mem::size_of::<$int_ty>() <= $buf.len());
+        debug_assert!($i + size_of::<$int_ty>() <= $buf.len());
         let mut data = 0 as $int_ty;
         ptr::copy_nonoverlapping(
             $buf.as_ptr().add($i),
             &mut data as *mut _ as *mut u8,
-            mem::size_of::<$int_ty>(),
+            size_of::<$int_ty>(),
         );
         data.to_le()
     }};
diff --git a/library/core/src/intrinsics/mod.rs b/library/core/src/intrinsics/mod.rs
index 38a60338e74..6af647b137d 100644
--- a/library/core/src/intrinsics/mod.rs
+++ b/library/core/src/intrinsics/mod.rs
@@ -10,7 +10,7 @@
 //!
 //! In order to make an intrinsic usable at compile-time, it needs to be declared in the "new"
 //! style, i.e. as a `#[rustc_intrinsic]` function, not inside an `extern` block. Then copy the
-//! implementation from <https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics> to
+//! implementation from <https://github.com/rust-lang/miri/blob/master/src/intrinsics> to
 //! <https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/intrinsics.rs>
 //! and make the intrinsic declaration a `const fn`.
 //!
@@ -3340,7 +3340,7 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize;
 /// More specifically, this is the offset in bytes between successive
 /// items of the same type, including alignment padding.
 ///
-/// The stabilized version of this intrinsic is [`core::mem::size_of`].
+/// The stabilized version of this intrinsic is [`size_of`].
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[rustc_intrinsic_const_stable_indirect]
@@ -3354,7 +3354,7 @@ pub const fn size_of<T>() -> usize;
 /// Therefore, implementations must not require the user to uphold
 /// any safety invariants.
 ///
-/// The stabilized version of this intrinsic is [`core::mem::align_of`].
+/// The stabilized version of this intrinsic is [`align_of`].
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
 #[rustc_intrinsic_const_stable_indirect]
@@ -3386,7 +3386,7 @@ pub const fn variant_count<T>() -> usize;
 
 /// The size of the referenced value in bytes.
 ///
-/// The stabilized version of this intrinsic is [`crate::mem::size_of_val`].
+/// The stabilized version of this intrinsic is [`size_of_val`].
 ///
 /// # Safety
 ///
@@ -3399,7 +3399,7 @@ pub const unsafe fn size_of_val<T: ?Sized>(_ptr: *const T) -> usize;
 
 /// The required alignment of the referenced value.
 ///
-/// The stabilized version of this intrinsic is [`core::mem::align_of_val`].
+/// The stabilized version of this intrinsic is [`align_of_val`].
 ///
 /// # Safety
 ///
diff --git a/library/core/src/iter/adapters/map_windows.rs b/library/core/src/iter/adapters/map_windows.rs
index cb13023c85c..a9c07fee2a9 100644
--- a/library/core/src/iter/adapters/map_windows.rs
+++ b/library/core/src/iter/adapters/map_windows.rs
@@ -1,5 +1,5 @@
 use crate::iter::FusedIterator;
-use crate::mem::{self, MaybeUninit};
+use crate::mem::MaybeUninit;
 use crate::{fmt, ptr};
 
 /// An iterator over the mapped windows of another iterator.
@@ -50,7 +50,7 @@ impl<I: Iterator, F, const N: usize> MapWindows<I, F, N> {
         assert!(N != 0, "array in `Iterator::map_windows` must contain more than 0 elements");
 
         // Only ZST arrays' length can be so large.
-        if mem::size_of::<I::Item>() == 0 {
+        if size_of::<I::Item>() == 0 {
             assert!(
                 N.checked_mul(2).is_some(),
                 "array size of `Iterator::map_windows` is too large"
diff --git a/library/core/src/iter/sources/successors.rs b/library/core/src/iter/sources/successors.rs
index e14c9235e55..5466131903f 100644
--- a/library/core/src/iter/sources/successors.rs
+++ b/library/core/src/iter/sources/successors.rs
@@ -1,11 +1,16 @@
 use crate::fmt;
 use crate::iter::FusedIterator;
 
-/// Creates a new iterator where each successive item is computed based on the preceding one.
+/// Creates an iterator which, starting from an initial item,
+/// computes each successive item from the preceding one.
 ///
-/// The iterator starts with the given first item (if any)
-/// and calls the given `FnMut(&T) -> Option<T>` closure to compute each item’s successor.
-/// The iterator will yield the `T`s returned from the closure.
+/// This iterator stores an optional item (`Option<T>`) and a successor closure (`impl FnMut(&T) -> Option<T>`).
+/// Its `next` method returns the stored optional item and
+/// if it is `Some(val)` calls the stored closure on `&val` to compute and store its successor.
+/// The iterator will apply the closure successively to the stored option's value until the option is `None`.
+/// This also means that once the stored option is `None` it will remain `None`,
+/// as the closure will not be called again, so the created iterator is a [`FusedIterator`].
+/// The iterator's items will be the initial item and all of its successors as calculated by the successor closure.
 ///
 /// ```
 /// use std::iter::successors;
@@ -24,7 +29,8 @@ where
     Successors { next: first, succ }
 }
 
-/// A new iterator where each successive item is computed based on the preceding one.
+/// An iterator which, starting from an initial item,
+/// computes each successive item from the preceding one.
 ///
 /// This `struct` is created by the [`iter::successors()`] function.
 /// See its documentation for more.
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index db68f472c42..987fa93d598 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -202,14 +202,17 @@
 //
 // Target features:
 // tidy-alphabetical-start
+#![feature(aarch64_unstable_target_feature)]
 #![feature(arm_target_feature)]
 #![feature(avx512_target_feature)]
 #![feature(hexagon_target_feature)]
+#![feature(keylocker_x86)]
 #![feature(loongarch_target_feature)]
 #![feature(mips_target_feature)]
 #![feature(powerpc_target_feature)]
 #![feature(riscv_target_feature)]
 #![feature(rtm_target_feature)]
+#![feature(s390x_target_feature)]
 #![feature(sha512_sm_x86)]
 #![feature(sse4a_target_feature)]
 #![feature(tbm_target_feature)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index b0571bf7247..e234f105b0b 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -405,7 +405,7 @@ marker_impls! {
 ///
 /// [`Vec<T>`]: ../../std/vec/struct.Vec.html
 /// [`String`]: ../../std/string/struct.String.html
-/// [`size_of::<T>`]: crate::mem::size_of
+/// [`size_of::<T>`]: size_of
 /// [impls]: #implementors
 #[stable(feature = "rust1", since = "1.0.0")]
 #[lang = "copy"]
@@ -453,8 +453,8 @@ impl Copy for ! {}
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Copy for &T {}
 
-/// Marker trait for the types that are allowed in union fields, unsafe fields,
-/// and unsafe binder types.
+/// Marker trait for the types that are allowed in union fields and unsafe
+/// binder types.
 ///
 /// Implemented for:
 /// * `&T`, `&mut T` for all `T`,
@@ -731,7 +731,6 @@ impl<T: ?Sized> !Sync for *mut T {}
 /// # }
 /// # fn convert_params(_: ParamType) -> usize { 42 }
 /// use std::marker::PhantomData;
-/// use std::mem;
 ///
 /// struct ExternalResource<R> {
 ///    resource_handle: *mut (),
@@ -740,7 +739,7 @@ impl<T: ?Sized> !Sync for *mut T {}
 ///
 /// impl<R: ResType> ExternalResource<R> {
 ///     fn new() -> Self {
-///         let size_of_res = mem::size_of::<R>();
+///         let size_of_res = size_of::<R>();
 ///         Self {
 ///             resource_handle: foreign_lib::new(size_of_res),
 ///             resource_type: PhantomData,
diff --git a/library/core/src/marker/variance.rs b/library/core/src/marker/variance.rs
index 23334e6575d..235f8a3bb79 100644
--- a/library/core/src/marker/variance.rs
+++ b/library/core/src/marker/variance.rs
@@ -136,6 +136,8 @@ phantom_lifetime! {
     /// For all `'a`, the following are guaranteed:
     /// * `size_of::<PhantomCovariantLifetime<'a>>() == 0`
     /// * `align_of::<PhantomCovariantLifetime<'a>>() == 1`
+    #[rustc_pub_transparent]
+    #[repr(transparent)]
     pub struct PhantomCovariantLifetime<'a>(PhantomCovariant<&'a ()>);
     /// Zero-sized type used to mark a lifetime as contravariant.
     ///
@@ -149,6 +151,8 @@ phantom_lifetime! {
     /// For all `'a`, the following are guaranteed:
     /// * `size_of::<PhantomContravariantLifetime<'a>>() == 0`
     /// * `align_of::<PhantomContravariantLifetime<'a>>() == 1`
+    #[rustc_pub_transparent]
+    #[repr(transparent)]
     pub struct PhantomContravariantLifetime<'a>(PhantomContravariant<&'a ()>);
     /// Zero-sized type used to mark a lifetime as invariant.
     ///
@@ -162,6 +166,8 @@ phantom_lifetime! {
     /// For all `'a`, the following are guaranteed:
     /// * `size_of::<PhantomInvariantLifetime<'a>>() == 0`
     /// * `align_of::<PhantomInvariantLifetime<'a>>() == 1`
+    #[rustc_pub_transparent]
+    #[repr(transparent)]
     pub struct PhantomInvariantLifetime<'a>(PhantomInvariant<&'a ()>);
 }
 
@@ -179,6 +185,8 @@ phantom_type! {
     /// For all `T`, the following are guaranteed:
     /// * `size_of::<PhantomCovariant<T>>() == 0`
     /// * `align_of::<PhantomCovariant<T>>() == 1`
+    #[rustc_pub_transparent]
+    #[repr(transparent)]
     pub struct PhantomCovariant<T>(PhantomData<fn() -> T>);
     /// Zero-sized type used to mark a type parameter as contravariant.
     ///
@@ -193,6 +201,8 @@ phantom_type! {
     /// For all `T`, the following are guaranteed:
     /// * `size_of::<PhantomContravariant<T>>() == 0`
     /// * `align_of::<PhantomContravariant<T>>() == 1`
+    #[rustc_pub_transparent]
+    #[repr(transparent)]
     pub struct PhantomContravariant<T>(PhantomData<fn(T)>);
     /// Zero-sized type used to mark a type parameter as invariant.
     ///
@@ -206,6 +216,8 @@ phantom_type! {
     /// For all `T`, the following are guaranteed:
     /// * `size_of::<PhantomInvariant<T>>() == 0`
     /// * `align_of::<PhantomInvariant<T>>() == 1`
+    #[rustc_pub_transparent]
+    #[repr(transparent)]
     pub struct PhantomInvariant<T>(PhantomData<fn(T) -> T>);
 }
 
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 067371c1b58..ce84f105e5c 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -203,7 +203,7 @@ use crate::{fmt, intrinsics, ptr, slice};
 /// `MaybeUninit<T>` is guaranteed to have the same size, alignment, and ABI as `T`:
 ///
 /// ```rust
-/// use std::mem::{MaybeUninit, size_of, align_of};
+/// use std::mem::MaybeUninit;
 /// assert_eq!(size_of::<MaybeUninit<u64>>(), size_of::<u64>());
 /// assert_eq!(align_of::<MaybeUninit<u64>>(), align_of::<u64>());
 /// ```
@@ -215,7 +215,7 @@ use crate::{fmt, intrinsics, ptr, slice};
 /// optimizations, potentially resulting in a larger size:
 ///
 /// ```rust
-/// # use std::mem::{MaybeUninit, size_of};
+/// # use std::mem::MaybeUninit;
 /// assert_eq!(size_of::<Option<bool>>(), 1);
 /// assert_eq!(size_of::<Option<MaybeUninit<bool>>>(), 2);
 /// ```
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index b9bb6d6a13f..caab7a6ddb5 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -226,31 +226,27 @@ pub fn forget_unsized<T: ?Sized>(t: T) {
 /// # Examples
 ///
 /// ```
-/// use std::mem;
-///
 /// // Some primitives
-/// assert_eq!(4, mem::size_of::<i32>());
-/// assert_eq!(8, mem::size_of::<f64>());
-/// assert_eq!(0, mem::size_of::<()>());
+/// assert_eq!(4, size_of::<i32>());
+/// assert_eq!(8, size_of::<f64>());
+/// assert_eq!(0, size_of::<()>());
 ///
 /// // Some arrays
-/// assert_eq!(8, mem::size_of::<[i32; 2]>());
-/// assert_eq!(12, mem::size_of::<[i32; 3]>());
-/// assert_eq!(0, mem::size_of::<[i32; 0]>());
+/// assert_eq!(8, size_of::<[i32; 2]>());
+/// assert_eq!(12, size_of::<[i32; 3]>());
+/// assert_eq!(0, size_of::<[i32; 0]>());
 ///
 ///
 /// // Pointer size equality
-/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<*const i32>());
-/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Box<i32>>());
-/// assert_eq!(mem::size_of::<&i32>(), mem::size_of::<Option<&i32>>());
-/// assert_eq!(mem::size_of::<Box<i32>>(), mem::size_of::<Option<Box<i32>>>());
+/// assert_eq!(size_of::<&i32>(), size_of::<*const i32>());
+/// assert_eq!(size_of::<&i32>(), size_of::<Box<i32>>());
+/// assert_eq!(size_of::<&i32>(), size_of::<Option<&i32>>());
+/// assert_eq!(size_of::<Box<i32>>(), size_of::<Option<Box<i32>>>());
 /// ```
 ///
 /// Using `#[repr(C)]`.
 ///
 /// ```
-/// use std::mem;
-///
 /// #[repr(C)]
 /// struct FieldStruct {
 ///     first: u8,
@@ -265,13 +261,13 @@ pub fn forget_unsized<T: ?Sized>(t: T) {
 /// // The size of the third field is 1, so add 1 to the size. Size is 5.
 /// // Finally, the alignment of the struct is 2 (because the largest alignment amongst its
 /// // fields is 2), so add 1 to the size for padding. Size is 6.
-/// assert_eq!(6, mem::size_of::<FieldStruct>());
+/// assert_eq!(6, size_of::<FieldStruct>());
 ///
 /// #[repr(C)]
 /// struct TupleStruct(u8, u16, u8);
 ///
 /// // Tuple structs follow the same rules.
-/// assert_eq!(6, mem::size_of::<TupleStruct>());
+/// assert_eq!(6, size_of::<TupleStruct>());
 ///
 /// // Note that reordering the fields can lower the size. We can remove both padding bytes
 /// // by putting `third` before `second`.
@@ -282,7 +278,7 @@ pub fn forget_unsized<T: ?Sized>(t: T) {
 ///     second: u16
 /// }
 ///
-/// assert_eq!(4, mem::size_of::<FieldStructOptimized>());
+/// assert_eq!(4, size_of::<FieldStructOptimized>());
 ///
 /// // Union size is the size of the largest field.
 /// #[repr(C)]
@@ -291,7 +287,7 @@ pub fn forget_unsized<T: ?Sized>(t: T) {
 ///     larger: u16
 /// }
 ///
-/// assert_eq!(2, mem::size_of::<ExampleUnion>());
+/// assert_eq!(2, size_of::<ExampleUnion>());
 /// ```
 ///
 /// [alignment]: align_of
@@ -320,13 +316,11 @@ pub const fn size_of<T>() -> usize {
 /// # Examples
 ///
 /// ```
-/// use std::mem;
-///
-/// assert_eq!(4, mem::size_of_val(&5i32));
+/// assert_eq!(4, size_of_val(&5i32));
 ///
 /// let x: [u8; 13] = [0; 13];
 /// let y: &[u8] = &x;
-/// assert_eq!(13, mem::size_of_val(y));
+/// assert_eq!(13, size_of_val(y));
 /// ```
 ///
 /// [`size_of::<T>()`]: size_of
@@ -381,7 +375,7 @@ pub const fn size_of_val<T: ?Sized>(val: &T) -> usize {
 /// #![feature(layout_for_ptr)]
 /// use std::mem;
 ///
-/// assert_eq!(4, mem::size_of_val(&5i32));
+/// assert_eq!(4, size_of_val(&5i32));
 ///
 /// let x: [u8; 13] = [0; 13];
 /// let y: &[u8] = &x;
@@ -454,9 +448,7 @@ pub fn min_align_of_val<T: ?Sized>(val: &T) -> usize {
 /// # Examples
 ///
 /// ```
-/// use std::mem;
-///
-/// assert_eq!(4, mem::align_of::<i32>());
+/// assert_eq!(4, align_of::<i32>());
 /// ```
 #[inline(always)]
 #[must_use]
@@ -477,9 +469,7 @@ pub const fn align_of<T>() -> usize {
 /// # Examples
 ///
 /// ```
-/// use std::mem;
-///
-/// assert_eq!(4, mem::align_of_val(&5i32));
+/// assert_eq!(4, align_of_val(&5i32));
 /// ```
 #[inline]
 #[must_use]
diff --git a/library/core/src/mem/transmutability.rs b/library/core/src/mem/transmutability.rs
index 7b920d7a777..782b826448a 100644
--- a/library/core/src/mem/transmutability.rs
+++ b/library/core/src/mem/transmutability.rs
@@ -153,7 +153,7 @@ pub struct Assume {
     ///
     /// ```compile_fail,E0277
     /// #![feature(transmutability)]
-    /// use core::mem::{align_of, TransmuteFrom};
+    /// use core::mem::TransmuteFrom;
     ///
     /// assert_eq!(align_of::<[u8; 2]>(), 1);
     /// assert_eq!(align_of::<u16>(), 2);
@@ -172,7 +172,7 @@ pub struct Assume {
     ///
     /// ```rust
     /// #![feature(pointer_is_aligned_to, transmutability)]
-    /// use core::mem::{align_of, Assume, TransmuteFrom};
+    /// use core::mem::{Assume, TransmuteFrom};
     ///
     /// let src: &[u8; 2] = &[0xFF, 0xFF];
     ///
@@ -337,7 +337,7 @@ impl Assume {
     ///     transmutability,
     /// )]
     /// #![allow(incomplete_features)]
-    /// use core::mem::{align_of, Assume, TransmuteFrom};
+    /// use core::mem::{Assume, TransmuteFrom};
     ///
     /// /// Attempts to transmute `src` to `&Dst`.
     /// ///
diff --git a/library/core/src/num/bignum.rs b/library/core/src/num/bignum.rs
index 2a47c89e2ae..40e6eaf075e 100644
--- a/library/core/src/num/bignum.rs
+++ b/library/core/src/num/bignum.rs
@@ -253,12 +253,11 @@ macro_rules! define_bignum {
 
             /// Multiplies itself by `5^e` and returns its own mutable reference.
             pub fn mul_pow5(&mut self, mut e: usize) -> &mut $name {
-                use crate::mem;
                 use crate::num::bignum::SMALL_POW5;
 
                 // There are exactly n trailing zeros on 2^n, and the only relevant digit sizes
                 // are consecutive powers of two, so this is well suited index for the table.
-                let table_index = mem::size_of::<$ty>().trailing_zeros() as usize;
+                let table_index = size_of::<$ty>().trailing_zeros() as usize;
                 let (small_power, small_e) = SMALL_POW5[table_index];
                 let small_power = small_power as $ty;
 
diff --git a/library/core/src/num/dec2flt/common.rs b/library/core/src/num/dec2flt/common.rs
index 4dadf406ae8..a140a311c45 100644
--- a/library/core/src/num/dec2flt/common.rs
+++ b/library/core/src/num/dec2flt/common.rs
@@ -8,12 +8,12 @@ pub(crate) trait ByteSlice {
     /// Writes a 64-bit integer as 8 bytes in little-endian order.
     fn write_u64(&mut self, value: u64);
 
-    /// Calculate the offset of a slice from another.
+    /// Calculate the difference in length between two slices.
     fn offset_from(&self, other: &Self) -> isize;
 
     /// Iteratively parse and consume digits from bytes.
-    /// Returns the same bytes with consumed digits being
-    /// elided.
+    ///
+    /// Returns the same bytes with consumed digits being elided. Breaks on invalid digits.
     fn parse_digits(&self, func: impl FnMut(u8)) -> &Self;
 }
 
@@ -39,11 +39,11 @@ impl ByteSlice for [u8] {
     fn parse_digits(&self, mut func: impl FnMut(u8)) -> &Self {
         let mut s = self;
 
-        while let Some((c, s_next)) = s.split_first() {
+        while let Some((c, rest)) = s.split_first() {
             let c = c.wrapping_sub(b'0');
             if c < 10 {
                 func(c);
-                s = s_next;
+                s = rest;
             } else {
                 break;
             }
@@ -53,7 +53,9 @@ impl ByteSlice for [u8] {
     }
 }
 
-/// Determine if 8 bytes are all decimal digits.
+/// Determine if all characters in an 8-byte byte string (represented as a `u64`) are all decimal
+/// digits.
+///
 /// This does not care about the order in which the bytes were loaded.
 pub(crate) fn is_8digits(v: u64) -> bool {
     let a = v.wrapping_add(0x4646_4646_4646_4646);
@@ -61,19 +63,20 @@ pub(crate) fn is_8digits(v: u64) -> bool {
     (a | b) & 0x8080_8080_8080_8080 == 0
 }
 
-/// A custom 64-bit floating point type, representing `f * 2^e`.
-/// e is biased, so it be directly shifted into the exponent bits.
+/// A custom 64-bit floating point type, representing `m * 2^p`.
+/// p is biased, so it be directly shifted into the exponent bits.
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Default)]
 pub struct BiasedFp {
     /// The significant digits.
-    pub f: u64,
+    pub m: u64,
     /// The biased, binary exponent.
-    pub e: i32,
+    pub p_biased: i32,
 }
 
 impl BiasedFp {
+    /// Represent `0 ^ p`
     #[inline]
-    pub const fn zero_pow2(e: i32) -> Self {
-        Self { f: 0, e }
+    pub const fn zero_pow2(p_biased: i32) -> Self {
+        Self { m: 0, p_biased }
     }
 }
diff --git a/library/core/src/num/dec2flt/decimal.rs b/library/core/src/num/dec2flt/decimal.rs
index b37724ba62d..db7176c1243 100644
--- a/library/core/src/num/dec2flt/decimal.rs
+++ b/library/core/src/num/dec2flt/decimal.rs
@@ -1,358 +1,87 @@
-//! Arbitrary-precision decimal class for fallback algorithms.
-//!
-//! This is only used if the fast-path (native floats) and
-//! the Eisel-Lemire algorithm are unable to unambiguously
-//! determine the float.
-//!
-//! The technique used is "Simple Decimal Conversion", developed
-//! by Nigel Tao and Ken Thompson. A detailed description of the
-//! algorithm can be found in "ParseNumberF64 by Simple Decimal Conversion",
-//! available online: <https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html>.
-
-use crate::num::dec2flt::common::{ByteSlice, is_8digits};
-
-#[derive(Clone)]
-pub(super) struct Decimal {
-    /// The number of significant digits in the decimal.
-    pub num_digits: usize,
-    /// The offset of the decimal point in the significant digits.
-    pub decimal_point: i32,
-    /// If the number of significant digits stored in the decimal is truncated.
-    pub truncated: bool,
-    /// Buffer of the raw digits, in the range [0, 9].
-    pub digits: [u8; Self::MAX_DIGITS],
+//! Representation of a float as the significant digits and exponent.
+
+use crate::num::dec2flt::float::RawFloat;
+use crate::num::dec2flt::fpu::set_precision;
+
+const INT_POW10: [u64; 16] = [
+    1,
+    10,
+    100,
+    1000,
+    10000,
+    100000,
+    1000000,
+    10000000,
+    100000000,
+    1000000000,
+    10000000000,
+    100000000000,
+    1000000000000,
+    10000000000000,
+    100000000000000,
+    1000000000000000,
+];
+
+/// A floating point number with up to 64 bits of mantissa and an `i64` exponent.
+#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
+pub struct Decimal {
+    pub exponent: i64,
+    pub mantissa: u64,
+    pub negative: bool,
+    pub many_digits: bool,
 }
 
-impl Default for Decimal {
-    fn default() -> Self {
-        Self { num_digits: 0, decimal_point: 0, truncated: false, digits: [0; Self::MAX_DIGITS] }
+impl Decimal {
+    /// Detect if the float can be accurately reconstructed from native floats.
+    #[inline]
+    fn can_use_fast_path<F: RawFloat>(&self) -> bool {
+        F::MIN_EXPONENT_FAST_PATH <= self.exponent
+            && self.exponent <= F::MAX_EXPONENT_DISGUISED_FAST_PATH
+            && self.mantissa <= F::MAX_MANTISSA_FAST_PATH
+            && !self.many_digits
     }
-}
 
-impl Decimal {
-    /// The maximum number of digits required to unambiguously round a float.
-    ///
-    /// For a double-precision IEEE 754 float, this required 767 digits,
-    /// so we store the max digits + 1.
-    ///
-    /// We can exactly represent a float in radix `b` from radix 2 if
-    /// `b` is divisible by 2. This function calculates the exact number of
-    /// digits required to exactly represent that float.
-    ///
-    /// According to the "Handbook of Floating Point Arithmetic",
-    /// for IEEE754, with emin being the min exponent, p2 being the
-    /// precision, and b being the radix, the number of digits follows as:
+    /// Try turning the decimal into an exact float representation, using machine-sized integers
+    /// and floats.
     ///
-    /// `−emin + p2 + ⌊(emin + 1) log(2, b) − log(1 − 2^(−p2), b)⌋`
+    /// This is extracted into a separate function so that it can be attempted before constructing
+    /// a Decimal. This only works if both the mantissa and the exponent
+    /// can be exactly represented as a machine float, since IEE-754 guarantees
+    /// no rounding will occur.
     ///
-    /// For f32, this follows as:
-    ///     emin = -126
-    ///     p2 = 24
-    ///
-    /// For f64, this follows as:
-    ///     emin = -1022
-    ///     p2 = 53
-    ///
-    /// In Python:
-    ///     `-emin + p2 + math.floor((emin+ 1)*math.log(2, b)-math.log(1-2**(-p2), b))`
-    pub(super) const MAX_DIGITS: usize = 768;
-    /// The max digits that can be exactly represented in a 64-bit integer.
-    pub(super) const MAX_DIGITS_WITHOUT_OVERFLOW: usize = 19;
-    pub(super) const DECIMAL_POINT_RANGE: i32 = 2047;
-
-    /// Append a digit to the buffer.
-    pub(super) fn try_add_digit(&mut self, digit: u8) {
-        if self.num_digits < Self::MAX_DIGITS {
-            self.digits[self.num_digits] = digit;
-        }
-        self.num_digits += 1;
-    }
-
-    /// Trim trailing zeros from the buffer.
-    pub(super) fn trim(&mut self) {
-        // All of the following calls to `Decimal::trim` can't panic because:
-        //
-        //  1. `parse_decimal` sets `num_digits` to a max of `Decimal::MAX_DIGITS`.
-        //  2. `right_shift` sets `num_digits` to `write_index`, which is bounded by `num_digits`.
-        //  3. `left_shift` `num_digits` to a max of `Decimal::MAX_DIGITS`.
-        //
-        // Trim is only called in `right_shift` and `left_shift`.
-        debug_assert!(self.num_digits <= Self::MAX_DIGITS);
-        while self.num_digits != 0 && self.digits[self.num_digits - 1] == 0 {
-            self.num_digits -= 1;
-        }
-    }
-
-    pub(super) fn round(&self) -> u64 {
-        if self.num_digits == 0 || self.decimal_point < 0 {
-            return 0;
-        } else if self.decimal_point > 18 {
-            return 0xFFFF_FFFF_FFFF_FFFF_u64;
-        }
-        let dp = self.decimal_point as usize;
-        let mut n = 0_u64;
-        for i in 0..dp {
-            n *= 10;
-            if i < self.num_digits {
-                n += self.digits[i] as u64;
-            }
-        }
-        let mut round_up = false;
-        if dp < self.num_digits {
-            round_up = self.digits[dp] >= 5;
-            if self.digits[dp] == 5 && dp + 1 == self.num_digits {
-                round_up = self.truncated || ((dp != 0) && (1 & self.digits[dp - 1] != 0))
-            }
-        }
-        if round_up {
-            n += 1;
-        }
-        n
-    }
-
-    /// Computes decimal * 2^shift.
-    pub(super) fn left_shift(&mut self, shift: usize) {
-        if self.num_digits == 0 {
-            return;
-        }
-        let num_new_digits = number_of_digits_decimal_left_shift(self, shift);
-        let mut read_index = self.num_digits;
-        let mut write_index = self.num_digits + num_new_digits;
-        let mut n = 0_u64;
-        while read_index != 0 {
-            read_index -= 1;
-            write_index -= 1;
-            n += (self.digits[read_index] as u64) << shift;
-            let quotient = n / 10;
-            let remainder = n - (10 * quotient);
-            if write_index < Self::MAX_DIGITS {
-                self.digits[write_index] = remainder as u8;
-            } else if remainder > 0 {
-                self.truncated = true;
-            }
-            n = quotient;
-        }
-        while n > 0 {
-            write_index -= 1;
-            let quotient = n / 10;
-            let remainder = n - (10 * quotient);
-            if write_index < Self::MAX_DIGITS {
-                self.digits[write_index] = remainder as u8;
-            } else if remainder > 0 {
-                self.truncated = true;
-            }
-            n = quotient;
-        }
-        self.num_digits += num_new_digits;
-        if self.num_digits > Self::MAX_DIGITS {
-            self.num_digits = Self::MAX_DIGITS;
-        }
-        self.decimal_point += num_new_digits as i32;
-        self.trim();
-    }
-
-    /// Computes decimal * 2^-shift.
-    pub(super) fn right_shift(&mut self, shift: usize) {
-        let mut read_index = 0;
-        let mut write_index = 0;
-        let mut n = 0_u64;
-        while (n >> shift) == 0 {
-            if read_index < self.num_digits {
-                n = (10 * n) + self.digits[read_index] as u64;
-                read_index += 1;
-            } else if n == 0 {
-                return;
+    /// There is an exception: disguised fast-path cases, where we can shift
+    /// powers-of-10 from the exponent to the significant digits.
+    pub fn try_fast_path<F: RawFloat>(&self) -> Option<F> {
+        // Here we need to work around <https://github.com/rust-lang/rust/issues/114479>.
+        // The fast path crucially depends on arithmetic being rounded to the correct number of bits
+        // without any intermediate rounding. On x86 (without SSE or SSE2) this requires the precision
+        // of the x87 FPU stack to be changed so that it directly rounds to 64/32 bit.
+        // The `set_precision` function takes care of setting the precision on architectures which
+        // require setting it by changing the global state (like the control word of the x87 FPU).
+        let _cw = set_precision::<F>();
+
+        if !self.can_use_fast_path::<F>() {
+            return None;
+        }
+
+        let value = if self.exponent <= F::MAX_EXPONENT_FAST_PATH {
+            // normal fast path
+            let value = F::from_u64(self.mantissa);
+            if self.exponent < 0 {
+                value / F::pow10_fast_path((-self.exponent) as _)
             } else {
-                while (n >> shift) == 0 {
-                    n *= 10;
-                    read_index += 1;
-                }
-                break;
-            }
-        }
-        self.decimal_point -= read_index as i32 - 1;
-        if self.decimal_point < -Self::DECIMAL_POINT_RANGE {
-            // `self = Self::Default()`, but without the overhead of clearing `digits`.
-            self.num_digits = 0;
-            self.decimal_point = 0;
-            self.truncated = false;
-            return;
-        }
-        let mask = (1_u64 << shift) - 1;
-        while read_index < self.num_digits {
-            let new_digit = (n >> shift) as u8;
-            n = (10 * (n & mask)) + self.digits[read_index] as u64;
-            read_index += 1;
-            self.digits[write_index] = new_digit;
-            write_index += 1;
-        }
-        while n > 0 {
-            let new_digit = (n >> shift) as u8;
-            n = 10 * (n & mask);
-            if write_index < Self::MAX_DIGITS {
-                self.digits[write_index] = new_digit;
-                write_index += 1;
-            } else if new_digit > 0 {
-                self.truncated = true;
-            }
-        }
-        self.num_digits = write_index;
-        self.trim();
-    }
-}
-
-/// Parse a big integer representation of the float as a decimal.
-pub(super) fn parse_decimal(mut s: &[u8]) -> Decimal {
-    let mut d = Decimal::default();
-    let start = s;
-
-    while let Some((&b'0', s_next)) = s.split_first() {
-        s = s_next;
-    }
-
-    s = s.parse_digits(|digit| d.try_add_digit(digit));
-
-    if let Some((b'.', s_next)) = s.split_first() {
-        s = s_next;
-        let first = s;
-        // Skip leading zeros.
-        if d.num_digits == 0 {
-            while let Some((&b'0', s_next)) = s.split_first() {
-                s = s_next;
-            }
-        }
-        while s.len() >= 8 && d.num_digits + 8 < Decimal::MAX_DIGITS {
-            let v = s.read_u64();
-            if !is_8digits(v) {
-                break;
+                value * F::pow10_fast_path(self.exponent as _)
             }
-            d.digits[d.num_digits..].write_u64(v - 0x3030_3030_3030_3030);
-            d.num_digits += 8;
-            s = &s[8..];
-        }
-        s = s.parse_digits(|digit| d.try_add_digit(digit));
-        d.decimal_point = s.len() as i32 - first.len() as i32;
-    }
-    if d.num_digits != 0 {
-        // Ignore the trailing zeros if there are any
-        let mut n_trailing_zeros = 0;
-        for &c in start[..(start.len() - s.len())].iter().rev() {
-            if c == b'0' {
-                n_trailing_zeros += 1;
-            } else if c != b'.' {
-                break;
-            }
-        }
-        d.decimal_point += n_trailing_zeros as i32;
-        d.num_digits -= n_trailing_zeros;
-        d.decimal_point += d.num_digits as i32;
-        if d.num_digits > Decimal::MAX_DIGITS {
-            d.truncated = true;
-            d.num_digits = Decimal::MAX_DIGITS;
-        }
-    }
-    if let Some((&ch, s_next)) = s.split_first() {
-        if ch == b'e' || ch == b'E' {
-            s = s_next;
-            let mut neg_exp = false;
-            if let Some((&ch, s_next)) = s.split_first() {
-                neg_exp = ch == b'-';
-                if ch == b'-' || ch == b'+' {
-                    s = s_next;
-                }
+        } else {
+            // disguised fast path
+            let shift = self.exponent - F::MAX_EXPONENT_FAST_PATH;
+            let mantissa = self.mantissa.checked_mul(INT_POW10[shift as usize])?;
+            if mantissa > F::MAX_MANTISSA_FAST_PATH {
+                return None;
             }
-            let mut exp_num = 0_i32;
-
-            s.parse_digits(|digit| {
-                if exp_num < 0x10000 {
-                    exp_num = 10 * exp_num + digit as i32;
-                }
-            });
+            F::from_u64(mantissa) * F::pow10_fast_path(F::MAX_EXPONENT_FAST_PATH as _)
+        };
 
-            d.decimal_point += if neg_exp { -exp_num } else { exp_num };
-        }
-    }
-    for i in d.num_digits..Decimal::MAX_DIGITS_WITHOUT_OVERFLOW {
-        d.digits[i] = 0;
-    }
-    d
-}
-
-fn number_of_digits_decimal_left_shift(d: &Decimal, mut shift: usize) -> usize {
-    #[rustfmt::skip]
-    const TABLE: [u16; 65] = [
-        0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817, 0x181D, 0x2024,
-        0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067, 0x3073, 0x3080, 0x388E, 0x389C,
-        0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF, 0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169,
-        0x5180, 0x5998, 0x59B0, 0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B,
-        0x72AA, 0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC, 0x8C02,
-        0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C, 0x051C, 0x051C,
-    ];
-    #[rustfmt::skip]
-    const TABLE_POW5: [u8; 0x051C] = [
-        5, 2, 5, 1, 2, 5, 6, 2, 5, 3, 1, 2, 5, 1, 5, 6, 2, 5, 7, 8, 1, 2, 5, 3, 9, 0, 6, 2, 5, 1,
-        9, 5, 3, 1, 2, 5, 9, 7, 6, 5, 6, 2, 5, 4, 8, 8, 2, 8, 1, 2, 5, 2, 4, 4, 1, 4, 0, 6, 2, 5,
-        1, 2, 2, 0, 7, 0, 3, 1, 2, 5, 6, 1, 0, 3, 5, 1, 5, 6, 2, 5, 3, 0, 5, 1, 7, 5, 7, 8, 1, 2,
-        5, 1, 5, 2, 5, 8, 7, 8, 9, 0, 6, 2, 5, 7, 6, 2, 9, 3, 9, 4, 5, 3, 1, 2, 5, 3, 8, 1, 4, 6,
-        9, 7, 2, 6, 5, 6, 2, 5, 1, 9, 0, 7, 3, 4, 8, 6, 3, 2, 8, 1, 2, 5, 9, 5, 3, 6, 7, 4, 3, 1,
-        6, 4, 0, 6, 2, 5, 4, 7, 6, 8, 3, 7, 1, 5, 8, 2, 0, 3, 1, 2, 5, 2, 3, 8, 4, 1, 8, 5, 7, 9,
-        1, 0, 1, 5, 6, 2, 5, 1, 1, 9, 2, 0, 9, 2, 8, 9, 5, 5, 0, 7, 8, 1, 2, 5, 5, 9, 6, 0, 4, 6,
-        4, 4, 7, 7, 5, 3, 9, 0, 6, 2, 5, 2, 9, 8, 0, 2, 3, 2, 2, 3, 8, 7, 6, 9, 5, 3, 1, 2, 5, 1,
-        4, 9, 0, 1, 1, 6, 1, 1, 9, 3, 8, 4, 7, 6, 5, 6, 2, 5, 7, 4, 5, 0, 5, 8, 0, 5, 9, 6, 9, 2,
-        3, 8, 2, 8, 1, 2, 5, 3, 7, 2, 5, 2, 9, 0, 2, 9, 8, 4, 6, 1, 9, 1, 4, 0, 6, 2, 5, 1, 8, 6,
-        2, 6, 4, 5, 1, 4, 9, 2, 3, 0, 9, 5, 7, 0, 3, 1, 2, 5, 9, 3, 1, 3, 2, 2, 5, 7, 4, 6, 1, 5,
-        4, 7, 8, 5, 1, 5, 6, 2, 5, 4, 6, 5, 6, 6, 1, 2, 8, 7, 3, 0, 7, 7, 3, 9, 2, 5, 7, 8, 1, 2,
-        5, 2, 3, 2, 8, 3, 0, 6, 4, 3, 6, 5, 3, 8, 6, 9, 6, 2, 8, 9, 0, 6, 2, 5, 1, 1, 6, 4, 1, 5,
-        3, 2, 1, 8, 2, 6, 9, 3, 4, 8, 1, 4, 4, 5, 3, 1, 2, 5, 5, 8, 2, 0, 7, 6, 6, 0, 9, 1, 3, 4,
-        6, 7, 4, 0, 7, 2, 2, 6, 5, 6, 2, 5, 2, 9, 1, 0, 3, 8, 3, 0, 4, 5, 6, 7, 3, 3, 7, 0, 3, 6,
-        1, 3, 2, 8, 1, 2, 5, 1, 4, 5, 5, 1, 9, 1, 5, 2, 2, 8, 3, 6, 6, 8, 5, 1, 8, 0, 6, 6, 4, 0,
-        6, 2, 5, 7, 2, 7, 5, 9, 5, 7, 6, 1, 4, 1, 8, 3, 4, 2, 5, 9, 0, 3, 3, 2, 0, 3, 1, 2, 5, 3,
-        6, 3, 7, 9, 7, 8, 8, 0, 7, 0, 9, 1, 7, 1, 2, 9, 5, 1, 6, 6, 0, 1, 5, 6, 2, 5, 1, 8, 1, 8,
-        9, 8, 9, 4, 0, 3, 5, 4, 5, 8, 5, 6, 4, 7, 5, 8, 3, 0, 0, 7, 8, 1, 2, 5, 9, 0, 9, 4, 9, 4,
-        7, 0, 1, 7, 7, 2, 9, 2, 8, 2, 3, 7, 9, 1, 5, 0, 3, 9, 0, 6, 2, 5, 4, 5, 4, 7, 4, 7, 3, 5,
-        0, 8, 8, 6, 4, 6, 4, 1, 1, 8, 9, 5, 7, 5, 1, 9, 5, 3, 1, 2, 5, 2, 2, 7, 3, 7, 3, 6, 7, 5,
-        4, 4, 3, 2, 3, 2, 0, 5, 9, 4, 7, 8, 7, 5, 9, 7, 6, 5, 6, 2, 5, 1, 1, 3, 6, 8, 6, 8, 3, 7,
-        7, 2, 1, 6, 1, 6, 0, 2, 9, 7, 3, 9, 3, 7, 9, 8, 8, 2, 8, 1, 2, 5, 5, 6, 8, 4, 3, 4, 1, 8,
-        8, 6, 0, 8, 0, 8, 0, 1, 4, 8, 6, 9, 6, 8, 9, 9, 4, 1, 4, 0, 6, 2, 5, 2, 8, 4, 2, 1, 7, 0,
-        9, 4, 3, 0, 4, 0, 4, 0, 0, 7, 4, 3, 4, 8, 4, 4, 9, 7, 0, 7, 0, 3, 1, 2, 5, 1, 4, 2, 1, 0,
-        8, 5, 4, 7, 1, 5, 2, 0, 2, 0, 0, 3, 7, 1, 7, 4, 2, 2, 4, 8, 5, 3, 5, 1, 5, 6, 2, 5, 7, 1,
-        0, 5, 4, 2, 7, 3, 5, 7, 6, 0, 1, 0, 0, 1, 8, 5, 8, 7, 1, 1, 2, 4, 2, 6, 7, 5, 7, 8, 1, 2,
-        5, 3, 5, 5, 2, 7, 1, 3, 6, 7, 8, 8, 0, 0, 5, 0, 0, 9, 2, 9, 3, 5, 5, 6, 2, 1, 3, 3, 7, 8,
-        9, 0, 6, 2, 5, 1, 7, 7, 6, 3, 5, 6, 8, 3, 9, 4, 0, 0, 2, 5, 0, 4, 6, 4, 6, 7, 7, 8, 1, 0,
-        6, 6, 8, 9, 4, 5, 3, 1, 2, 5, 8, 8, 8, 1, 7, 8, 4, 1, 9, 7, 0, 0, 1, 2, 5, 2, 3, 2, 3, 3,
-        8, 9, 0, 5, 3, 3, 4, 4, 7, 2, 6, 5, 6, 2, 5, 4, 4, 4, 0, 8, 9, 2, 0, 9, 8, 5, 0, 0, 6, 2,
-        6, 1, 6, 1, 6, 9, 4, 5, 2, 6, 6, 7, 2, 3, 6, 3, 2, 8, 1, 2, 5, 2, 2, 2, 0, 4, 4, 6, 0, 4,
-        9, 2, 5, 0, 3, 1, 3, 0, 8, 0, 8, 4, 7, 2, 6, 3, 3, 3, 6, 1, 8, 1, 6, 4, 0, 6, 2, 5, 1, 1,
-        1, 0, 2, 2, 3, 0, 2, 4, 6, 2, 5, 1, 5, 6, 5, 4, 0, 4, 2, 3, 6, 3, 1, 6, 6, 8, 0, 9, 0, 8,
-        2, 0, 3, 1, 2, 5, 5, 5, 5, 1, 1, 1, 5, 1, 2, 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5,
-        8, 3, 4, 0, 4, 5, 4, 1, 0, 1, 5, 6, 2, 5, 2, 7, 7, 5, 5, 5, 7, 5, 6, 1, 5, 6, 2, 8, 9, 1,
-        3, 5, 1, 0, 5, 9, 0, 7, 9, 1, 7, 0, 2, 2, 7, 0, 5, 0, 7, 8, 1, 2, 5, 1, 3, 8, 7, 7, 7, 8,
-        7, 8, 0, 7, 8, 1, 4, 4, 5, 6, 7, 5, 5, 2, 9, 5, 3, 9, 5, 8, 5, 1, 1, 3, 5, 2, 5, 3, 9, 0,
-        6, 2, 5, 6, 9, 3, 8, 8, 9, 3, 9, 0, 3, 9, 0, 7, 2, 2, 8, 3, 7, 7, 6, 4, 7, 6, 9, 7, 9, 2,
-        5, 5, 6, 7, 6, 2, 6, 9, 5, 3, 1, 2, 5, 3, 4, 6, 9, 4, 4, 6, 9, 5, 1, 9, 5, 3, 6, 1, 4, 1,
-        8, 8, 8, 2, 3, 8, 4, 8, 9, 6, 2, 7, 8, 3, 8, 1, 3, 4, 7, 6, 5, 6, 2, 5, 1, 7, 3, 4, 7, 2,
-        3, 4, 7, 5, 9, 7, 6, 8, 0, 7, 0, 9, 4, 4, 1, 1, 9, 2, 4, 4, 8, 1, 3, 9, 1, 9, 0, 6, 7, 3,
-        8, 2, 8, 1, 2, 5, 8, 6, 7, 3, 6, 1, 7, 3, 7, 9, 8, 8, 4, 0, 3, 5, 4, 7, 2, 0, 5, 9, 6, 2,
-        2, 4, 0, 6, 9, 5, 9, 5, 3, 3, 6, 9, 1, 4, 0, 6, 2, 5,
-    ];
-
-    shift &= 63;
-    let x_a = TABLE[shift];
-    let x_b = TABLE[shift + 1];
-    let num_new_digits = (x_a >> 11) as _;
-    let pow5_a = (0x7FF & x_a) as usize;
-    let pow5_b = (0x7FF & x_b) as usize;
-    let pow5 = &TABLE_POW5[pow5_a..];
-    for (i, &p5) in pow5.iter().enumerate().take(pow5_b - pow5_a) {
-        if i >= d.num_digits {
-            return num_new_digits - 1;
-        } else if d.digits[i] == p5 {
-            continue;
-        } else if d.digits[i] < p5 {
-            return num_new_digits - 1;
-        } else {
-            return num_new_digits;
-        }
+        if self.negative { Some(-value) } else { Some(value) }
     }
-    num_new_digits
 }
diff --git a/library/core/src/num/dec2flt/decimal_seq.rs b/library/core/src/num/dec2flt/decimal_seq.rs
new file mode 100644
index 00000000000..de22280c001
--- /dev/null
+++ b/library/core/src/num/dec2flt/decimal_seq.rs
@@ -0,0 +1,379 @@
+//! Arbitrary-precision decimal type used by fallback algorithms.
+//!
+//! This is only used if the fast-path (native floats) and
+//! the Eisel-Lemire algorithm are unable to unambiguously
+//! determine the float.
+//!
+//! The technique used is "Simple Decimal Conversion", developed
+//! by Nigel Tao and Ken Thompson. A detailed description of the
+//! algorithm can be found in "ParseNumberF64 by Simple Decimal Conversion",
+//! available online: <https://nigeltao.github.io/blog/2020/parse-number-f64-simple.html>.
+
+use crate::num::dec2flt::common::{ByteSlice, is_8digits};
+
+/// A decimal floating-point number, represented as a sequence of decimal digits.
+#[derive(Clone, Debug, PartialEq)]
+pub struct DecimalSeq {
+    /// The number of significant digits in the decimal.
+    pub num_digits: usize,
+    /// The offset of the decimal point in the significant digits.
+    pub decimal_point: i32,
+    /// If the number of significant digits stored in the decimal is truncated.
+    pub truncated: bool,
+    /// Buffer of the raw digits, in the range [0, 9].
+    pub digits: [u8; Self::MAX_DIGITS],
+}
+
+impl Default for DecimalSeq {
+    fn default() -> Self {
+        Self { num_digits: 0, decimal_point: 0, truncated: false, digits: [0; Self::MAX_DIGITS] }
+    }
+}
+
+impl DecimalSeq {
+    /// The maximum number of digits required to unambiguously round up to a 64-bit float.
+    ///
+    /// For an IEEE 754 binary64 float, this required 767 digits. So we store the max digits + 1.
+    ///
+    /// We can exactly represent a float in radix `b` from radix 2 if
+    /// `b` is divisible by 2. This function calculates the exact number of
+    /// digits required to exactly represent that float.
+    ///
+    /// According to the "Handbook of Floating Point Arithmetic",
+    /// for IEEE754, with `emin` being the min exponent, `p2` being the
+    /// precision, and `b` being the radix, the number of digits follows as:
+    ///
+    /// `−emin + p2 + ⌊(emin + 1) log(2, b) − log(1 − 2^(−p2), b)⌋`
+    ///
+    /// For f32, this follows as:
+    ///     emin = -126
+    ///     p2 = 24
+    ///
+    /// For f64, this follows as:
+    ///     emin = -1022
+    ///     p2 = 53
+    ///
+    /// In Python:
+    ///     `-emin + p2 + math.floor((emin+ 1)*math.log(2, b)-math.log(1-2**(-p2), b))`
+    pub const MAX_DIGITS: usize = 768;
+
+    /// The max decimal digits that can be exactly represented in a 64-bit integer.
+    pub(super) const MAX_DIGITS_WITHOUT_OVERFLOW: usize = 19;
+    pub(super) const DECIMAL_POINT_RANGE: i32 = 2047;
+
+    /// Append a digit to the buffer if it fits.
+    // FIXME(tgross35): it may be better for this to return an option
+    // FIXME(tgross35): incrementing the digit counter even if we don't push anything
+    // seems incorrect.
+    pub(super) fn try_add_digit(&mut self, digit: u8) {
+        if self.num_digits < Self::MAX_DIGITS {
+            self.digits[self.num_digits] = digit;
+        }
+        self.num_digits += 1;
+    }
+
+    /// Trim trailing zeros from the buffer.
+    // FIXME(tgross35): this could be `.rev().position()` if perf is okay
+    pub fn trim(&mut self) {
+        // All of the following calls to `DecimalSeq::trim` can't panic because:
+        //
+        //  1. `parse_decimal` sets `num_digits` to a max of `DecimalSeq::MAX_DIGITS`.
+        //  2. `right_shift` sets `num_digits` to `write_index`, which is bounded by `num_digits`.
+        //  3. `left_shift` `num_digits` to a max of `DecimalSeq::MAX_DIGITS`.
+        //
+        // Trim is only called in `right_shift` and `left_shift`.
+        debug_assert!(self.num_digits <= Self::MAX_DIGITS);
+        while self.num_digits != 0 && self.digits[self.num_digits - 1] == 0 {
+            self.num_digits -= 1;
+        }
+    }
+
+    pub(super) fn round(&self) -> u64 {
+        if self.num_digits == 0 || self.decimal_point < 0 {
+            return 0;
+        } else if self.decimal_point >= Self::MAX_DIGITS_WITHOUT_OVERFLOW as i32 {
+            return 0xFFFF_FFFF_FFFF_FFFF_u64;
+        }
+
+        let dp = self.decimal_point as usize;
+        let mut n = 0_u64;
+
+        for i in 0..dp {
+            n *= 10;
+            if i < self.num_digits {
+                n += self.digits[i] as u64;
+            }
+        }
+
+        let mut round_up = false;
+
+        if dp < self.num_digits {
+            round_up = self.digits[dp] >= 5;
+            if self.digits[dp] == 5 && dp + 1 == self.num_digits {
+                round_up = self.truncated || ((dp != 0) && (1 & self.digits[dp - 1] != 0))
+            }
+        }
+
+        if round_up {
+            n += 1;
+        }
+        n
+    }
+
+    /// Computes decimal * 2^shift.
+    pub(super) fn left_shift(&mut self, shift: usize) {
+        if self.num_digits == 0 {
+            return;
+        }
+        let num_new_digits = number_of_digits_decimal_left_shift(self, shift);
+        let mut read_index = self.num_digits;
+        let mut write_index = self.num_digits + num_new_digits;
+        let mut n = 0_u64;
+
+        while read_index != 0 {
+            read_index -= 1;
+            write_index -= 1;
+            n += (self.digits[read_index] as u64) << shift;
+            let quotient = n / 10;
+            let remainder = n - (10 * quotient);
+            if write_index < Self::MAX_DIGITS {
+                self.digits[write_index] = remainder as u8;
+            } else if remainder > 0 {
+                self.truncated = true;
+            }
+            n = quotient;
+        }
+
+        while n > 0 {
+            write_index -= 1;
+            let quotient = n / 10;
+            let remainder = n - (10 * quotient);
+            if write_index < Self::MAX_DIGITS {
+                self.digits[write_index] = remainder as u8;
+            } else if remainder > 0 {
+                self.truncated = true;
+            }
+            n = quotient;
+        }
+
+        self.num_digits += num_new_digits;
+
+        if self.num_digits > Self::MAX_DIGITS {
+            self.num_digits = Self::MAX_DIGITS;
+        }
+
+        self.decimal_point += num_new_digits as i32;
+        self.trim();
+    }
+
+    /// Computes decimal * 2^-shift.
+    pub(super) fn right_shift(&mut self, shift: usize) {
+        let mut read_index = 0;
+        let mut write_index = 0;
+        let mut n = 0_u64;
+        while (n >> shift) == 0 {
+            if read_index < self.num_digits {
+                n = (10 * n) + self.digits[read_index] as u64;
+                read_index += 1;
+            } else if n == 0 {
+                return;
+            } else {
+                while (n >> shift) == 0 {
+                    n *= 10;
+                    read_index += 1;
+                }
+                break;
+            }
+        }
+        self.decimal_point -= read_index as i32 - 1;
+        if self.decimal_point < -Self::DECIMAL_POINT_RANGE {
+            // `self = Self::Default()`, but without the overhead of clearing `digits`.
+            self.num_digits = 0;
+            self.decimal_point = 0;
+            self.truncated = false;
+            return;
+        }
+        let mask = (1_u64 << shift) - 1;
+        while read_index < self.num_digits {
+            let new_digit = (n >> shift) as u8;
+            n = (10 * (n & mask)) + self.digits[read_index] as u64;
+            read_index += 1;
+            self.digits[write_index] = new_digit;
+            write_index += 1;
+        }
+        while n > 0 {
+            let new_digit = (n >> shift) as u8;
+            n = 10 * (n & mask);
+            if write_index < Self::MAX_DIGITS {
+                self.digits[write_index] = new_digit;
+                write_index += 1;
+            } else if new_digit > 0 {
+                self.truncated = true;
+            }
+        }
+        self.num_digits = write_index;
+        self.trim();
+    }
+}
+
+/// Parse a big integer representation of the float as a decimal.
+pub fn parse_decimal_seq(mut s: &[u8]) -> DecimalSeq {
+    let mut d = DecimalSeq::default();
+    let start = s;
+
+    while let Some((&b'0', s_next)) = s.split_first() {
+        s = s_next;
+    }
+
+    s = s.parse_digits(|digit| d.try_add_digit(digit));
+
+    if let Some((b'.', s_next)) = s.split_first() {
+        s = s_next;
+        let first = s;
+        // Skip leading zeros.
+        if d.num_digits == 0 {
+            while let Some((&b'0', s_next)) = s.split_first() {
+                s = s_next;
+            }
+        }
+        while s.len() >= 8 && d.num_digits + 8 < DecimalSeq::MAX_DIGITS {
+            let v = s.read_u64();
+            if !is_8digits(v) {
+                break;
+            }
+            d.digits[d.num_digits..].write_u64(v - 0x3030_3030_3030_3030);
+            d.num_digits += 8;
+            s = &s[8..];
+        }
+        s = s.parse_digits(|digit| d.try_add_digit(digit));
+        d.decimal_point = s.len() as i32 - first.len() as i32;
+    }
+
+    if d.num_digits != 0 {
+        // Ignore the trailing zeros if there are any
+        let mut n_trailing_zeros = 0;
+        for &c in start[..(start.len() - s.len())].iter().rev() {
+            if c == b'0' {
+                n_trailing_zeros += 1;
+            } else if c != b'.' {
+                break;
+            }
+        }
+        d.decimal_point += n_trailing_zeros as i32;
+        d.num_digits -= n_trailing_zeros;
+        d.decimal_point += d.num_digits as i32;
+        if d.num_digits > DecimalSeq::MAX_DIGITS {
+            d.truncated = true;
+            d.num_digits = DecimalSeq::MAX_DIGITS;
+        }
+    }
+
+    if let Some((&ch, s_next)) = s.split_first() {
+        if ch == b'e' || ch == b'E' {
+            s = s_next;
+            let mut neg_exp = false;
+            if let Some((&ch, s_next)) = s.split_first() {
+                neg_exp = ch == b'-';
+                if ch == b'-' || ch == b'+' {
+                    s = s_next;
+                }
+            }
+            let mut exp_num = 0_i32;
+
+            s.parse_digits(|digit| {
+                if exp_num < 0x10000 {
+                    exp_num = 10 * exp_num + digit as i32;
+                }
+            });
+
+            d.decimal_point += if neg_exp { -exp_num } else { exp_num };
+        }
+    }
+
+    for i in d.num_digits..DecimalSeq::MAX_DIGITS_WITHOUT_OVERFLOW {
+        d.digits[i] = 0;
+    }
+
+    d
+}
+
+fn number_of_digits_decimal_left_shift(d: &DecimalSeq, mut shift: usize) -> usize {
+    #[rustfmt::skip]
+    const TABLE: [u16; 65] = [
+        0x0000, 0x0800, 0x0801, 0x0803, 0x1006, 0x1009, 0x100D, 0x1812, 0x1817, 0x181D, 0x2024,
+        0x202B, 0x2033, 0x203C, 0x2846, 0x2850, 0x285B, 0x3067, 0x3073, 0x3080, 0x388E, 0x389C,
+        0x38AB, 0x38BB, 0x40CC, 0x40DD, 0x40EF, 0x4902, 0x4915, 0x4929, 0x513E, 0x5153, 0x5169,
+        0x5180, 0x5998, 0x59B0, 0x59C9, 0x61E3, 0x61FD, 0x6218, 0x6A34, 0x6A50, 0x6A6D, 0x6A8B,
+        0x72AA, 0x72C9, 0x72E9, 0x7B0A, 0x7B2B, 0x7B4D, 0x8370, 0x8393, 0x83B7, 0x83DC, 0x8C02,
+        0x8C28, 0x8C4F, 0x9477, 0x949F, 0x94C8, 0x9CF2, 0x051C, 0x051C, 0x051C, 0x051C,
+    ];
+    #[rustfmt::skip]
+    const TABLE_POW5: [u8; 0x051C] = [
+        5, 2, 5, 1, 2, 5, 6, 2, 5, 3, 1, 2, 5, 1, 5, 6, 2, 5, 7, 8, 1, 2, 5, 3, 9, 0, 6, 2, 5, 1,
+        9, 5, 3, 1, 2, 5, 9, 7, 6, 5, 6, 2, 5, 4, 8, 8, 2, 8, 1, 2, 5, 2, 4, 4, 1, 4, 0, 6, 2, 5,
+        1, 2, 2, 0, 7, 0, 3, 1, 2, 5, 6, 1, 0, 3, 5, 1, 5, 6, 2, 5, 3, 0, 5, 1, 7, 5, 7, 8, 1, 2,
+        5, 1, 5, 2, 5, 8, 7, 8, 9, 0, 6, 2, 5, 7, 6, 2, 9, 3, 9, 4, 5, 3, 1, 2, 5, 3, 8, 1, 4, 6,
+        9, 7, 2, 6, 5, 6, 2, 5, 1, 9, 0, 7, 3, 4, 8, 6, 3, 2, 8, 1, 2, 5, 9, 5, 3, 6, 7, 4, 3, 1,
+        6, 4, 0, 6, 2, 5, 4, 7, 6, 8, 3, 7, 1, 5, 8, 2, 0, 3, 1, 2, 5, 2, 3, 8, 4, 1, 8, 5, 7, 9,
+        1, 0, 1, 5, 6, 2, 5, 1, 1, 9, 2, 0, 9, 2, 8, 9, 5, 5, 0, 7, 8, 1, 2, 5, 5, 9, 6, 0, 4, 6,
+        4, 4, 7, 7, 5, 3, 9, 0, 6, 2, 5, 2, 9, 8, 0, 2, 3, 2, 2, 3, 8, 7, 6, 9, 5, 3, 1, 2, 5, 1,
+        4, 9, 0, 1, 1, 6, 1, 1, 9, 3, 8, 4, 7, 6, 5, 6, 2, 5, 7, 4, 5, 0, 5, 8, 0, 5, 9, 6, 9, 2,
+        3, 8, 2, 8, 1, 2, 5, 3, 7, 2, 5, 2, 9, 0, 2, 9, 8, 4, 6, 1, 9, 1, 4, 0, 6, 2, 5, 1, 8, 6,
+        2, 6, 4, 5, 1, 4, 9, 2, 3, 0, 9, 5, 7, 0, 3, 1, 2, 5, 9, 3, 1, 3, 2, 2, 5, 7, 4, 6, 1, 5,
+        4, 7, 8, 5, 1, 5, 6, 2, 5, 4, 6, 5, 6, 6, 1, 2, 8, 7, 3, 0, 7, 7, 3, 9, 2, 5, 7, 8, 1, 2,
+        5, 2, 3, 2, 8, 3, 0, 6, 4, 3, 6, 5, 3, 8, 6, 9, 6, 2, 8, 9, 0, 6, 2, 5, 1, 1, 6, 4, 1, 5,
+        3, 2, 1, 8, 2, 6, 9, 3, 4, 8, 1, 4, 4, 5, 3, 1, 2, 5, 5, 8, 2, 0, 7, 6, 6, 0, 9, 1, 3, 4,
+        6, 7, 4, 0, 7, 2, 2, 6, 5, 6, 2, 5, 2, 9, 1, 0, 3, 8, 3, 0, 4, 5, 6, 7, 3, 3, 7, 0, 3, 6,
+        1, 3, 2, 8, 1, 2, 5, 1, 4, 5, 5, 1, 9, 1, 5, 2, 2, 8, 3, 6, 6, 8, 5, 1, 8, 0, 6, 6, 4, 0,
+        6, 2, 5, 7, 2, 7, 5, 9, 5, 7, 6, 1, 4, 1, 8, 3, 4, 2, 5, 9, 0, 3, 3, 2, 0, 3, 1, 2, 5, 3,
+        6, 3, 7, 9, 7, 8, 8, 0, 7, 0, 9, 1, 7, 1, 2, 9, 5, 1, 6, 6, 0, 1, 5, 6, 2, 5, 1, 8, 1, 8,
+        9, 8, 9, 4, 0, 3, 5, 4, 5, 8, 5, 6, 4, 7, 5, 8, 3, 0, 0, 7, 8, 1, 2, 5, 9, 0, 9, 4, 9, 4,
+        7, 0, 1, 7, 7, 2, 9, 2, 8, 2, 3, 7, 9, 1, 5, 0, 3, 9, 0, 6, 2, 5, 4, 5, 4, 7, 4, 7, 3, 5,
+        0, 8, 8, 6, 4, 6, 4, 1, 1, 8, 9, 5, 7, 5, 1, 9, 5, 3, 1, 2, 5, 2, 2, 7, 3, 7, 3, 6, 7, 5,
+        4, 4, 3, 2, 3, 2, 0, 5, 9, 4, 7, 8, 7, 5, 9, 7, 6, 5, 6, 2, 5, 1, 1, 3, 6, 8, 6, 8, 3, 7,
+        7, 2, 1, 6, 1, 6, 0, 2, 9, 7, 3, 9, 3, 7, 9, 8, 8, 2, 8, 1, 2, 5, 5, 6, 8, 4, 3, 4, 1, 8,
+        8, 6, 0, 8, 0, 8, 0, 1, 4, 8, 6, 9, 6, 8, 9, 9, 4, 1, 4, 0, 6, 2, 5, 2, 8, 4, 2, 1, 7, 0,
+        9, 4, 3, 0, 4, 0, 4, 0, 0, 7, 4, 3, 4, 8, 4, 4, 9, 7, 0, 7, 0, 3, 1, 2, 5, 1, 4, 2, 1, 0,
+        8, 5, 4, 7, 1, 5, 2, 0, 2, 0, 0, 3, 7, 1, 7, 4, 2, 2, 4, 8, 5, 3, 5, 1, 5, 6, 2, 5, 7, 1,
+        0, 5, 4, 2, 7, 3, 5, 7, 6, 0, 1, 0, 0, 1, 8, 5, 8, 7, 1, 1, 2, 4, 2, 6, 7, 5, 7, 8, 1, 2,
+        5, 3, 5, 5, 2, 7, 1, 3, 6, 7, 8, 8, 0, 0, 5, 0, 0, 9, 2, 9, 3, 5, 5, 6, 2, 1, 3, 3, 7, 8,
+        9, 0, 6, 2, 5, 1, 7, 7, 6, 3, 5, 6, 8, 3, 9, 4, 0, 0, 2, 5, 0, 4, 6, 4, 6, 7, 7, 8, 1, 0,
+        6, 6, 8, 9, 4, 5, 3, 1, 2, 5, 8, 8, 8, 1, 7, 8, 4, 1, 9, 7, 0, 0, 1, 2, 5, 2, 3, 2, 3, 3,
+        8, 9, 0, 5, 3, 3, 4, 4, 7, 2, 6, 5, 6, 2, 5, 4, 4, 4, 0, 8, 9, 2, 0, 9, 8, 5, 0, 0, 6, 2,
+        6, 1, 6, 1, 6, 9, 4, 5, 2, 6, 6, 7, 2, 3, 6, 3, 2, 8, 1, 2, 5, 2, 2, 2, 0, 4, 4, 6, 0, 4,
+        9, 2, 5, 0, 3, 1, 3, 0, 8, 0, 8, 4, 7, 2, 6, 3, 3, 3, 6, 1, 8, 1, 6, 4, 0, 6, 2, 5, 1, 1,
+        1, 0, 2, 2, 3, 0, 2, 4, 6, 2, 5, 1, 5, 6, 5, 4, 0, 4, 2, 3, 6, 3, 1, 6, 6, 8, 0, 9, 0, 8,
+        2, 0, 3, 1, 2, 5, 5, 5, 5, 1, 1, 1, 5, 1, 2, 3, 1, 2, 5, 7, 8, 2, 7, 0, 2, 1, 1, 8, 1, 5,
+        8, 3, 4, 0, 4, 5, 4, 1, 0, 1, 5, 6, 2, 5, 2, 7, 7, 5, 5, 5, 7, 5, 6, 1, 5, 6, 2, 8, 9, 1,
+        3, 5, 1, 0, 5, 9, 0, 7, 9, 1, 7, 0, 2, 2, 7, 0, 5, 0, 7, 8, 1, 2, 5, 1, 3, 8, 7, 7, 7, 8,
+        7, 8, 0, 7, 8, 1, 4, 4, 5, 6, 7, 5, 5, 2, 9, 5, 3, 9, 5, 8, 5, 1, 1, 3, 5, 2, 5, 3, 9, 0,
+        6, 2, 5, 6, 9, 3, 8, 8, 9, 3, 9, 0, 3, 9, 0, 7, 2, 2, 8, 3, 7, 7, 6, 4, 7, 6, 9, 7, 9, 2,
+        5, 5, 6, 7, 6, 2, 6, 9, 5, 3, 1, 2, 5, 3, 4, 6, 9, 4, 4, 6, 9, 5, 1, 9, 5, 3, 6, 1, 4, 1,
+        8, 8, 8, 2, 3, 8, 4, 8, 9, 6, 2, 7, 8, 3, 8, 1, 3, 4, 7, 6, 5, 6, 2, 5, 1, 7, 3, 4, 7, 2,
+        3, 4, 7, 5, 9, 7, 6, 8, 0, 7, 0, 9, 4, 4, 1, 1, 9, 2, 4, 4, 8, 1, 3, 9, 1, 9, 0, 6, 7, 3,
+        8, 2, 8, 1, 2, 5, 8, 6, 7, 3, 6, 1, 7, 3, 7, 9, 8, 8, 4, 0, 3, 5, 4, 7, 2, 0, 5, 9, 6, 2,
+        2, 4, 0, 6, 9, 5, 9, 5, 3, 3, 6, 9, 1, 4, 0, 6, 2, 5,
+    ];
+
+    shift &= 63;
+    let x_a = TABLE[shift];
+    let x_b = TABLE[shift + 1];
+    let num_new_digits = (x_a >> 11) as _;
+    let pow5_a = (0x7FF & x_a) as usize;
+    let pow5_b = (0x7FF & x_b) as usize;
+    let pow5 = &TABLE_POW5[pow5_a..];
+
+    for (i, &p5) in pow5.iter().enumerate().take(pow5_b - pow5_a) {
+        if i >= d.num_digits {
+            return num_new_digits - 1;
+        } else if d.digits[i] == p5 {
+            continue;
+        } else if d.digits[i] < p5 {
+            return num_new_digits - 1;
+        } else {
+            return num_new_digits;
+        }
+    }
+
+    num_new_digits
+}
diff --git a/library/core/src/num/dec2flt/float.rs b/library/core/src/num/dec2flt/float.rs
index da57aa9a546..b8a28a67569 100644
--- a/library/core/src/num/dec2flt/float.rs
+++ b/library/core/src/num/dec2flt/float.rs
@@ -1,14 +1,57 @@
 //! Helper trait for generic float types.
 
+use core::f64;
+
 use crate::fmt::{Debug, LowerExp};
 use crate::num::FpCategory;
-use crate::ops::{Add, Div, Mul, Neg};
+use crate::ops::{self, Add, Div, Mul, Neg};
+
+/// Lossy `as` casting between two types.
+pub trait CastInto<T: Copy>: Copy {
+    fn cast(self) -> T;
+}
+
+/// Collection of traits that allow us to be generic over integer size.
+pub trait Integer:
+    Sized
+    + Clone
+    + Copy
+    + Debug
+    + ops::Shr<u32, Output = Self>
+    + ops::Shl<u32, Output = Self>
+    + ops::BitAnd<Output = Self>
+    + ops::BitOr<Output = Self>
+    + PartialEq
+    + CastInto<i16>
+{
+    const ZERO: Self;
+    const ONE: Self;
+}
+
+macro_rules! int {
+    ($($ty:ty),+) => {
+        $(
+            impl CastInto<i16> for $ty {
+                fn cast(self) -> i16 {
+                    self as i16
+                }
+            }
+
+            impl Integer for $ty {
+                const ZERO: Self = 0;
+                const ONE: Self = 1;
+            }
+        )+
+    }
+}
+
+int!(u32, u64);
 
-/// A helper trait to avoid duplicating basically all the conversion code for `f32` and `f64`.
+/// A helper trait to avoid duplicating basically all the conversion code for IEEE floats.
 ///
 /// See the parent module's doc comment for why this is necessary.
 ///
-/// Should **never ever** be implemented for other types or be used outside the dec2flt module.
+/// Should **never ever** be implemented for other types or be used outside the `dec2flt` module.
 #[doc(hidden)]
 pub trait RawFloat:
     Sized
@@ -24,62 +67,107 @@ pub trait RawFloat:
     + Copy
     + Debug
 {
+    /// The unsigned integer with the same size as the float
+    type Int: Integer + Into<u64>;
+
+    /* general constants */
+
     const INFINITY: Self;
     const NEG_INFINITY: Self;
     const NAN: Self;
     const NEG_NAN: Self;
 
-    /// The number of bits in the significand, *excluding* the hidden bit.
-    const MANTISSA_EXPLICIT_BITS: usize;
-
-    // Round-to-even only happens for negative values of q
-    // when q ≥ −4 in the 64-bit case and when q ≥ −17 in
-    // the 32-bitcase.
-    //
-    // When q ≥ 0,we have that 5^q ≤ 2m+1. In the 64-bit case,we
-    // have 5^q ≤ 2m+1 ≤ 2^54 or q ≤ 23. In the 32-bit case,we have
-    // 5^q ≤ 2m+1 ≤ 2^25 or q ≤ 10.
-    //
-    // When q < 0, we have w ≥ (2m+1)×5^−q. We must have that w < 2^64
-    // so (2m+1)×5^−q < 2^64. We have that 2m+1 > 2^53 (64-bit case)
-    // or 2m+1 > 2^24 (32-bit case). Hence,we must have 2^53×5^−q < 2^64
-    // (64-bit) and 2^24×5^−q < 2^64 (32-bit). Hence we have 5^−q < 2^11
-    // or q ≥ −4 (64-bit case) and 5^−q < 2^40 or q ≥ −17 (32-bitcase).
-    //
-    // Thus we have that we only need to round ties to even when
-    // we have that q ∈ [−4,23](in the 64-bit case) or q∈[−17,10]
-    // (in the 32-bit case). In both cases,the power of five(5^|q|)
-    // fits in a 64-bit word.
-    const MIN_EXPONENT_ROUND_TO_EVEN: i32;
-    const MAX_EXPONENT_ROUND_TO_EVEN: i32;
+    /// Bit width of the float
+    const BITS: u32;
 
-    // Minimum exponent that for a fast path case, or `-⌊(MANTISSA_EXPLICIT_BITS+1)/log2(5)⌋`
-    const MIN_EXPONENT_FAST_PATH: i64;
+    /// The number of bits in the significand, *including* the hidden bit.
+    const SIG_TOTAL_BITS: u32;
 
-    // Maximum exponent that for a fast path case, or `⌊(MANTISSA_EXPLICIT_BITS+1)/log2(5)⌋`
-    const MAX_EXPONENT_FAST_PATH: i64;
+    const EXP_MASK: Self::Int;
+    const SIG_MASK: Self::Int;
 
-    // Maximum exponent that can be represented for a disguised-fast path case.
-    // This is `MAX_EXPONENT_FAST_PATH + ⌊(MANTISSA_EXPLICIT_BITS+1)/log2(10)⌋`
-    const MAX_EXPONENT_DISGUISED_FAST_PATH: i64;
-
-    // Minimum exponent value `-(1 << (EXP_BITS - 1)) + 1`.
-    const MINIMUM_EXPONENT: i32;
+    /// The number of bits in the significand, *excluding* the hidden bit.
+    const SIG_BITS: u32 = Self::SIG_TOTAL_BITS - 1;
+
+    /// Number of bits in the exponent.
+    const EXP_BITS: u32 = Self::BITS - Self::SIG_BITS - 1;
+
+    /// The saturated (maximum bitpattern) value of the exponent, i.e. the infinite
+    /// representation.
+    ///
+    /// This shifted fully right, use `EXP_MASK` for the shifted value.
+    const EXP_SAT: u32 = (1 << Self::EXP_BITS) - 1;
+
+    /// Signed version of `EXP_SAT` since we convert a lot.
+    const INFINITE_POWER: i32 = Self::EXP_SAT as i32;
+
+    /// The exponent bias value. This is also the maximum value of the exponent.
+    const EXP_BIAS: u32 = Self::EXP_SAT >> 1;
+
+    /// Minimum exponent value of normal values.
+    const EXP_MIN: i32 = -(Self::EXP_BIAS as i32 - 1);
+
+    /// Round-to-even only happens for negative values of q
+    /// when q ≥ −4 in the 64-bit case and when q ≥ −17 in
+    /// the 32-bitcase.
+    ///
+    /// When q ≥ 0,we have that 5^q ≤ 2m+1. In the 64-bit case,we
+    /// have 5^q ≤ 2m+1 ≤ 2^54 or q ≤ 23. In the 32-bit case,we have
+    /// 5^q ≤ 2m+1 ≤ 2^25 or q ≤ 10.
+    ///
+    /// When q < 0, we have w ≥ (2m+1)×5^−q. We must have that w < 2^64
+    /// so (2m+1)×5^−q < 2^64. We have that 2m+1 > 2^53 (64-bit case)
+    /// or 2m+1 > 2^24 (32-bit case). Hence,we must have 2^53×5^−q < 2^64
+    /// (64-bit) and 2^24×5^−q < 2^64 (32-bit). Hence we have 5^−q < 2^11
+    /// or q ≥ −4 (64-bit case) and 5^−q < 2^40 or q ≥ −17 (32-bitcase).
+    ///
+    /// Thus we have that we only need to round ties to even when
+    /// we have that q ∈ [−4,23](in the 64-bit case) or q∈[−17,10]
+    /// (in the 32-bit case). In both cases,the power of five(5^|q|)
+    /// fits in a 64-bit word.
+    const MIN_EXPONENT_ROUND_TO_EVEN: i32;
+    const MAX_EXPONENT_ROUND_TO_EVEN: i32;
 
-    // Largest exponent value `(1 << EXP_BITS) - 1`.
-    const INFINITE_POWER: i32;
+    /* limits related to Fast pathing */
+
+    /// Largest decimal exponent for a non-infinite value.
+    ///
+    /// This is the max exponent in binary converted to the max exponent in decimal. Allows fast
+    /// pathing anything larger than `10^LARGEST_POWER_OF_TEN`, which will round to infinity.
+    const LARGEST_POWER_OF_TEN: i32 = {
+        let largest_pow2 = Self::EXP_BIAS + 1;
+        pow2_to_pow10(largest_pow2 as i64) as i32
+    };
+
+    /// Smallest decimal exponent for a non-zero value. This allows for fast pathing anything
+    /// smaller than `10^SMALLEST_POWER_OF_TEN`, which will round to zero.
+    ///
+    /// The smallest power of ten is represented by `⌊log10(2^-n / (2^64 - 1))⌋`, where `n` is
+    /// the smallest power of two. The `2^64 - 1)` denomenator comes from the number of values
+    /// that are representable by the intermediate storage format. I don't actually know _why_
+    /// the storage format is relevant here.
+    ///
+    /// The values may be calculated using the formula. Unfortunately we cannot calculate them at
+    /// compile time since intermediates exceed the range of an `f64`.
+    const SMALLEST_POWER_OF_TEN: i32;
 
-    // Index (in bits) of the sign.
-    const SIGN_INDEX: usize;
+    /// Maximum exponent for a fast path case, or `⌊(SIG_BITS+1)/log2(5)⌋`
+    // assuming FLT_EVAL_METHOD = 0
+    const MAX_EXPONENT_FAST_PATH: i64 = {
+        let log2_5 = f64::consts::LOG2_10 - 1.0;
+        (Self::SIG_TOTAL_BITS as f64 / log2_5) as i64
+    };
 
-    // Smallest decimal exponent for a non-zero value.
-    const SMALLEST_POWER_OF_TEN: i32;
+    /// Minimum exponent for a fast path case, or `-⌊(SIG_BITS+1)/log2(5)⌋`
+    const MIN_EXPONENT_FAST_PATH: i64 = -Self::MAX_EXPONENT_FAST_PATH;
 
-    // Largest decimal exponent for a non-infinite value.
-    const LARGEST_POWER_OF_TEN: i32;
+    /// Maximum exponent that can be represented for a disguised-fast path case.
+    /// This is `MAX_EXPONENT_FAST_PATH + ⌊(SIG_BITS+1)/log2(10)⌋`
+    const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 =
+        Self::MAX_EXPONENT_FAST_PATH + (Self::SIG_TOTAL_BITS as f64 / f64::consts::LOG2_10) as i64;
 
-    // Maximum mantissa for the fast-path (`1 << 53` for f64).
-    const MAX_MANTISSA_FAST_PATH: u64 = 2_u64 << Self::MANTISSA_EXPLICIT_BITS;
+    /// Maximum mantissa for the fast-path (`1 << 53` for f64).
+    const MAX_MANTISSA_FAST_PATH: u64 = 1 << Self::SIG_TOTAL_BITS;
 
     /// Converts integer into float through an as cast.
     /// This is only called in the fast-path algorithm, and therefore
@@ -96,27 +184,51 @@ pub trait RawFloat:
     /// Returns the category that this number falls into.
     fn classify(self) -> FpCategory;
 
+    /// Transmute to the integer representation
+    fn to_bits(self) -> Self::Int;
+
     /// Returns the mantissa, exponent and sign as integers.
-    fn integer_decode(self) -> (u64, i16, i8);
+    ///
+    /// That is, this returns `(m, p, s)` such that `s * m * 2^p` represents the original float.
+    /// For 0, the exponent will be `-(EXP_BIAS + SIG_BITS`, which is the
+    /// minimum subnormal power.
+    fn integer_decode(self) -> (u64, i16, i8) {
+        let bits = self.to_bits();
+        let sign: i8 = if bits >> (Self::BITS - 1) == Self::Int::ZERO { 1 } else { -1 };
+        let mut exponent: i16 = ((bits & Self::EXP_MASK) >> Self::SIG_BITS).cast();
+        let mantissa = if exponent == 0 {
+            (bits & Self::SIG_MASK) << 1
+        } else {
+            (bits & Self::SIG_MASK) | (Self::Int::ONE << Self::SIG_BITS)
+        };
+        // Exponent bias + mantissa shift
+        exponent -= (Self::EXP_BIAS + Self::SIG_BITS) as i16;
+        (mantissa.into(), exponent, sign)
+    }
+}
+
+/// Solve for `b` in `10^b = 2^a`
+const fn pow2_to_pow10(a: i64) -> i64 {
+    let res = (a as f64) / f64::consts::LOG2_10;
+    res as i64
 }
 
 impl RawFloat for f32 {
+    type Int = u32;
+
     const INFINITY: Self = f32::INFINITY;
     const NEG_INFINITY: Self = f32::NEG_INFINITY;
     const NAN: Self = f32::NAN;
     const NEG_NAN: Self = -f32::NAN;
 
-    const MANTISSA_EXPLICIT_BITS: usize = 23;
+    const BITS: u32 = 32;
+    const SIG_TOTAL_BITS: u32 = Self::MANTISSA_DIGITS;
+    const EXP_MASK: Self::Int = Self::EXP_MASK;
+    const SIG_MASK: Self::Int = Self::MAN_MASK;
+
     const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -17;
     const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 10;
-    const MIN_EXPONENT_FAST_PATH: i64 = -10; // assuming FLT_EVAL_METHOD = 0
-    const MAX_EXPONENT_FAST_PATH: i64 = 10;
-    const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = 17;
-    const MINIMUM_EXPONENT: i32 = -127;
-    const INFINITE_POWER: i32 = 0xFF;
-    const SIGN_INDEX: usize = 31;
     const SMALLEST_POWER_OF_TEN: i32 = -65;
-    const LARGEST_POWER_OF_TEN: i32 = 38;
 
     #[inline]
     fn from_u64(v: u64) -> Self {
@@ -136,16 +248,8 @@ impl RawFloat for f32 {
         TABLE[exponent & 15]
     }
 
-    /// Returns the mantissa, exponent and sign as integers.
-    fn integer_decode(self) -> (u64, i16, i8) {
-        let bits = self.to_bits();
-        let sign: i8 = if bits >> 31 == 0 { 1 } else { -1 };
-        let mut exponent: i16 = ((bits >> 23) & 0xff) as i16;
-        let mantissa =
-            if exponent == 0 { (bits & 0x7fffff) << 1 } else { (bits & 0x7fffff) | 0x800000 };
-        // Exponent bias + mantissa shift
-        exponent -= 127 + 23;
-        (mantissa as u64, exponent, sign)
+    fn to_bits(self) -> Self::Int {
+        self.to_bits()
     }
 
     fn classify(self) -> FpCategory {
@@ -154,22 +258,21 @@ impl RawFloat for f32 {
 }
 
 impl RawFloat for f64 {
-    const INFINITY: Self = f64::INFINITY;
-    const NEG_INFINITY: Self = f64::NEG_INFINITY;
-    const NAN: Self = f64::NAN;
-    const NEG_NAN: Self = -f64::NAN;
+    type Int = u64;
+
+    const INFINITY: Self = Self::INFINITY;
+    const NEG_INFINITY: Self = Self::NEG_INFINITY;
+    const NAN: Self = Self::NAN;
+    const NEG_NAN: Self = -Self::NAN;
+
+    const BITS: u32 = 64;
+    const SIG_TOTAL_BITS: u32 = Self::MANTISSA_DIGITS;
+    const EXP_MASK: Self::Int = Self::EXP_MASK;
+    const SIG_MASK: Self::Int = Self::MAN_MASK;
 
-    const MANTISSA_EXPLICIT_BITS: usize = 52;
     const MIN_EXPONENT_ROUND_TO_EVEN: i32 = -4;
     const MAX_EXPONENT_ROUND_TO_EVEN: i32 = 23;
-    const MIN_EXPONENT_FAST_PATH: i64 = -22; // assuming FLT_EVAL_METHOD = 0
-    const MAX_EXPONENT_FAST_PATH: i64 = 22;
-    const MAX_EXPONENT_DISGUISED_FAST_PATH: i64 = 37;
-    const MINIMUM_EXPONENT: i32 = -1023;
-    const INFINITE_POWER: i32 = 0x7FF;
-    const SIGN_INDEX: usize = 63;
     const SMALLEST_POWER_OF_TEN: i32 = -342;
-    const LARGEST_POWER_OF_TEN: i32 = 308;
 
     #[inline]
     fn from_u64(v: u64) -> Self {
@@ -190,19 +293,8 @@ impl RawFloat for f64 {
         TABLE[exponent & 31]
     }
 
-    /// Returns the mantissa, exponent and sign as integers.
-    fn integer_decode(self) -> (u64, i16, i8) {
-        let bits = self.to_bits();
-        let sign: i8 = if bits >> 63 == 0 { 1 } else { -1 };
-        let mut exponent: i16 = ((bits >> 52) & 0x7ff) as i16;
-        let mantissa = if exponent == 0 {
-            (bits & 0xfffffffffffff) << 1
-        } else {
-            (bits & 0xfffffffffffff) | 0x10000000000000
-        };
-        // Exponent bias + mantissa shift
-        exponent -= 1023 + 52;
-        (mantissa, exponent, sign)
+    fn to_bits(self) -> Self::Int {
+        self.to_bits()
     }
 
     fn classify(self) -> FpCategory {
diff --git a/library/core/src/num/dec2flt/fpu.rs b/library/core/src/num/dec2flt/fpu.rs
index daeee1755b0..8aad087ec1b 100644
--- a/library/core/src/num/dec2flt/fpu.rs
+++ b/library/core/src/num/dec2flt/fpu.rs
@@ -22,7 +22,6 @@ pub(super) use fpu_precision::set_precision;
 #[cfg(all(target_arch = "x86", not(target_feature = "sse2")))]
 mod fpu_precision {
     use core::arch::asm;
-    use core::mem::size_of;
 
     /// A structure used to preserve the original value of the FPU control word, so that it can be
     /// restored when the structure is dropped.
diff --git a/library/core/src/num/dec2flt/lemire.rs b/library/core/src/num/dec2flt/lemire.rs
index 01642e1b111..f84929a03c1 100644
--- a/library/core/src/num/dec2flt/lemire.rs
+++ b/library/core/src/num/dec2flt/lemire.rs
@@ -38,7 +38,7 @@ pub fn compute_float<F: RawFloat>(q: i64, mut w: u64) -> BiasedFp {
     // Normalize our significant digits, so the most-significant bit is set.
     let lz = w.leading_zeros();
     w <<= lz;
-    let (lo, hi) = compute_product_approx(q, w, F::MANTISSA_EXPLICIT_BITS + 3);
+    let (lo, hi) = compute_product_approx(q, w, F::SIG_BITS as usize + 3);
     if lo == 0xFFFF_FFFF_FFFF_FFFF {
         // If we have failed to approximate w x 5^-q with our 128-bit value.
         // Since the addition of 1 could lead to an overflow which could then
@@ -61,8 +61,8 @@ pub fn compute_float<F: RawFloat>(q: i64, mut w: u64) -> BiasedFp {
         }
     }
     let upperbit = (hi >> 63) as i32;
-    let mut mantissa = hi >> (upperbit + 64 - F::MANTISSA_EXPLICIT_BITS as i32 - 3);
-    let mut power2 = power(q as i32) + upperbit - lz as i32 - F::MINIMUM_EXPONENT;
+    let mut mantissa = hi >> (upperbit + 64 - F::SIG_BITS as i32 - 3);
+    let mut power2 = power(q as i32) + upperbit - lz as i32 - F::EXP_MIN + 1;
     if power2 <= 0 {
         if -power2 + 1 >= 64 {
             // Have more than 64 bits below the minimum exponent, must be 0.
@@ -72,8 +72,8 @@ pub fn compute_float<F: RawFloat>(q: i64, mut w: u64) -> BiasedFp {
         mantissa >>= -power2 + 1;
         mantissa += mantissa & 1;
         mantissa >>= 1;
-        power2 = (mantissa >= (1_u64 << F::MANTISSA_EXPLICIT_BITS)) as i32;
-        return BiasedFp { f: mantissa, e: power2 };
+        power2 = (mantissa >= (1_u64 << F::SIG_BITS)) as i32;
+        return BiasedFp { m: mantissa, p_biased: power2 };
     }
     // Need to handle rounding ties. Normally, we need to round up,
     // but if we fall right in between and we have an even basis, we
@@ -89,8 +89,8 @@ pub fn compute_float<F: RawFloat>(q: i64, mut w: u64) -> BiasedFp {
     if lo <= 1
         && q >= F::MIN_EXPONENT_ROUND_TO_EVEN as i64
         && q <= F::MAX_EXPONENT_ROUND_TO_EVEN as i64
-        && mantissa & 3 == 1
-        && (mantissa << (upperbit + 64 - F::MANTISSA_EXPLICIT_BITS as i32 - 3)) == hi
+        && mantissa & 0b11 == 0b01
+        && (mantissa << (upperbit + 64 - F::SIG_BITS as i32 - 3)) == hi
     {
         // Zero the lowest bit, so we don't round up.
         mantissa &= !1_u64;
@@ -98,20 +98,20 @@ pub fn compute_float<F: RawFloat>(q: i64, mut w: u64) -> BiasedFp {
     // Round-to-even, then shift the significant digits into place.
     mantissa += mantissa & 1;
     mantissa >>= 1;
-    if mantissa >= (2_u64 << F::MANTISSA_EXPLICIT_BITS) {
+    if mantissa >= (2_u64 << F::SIG_BITS) {
         // Rounding up overflowed, so the carry bit is set. Set the
         // mantissa to 1 (only the implicit, hidden bit is set) and
         // increase the exponent.
-        mantissa = 1_u64 << F::MANTISSA_EXPLICIT_BITS;
+        mantissa = 1_u64 << F::SIG_BITS;
         power2 += 1;
     }
     // Zero out the hidden bit.
-    mantissa &= !(1_u64 << F::MANTISSA_EXPLICIT_BITS);
+    mantissa &= !(1_u64 << F::SIG_BITS);
     if power2 >= F::INFINITE_POWER {
         // Exponent is above largest normal value, must be infinite.
         return fp_inf;
     }
-    BiasedFp { f: mantissa, e: power2 }
+    BiasedFp { m: mantissa, p_biased: power2 }
 }
 
 /// Calculate a base 2 exponent from a decimal exponent.
diff --git a/library/core/src/num/dec2flt/mod.rs b/library/core/src/num/dec2flt/mod.rs
index 6dca7406845..d1a0e1db313 100644
--- a/library/core/src/num/dec2flt/mod.rs
+++ b/library/core/src/num/dec2flt/mod.rs
@@ -3,8 +3,8 @@
 //! # Problem statement
 //!
 //! We are given a decimal string such as `12.34e56`. This string consists of integral (`12`),
-//! fractional (`34`), and exponent (`56`) parts. All parts are optional and interpreted as zero
-//! when missing.
+//! fractional (`34`), and exponent (`56`) parts. All parts are optional and interpreted as a
+//! default value (1 or 0) when missing.
 //!
 //! We seek the IEEE 754 floating point number that is closest to the exact value of the decimal
 //! string. It is well-known that many decimal strings do not have terminating representations in
@@ -67,6 +67,18 @@
 //! "such that the exponent +/- the number of decimal digits fits into a 64 bit integer".
 //! Larger exponents are accepted, but we don't do arithmetic with them, they are immediately
 //! turned into {positive,negative} {zero,infinity}.
+//!
+//! # Notation
+//!
+//! This module uses the same notation as the Lemire paper:
+//!
+//! - `m`: binary mantissa; always nonnegative
+//! - `p`: binary exponent; a signed integer
+//! - `w`: decimal significand; always nonnegative
+//! - `q`: decimal exponent; a signed integer
+//!
+//! This gives `m * 2^p` for the binary floating-point number, with `w * 10^q` as the decimal
+//! equivalent.
 
 #![doc(hidden)]
 #![unstable(
@@ -85,14 +97,14 @@ use crate::fmt;
 use crate::str::FromStr;
 
 mod common;
-mod decimal;
+pub mod decimal;
+pub mod decimal_seq;
 mod fpu;
 mod slow;
 mod table;
 // float is used in flt2dec, and all are used in unit tests.
 pub mod float;
 pub mod lemire;
-pub mod number;
 pub mod parse;
 
 macro_rules! from_str_float_impl {
@@ -220,10 +232,10 @@ pub fn pfe_invalid() -> ParseFloatError {
 }
 
 /// Converts a `BiasedFp` to the closest machine float type.
-fn biased_fp_to_float<T: RawFloat>(x: BiasedFp) -> T {
-    let mut word = x.f;
-    word |= (x.e as u64) << T::MANTISSA_EXPLICIT_BITS;
-    T::from_u64_bits(word)
+fn biased_fp_to_float<F: RawFloat>(x: BiasedFp) -> F {
+    let mut word = x.m;
+    word |= (x.p_biased as u64) << F::SIG_BITS;
+    F::from_u64_bits(word)
 }
 
 /// Converts a decimal string into a floating point number.
@@ -260,12 +272,15 @@ pub fn dec2flt<F: RawFloat>(s: &str) -> Result<F, ParseFloatError> {
     // redundantly using the Eisel-Lemire algorithm if it was unable to
     // correctly round on the first pass.
     let mut fp = compute_float::<F>(num.exponent, num.mantissa);
-    if num.many_digits && fp.e >= 0 && fp != compute_float::<F>(num.exponent, num.mantissa + 1) {
-        fp.e = -1;
+    if num.many_digits
+        && fp.p_biased >= 0
+        && fp != compute_float::<F>(num.exponent, num.mantissa + 1)
+    {
+        fp.p_biased = -1;
     }
     // Unable to correctly round the float using the Eisel-Lemire algorithm.
     // Fallback to a slower, but always correct algorithm.
-    if fp.e < 0 {
+    if fp.p_biased < 0 {
         fp = parse_long_mantissa::<F>(s);
     }
 
diff --git a/library/core/src/num/dec2flt/number.rs b/library/core/src/num/dec2flt/number.rs
deleted file mode 100644
index 2538991564a..00000000000
--- a/library/core/src/num/dec2flt/number.rs
+++ /dev/null
@@ -1,88 +0,0 @@
-//! Representation of a float as the significant digits and exponent.
-
-use crate::num::dec2flt::float::RawFloat;
-use crate::num::dec2flt::fpu::set_precision;
-
-#[rustfmt::skip]
-const INT_POW10: [u64; 16] = [
-    1,
-    10,
-    100,
-    1000,
-    10000,
-    100000,
-    1000000,
-    10000000,
-    100000000,
-    1000000000,
-    10000000000,
-    100000000000,
-    1000000000000,
-    10000000000000,
-    100000000000000,
-    1000000000000000,
-];
-
-#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
-pub struct Number {
-    pub exponent: i64,
-    pub mantissa: u64,
-    pub negative: bool,
-    pub many_digits: bool,
-}
-
-impl Number {
-    /// Detect if the float can be accurately reconstructed from native floats.
-    #[inline]
-    fn is_fast_path<F: RawFloat>(&self) -> bool {
-        F::MIN_EXPONENT_FAST_PATH <= self.exponent
-            && self.exponent <= F::MAX_EXPONENT_DISGUISED_FAST_PATH
-            && self.mantissa <= F::MAX_MANTISSA_FAST_PATH
-            && !self.many_digits
-    }
-
-    /// The fast path algorithm using machine-sized integers and floats.
-    ///
-    /// This is extracted into a separate function so that it can be attempted before constructing
-    /// a Decimal. This only works if both the mantissa and the exponent
-    /// can be exactly represented as a machine float, since IEE-754 guarantees
-    /// no rounding will occur.
-    ///
-    /// There is an exception: disguised fast-path cases, where we can shift
-    /// powers-of-10 from the exponent to the significant digits.
-    pub fn try_fast_path<F: RawFloat>(&self) -> Option<F> {
-        // Here we need to work around <https://github.com/rust-lang/rust/issues/114479>.
-        // The fast path crucially depends on arithmetic being rounded to the correct number of bits
-        // without any intermediate rounding. On x86 (without SSE or SSE2) this requires the precision
-        // of the x87 FPU stack to be changed so that it directly rounds to 64/32 bit.
-        // The `set_precision` function takes care of setting the precision on architectures which
-        // require setting it by changing the global state (like the control word of the x87 FPU).
-        let _cw = set_precision::<F>();
-
-        if self.is_fast_path::<F>() {
-            let mut value = if self.exponent <= F::MAX_EXPONENT_FAST_PATH {
-                // normal fast path
-                let value = F::from_u64(self.mantissa);
-                if self.exponent < 0 {
-                    value / F::pow10_fast_path((-self.exponent) as _)
-                } else {
-                    value * F::pow10_fast_path(self.exponent as _)
-                }
-            } else {
-                // disguised fast path
-                let shift = self.exponent - F::MAX_EXPONENT_FAST_PATH;
-                let mantissa = self.mantissa.checked_mul(INT_POW10[shift as usize])?;
-                if mantissa > F::MAX_MANTISSA_FAST_PATH {
-                    return None;
-                }
-                F::from_u64(mantissa) * F::pow10_fast_path(F::MAX_EXPONENT_FAST_PATH as _)
-            };
-            if self.negative {
-                value = -value;
-            }
-            Some(value)
-        } else {
-            None
-        }
-    }
-}
diff --git a/library/core/src/num/dec2flt/parse.rs b/library/core/src/num/dec2flt/parse.rs
index 06ee8e95fbc..e38fedc58be 100644
--- a/library/core/src/num/dec2flt/parse.rs
+++ b/library/core/src/num/dec2flt/parse.rs
@@ -1,8 +1,8 @@
 //! Functions to parse floating-point numbers.
 
 use crate::num::dec2flt::common::{ByteSlice, is_8digits};
+use crate::num::dec2flt::decimal::Decimal;
 use crate::num::dec2flt::float::RawFloat;
-use crate::num::dec2flt::number::Number;
 
 const MIN_19DIGIT_INT: u64 = 100_0000_0000_0000_0000;
 
@@ -100,7 +100,7 @@ fn parse_scientific(s_ref: &mut &[u8]) -> Option<i64> {
 ///
 /// This creates a representation of the float as the
 /// significant digits and the decimal exponent.
-fn parse_partial_number(mut s: &[u8]) -> Option<(Number, usize)> {
+fn parse_partial_number(mut s: &[u8]) -> Option<(Decimal, usize)> {
     debug_assert!(!s.is_empty());
 
     // parse initial digits before dot
@@ -146,7 +146,7 @@ fn parse_partial_number(mut s: &[u8]) -> Option<(Number, usize)> {
 
     // handle uncommon case with many digits
     if n_digits <= 19 {
-        return Some((Number { exponent, mantissa, negative: false, many_digits: false }, len));
+        return Some((Decimal { exponent, mantissa, negative: false, many_digits: false }, len));
     }
 
     n_digits -= 19;
@@ -179,13 +179,13 @@ fn parse_partial_number(mut s: &[u8]) -> Option<(Number, usize)> {
         exponent += exp_number;
     }
 
-    Some((Number { exponent, mantissa, negative: false, many_digits }, len))
+    Some((Decimal { exponent, mantissa, negative: false, many_digits }, len))
 }
 
 /// Try to parse a non-special floating point number,
 /// as well as two slices with integer and fractional parts
 /// and the parsed exponent.
-pub fn parse_number(s: &[u8]) -> Option<Number> {
+pub fn parse_number(s: &[u8]) -> Option<Decimal> {
     if let Some((float, rest)) = parse_partial_number(s) {
         if rest == s.len() {
             return Some(float);
diff --git a/library/core/src/num/dec2flt/slow.rs b/library/core/src/num/dec2flt/slow.rs
index 85d4b13284b..3baed426523 100644
--- a/library/core/src/num/dec2flt/slow.rs
+++ b/library/core/src/num/dec2flt/slow.rs
@@ -1,7 +1,7 @@
 //! Slow, fallback algorithm for cases the Eisel-Lemire algorithm cannot round.
 
 use crate::num::dec2flt::common::BiasedFp;
-use crate::num::dec2flt::decimal::{Decimal, parse_decimal};
+use crate::num::dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq};
 use crate::num::dec2flt::float::RawFloat;
 
 /// Parse the significant digits and biased, binary exponent of a float.
@@ -36,7 +36,7 @@ pub(crate) fn parse_long_mantissa<F: RawFloat>(s: &[u8]) -> BiasedFp {
     let fp_zero = BiasedFp::zero_pow2(0);
     let fp_inf = BiasedFp::zero_pow2(F::INFINITE_POWER);
 
-    let mut d = parse_decimal(s);
+    let mut d = parse_decimal_seq(s);
 
     // Short-circuit if the value can only be a literal 0 or infinity.
     if d.num_digits == 0 || d.decimal_point < -324 {
@@ -50,7 +50,7 @@ pub(crate) fn parse_long_mantissa<F: RawFloat>(s: &[u8]) -> BiasedFp {
         let n = d.decimal_point as usize;
         let shift = get_shift(n);
         d.right_shift(shift);
-        if d.decimal_point < -Decimal::DECIMAL_POINT_RANGE {
+        if d.decimal_point < -DecimalSeq::DECIMAL_POINT_RANGE {
             return fp_zero;
         }
         exp2 += shift as i32;
@@ -67,43 +67,43 @@ pub(crate) fn parse_long_mantissa<F: RawFloat>(s: &[u8]) -> BiasedFp {
             get_shift((-d.decimal_point) as _)
         };
         d.left_shift(shift);
-        if d.decimal_point > Decimal::DECIMAL_POINT_RANGE {
+        if d.decimal_point > DecimalSeq::DECIMAL_POINT_RANGE {
             return fp_inf;
         }
         exp2 -= shift as i32;
     }
     // We are now in the range [1/2 ... 1] but the binary format uses [1 ... 2].
     exp2 -= 1;
-    while (F::MINIMUM_EXPONENT + 1) > exp2 {
-        let mut n = ((F::MINIMUM_EXPONENT + 1) - exp2) as usize;
+    while F::EXP_MIN > exp2 {
+        let mut n = (F::EXP_MIN - exp2) as usize;
         if n > MAX_SHIFT {
             n = MAX_SHIFT;
         }
         d.right_shift(n);
         exp2 += n as i32;
     }
-    if (exp2 - F::MINIMUM_EXPONENT) >= F::INFINITE_POWER {
+    if (exp2 - F::EXP_MIN + 1) >= F::INFINITE_POWER {
         return fp_inf;
     }
     // Shift the decimal to the hidden bit, and then round the value
     // to get the high mantissa+1 bits.
-    d.left_shift(F::MANTISSA_EXPLICIT_BITS + 1);
+    d.left_shift(F::SIG_BITS as usize + 1);
     let mut mantissa = d.round();
-    if mantissa >= (1_u64 << (F::MANTISSA_EXPLICIT_BITS + 1)) {
+    if mantissa >= (1_u64 << (F::SIG_BITS + 1)) {
         // Rounding up overflowed to the carry bit, need to
         // shift back to the hidden bit.
         d.right_shift(1);
         exp2 += 1;
         mantissa = d.round();
-        if (exp2 - F::MINIMUM_EXPONENT) >= F::INFINITE_POWER {
+        if (exp2 - F::EXP_MIN + 1) >= F::INFINITE_POWER {
             return fp_inf;
         }
     }
-    let mut power2 = exp2 - F::MINIMUM_EXPONENT;
-    if mantissa < (1_u64 << F::MANTISSA_EXPLICIT_BITS) {
+    let mut power2 = exp2 - F::EXP_MIN + 1;
+    if mantissa < (1_u64 << F::SIG_BITS) {
         power2 -= 1;
     }
     // Zero out all the bits above the explicit mantissa bits.
-    mantissa &= (1_u64 << F::MANTISSA_EXPLICIT_BITS) - 1;
-    BiasedFp { f: mantissa, e: power2 }
+    mantissa &= (1_u64 << F::SIG_BITS) - 1;
+    BiasedFp { m: mantissa, p_biased: power2 }
 }
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index a200fd53186..de1557ccc90 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -493,13 +493,13 @@ impl f32 {
     pub const NEG_INFINITY: f32 = -1.0_f32 / 0.0_f32;
 
     /// Sign bit
-    const SIGN_MASK: u32 = 0x8000_0000;
+    pub(crate) const SIGN_MASK: u32 = 0x8000_0000;
 
     /// Exponent mask
-    const EXP_MASK: u32 = 0x7f80_0000;
+    pub(crate) const EXP_MASK: u32 = 0x7f80_0000;
 
     /// Mantissa mask
-    const MAN_MASK: u32 = 0x007f_ffff;
+    pub(crate) const MAN_MASK: u32 = 0x007f_ffff;
 
     /// Minimum representable positive value (min subnormal)
     const TINY_BITS: u32 = 0x1;
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index de63a462b61..65b5f3b9af0 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -492,13 +492,13 @@ impl f64 {
     pub const NEG_INFINITY: f64 = -1.0_f64 / 0.0_f64;
 
     /// Sign bit
-    const SIGN_MASK: u64 = 0x8000_0000_0000_0000;
+    pub(crate) const SIGN_MASK: u64 = 0x8000_0000_0000_0000;
 
     /// Exponent mask
-    const EXP_MASK: u64 = 0x7ff0_0000_0000_0000;
+    pub(crate) const EXP_MASK: u64 = 0x7ff0_0000_0000_0000;
 
     /// Mantissa mask
-    const MAN_MASK: u64 = 0x000f_ffff_ffff_ffff;
+    pub(crate) const MAN_MASK: u64 = 0x000f_ffff_ffff_ffff;
 
     /// Minimum representable positive value (min subnormal)
     const TINY_BITS: u64 = 0x1;
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 7d99aaa1731..a72ca4bcb05 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -3627,7 +3627,7 @@ macro_rules! int_impl {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
-        pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
+        pub const fn to_be_bytes(self) -> [u8; size_of::<Self>()] {
             self.to_be().to_ne_bytes()
         }
 
@@ -3647,7 +3647,7 @@ macro_rules! int_impl {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
-        pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
+        pub const fn to_le_bytes(self) -> [u8; size_of::<Self>()] {
             self.to_le().to_ne_bytes()
         }
 
@@ -3683,7 +3683,7 @@ macro_rules! int_impl {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
-        pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
+        pub const fn to_ne_bytes(self) -> [u8; size_of::<Self>()] {
             // SAFETY: integers are plain old datatypes so we can always transmute them to
             // arrays of bytes
             unsafe { mem::transmute(self) }
@@ -3705,7 +3705,7 @@ macro_rules! int_impl {
         ///
         /// ```
         #[doc = concat!("fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")]
-        #[doc = concat!("    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")]
+        #[doc = concat!("    let (int_bytes, rest) = input.split_at(size_of::<", stringify!($SelfT), ">());")]
         ///     *input = rest;
         #[doc = concat!("    ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())")]
         /// }
@@ -3714,7 +3714,7 @@ macro_rules! int_impl {
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
         #[must_use]
         #[inline]
-        pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+        pub const fn from_be_bytes(bytes: [u8; size_of::<Self>()]) -> Self {
             Self::from_be(Self::from_ne_bytes(bytes))
         }
 
@@ -3734,7 +3734,7 @@ macro_rules! int_impl {
         ///
         /// ```
         #[doc = concat!("fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")]
-        #[doc = concat!("    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")]
+        #[doc = concat!("    let (int_bytes, rest) = input.split_at(size_of::<", stringify!($SelfT), ">());")]
         ///     *input = rest;
         #[doc = concat!("    ", stringify!($SelfT), "::from_le_bytes(int_bytes.try_into().unwrap())")]
         /// }
@@ -3743,7 +3743,7 @@ macro_rules! int_impl {
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
         #[must_use]
         #[inline]
-        pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+        pub const fn from_le_bytes(bytes: [u8; size_of::<Self>()]) -> Self {
             Self::from_le(Self::from_ne_bytes(bytes))
         }
 
@@ -3774,7 +3774,7 @@ macro_rules! int_impl {
         ///
         /// ```
         #[doc = concat!("fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")]
-        #[doc = concat!("    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")]
+        #[doc = concat!("    let (int_bytes, rest) = input.split_at(size_of::<", stringify!($SelfT), ">());")]
         ///     *input = rest;
         #[doc = concat!("    ", stringify!($SelfT), "::from_ne_bytes(int_bytes.try_into().unwrap())")]
         /// }
@@ -3785,7 +3785,7 @@ macro_rules! int_impl {
         // SAFETY: const sound because integers are plain old datatypes so we can always
         // transmute to them
         #[inline]
-        pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+        pub const fn from_ne_bytes(bytes: [u8; size_of::<Self>()]) -> Self {
             // SAFETY: integers are plain old datatypes so we can always transmute to them
             unsafe { mem::transmute(bytes) }
         }
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index 80a38a6013d..151e128cd78 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -1241,7 +1241,7 @@ impl usize {
     /// Returns an `usize` where every byte is equal to `x`.
     #[inline]
     pub(crate) const fn repeat_u8(x: u8) -> usize {
-        usize::from_ne_bytes([x; mem::size_of::<usize>()])
+        usize::from_ne_bytes([x; size_of::<usize>()])
     }
 
     /// Returns an `usize` where every byte pair is equal to `x`.
@@ -1249,7 +1249,7 @@ impl usize {
     pub(crate) const fn repeat_u16(x: u16) -> usize {
         let mut r = 0usize;
         let mut i = 0;
-        while i < mem::size_of::<usize>() {
+        while i < size_of::<usize>() {
             // Use `wrapping_shl` to make it work on targets with 16-bit `usize`
             r = r.wrapping_shl(16) | (x as usize);
             i += 2;
@@ -1330,7 +1330,7 @@ pub enum FpCategory {
 #[inline(always)]
 #[unstable(issue = "none", feature = "std_internals")]
 pub const fn can_not_overflow<T>(radix: u32, is_signed_ty: bool, digits: &[u8]) -> bool {
-    radix <= 16 && digits.len() <= mem::size_of::<T>() * 2 - is_signed_ty as usize
+    radix <= 16 && digits.len() <= size_of::<T>() * 2 - is_signed_ty as usize
 }
 
 #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index a967b72c4fa..6c9b366d903 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -86,7 +86,7 @@ impl_zeroable_primitive!(
 /// For example, `Option<NonZero<u32>>` is the same size as `u32`:
 ///
 /// ```
-/// use core::{mem::size_of, num::NonZero};
+/// use core::{num::NonZero};
 ///
 /// assert_eq!(size_of::<Option<NonZero<u32>>>(), size_of::<u32>());
 /// ```
@@ -102,7 +102,6 @@ impl_zeroable_primitive!(
 /// `Option<NonZero<T>>` are guaranteed to have the same size and alignment:
 ///
 /// ```
-/// # use std::mem::{size_of, align_of};
 /// use std::num::NonZero;
 ///
 /// assert_eq!(size_of::<NonZero<u32>>(), size_of::<Option<NonZero<u32>>>());
@@ -500,7 +499,6 @@ macro_rules! nonzero_integer {
         #[doc = concat!("For example, `Option<", stringify!($Ty), ">` is the same size as `", stringify!($Int), "`:")]
         ///
         /// ```rust
-        /// use std::mem::size_of;
         #[doc = concat!("assert_eq!(size_of::<Option<core::num::", stringify!($Ty), ">>(), size_of::<", stringify!($Int), ">());")]
         /// ```
         ///
@@ -516,7 +514,6 @@ macro_rules! nonzero_integer {
         /// are guaranteed to have the same size and alignment:
         ///
         /// ```
-        /// # use std::mem::{size_of, align_of};
         #[doc = concat!("use std::num::", stringify!($Ty), ";")]
         ///
         #[doc = concat!("assert_eq!(size_of::<", stringify!($Ty), ">(), size_of::<Option<", stringify!($Ty), ">>());")]
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 405c71121ca..d8709d51ccc 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -2586,7 +2586,7 @@ macro_rules! uint_impl {
                       without modifying the original"]
         #[inline]
         pub const fn abs_diff(self, other: Self) -> Self {
-            if mem::size_of::<Self>() == 1 {
+            if size_of::<Self>() == 1 {
                 // Trick LLVM into generating the psadbw instruction when SSE2
                 // is available and this function is autovectorized for u8's.
                 (self as i32).wrapping_sub(other as i32).abs() as Self
@@ -3465,7 +3465,7 @@ macro_rules! uint_impl {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
-        pub const fn to_be_bytes(self) -> [u8; mem::size_of::<Self>()] {
+        pub const fn to_be_bytes(self) -> [u8; size_of::<Self>()] {
             self.to_be().to_ne_bytes()
         }
 
@@ -3485,7 +3485,7 @@ macro_rules! uint_impl {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
-        pub const fn to_le_bytes(self) -> [u8; mem::size_of::<Self>()] {
+        pub const fn to_le_bytes(self) -> [u8; size_of::<Self>()] {
             self.to_le().to_ne_bytes()
         }
 
@@ -3521,7 +3521,7 @@ macro_rules! uint_impl {
         // SAFETY: const sound because integers are plain old datatypes so we can always
         // transmute them to arrays of bytes
         #[inline]
-        pub const fn to_ne_bytes(self) -> [u8; mem::size_of::<Self>()] {
+        pub const fn to_ne_bytes(self) -> [u8; size_of::<Self>()] {
             // SAFETY: integers are plain old datatypes so we can always transmute them to
             // arrays of bytes
             unsafe { mem::transmute(self) }
@@ -3543,7 +3543,7 @@ macro_rules! uint_impl {
         ///
         /// ```
         #[doc = concat!("fn read_be_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")]
-        #[doc = concat!("    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")]
+        #[doc = concat!("    let (int_bytes, rest) = input.split_at(size_of::<", stringify!($SelfT), ">());")]
         ///     *input = rest;
         #[doc = concat!("    ", stringify!($SelfT), "::from_be_bytes(int_bytes.try_into().unwrap())")]
         /// }
@@ -3552,7 +3552,7 @@ macro_rules! uint_impl {
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
         #[must_use]
         #[inline]
-        pub const fn from_be_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+        pub const fn from_be_bytes(bytes: [u8; size_of::<Self>()]) -> Self {
             Self::from_be(Self::from_ne_bytes(bytes))
         }
 
@@ -3572,7 +3572,7 @@ macro_rules! uint_impl {
         ///
         /// ```
         #[doc = concat!("fn read_le_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")]
-        #[doc = concat!("    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")]
+        #[doc = concat!("    let (int_bytes, rest) = input.split_at(size_of::<", stringify!($SelfT), ">());")]
         ///     *input = rest;
         #[doc = concat!("    ", stringify!($SelfT), "::from_le_bytes(int_bytes.try_into().unwrap())")]
         /// }
@@ -3581,7 +3581,7 @@ macro_rules! uint_impl {
         #[rustc_const_stable(feature = "const_int_conversion", since = "1.44.0")]
         #[must_use]
         #[inline]
-        pub const fn from_le_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+        pub const fn from_le_bytes(bytes: [u8; size_of::<Self>()]) -> Self {
             Self::from_le(Self::from_ne_bytes(bytes))
         }
 
@@ -3612,7 +3612,7 @@ macro_rules! uint_impl {
         ///
         /// ```
         #[doc = concat!("fn read_ne_", stringify!($SelfT), "(input: &mut &[u8]) -> ", stringify!($SelfT), " {")]
-        #[doc = concat!("    let (int_bytes, rest) = input.split_at(std::mem::size_of::<", stringify!($SelfT), ">());")]
+        #[doc = concat!("    let (int_bytes, rest) = input.split_at(size_of::<", stringify!($SelfT), ">());")]
         ///     *input = rest;
         #[doc = concat!("    ", stringify!($SelfT), "::from_ne_bytes(int_bytes.try_into().unwrap())")]
         /// }
@@ -3623,7 +3623,7 @@ macro_rules! uint_impl {
         // SAFETY: const sound because integers are plain old datatypes so we can always
         // transmute to them
         #[inline]
-        pub const fn from_ne_bytes(bytes: [u8; mem::size_of::<Self>()]) -> Self {
+        pub const fn from_ne_bytes(bytes: [u8; size_of::<Self>()]) -> Self {
             // SAFETY: integers are plain old datatypes so we can always transmute to them
             unsafe { mem::transmute(bytes) }
         }
diff --git a/library/core/src/ops/bit.rs b/library/core/src/ops/bit.rs
index 6984100e498..deb54c8ba34 100644
--- a/library/core/src/ops/bit.rs
+++ b/library/core/src/ops/bit.rs
@@ -493,7 +493,7 @@ macro_rules! shl_impl_all {
     )*)
 }
 
-shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 isize i128 }
+shl_impl_all! { u8 u16 u32 u64 u128 usize i8 i16 i32 i64 i128 isize }
 
 /// The right shift operator `>>`. Note that because this trait is implemented
 /// for all integer types with multiple right-hand-side types, Rust's type
diff --git a/library/core/src/pat.rs b/library/core/src/pat.rs
index 752e79c2dac..f8826096df3 100644
--- a/library/core/src/pat.rs
+++ b/library/core/src/pat.rs
@@ -12,3 +12,65 @@ macro_rules! pattern_type {
         /* compiler built-in */
     };
 }
+
+/// A trait implemented for integer types and `char`.
+/// Useful in the future for generic pattern types, but
+/// used right now to simplify ast lowering of pattern type ranges.
+#[unstable(feature = "pattern_type_range_trait", issue = "123646")]
+#[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")]
+#[const_trait]
+#[diagnostic::on_unimplemented(
+    message = "`{Self}` is not a valid base type for range patterns",
+    label = "only integer types and `char` are supported"
+)]
+pub trait RangePattern {
+    /// Trait version of the inherent `MIN` assoc const.
+    #[cfg_attr(not(bootstrap), lang = "RangeMin")]
+    const MIN: Self;
+
+    /// Trait version of the inherent `MIN` assoc const.
+    #[cfg_attr(not(bootstrap), lang = "RangeMax")]
+    const MAX: Self;
+
+    /// A compile-time helper to subtract 1 for exclusive ranges.
+    #[cfg_attr(not(bootstrap), lang = "RangeSub")]
+    #[track_caller]
+    fn sub_one(self) -> Self;
+}
+
+macro_rules! impl_range_pat {
+    ($($ty:ty,)*) => {
+        $(
+            #[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")]
+            impl const RangePattern for $ty {
+                const MIN: $ty = <$ty>::MIN;
+                const MAX: $ty = <$ty>::MAX;
+                fn sub_one(self) -> Self {
+                    match self.checked_sub(1) {
+                        Some(val) => val,
+                        None => panic!("exclusive range end at minimum value of type")
+                    }
+                }
+            }
+        )*
+    }
+}
+
+impl_range_pat! {
+    i8, i16, i32, i64, i128, isize,
+    u8, u16, u32, u64, u128, usize,
+}
+
+#[rustc_const_unstable(feature = "pattern_type_range_trait", issue = "123646")]
+impl const RangePattern for char {
+    const MIN: Self = char::MIN;
+
+    const MAX: Self = char::MAX;
+
+    fn sub_one(self) -> Self {
+        match char::from_u32(self as u32 - 1) {
+            None => panic!("exclusive range to start of valid chars"),
+            Some(val) => val,
+        }
+    }
+}
diff --git a/library/core/src/primitive_docs.rs b/library/core/src/primitive_docs.rs
index bbf5939fe1b..89c856fe107 100644
--- a/library/core/src/primitive_docs.rs
+++ b/library/core/src/primitive_docs.rs
@@ -398,12 +398,12 @@ mod prim_never {}
 /// let v = vec!['h', 'e', 'l', 'l', 'o'];
 ///
 /// // five elements times four bytes for each element
-/// assert_eq!(20, v.len() * std::mem::size_of::<char>());
+/// assert_eq!(20, v.len() * size_of::<char>());
 ///
 /// let s = String::from("hello");
 ///
 /// // five elements times one byte per element
-/// assert_eq!(5, s.len() * std::mem::size_of::<u8>());
+/// assert_eq!(5, s.len() * size_of::<u8>());
 /// ```
 ///
 /// [`String`]: ../std/string/struct.String.html
@@ -443,8 +443,8 @@ mod prim_never {}
 /// let s = String::from("love: ❤️");
 /// let v: Vec<char> = s.chars().collect();
 ///
-/// assert_eq!(12, std::mem::size_of_val(&s[..]));
-/// assert_eq!(32, std::mem::size_of_val(&v[..]));
+/// assert_eq!(12, size_of_val(&s[..]));
+/// assert_eq!(32, size_of_val(&v[..]));
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
 mod prim_char {}
@@ -594,10 +594,8 @@ impl () {}
 /// #[allow(unused_extern_crates)]
 /// extern crate libc;
 ///
-/// use std::mem;
-///
 /// unsafe {
-///     let my_num: *mut i32 = libc::malloc(mem::size_of::<i32>()) as *mut i32;
+///     let my_num: *mut i32 = libc::malloc(size_of::<i32>()) as *mut i32;
 ///     if my_num.is_null() {
 ///         panic!("failed to allocate memory");
 ///     }
@@ -893,11 +891,11 @@ mod prim_array {}
 ///
 /// ```
 /// # use std::rc::Rc;
-/// let pointer_size = std::mem::size_of::<&u8>();
-/// assert_eq!(2 * pointer_size, std::mem::size_of::<&[u8]>());
-/// assert_eq!(2 * pointer_size, std::mem::size_of::<*const [u8]>());
-/// assert_eq!(2 * pointer_size, std::mem::size_of::<Box<[u8]>>());
-/// assert_eq!(2 * pointer_size, std::mem::size_of::<Rc<[u8]>>());
+/// let pointer_size = size_of::<&u8>();
+/// assert_eq!(2 * pointer_size, size_of::<&[u8]>());
+/// assert_eq!(2 * pointer_size, size_of::<*const [u8]>());
+/// assert_eq!(2 * pointer_size, size_of::<Box<[u8]>>());
+/// assert_eq!(2 * pointer_size, size_of::<Rc<[u8]>>());
 /// ```
 ///
 /// ## Trait Implementations
@@ -1692,15 +1690,13 @@ mod prim_ref {}
 /// This zero-sized type *coerces* to a regular function pointer. For example:
 ///
 /// ```rust
-/// use std::mem;
-///
 /// fn bar(x: i32) {}
 ///
 /// let not_bar_ptr = bar; // `not_bar_ptr` is zero-sized, uniquely identifying `bar`
-/// assert_eq!(mem::size_of_val(&not_bar_ptr), 0);
+/// assert_eq!(size_of_val(&not_bar_ptr), 0);
 ///
 /// let bar_ptr: fn(i32) = not_bar_ptr; // force coercion to function pointer
-/// assert_eq!(mem::size_of_val(&bar_ptr), mem::size_of::<usize>());
+/// assert_eq!(size_of_val(&bar_ptr), size_of::<usize>());
 ///
 /// let footgun = &bar; // this is a shared reference to the zero-sized type identifying `bar`
 /// ```
diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs
index 2da94e72566..19311e39b45 100644
--- a/library/core/src/ptr/alignment.rs
+++ b/library/core/src/ptr/alignment.rs
@@ -13,8 +13,8 @@ use crate::{cmp, fmt, hash, mem, num};
 pub struct Alignment(AlignmentEnum);
 
 // Alignment is `repr(usize)`, but via extra steps.
-const _: () = assert!(mem::size_of::<Alignment>() == mem::size_of::<usize>());
-const _: () = assert!(mem::align_of::<Alignment>() == mem::align_of::<usize>());
+const _: () = assert!(size_of::<Alignment>() == size_of::<usize>());
+const _: () = assert!(align_of::<Alignment>() == align_of::<usize>());
 
 fn _alignment_can_be_structurally_matched(a: Alignment) -> bool {
     matches!(a, Alignment::MIN)
@@ -38,14 +38,14 @@ impl Alignment {
 
     /// Returns the alignment for a type.
     ///
-    /// This provides the same numerical value as [`mem::align_of`],
+    /// This provides the same numerical value as [`align_of`],
     /// but in an `Alignment` instead of a `usize`.
     #[unstable(feature = "ptr_alignment_type", issue = "102070")]
     #[inline]
     #[must_use]
     pub const fn of<T>() -> Self {
         // This can't actually panic since type alignment is always a power of two.
-        const { Alignment::new(mem::align_of::<T>()).unwrap() }
+        const { Alignment::new(align_of::<T>()).unwrap() }
     }
 
     /// Creates an `Alignment` from a `usize`, or returns `None` if it's
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 8db620596dd..9a4f916803e 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -1,7 +1,7 @@
 use super::*;
 use crate::cmp::Ordering::{Equal, Greater, Less};
 use crate::intrinsics::const_eval_select;
-use crate::mem::SizedTypeProperties;
+use crate::mem::{self, SizedTypeProperties};
 use crate::slice::{self, SliceIndex};
 
 impl<T: ?Sized> *const T {
@@ -595,9 +595,9 @@ impl<T: ?Sized> *const T {
     }
 
     /// Calculates the distance between two pointers within the same allocation. The returned value is in
-    /// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
+    /// units of T: the distance in bytes divided by `size_of::<T>()`.
     ///
-    /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`,
+    /// This is equivalent to `(self as isize - origin as isize) / (size_of::<T>() as isize)`,
     /// except that it has a lot more opportunities for UB, in exchange for the compiler
     /// better understanding what you are doing.
     ///
@@ -633,7 +633,7 @@ impl<T: ?Sized> *const T {
     /// objects is not known at compile-time. However, the requirement also exists at
     /// runtime and may be exploited by optimizations. If you wish to compute the difference between
     /// pointers that are not guaranteed to be from the same allocation, use `(self as isize -
-    /// origin as isize) / mem::size_of::<T>()`.
+    /// origin as isize) / size_of::<T>()`.
     // FIXME: recommend `addr()` instead of `as usize` once that is stable.
     ///
     /// [`add`]: #method.add
@@ -683,7 +683,7 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
-        let pointee_size = mem::size_of::<T>();
+        let pointee_size = size_of::<T>();
         assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
         // SAFETY: the caller must uphold the safety contract for `ptr_offset_from`.
         unsafe { intrinsics::ptr_offset_from(self, origin) }
@@ -709,7 +709,7 @@ impl<T: ?Sized> *const T {
 
     /// Calculates the distance between two pointers within the same allocation, *where it's known that
     /// `self` is equal to or greater than `origin`*. The returned value is in
-    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    /// units of T: the distance in bytes is divided by `size_of::<T>()`.
     ///
     /// This computes the same value that [`offset_from`](#method.offset_from)
     /// would compute, but with the added precondition that the offset is
@@ -793,7 +793,7 @@ impl<T: ?Sized> *const T {
             ) => runtime_ptr_ge(this, origin)
         );
 
-        let pointee_size = mem::size_of::<T>();
+        let pointee_size = size_of::<T>();
         assert!(0 < pointee_size && pointee_size <= isize::MAX as usize);
         // SAFETY: the caller must uphold the safety contract for `ptr_offset_from_unsigned`.
         unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
@@ -1313,7 +1313,7 @@ impl<T: ?Sized> *const T {
         unsafe { read_unaligned(self) }
     }
 
-    /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
+    /// Copies `count * size_of::<T>()` bytes from `self` to `dest`. The source
     /// and destination may overlap.
     ///
     /// NOTE: this has the *same* argument order as [`ptr::copy`].
@@ -1333,7 +1333,7 @@ impl<T: ?Sized> *const T {
         unsafe { copy(self, dest, count) }
     }
 
-    /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
+    /// Copies `count * size_of::<T>()` bytes from `self` to `dest`. The source
     /// and destination may *not* overlap.
     ///
     /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`].
@@ -1375,8 +1375,6 @@ impl<T: ?Sized> *const T {
     /// Accessing adjacent `u8` as `u16`
     ///
     /// ```
-    /// use std::mem::align_of;
-    ///
     /// # unsafe {
     /// let x = [5_u8, 6, 7, 8, 9];
     /// let ptr = x.as_ptr();
@@ -1436,7 +1434,7 @@ impl<T: ?Sized> *const T {
     where
         T: Sized,
     {
-        self.is_aligned_to(mem::align_of::<T>())
+        self.is_aligned_to(align_of::<T>())
     }
 
     /// Returns whether the pointer is aligned to `align`.
@@ -1595,7 +1593,7 @@ impl<T> *const [T] {
     /// When calling this method, you have to ensure that *either* the pointer is null *or*
     /// all of the following is true:
     ///
-    /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::<T>()` many bytes,
+    /// * The pointer must be [valid] for reads for `ptr.len() * size_of::<T>()` many bytes,
     ///   and it must be properly aligned. This means in particular:
     ///
     ///     * The entire memory range of this slice must be contained within a single [allocated object]!
@@ -1607,7 +1605,7 @@ impl<T> *const [T] {
     ///       them from other data. You can obtain a pointer that is usable as `data`
     ///       for zero-length slices using [`NonNull::dangling()`].
     ///
-    /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+    /// * The total size `ptr.len() * size_of::<T>()` of the slice must be no larger than `isize::MAX`.
     ///   See the safety documentation of [`pointer::offset`].
     ///
     /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs
index 9eee29d485f..48707506389 100644
--- a/library/core/src/ptr/metadata.rs
+++ b/library/core/src/ptr/metadata.rs
@@ -74,7 +74,7 @@ pub trait Pointee {
 /// #![feature(ptr_metadata)]
 ///
 /// fn this_never_panics<T: std::ptr::Thin>() {
-///     assert_eq!(std::mem::size_of::<&T>(), std::mem::size_of::<usize>())
+///     assert_eq!(size_of::<&T>(), size_of::<usize>())
 /// }
 /// ```
 #[unstable(feature = "ptr_metadata", issue = "81513")]
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index eb99be817a2..ea53da78d3b 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -48,7 +48,7 @@
 //!
 //! Valid raw pointers as defined above are not necessarily properly aligned (where
 //! "proper" alignment is defined by the pointee type, i.e., `*const T` must be
-//! aligned to `mem::align_of::<T>()`). However, most functions require their
+//! aligned to `align_of::<T>()`). However, most functions require their
 //! arguments to be properly aligned, and will explicitly state
 //! this requirement in their documentation. Notable exceptions to this are
 //! [`read_unaligned`] and [`write_unaligned`].
@@ -297,7 +297,7 @@
 //!
 //!     // Our value, which must have enough alignment to have spare least-significant-bits.
 //!     let my_precious_data: u32 = 17;
-//!     assert!(core::mem::align_of::<u32>() > 1);
+//!     assert!(align_of::<u32>() > 1);
 //!
 //!     // Create a tagged pointer
 //!     let ptr = &my_precious_data as *const u32;
@@ -1098,12 +1098,12 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
         } else {
             macro_rules! attempt_swap_as_chunks {
                 ($ChunkTy:ty) => {
-                    if mem::align_of::<T>() >= mem::align_of::<$ChunkTy>()
-                        && mem::size_of::<T>() % mem::size_of::<$ChunkTy>() == 0
+                    if align_of::<T>() >= align_of::<$ChunkTy>()
+                        && size_of::<T>() % size_of::<$ChunkTy>() == 0
                     {
                         let x: *mut $ChunkTy = x.cast();
                         let y: *mut $ChunkTy = y.cast();
-                        let count = count * (mem::size_of::<T>() / mem::size_of::<$ChunkTy>());
+                        let count = count * (size_of::<T>() / size_of::<$ChunkTy>());
                         // SAFETY: these are the same bytes that the caller promised were
                         // ok, just typed as `MaybeUninit<ChunkTy>`s instead of as `T`s.
                         // The `if` condition above ensures that we're not violating
@@ -1117,9 +1117,9 @@ pub const unsafe fn swap_nonoverlapping<T>(x: *mut T, y: *mut T, count: usize) {
             // Split up the slice into small power-of-two-sized chunks that LLVM is able
             // to vectorize (unless it's a special type with more-than-pointer alignment,
             // because we don't want to pessimize things like slices of SIMD vectors.)
-            if mem::align_of::<T>() <= mem::size_of::<usize>()
-            && (!mem::size_of::<T>().is_power_of_two()
-                || mem::size_of::<T>() > mem::size_of::<usize>() * 2)
+            if align_of::<T>() <= size_of::<usize>()
+            && (!size_of::<T>().is_power_of_two()
+                || size_of::<T>() > size_of::<usize>() * 2)
             {
                 attempt_swap_as_chunks!(usize);
                 attempt_swap_as_chunks!(u8);
@@ -1443,10 +1443,8 @@ pub const unsafe fn read<T>(src: *const T) -> T {
 /// Read a `usize` value from a byte buffer:
 ///
 /// ```
-/// use std::mem;
-///
 /// fn read_usize(x: &[u8]) -> usize {
-///     assert!(x.len() >= mem::size_of::<usize>());
+///     assert!(x.len() >= size_of::<usize>());
 ///
 ///     let ptr = x.as_ptr() as *const usize;
 ///
@@ -1467,7 +1465,7 @@ pub const unsafe fn read_unaligned<T>(src: *const T) -> T {
     // Also, since we just wrote a valid value into `tmp`, it is guaranteed
     // to be properly initialized.
     unsafe {
-        copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, mem::size_of::<T>());
+        copy_nonoverlapping(src as *const u8, tmp.as_mut_ptr() as *mut u8, size_of::<T>());
         tmp.assume_init()
     }
 }
@@ -1647,10 +1645,8 @@ pub const unsafe fn write<T>(dst: *mut T, src: T) {
 /// Write a `usize` value to a byte buffer:
 ///
 /// ```
-/// use std::mem;
-///
 /// fn write_usize(x: &mut [u8], val: usize) {
-///     assert!(x.len() >= mem::size_of::<usize>());
+///     assert!(x.len() >= size_of::<usize>());
 ///
 ///     let ptr = x.as_mut_ptr() as *mut usize;
 ///
@@ -1667,7 +1663,7 @@ pub const unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
     // `dst` cannot overlap `src` because the caller has mutable access
     // to `dst` while `src` is owned by this function.
     unsafe {
-        copy_nonoverlapping((&raw const src) as *const u8, dst as *mut u8, mem::size_of::<T>());
+        copy_nonoverlapping((&raw const src) as *const u8, dst as *mut u8, size_of::<T>());
         // We are calling the intrinsic directly to avoid function calls in the generated code.
         intrinsics::forget(src);
     }
@@ -1911,7 +1907,7 @@ pub(crate) unsafe fn align_offset<T: Sized>(p: *const T, a: usize) -> usize {
         inverse & m_minus_one
     }
 
-    let stride = mem::size_of::<T>();
+    let stride = size_of::<T>();
 
     let addr: usize = p.addr();
 
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 5a64f12ca99..b960a3d86be 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -1,7 +1,7 @@
 use super::*;
 use crate::cmp::Ordering::{Equal, Greater, Less};
 use crate::intrinsics::const_eval_select;
-use crate::mem::SizedTypeProperties;
+use crate::mem::{self, SizedTypeProperties};
 use crate::slice::{self, SliceIndex};
 
 impl<T: ?Sized> *mut T {
@@ -769,9 +769,9 @@ impl<T: ?Sized> *mut T {
     }
 
     /// Calculates the distance between two pointers within the same allocation. The returned value is in
-    /// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
+    /// units of T: the distance in bytes divided by `size_of::<T>()`.
     ///
-    /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`,
+    /// This is equivalent to `(self as isize - origin as isize) / (size_of::<T>() as isize)`,
     /// except that it has a lot more opportunities for UB, in exchange for the compiler
     /// better understanding what you are doing.
     ///
@@ -807,7 +807,7 @@ impl<T: ?Sized> *mut T {
     /// objects is not known at compile-time. However, the requirement also exists at
     /// runtime and may be exploited by optimizations. If you wish to compute the difference between
     /// pointers that are not guaranteed to be from the same allocation, use `(self as isize -
-    /// origin as isize) / mem::size_of::<T>()`.
+    /// origin as isize) / size_of::<T>()`.
     // FIXME: recommend `addr()` instead of `as usize` once that is stable.
     ///
     /// [`add`]: #method.add
@@ -881,7 +881,7 @@ impl<T: ?Sized> *mut T {
 
     /// Calculates the distance between two pointers within the same allocation, *where it's known that
     /// `self` is equal to or greater than `origin`*. The returned value is in
-    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    /// units of T: the distance in bytes is divided by `size_of::<T>()`.
     ///
     /// This computes the same value that [`offset_from`](#method.offset_from)
     /// would compute, but with the added precondition that the offset is
@@ -1397,7 +1397,7 @@ impl<T: ?Sized> *mut T {
         unsafe { read_unaligned(self) }
     }
 
-    /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
+    /// Copies `count * size_of::<T>()` bytes from `self` to `dest`. The source
     /// and destination may overlap.
     ///
     /// NOTE: this has the *same* argument order as [`ptr::copy`].
@@ -1417,7 +1417,7 @@ impl<T: ?Sized> *mut T {
         unsafe { copy(self, dest, count) }
     }
 
-    /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
+    /// Copies `count * size_of::<T>()` bytes from `self` to `dest`. The source
     /// and destination may *not* overlap.
     ///
     /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`].
@@ -1437,7 +1437,7 @@ impl<T: ?Sized> *mut T {
         unsafe { copy_nonoverlapping(self, dest, count) }
     }
 
-    /// Copies `count * size_of<T>` bytes from `src` to `self`. The source
+    /// Copies `count * size_of::<T>()` bytes from `src` to `self`. The source
     /// and destination may overlap.
     ///
     /// NOTE: this has the *opposite* argument order of [`ptr::copy`].
@@ -1457,7 +1457,7 @@ impl<T: ?Sized> *mut T {
         unsafe { copy(src, self, count) }
     }
 
-    /// Copies `count * size_of<T>` bytes from `src` to `self`. The source
+    /// Copies `count * size_of::<T>()` bytes from `src` to `self`. The source
     /// and destination may *not* overlap.
     ///
     /// NOTE: this has the *opposite* argument order of [`ptr::copy_nonoverlapping`].
@@ -1623,8 +1623,6 @@ impl<T: ?Sized> *mut T {
     /// Accessing adjacent `u8` as `u16`
     ///
     /// ```
-    /// use std::mem::align_of;
-    ///
     /// # unsafe {
     /// let mut x = [5_u8, 6, 7, 8, 9];
     /// let ptr = x.as_mut_ptr();
@@ -1689,7 +1687,7 @@ impl<T: ?Sized> *mut T {
     where
         T: Sized,
     {
-        self.is_aligned_to(mem::align_of::<T>())
+        self.is_aligned_to(align_of::<T>())
     }
 
     /// Returns whether the pointer is aligned to `align`.
@@ -1950,7 +1948,7 @@ impl<T> *mut [T] {
     /// When calling this method, you have to ensure that *either* the pointer is null *or*
     /// all of the following is true:
     ///
-    /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::<T>()` many bytes,
+    /// * The pointer must be [valid] for reads for `ptr.len() * size_of::<T>()` many bytes,
     ///   and it must be properly aligned. This means in particular:
     ///
     ///     * The entire memory range of this slice must be contained within a single [allocated object]!
@@ -1962,7 +1960,7 @@ impl<T> *mut [T] {
     ///       them from other data. You can obtain a pointer that is usable as `data`
     ///       for zero-length slices using [`NonNull::dangling()`].
     ///
-    /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+    /// * The total size `ptr.len() * size_of::<T>()` of the slice must be no larger than `isize::MAX`.
     ///   See the safety documentation of [`pointer::offset`].
     ///
     /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
@@ -2008,7 +2006,7 @@ impl<T> *mut [T] {
     /// When calling this method, you have to ensure that *either* the pointer is null *or*
     /// all of the following is true:
     ///
-    /// * The pointer must be [valid] for reads and writes for `ptr.len() * mem::size_of::<T>()`
+    /// * The pointer must be [valid] for reads and writes for `ptr.len() * size_of::<T>()`
     ///   many bytes, and it must be properly aligned. This means in particular:
     ///
     ///     * The entire memory range of this slice must be contained within a single [allocated object]!
@@ -2020,7 +2018,7 @@ impl<T> *mut [T] {
     ///       them from other data. You can obtain a pointer that is usable as `data`
     ///       for zero-length slices using [`NonNull::dangling()`].
     ///
-    /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+    /// * The total size `ptr.len() * size_of::<T>()` of the slice must be no larger than `isize::MAX`.
     ///   See the safety documentation of [`pointer::offset`].
     ///
     /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 7abd3ddaa9e..c769ba673c6 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -49,7 +49,6 @@ use crate::{fmt, hash, intrinsics, mem, ptr};
 /// are guaranteed to have the same size and alignment:
 ///
 /// ```
-/// # use std::mem::{size_of, align_of};
 /// use std::ptr::NonNull;
 ///
 /// assert_eq!(size_of::<NonNull<i16>>(), size_of::<Option<NonNull<i16>>>());
@@ -724,9 +723,9 @@ impl<T: ?Sized> NonNull<T> {
     }
 
     /// Calculates the distance between two pointers within the same allocation. The returned value is in
-    /// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
+    /// units of T: the distance in bytes divided by `size_of::<T>()`.
     ///
-    /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`,
+    /// This is equivalent to `(self as isize - origin as isize) / (size_of::<T>() as isize)`,
     /// except that it has a lot more opportunities for UB, in exchange for the compiler
     /// better understanding what you are doing.
     ///
@@ -762,7 +761,7 @@ impl<T: ?Sized> NonNull<T> {
     /// objects is not known at compile-time. However, the requirement also exists at
     /// runtime and may be exploited by optimizations. If you wish to compute the difference between
     /// pointers that are not guaranteed to be from the same allocation, use `(self as isize -
-    /// origin as isize) / mem::size_of::<T>()`.
+    /// origin as isize) / size_of::<T>()`.
     // FIXME: recommend `addr()` instead of `as usize` once that is stable.
     ///
     /// [`add`]: #method.add
@@ -842,7 +841,7 @@ impl<T: ?Sized> NonNull<T> {
 
     /// Calculates the distance between two pointers within the same allocation, *where it's known that
     /// `self` is equal to or greater than `origin`*. The returned value is in
-    /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
+    /// units of T: the distance in bytes is divided by `size_of::<T>()`.
     ///
     /// This computes the same value that [`offset_from`](#method.offset_from)
     /// would compute, but with the added precondition that the offset is
@@ -989,7 +988,7 @@ impl<T: ?Sized> NonNull<T> {
         unsafe { ptr::read_unaligned(self.as_ptr()) }
     }
 
-    /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
+    /// Copies `count * size_of::<T>()` bytes from `self` to `dest`. The source
     /// and destination may overlap.
     ///
     /// NOTE: this has the *same* argument order as [`ptr::copy`].
@@ -1009,7 +1008,7 @@ impl<T: ?Sized> NonNull<T> {
         unsafe { ptr::copy(self.as_ptr(), dest.as_ptr(), count) }
     }
 
-    /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
+    /// Copies `count * size_of::<T>()` bytes from `self` to `dest`. The source
     /// and destination may *not* overlap.
     ///
     /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`].
@@ -1029,7 +1028,7 @@ impl<T: ?Sized> NonNull<T> {
         unsafe { ptr::copy_nonoverlapping(self.as_ptr(), dest.as_ptr(), count) }
     }
 
-    /// Copies `count * size_of<T>` bytes from `src` to `self`. The source
+    /// Copies `count * size_of::<T>()` bytes from `src` to `self`. The source
     /// and destination may overlap.
     ///
     /// NOTE: this has the *opposite* argument order of [`ptr::copy`].
@@ -1049,7 +1048,7 @@ impl<T: ?Sized> NonNull<T> {
         unsafe { ptr::copy(src.as_ptr(), self.as_ptr(), count) }
     }
 
-    /// Copies `count * size_of<T>` bytes from `src` to `self`. The source
+    /// Copies `count * size_of::<T>()` bytes from `src` to `self`. The source
     /// and destination may *not* overlap.
     ///
     /// NOTE: this has the *opposite* argument order of [`ptr::copy_nonoverlapping`].
@@ -1223,7 +1222,6 @@ impl<T: ?Sized> NonNull<T> {
     /// Accessing adjacent `u8` as `u16`
     ///
     /// ```
-    /// use std::mem::align_of;
     /// use std::ptr::NonNull;
     ///
     /// # unsafe {
@@ -1443,7 +1441,7 @@ impl<T> NonNull<[T]> {
     ///
     /// When calling this method, you have to ensure that all of the following is true:
     ///
-    /// * The pointer must be [valid] for reads for `ptr.len() * mem::size_of::<T>()` many bytes,
+    /// * The pointer must be [valid] for reads for `ptr.len() * size_of::<T>()` many bytes,
     ///   and it must be properly aligned. This means in particular:
     ///
     ///     * The entire memory range of this slice must be contained within a single allocated object!
@@ -1455,7 +1453,7 @@ impl<T> NonNull<[T]> {
     ///       them from other data. You can obtain a pointer that is usable as `data`
     ///       for zero-length slices using [`NonNull::dangling()`].
     ///
-    /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+    /// * The total size `ptr.len() * size_of::<T>()` of the slice must be no larger than `isize::MAX`.
     ///   See the safety documentation of [`pointer::offset`].
     ///
     /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
@@ -1488,7 +1486,7 @@ impl<T> NonNull<[T]> {
     ///
     /// When calling this method, you have to ensure that all of the following is true:
     ///
-    /// * The pointer must be [valid] for reads and writes for `ptr.len() * mem::size_of::<T>()`
+    /// * The pointer must be [valid] for reads and writes for `ptr.len() * size_of::<T>()`
     ///   many bytes, and it must be properly aligned. This means in particular:
     ///
     ///     * The entire memory range of this slice must be contained within a single allocated object!
@@ -1500,7 +1498,7 @@ impl<T> NonNull<[T]> {
     ///       them from other data. You can obtain a pointer that is usable as `data`
     ///       for zero-length slices using [`NonNull::dangling()`].
     ///
-    /// * The total size `ptr.len() * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+    /// * The total size `ptr.len() * size_of::<T>()` of the slice must be no larger than `isize::MAX`.
     ///   See the safety documentation of [`pointer::offset`].
     ///
     /// * You must enforce Rust's aliasing rules, since the returned lifetime `'a` is
diff --git a/library/core/src/slice/cmp.rs b/library/core/src/slice/cmp.rs
index 9cb00644e64..804bdfcbb4f 100644
--- a/library/core/src/slice/cmp.rs
+++ b/library/core/src/slice/cmp.rs
@@ -1,10 +1,10 @@
 //! Comparison traits for `[T]`.
 
 use super::{from_raw_parts, memchr};
+use crate::ascii;
 use crate::cmp::{self, BytewiseEq, Ordering};
 use crate::intrinsics::compare_bytes;
 use crate::num::NonZero;
-use crate::{ascii, mem};
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T, U> PartialEq<[U]> for [T]
@@ -87,7 +87,7 @@ where
         // SAFETY: `self` and `other` are references and are thus guaranteed to be valid.
         // The two slices have been checked to have the same size above.
         unsafe {
-            let size = mem::size_of_val(self);
+            let size = size_of_val(self);
             compare_bytes(self.as_ptr() as *const u8, other.as_ptr() as *const u8, size) == 0
         }
     }
@@ -266,7 +266,7 @@ macro_rules! impl_slice_contains {
                 fn slice_contains(&self, arr: &[$t]) -> bool {
                     // Make our LANE_COUNT 4x the normal lane count (aiming for 128 bit vectors).
                     // The compiler will nicely unroll it.
-                    const LANE_COUNT: usize = 4 * (128 / (mem::size_of::<$t>() * 8));
+                    const LANE_COUNT: usize = 4 * (128 / (size_of::<$t>() * 8));
                     // SIMD
                     let mut chunks = arr.chunks_exact(LANE_COUNT);
                     for chunk in &mut chunks {
diff --git a/library/core/src/slice/memchr.rs b/library/core/src/slice/memchr.rs
index 98db7aaf533..1e1053583a6 100644
--- a/library/core/src/slice/memchr.rs
+++ b/library/core/src/slice/memchr.rs
@@ -2,11 +2,10 @@
 // Copyright 2015 Andrew Gallant, bluss and Nicolas Koch
 
 use crate::intrinsics::const_eval_select;
-use crate::mem;
 
 const LO_USIZE: usize = usize::repeat_u8(0x01);
 const HI_USIZE: usize = usize::repeat_u8(0x80);
-const USIZE_BYTES: usize = mem::size_of::<usize>();
+const USIZE_BYTES: usize = size_of::<usize>();
 
 /// Returns `true` if `x` contains any zero byte.
 ///
@@ -138,7 +137,7 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
     // offset is always aligned, so just testing `>` is sufficient and avoids possible
     // overflow.
     let repeated_x = usize::repeat_u8(x);
-    let chunk_bytes = mem::size_of::<Chunk>();
+    let chunk_bytes = size_of::<Chunk>();
 
     while offset > min_aligned_offset {
         // SAFETY: offset starts at len - suffix.len(), as long as it is greater than
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 7a2764206e8..3570d8d0876 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -78,7 +78,7 @@ pub use raw::{from_raw_parts, from_raw_parts_mut};
 
 /// Calculates the direction and split point of a one-sided range.
 ///
-/// This is a helper function for `take` and `take_mut` that returns
+/// This is a helper function for `split_off` and `split_off_mut` that returns
 /// the direction of the split (front or back) as well as the index at
 /// which to split. Returns `None` if the split index would overflow.
 #[inline]
@@ -3732,8 +3732,7 @@ impl<T> [T] {
     #[doc(alias = "memcpy")]
     #[inline]
     #[stable(feature = "copy_from_slice", since = "1.9.0")]
-    #[rustc_const_unstable(feature = "const_copy_from_slice", issue = "131415")]
-    #[rustc_const_stable_indirect]
+    #[rustc_const_stable(feature = "const_copy_from_slice", since = "CURRENT_RUSTC_VERSION")]
     #[track_caller]
     pub const fn copy_from_slice(&mut self, src: &[T])
     where
@@ -3894,9 +3893,9 @@ impl<T> [T] {
 
         // Explicitly wrap the function call in a const block so it gets
         // constant-evaluated even in debug mode.
-        let gcd: usize = const { gcd(mem::size_of::<T>(), mem::size_of::<U>()) };
-        let ts: usize = mem::size_of::<U>() / gcd;
-        let us: usize = mem::size_of::<T>() / gcd;
+        let gcd: usize = const { gcd(size_of::<T>(), size_of::<U>()) };
+        let ts: usize = size_of::<U>() / gcd;
+        let us: usize = size_of::<T>() / gcd;
 
         // Armed with this knowledge, we can find how many `U`s we can fit!
         let us_len = self.len() / ts * us;
@@ -3946,7 +3945,7 @@ impl<T> [T] {
         // ptr.align_offset.
         let ptr = self.as_ptr();
         // SAFETY: See the `align_to_mut` method for the detailed safety comment.
-        let offset = unsafe { crate::ptr::align_offset(ptr, mem::align_of::<U>()) };
+        let offset = unsafe { crate::ptr::align_offset(ptr, align_of::<U>()) };
         if offset > self.len() {
             (self, &[], &[])
         } else {
@@ -3956,7 +3955,7 @@ impl<T> [T] {
             #[cfg(miri)]
             crate::intrinsics::miri_promise_symbolic_alignment(
                 rest.as_ptr().cast(),
-                mem::align_of::<U>(),
+                align_of::<U>(),
             );
             // SAFETY: now `rest` is definitely aligned, so `from_raw_parts` below is okay,
             // since the caller guarantees that we can transmute `T` to `U` safely.
@@ -4017,7 +4016,7 @@ impl<T> [T] {
         // valid pointer `ptr` (it comes from a reference to `self`) and with
         // a size that is a power of two (since it comes from the alignment for U),
         // satisfying its safety constraints.
-        let offset = unsafe { crate::ptr::align_offset(ptr, mem::align_of::<U>()) };
+        let offset = unsafe { crate::ptr::align_offset(ptr, align_of::<U>()) };
         if offset > self.len() {
             (self, &mut [], &mut [])
         } else {
@@ -4029,7 +4028,7 @@ impl<T> [T] {
             #[cfg(miri)]
             crate::intrinsics::miri_promise_symbolic_alignment(
                 mut_ptr.cast() as *const (),
-                mem::align_of::<U>(),
+                align_of::<U>(),
             );
             // We can't use `rest` again after this, that would invalidate its alias `mut_ptr`!
             // SAFETY: see comments for `align_to`.
@@ -4100,7 +4099,7 @@ impl<T> [T] {
         // These are expected to always match, as vector types are laid out like
         // arrays per <https://llvm.org/docs/LangRef.html#vector-type>, but we
         // might as well double-check since it'll optimize away anyhow.
-        assert_eq!(mem::size_of::<Simd<T, LANES>>(), mem::size_of::<[T; LANES]>());
+        assert_eq!(size_of::<Simd<T, LANES>>(), size_of::<[T; LANES]>());
 
         // SAFETY: The simd types have the same layout as arrays, just with
         // potentially-higher alignment, so the de-facto transmutes are sound.
@@ -4136,7 +4135,7 @@ impl<T> [T] {
         // These are expected to always match, as vector types are laid out like
         // arrays per <https://llvm.org/docs/LangRef.html#vector-type>, but we
         // might as well double-check since it'll optimize away anyhow.
-        assert_eq!(mem::size_of::<Simd<T, LANES>>(), mem::size_of::<[T; LANES]>());
+        assert_eq!(size_of::<Simd<T, LANES>>(), size_of::<[T; LANES]>());
 
         // SAFETY: The simd types have the same layout as arrays, just with
         // potentially-higher alignment, so the de-facto transmutes are sound.
@@ -4313,8 +4312,6 @@ impl<T> [T] {
     /// Splitting off the first three elements of a slice:
     ///
     /// ```
-    /// #![feature(slice_take)]
-    ///
     /// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
     /// let mut first_three = slice.split_off(..3).unwrap();
     ///
@@ -4325,8 +4322,6 @@ impl<T> [T] {
     /// Splitting off the last two elements of a slice:
     ///
     /// ```
-    /// #![feature(slice_take)]
-    ///
     /// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
     /// let mut tail = slice.split_off(2..).unwrap();
     ///
@@ -4337,8 +4332,6 @@ impl<T> [T] {
     /// Getting `None` when `range` is out of bounds:
     ///
     /// ```
-    /// #![feature(slice_take)]
-    ///
     /// let mut slice: &[_] = &['a', 'b', 'c', 'd'];
     ///
     /// assert_eq!(None, slice.split_off(5..));
@@ -4349,7 +4342,7 @@ impl<T> [T] {
     /// ```
     #[inline]
     #[must_use = "method does not modify the slice if the range is out of bounds"]
-    #[unstable(feature = "slice_take", issue = "62280")]
+    #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
     pub fn split_off<'a, R: OneSidedRange<usize>>(
         self: &mut &'a Self,
         range: R,
@@ -4385,8 +4378,6 @@ impl<T> [T] {
     /// Splitting off the first three elements of a slice:
     ///
     /// ```
-    /// #![feature(slice_take)]
-    ///
     /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
     /// let mut first_three = slice.split_off_mut(..3).unwrap();
     ///
@@ -4397,8 +4388,6 @@ impl<T> [T] {
     /// Taking the last two elements of a slice:
     ///
     /// ```
-    /// #![feature(slice_take)]
-    ///
     /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
     /// let mut tail = slice.split_off_mut(2..).unwrap();
     ///
@@ -4409,8 +4398,6 @@ impl<T> [T] {
     /// Getting `None` when `range` is out of bounds:
     ///
     /// ```
-    /// #![feature(slice_take)]
-    ///
     /// let mut slice: &mut [_] = &mut ['a', 'b', 'c', 'd'];
     ///
     /// assert_eq!(None, slice.split_off_mut(5..));
@@ -4421,7 +4408,7 @@ impl<T> [T] {
     /// ```
     #[inline]
     #[must_use = "method does not modify the slice if the range is out of bounds"]
-    #[unstable(feature = "slice_take", issue = "62280")]
+    #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
     pub fn split_off_mut<'a, R: OneSidedRange<usize>>(
         self: &mut &'a mut Self,
         range: R,
@@ -4451,8 +4438,6 @@ impl<T> [T] {
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_take)]
-    ///
     /// let mut slice: &[_] = &['a', 'b', 'c'];
     /// let first = slice.split_off_first().unwrap();
     ///
@@ -4460,7 +4445,7 @@ impl<T> [T] {
     /// assert_eq!(first, &'a');
     /// ```
     #[inline]
-    #[unstable(feature = "slice_take", issue = "62280")]
+    #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
     pub fn split_off_first<'a>(self: &mut &'a Self) -> Option<&'a T> {
         let (first, rem) = self.split_first()?;
         *self = rem;
@@ -4475,8 +4460,6 @@ impl<T> [T] {
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_take)]
-    ///
     /// let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
     /// let first = slice.split_off_first_mut().unwrap();
     /// *first = 'd';
@@ -4485,7 +4468,7 @@ impl<T> [T] {
     /// assert_eq!(first, &'d');
     /// ```
     #[inline]
-    #[unstable(feature = "slice_take", issue = "62280")]
+    #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
     pub fn split_off_first_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
         let (first, rem) = mem::take(self).split_first_mut()?;
         *self = rem;
@@ -4500,8 +4483,6 @@ impl<T> [T] {
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_take)]
-    ///
     /// let mut slice: &[_] = &['a', 'b', 'c'];
     /// let last = slice.split_off_last().unwrap();
     ///
@@ -4509,7 +4490,7 @@ impl<T> [T] {
     /// assert_eq!(last, &'c');
     /// ```
     #[inline]
-    #[unstable(feature = "slice_take", issue = "62280")]
+    #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
     pub fn split_off_last<'a>(self: &mut &'a Self) -> Option<&'a T> {
         let (last, rem) = self.split_last()?;
         *self = rem;
@@ -4524,8 +4505,6 @@ impl<T> [T] {
     /// # Examples
     ///
     /// ```
-    /// #![feature(slice_take)]
-    ///
     /// let mut slice: &mut [_] = &mut ['a', 'b', 'c'];
     /// let last = slice.split_off_last_mut().unwrap();
     /// *last = 'd';
@@ -4534,7 +4513,7 @@ impl<T> [T] {
     /// assert_eq!(last, &'d');
     /// ```
     #[inline]
-    #[unstable(feature = "slice_take", issue = "62280")]
+    #[stable(feature = "slice_take", since = "CURRENT_RUSTC_VERSION")]
     pub fn split_off_last_mut<'a>(self: &mut &'a mut Self) -> Option<&'a mut T> {
         let (last, rem) = mem::take(self).split_last_mut()?;
         *self = rem;
@@ -4721,11 +4700,11 @@ impl<T> [T] {
 
         let byte_offset = elem_start.wrapping_sub(self_start);
 
-        if byte_offset % mem::size_of::<T>() != 0 {
+        if byte_offset % size_of::<T>() != 0 {
             return None;
         }
 
-        let offset = byte_offset / mem::size_of::<T>();
+        let offset = byte_offset / size_of::<T>();
 
         if offset < self.len() { Some(offset) } else { None }
     }
@@ -4775,11 +4754,11 @@ impl<T> [T] {
 
         let byte_start = subslice_start.wrapping_sub(self_start);
 
-        if byte_start % core::mem::size_of::<T>() != 0 {
+        if byte_start % size_of::<T>() != 0 {
             return None;
         }
 
-        let start = byte_start / core::mem::size_of::<T>();
+        let start = byte_start / size_of::<T>();
         let end = start.wrapping_add(subslice.len());
 
         if start <= self.len() && end <= self.len() { Some(start..end) } else { None }
diff --git a/library/core/src/slice/raw.rs b/library/core/src/slice/raw.rs
index e24b52cff82..3582c7e8b3f 100644
--- a/library/core/src/slice/raw.rs
+++ b/library/core/src/slice/raw.rs
@@ -11,7 +11,7 @@ use crate::{array, ptr, ub_checks};
 ///
 /// Behavior is undefined if any of the following conditions are violated:
 ///
-/// * `data` must be non-null, [valid] for reads for `len * mem::size_of::<T>()` many bytes,
+/// * `data` must be non-null, [valid] for reads for `len * size_of::<T>()` many bytes,
 ///   and it must be properly aligned. This means in particular:
 ///
 ///     * The entire memory range of this slice must be contained within a single allocated object!
@@ -28,7 +28,7 @@ use crate::{array, ptr, ub_checks};
 /// * The memory referenced by the returned slice must not be mutated for the duration
 ///   of lifetime `'a`, except inside an `UnsafeCell`.
 ///
-/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`,
+/// * The total size `len * size_of::<T>()` of the slice must be no larger than `isize::MAX`,
 ///   and adding that size to `data` must not "wrap around" the address space.
 ///   See the safety documentation of [`pointer::offset`].
 ///
@@ -146,7 +146,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T]
 ///
 /// Behavior is undefined if any of the following conditions are violated:
 ///
-/// * `data` must be non-null, [valid] for both reads and writes for `len * mem::size_of::<T>()` many bytes,
+/// * `data` must be non-null, [valid] for both reads and writes for `len * size_of::<T>()` many bytes,
 ///   and it must be properly aligned. This means in particular:
 ///
 ///     * The entire memory range of this slice must be contained within a single allocated object!
@@ -163,7 +163,7 @@ pub const unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T]
 ///   (not derived from the return value) for the duration of lifetime `'a`.
 ///   Both read and write accesses are forbidden.
 ///
-/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`,
+/// * The total size `len * size_of::<T>()` of the slice must be no larger than `isize::MAX`,
 ///   and adding that size to `data` must not "wrap around" the address space.
 ///   See the safety documentation of [`pointer::offset`].
 ///
diff --git a/library/core/src/slice/rotate.rs b/library/core/src/slice/rotate.rs
index 5d5ee4c7b62..80178f297ea 100644
--- a/library/core/src/slice/rotate.rs
+++ b/library/core/src/slice/rotate.rs
@@ -1,4 +1,4 @@
-use crate::mem::{self, MaybeUninit, SizedTypeProperties};
+use crate::mem::{MaybeUninit, SizedTypeProperties};
 use crate::{cmp, ptr};
 
 type BufType = [usize; 32];
@@ -21,12 +21,12 @@ pub(super) unsafe fn ptr_rotate<T>(left: usize, mid: *mut T, right: usize) {
     }
     // `T` is not a zero-sized type, so it's okay to divide by its size.
     if !cfg!(feature = "optimize_for_size")
-        && cmp::min(left, right) <= mem::size_of::<BufType>() / mem::size_of::<T>()
+        && cmp::min(left, right) <= size_of::<BufType>() / size_of::<T>()
     {
         // SAFETY: guaranteed by the caller
         unsafe { ptr_rotate_memmove(left, mid, right) };
     } else if !cfg!(feature = "optimize_for_size")
-        && ((left + right < 24) || (mem::size_of::<T>() > mem::size_of::<[usize; 4]>()))
+        && ((left + right < 24) || (size_of::<T>() > size_of::<[usize; 4]>()))
     {
         // SAFETY: guaranteed by the caller
         unsafe { ptr_rotate_gcd(left, mid, right) }
diff --git a/library/core/src/slice/sort/shared/smallsort.rs b/library/core/src/slice/sort/shared/smallsort.rs
index f6dcf42ba60..95f196a40d0 100644
--- a/library/core/src/slice/sort/shared/smallsort.rs
+++ b/library/core/src/slice/sort/shared/smallsort.rs
@@ -113,7 +113,7 @@ pub(crate) trait UnstableSmallSortFreezeTypeImpl: Sized + FreezeMarker {
 impl<T: FreezeMarker> UnstableSmallSortFreezeTypeImpl for T {
     #[inline(always)]
     default fn small_sort_threshold() -> usize {
-        if (mem::size_of::<T>() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE {
+        if (size_of::<T>() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE {
             SMALL_SORT_GENERAL_THRESHOLD
         } else {
             SMALL_SORT_FALLBACK_THRESHOLD
@@ -125,7 +125,7 @@ impl<T: FreezeMarker> UnstableSmallSortFreezeTypeImpl for T {
     where
         F: FnMut(&T, &T) -> bool,
     {
-        if (mem::size_of::<T>() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE {
+        if (size_of::<T>() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE {
             small_sort_general(v, is_less);
         } else {
             small_sort_fallback(v, is_less);
@@ -143,10 +143,10 @@ impl<T: FreezeMarker + CopyMarker> UnstableSmallSortFreezeTypeImpl for T {
     #[inline(always)]
     fn small_sort_threshold() -> usize {
         if has_efficient_in_place_swap::<T>()
-            && (mem::size_of::<T>() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE
+            && (size_of::<T>() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE
         {
             SMALL_SORT_NETWORK_THRESHOLD
-        } else if (mem::size_of::<T>() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE {
+        } else if (size_of::<T>() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE {
             SMALL_SORT_GENERAL_THRESHOLD
         } else {
             SMALL_SORT_FALLBACK_THRESHOLD
@@ -159,10 +159,10 @@ impl<T: FreezeMarker + CopyMarker> UnstableSmallSortFreezeTypeImpl for T {
         F: FnMut(&T, &T) -> bool,
     {
         if has_efficient_in_place_swap::<T>()
-            && (mem::size_of::<T>() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE
+            && (size_of::<T>() * SMALL_SORT_NETWORK_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE
         {
             small_sort_network(v, is_less);
-        } else if (mem::size_of::<T>() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE {
+        } else if (size_of::<T>() * SMALL_SORT_GENERAL_SCRATCH_LEN) <= MAX_STACK_ARRAY_SIZE {
             small_sort_general(v, is_less);
         } else {
             small_sort_fallback(v, is_less);
@@ -238,7 +238,7 @@ fn small_sort_general_with_scratch<T: FreezeMarker, F: FnMut(&T, &T) -> bool>(
     unsafe {
         let scratch_base = scratch.as_mut_ptr() as *mut T;
 
-        let presorted_len = if const { mem::size_of::<T>() <= 16 } && len >= 16 {
+        let presorted_len = if const { size_of::<T>() <= 16 } && len >= 16 {
             // SAFETY: scratch_base is valid and has enough space.
             sort8_stable(v_base, scratch_base, scratch_base.add(len), is_less);
             sort8_stable(
@@ -863,5 +863,5 @@ fn panic_on_ord_violation() -> ! {
 #[must_use]
 pub(crate) const fn has_efficient_in_place_swap<T>() -> bool {
     // Heuristic that holds true on all tested 64-bit capable architectures.
-    mem::size_of::<T>() <= 8 // mem::size_of::<u64>()
+    size_of::<T>() <= 8 // size_of::<u64>()
 }
diff --git a/library/core/src/slice/sort/stable/mod.rs b/library/core/src/slice/sort/stable/mod.rs
index 3ff2e71fd05..090367cdaba 100644
--- a/library/core/src/slice/sort/stable/mod.rs
+++ b/library/core/src/slice/sort/stable/mod.rs
@@ -3,7 +3,7 @@
 #[cfg(not(any(feature = "optimize_for_size", target_pointer_width = "16")))]
 use crate::cmp;
 use crate::intrinsics;
-use crate::mem::{self, MaybeUninit, SizedTypeProperties};
+use crate::mem::{MaybeUninit, SizedTypeProperties};
 #[cfg(not(any(feature = "optimize_for_size", target_pointer_width = "16")))]
 use crate::slice::sort::shared::smallsort::{
     SMALL_SORT_GENERAL_SCRATCH_LEN, StableSmallSortTypeImpl, insertion_sort_shift_left,
@@ -107,7 +107,7 @@ fn driftsort_main<T, F: FnMut(&T, &T) -> bool, BufT: BufGuard<T>>(v: &mut [T], i
     // If min_good_run_len is ever modified, this code must be updated to allocate
     // the correct scratch size for it.
     const MAX_FULL_ALLOC_BYTES: usize = 8_000_000; // 8MB
-    let max_full_alloc = MAX_FULL_ALLOC_BYTES / mem::size_of::<T>();
+    let max_full_alloc = MAX_FULL_ALLOC_BYTES / size_of::<T>();
     let len = v.len();
     let alloc_len = cmp::max(
         cmp::max(len - len / 2, cmp::min(len, max_full_alloc)),
@@ -155,7 +155,7 @@ impl<T, const N: usize> AlignedStorage<T, N> {
     }
 
     fn as_uninit_slice_mut(&mut self) -> &mut [MaybeUninit<T>] {
-        let len = N / mem::size_of::<T>();
+        let len = N / size_of::<T>();
 
         // SAFETY: `_align` ensures we are correctly aligned.
         unsafe { core::slice::from_raw_parts_mut(self.storage.as_mut_ptr().cast(), len) }
diff --git a/library/core/src/slice/sort/stable/quicksort.rs b/library/core/src/slice/sort/stable/quicksort.rs
index 630c6ff9077..3c9688790c4 100644
--- a/library/core/src/slice/sort/stable/quicksort.rs
+++ b/library/core/src/slice/sort/stable/quicksort.rs
@@ -1,6 +1,6 @@
 //! This module contains a stable quicksort and partition implementation.
 
-use crate::mem::{self, ManuallyDrop, MaybeUninit};
+use crate::mem::{ManuallyDrop, MaybeUninit};
 use crate::slice::sort::shared::FreezeMarker;
 use crate::slice::sort::shared::pivot::choose_pivot;
 use crate::slice::sort::shared::smallsort::StableSmallSortTypeImpl;
@@ -126,7 +126,7 @@ fn stable_partition<T, F: FnMut(&T, &T) -> bool>(
             // this gave significant performance boosts in benchmarks. Unrolling
             // through for _ in 0..UNROLL_LEN { .. } instead of manually improves
             // compile times but has a ~10-20% performance penalty on opt-level=s.
-            if const { mem::size_of::<T>() <= 16 } {
+            if const { size_of::<T>() <= 16 } {
                 const UNROLL_LEN: usize = 4;
                 let unroll_end = v_base.add(loop_end_pos.saturating_sub(UNROLL_LEN - 1));
                 while state.scan < unroll_end {
diff --git a/library/core/src/slice/sort/unstable/quicksort.rs b/library/core/src/slice/sort/unstable/quicksort.rs
index bb9f90fc881..68a16118716 100644
--- a/library/core/src/slice/sort/unstable/quicksort.rs
+++ b/library/core/src/slice/sort/unstable/quicksort.rs
@@ -1,6 +1,8 @@
 //! This module contains an unstable quicksort and two partition implementations.
 
-use crate::mem::{self, ManuallyDrop};
+#[cfg(not(feature = "optimize_for_size"))]
+use crate::mem;
+use crate::mem::ManuallyDrop;
 #[cfg(not(feature = "optimize_for_size"))]
 use crate::slice::sort::shared::pivot::choose_pivot;
 #[cfg(not(feature = "optimize_for_size"))]
@@ -137,7 +139,7 @@ where
 
 const fn inst_partition<T, F: FnMut(&T, &T) -> bool>() -> fn(&mut [T], &T, &mut F) -> usize {
     const MAX_BRANCHLESS_PARTITION_SIZE: usize = 96;
-    if mem::size_of::<T>() <= MAX_BRANCHLESS_PARTITION_SIZE {
+    if size_of::<T>() <= MAX_BRANCHLESS_PARTITION_SIZE {
         // Specialize for types that are relatively cheap to copy, where branchless optimizations
         // have large leverage e.g. `u64` and `String`.
         cfg_if! {
@@ -304,7 +306,7 @@ where
 
         // Manual unrolling that works well on x86, Arm and with opt-level=s without murdering
         // compile-times. Leaving this to the compiler yields ok to bad results.
-        let unroll_len = const { if mem::size_of::<T>() <= 16 { 2 } else { 1 } };
+        let unroll_len = const { if size_of::<T>() <= 16 { 2 } else { 1 } };
 
         let unroll_end = v_base.add(len - (unroll_len - 1));
         while state.right < unroll_end {
diff --git a/library/core/src/str/count.rs b/library/core/src/str/count.rs
index b5d7aaf05d4..452403b23de 100644
--- a/library/core/src/str/count.rs
+++ b/library/core/src/str/count.rs
@@ -20,7 +20,7 @@
 
 use core::intrinsics::unlikely;
 
-const USIZE_SIZE: usize = core::mem::size_of::<usize>();
+const USIZE_SIZE: usize = size_of::<usize>();
 const UNROLL_INNER: usize = 4;
 
 #[inline]
diff --git a/library/core/src/str/validations.rs b/library/core/src/str/validations.rs
index 0f724dd9613..8174e4ff97d 100644
--- a/library/core/src/str/validations.rs
+++ b/library/core/src/str/validations.rs
@@ -2,7 +2,6 @@
 
 use super::Utf8Error;
 use crate::intrinsics::const_eval_select;
-use crate::mem;
 
 /// Returns the initial codepoint accumulator for the first byte.
 /// The first byte is special, only want bottom 5 bits for width 2, 4 bits
@@ -128,7 +127,7 @@ pub(super) const fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
     let mut index = 0;
     let len = v.len();
 
-    const USIZE_BYTES: usize = mem::size_of::<usize>();
+    const USIZE_BYTES: usize = size_of::<usize>();
 
     let ascii_block_size = 2 * USIZE_BYTES;
     let blocks_end = if len >= ascii_block_size { len - ascii_block_size + 1 } else { 0 };
diff --git a/library/core/src/sync/atomic.rs b/library/core/src/sync/atomic.rs
index 73180bde54a..bac92ef94e7 100644
--- a/library/core/src/sync/atomic.rs
+++ b/library/core/src/sync/atomic.rs
@@ -2033,7 +2033,7 @@ impl<T> AtomicPtr<T> {
     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub fn fetch_ptr_add(&self, val: usize, order: Ordering) -> *mut T {
-        self.fetch_byte_add(val.wrapping_mul(core::mem::size_of::<T>()), order)
+        self.fetch_byte_add(val.wrapping_mul(size_of::<T>()), order)
     }
 
     /// Offsets the pointer's address by subtracting `val` (in units of `T`),
@@ -2078,7 +2078,7 @@ impl<T> AtomicPtr<T> {
     #[unstable(feature = "strict_provenance_atomic_ptr", issue = "99108")]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub fn fetch_ptr_sub(&self, val: usize, order: Ordering) -> *mut T {
-        self.fetch_byte_sub(val.wrapping_mul(core::mem::size_of::<T>()), order)
+        self.fetch_byte_sub(val.wrapping_mul(size_of::<T>()), order)
     }
 
     /// Offsets the pointer's address by adding `val` *bytes*, returning the
diff --git a/library/coretests/benches/ascii/is_ascii.rs b/library/coretests/benches/ascii/is_ascii.rs
index ced7084fb0e..a6c718409ee 100644
--- a/library/coretests/benches/ascii/is_ascii.rs
+++ b/library/coretests/benches/ascii/is_ascii.rs
@@ -95,7 +95,7 @@ benches! {
 // These are separate since it's easier to debug errors if they don't go through
 // macro expansion first.
 fn is_ascii_align_to(bytes: &[u8]) -> bool {
-    if bytes.len() < core::mem::size_of::<usize>() {
+    if bytes.len() < size_of::<usize>() {
         return bytes.iter().all(|b| b.is_ascii());
     }
     // SAFETY: transmuting a sequence of `u8` to `usize` is always fine
@@ -106,7 +106,7 @@ fn is_ascii_align_to(bytes: &[u8]) -> bool {
 }
 
 fn is_ascii_align_to_unrolled(bytes: &[u8]) -> bool {
-    if bytes.len() < core::mem::size_of::<usize>() {
+    if bytes.len() < size_of::<usize>() {
         return bytes.iter().all(|b| b.is_ascii());
     }
     // SAFETY: transmuting a sequence of `u8` to `[usize; 2]` is always fine
@@ -118,6 +118,6 @@ fn is_ascii_align_to_unrolled(bytes: &[u8]) -> bool {
 
 #[inline]
 fn contains_nonascii(v: usize) -> bool {
-    const NONASCII_MASK: usize = usize::from_ne_bytes([0x80; core::mem::size_of::<usize>()]);
+    const NONASCII_MASK: usize = usize::from_ne_bytes([0x80; size_of::<usize>()]);
     (NONASCII_MASK & v) != 0
 }
diff --git a/library/coretests/benches/iter.rs b/library/coretests/benches/iter.rs
index e14f26b7290..e49d152eb53 100644
--- a/library/coretests/benches/iter.rs
+++ b/library/coretests/benches/iter.rs
@@ -1,6 +1,5 @@
 use core::borrow::Borrow;
 use core::iter::*;
-use core::mem;
 use core::num::Wrapping;
 use core::ops::Range;
 
@@ -477,7 +476,7 @@ fn bench_next_chunk_copied(b: &mut Bencher) {
         let mut iter = black_box(&v).iter().copied();
         let mut acc = Wrapping(0);
         // This uses a while-let loop to side-step the TRA specialization in ArrayChunks
-        while let Ok(chunk) = iter.next_chunk::<{ mem::size_of::<u64>() }>() {
+        while let Ok(chunk) = iter.next_chunk::<{ size_of::<u64>() }>() {
             let d = u64::from_ne_bytes(chunk);
             acc += Wrapping(d.rotate_left(7).wrapping_add(1));
         }
@@ -496,7 +495,7 @@ fn bench_next_chunk_trusted_random_access(b: &mut Bencher) {
             .iter()
             // this shows that we're not relying on the slice::Iter specialization in Copied
             .map(|b| *b.borrow())
-            .array_chunks::<{ mem::size_of::<u64>() }>()
+            .array_chunks::<{ size_of::<u64>() }>()
             .map(|ary| {
                 let d = u64::from_ne_bytes(ary);
                 Wrapping(d.rotate_left(7).wrapping_add(1))
diff --git a/library/coretests/tests/alloc.rs b/library/coretests/tests/alloc.rs
index b88f1821cd7..72fdf82c1f8 100644
--- a/library/coretests/tests/alloc.rs
+++ b/library/coretests/tests/alloc.rs
@@ -1,5 +1,4 @@
 use core::alloc::Layout;
-use core::mem::size_of;
 use core::ptr::{self, NonNull};
 
 #[test]
diff --git a/library/coretests/tests/atomic.rs b/library/coretests/tests/atomic.rs
index 0ffba538b20..e0c0fe4790c 100644
--- a/library/coretests/tests/atomic.rs
+++ b/library/coretests/tests/atomic.rs
@@ -250,8 +250,6 @@ fn atomic_access_bool() {
 
 #[test]
 fn atomic_alignment() {
-    use std::mem::{align_of, size_of};
-
     #[cfg(target_has_atomic = "8")]
     assert_eq!(align_of::<AtomicBool>(), size_of::<AtomicBool>());
     #[cfg(target_has_atomic = "ptr")]
diff --git a/library/coretests/tests/hash/sip.rs b/library/coretests/tests/hash/sip.rs
index f79954f916b..6add1a33cb9 100644
--- a/library/coretests/tests/hash/sip.rs
+++ b/library/coretests/tests/hash/sip.rs
@@ -1,7 +1,7 @@
 #![allow(deprecated)]
 
 use core::hash::{Hash, Hasher, SipHasher, SipHasher13};
-use core::{mem, slice};
+use core::slice;
 
 // Hash just the bytes of the slice, without length prefix
 struct Bytes<'a>(&'a [u8]);
@@ -314,7 +314,7 @@ fn test_write_short_works() {
     h1.write_u8(0x01u8);
     let mut h2 = SipHasher::new();
     h2.write(unsafe {
-        slice::from_raw_parts(&test_usize as *const _ as *const u8, mem::size_of::<usize>())
+        slice::from_raw_parts(&test_usize as *const _ as *const u8, size_of::<usize>())
     });
     h2.write(b"bytes");
     h2.write(b"string");
diff --git a/library/coretests/tests/lib.rs b/library/coretests/tests/lib.rs
index 4f21ae5013b..79022fec8a2 100644
--- a/library/coretests/tests/lib.rs
+++ b/library/coretests/tests/lib.rs
@@ -73,7 +73,6 @@
 #![feature(slice_internals)]
 #![feature(slice_partition_dedup)]
 #![feature(slice_split_once)]
-#![feature(slice_take)]
 #![feature(split_array)]
 #![feature(split_as_slice)]
 #![feature(std_internals)]
@@ -88,7 +87,6 @@
 #![feature(try_find)]
 #![feature(try_trait_v2)]
 #![feature(unsize)]
-#![feature(unsized_tuple_coercion)]
 #![feature(unwrap_infallible)]
 // tidy-alphabetical-end
 #![allow(internal_features)]
diff --git a/library/coretests/tests/nonzero.rs b/library/coretests/tests/nonzero.rs
index bdc5701d9fd..00232c9b706 100644
--- a/library/coretests/tests/nonzero.rs
+++ b/library/coretests/tests/nonzero.rs
@@ -1,6 +1,5 @@
 use core::num::{IntErrorKind, NonZero};
 use core::option::Option::None;
-use std::mem::size_of;
 
 #[test]
 fn test_create_nonzero_instance() {
diff --git a/library/coretests/tests/num/dec2flt/decimal.rs b/library/coretests/tests/num/dec2flt/decimal.rs
new file mode 100644
index 00000000000..1fa06de692e
--- /dev/null
+++ b/library/coretests/tests/num/dec2flt/decimal.rs
@@ -0,0 +1,28 @@
+use core::num::dec2flt::decimal::Decimal;
+
+type FPath<F> = ((i64, u64, bool, bool), Option<F>);
+
+const FPATHS_F32: &[FPath<f32>] =
+    &[((0, 0, false, false), Some(0.0)), ((0, 0, false, false), Some(0.0))];
+const FPATHS_F64: &[FPath<f64>] =
+    &[((0, 0, false, false), Some(0.0)), ((0, 0, false, false), Some(0.0))];
+
+#[test]
+fn check_fast_path_f32() {
+    for ((exponent, mantissa, negative, many_digits), expected) in FPATHS_F32.iter().copied() {
+        let dec = Decimal { exponent, mantissa, negative, many_digits };
+        let actual = dec.try_fast_path::<f32>();
+
+        assert_eq!(actual, expected);
+    }
+}
+
+#[test]
+fn check_fast_path_f64() {
+    for ((exponent, mantissa, negative, many_digits), expected) in FPATHS_F64.iter().copied() {
+        let dec = Decimal { exponent, mantissa, negative, many_digits };
+        let actual = dec.try_fast_path::<f64>();
+
+        assert_eq!(actual, expected);
+    }
+}
diff --git a/library/coretests/tests/num/dec2flt/decimal_seq.rs b/library/coretests/tests/num/dec2flt/decimal_seq.rs
new file mode 100644
index 00000000000..f46ba7c465a
--- /dev/null
+++ b/library/coretests/tests/num/dec2flt/decimal_seq.rs
@@ -0,0 +1,30 @@
+use core::num::dec2flt::decimal_seq::{DecimalSeq, parse_decimal_seq};
+
+#[test]
+fn test_trim() {
+    let mut dec = DecimalSeq::default();
+    let digits = [1, 2, 3, 4];
+
+    dec.digits[0..4].copy_from_slice(&digits);
+    dec.num_digits = 8;
+    dec.trim();
+
+    assert_eq!(dec.digits[0..4], digits);
+    assert_eq!(dec.num_digits, 4);
+}
+
+#[test]
+fn test_parse() {
+    let tests = [("1.234", [1, 2, 3, 4], 1)];
+
+    for (s, exp_digits, decimal_point) in tests {
+        let actual = parse_decimal_seq(s.as_bytes());
+        let mut digits = [0; DecimalSeq::MAX_DIGITS];
+        digits[..exp_digits.len()].copy_from_slice(&exp_digits);
+
+        let expected =
+            DecimalSeq { num_digits: exp_digits.len(), decimal_point, truncated: false, digits };
+
+        assert_eq!(actual, expected);
+    }
+}
diff --git a/library/coretests/tests/num/dec2flt/float.rs b/library/coretests/tests/num/dec2flt/float.rs
index 7a9587a18d0..b5afd3e3b24 100644
--- a/library/coretests/tests/num/dec2flt/float.rs
+++ b/library/coretests/tests/num/dec2flt/float.rs
@@ -12,8 +12,8 @@ fn test_f32_integer_decode() {
 
     // Ignore the "sign" (quiet / signalling flag) of NAN.
     // It can vary between runtime operations and LLVM folding.
-    let (nan_m, nan_e, _nan_s) = f32::NAN.integer_decode();
-    assert_eq!((nan_m, nan_e), (12582912, 105));
+    let (nan_m, nan_p, _nan_s) = f32::NAN.integer_decode();
+    assert_eq!((nan_m, nan_p), (12582912, 105));
 }
 
 #[test]
@@ -28,6 +28,46 @@ fn test_f64_integer_decode() {
 
     // Ignore the "sign" (quiet / signalling flag) of NAN.
     // It can vary between runtime operations and LLVM folding.
-    let (nan_m, nan_e, _nan_s) = f64::NAN.integer_decode();
-    assert_eq!((nan_m, nan_e), (6755399441055744, 972));
+    let (nan_m, nan_p, _nan_s) = f64::NAN.integer_decode();
+    assert_eq!((nan_m, nan_p), (6755399441055744, 972));
+}
+
+/* Sanity checks of computed magic numbers */
+
+#[test]
+fn test_f32_consts() {
+    assert_eq!(<f32 as RawFloat>::INFINITY, f32::INFINITY);
+    assert_eq!(<f32 as RawFloat>::NEG_INFINITY, -f32::INFINITY);
+    assert_eq!(<f32 as RawFloat>::NAN.to_bits(), f32::NAN.to_bits());
+    assert_eq!(<f32 as RawFloat>::NEG_NAN.to_bits(), (-f32::NAN).to_bits());
+    assert_eq!(<f32 as RawFloat>::SIG_BITS, 23);
+    assert_eq!(<f32 as RawFloat>::MIN_EXPONENT_ROUND_TO_EVEN, -17);
+    assert_eq!(<f32 as RawFloat>::MAX_EXPONENT_ROUND_TO_EVEN, 10);
+    assert_eq!(<f32 as RawFloat>::MIN_EXPONENT_FAST_PATH, -10);
+    assert_eq!(<f32 as RawFloat>::MAX_EXPONENT_FAST_PATH, 10);
+    assert_eq!(<f32 as RawFloat>::MAX_EXPONENT_DISGUISED_FAST_PATH, 17);
+    assert_eq!(<f32 as RawFloat>::EXP_MIN, -126);
+    assert_eq!(<f32 as RawFloat>::EXP_SAT, 0xff);
+    assert_eq!(<f32 as RawFloat>::SMALLEST_POWER_OF_TEN, -65);
+    assert_eq!(<f32 as RawFloat>::LARGEST_POWER_OF_TEN, 38);
+    assert_eq!(<f32 as RawFloat>::MAX_MANTISSA_FAST_PATH, 16777216);
+}
+
+#[test]
+fn test_f64_consts() {
+    assert_eq!(<f64 as RawFloat>::INFINITY, f64::INFINITY);
+    assert_eq!(<f64 as RawFloat>::NEG_INFINITY, -f64::INFINITY);
+    assert_eq!(<f64 as RawFloat>::NAN.to_bits(), f64::NAN.to_bits());
+    assert_eq!(<f64 as RawFloat>::NEG_NAN.to_bits(), (-f64::NAN).to_bits());
+    assert_eq!(<f64 as RawFloat>::SIG_BITS, 52);
+    assert_eq!(<f64 as RawFloat>::MIN_EXPONENT_ROUND_TO_EVEN, -4);
+    assert_eq!(<f64 as RawFloat>::MAX_EXPONENT_ROUND_TO_EVEN, 23);
+    assert_eq!(<f64 as RawFloat>::MIN_EXPONENT_FAST_PATH, -22);
+    assert_eq!(<f64 as RawFloat>::MAX_EXPONENT_FAST_PATH, 22);
+    assert_eq!(<f64 as RawFloat>::MAX_EXPONENT_DISGUISED_FAST_PATH, 37);
+    assert_eq!(<f64 as RawFloat>::EXP_MIN, -1022);
+    assert_eq!(<f64 as RawFloat>::EXP_SAT, 0x7ff);
+    assert_eq!(<f64 as RawFloat>::SMALLEST_POWER_OF_TEN, -342);
+    assert_eq!(<f64 as RawFloat>::LARGEST_POWER_OF_TEN, 308);
+    assert_eq!(<f64 as RawFloat>::MAX_MANTISSA_FAST_PATH, 9007199254740992);
 }
diff --git a/library/coretests/tests/num/dec2flt/lemire.rs b/library/coretests/tests/num/dec2flt/lemire.rs
index f71bbb7c7a3..0db80fbd525 100644
--- a/library/coretests/tests/num/dec2flt/lemire.rs
+++ b/library/coretests/tests/num/dec2flt/lemire.rs
@@ -1,13 +1,14 @@
+use core::num::dec2flt::float::RawFloat;
 use core::num::dec2flt::lemire::compute_float;
 
 fn compute_float32(q: i64, w: u64) -> (i32, u64) {
     let fp = compute_float::<f32>(q, w);
-    (fp.e, fp.f)
+    (fp.p_biased, fp.m)
 }
 
 fn compute_float64(q: i64, w: u64) -> (i32, u64) {
     let fp = compute_float::<f64>(q, w);
-    (fp.e, fp.f)
+    (fp.p_biased, fp.m)
 }
 
 #[test]
@@ -27,6 +28,11 @@ fn compute_float_f32_rounding() {
     // Let's check the lines to see if anything is different in table...
     assert_eq!(compute_float32(-10, 167772190000000000), (151, 2));
     assert_eq!(compute_float32(-10, 167772200000000000), (151, 2));
+
+    // Check the rounding point between infinity and the next representable number down
+    assert_eq!(compute_float32(38, 3), (f32::INFINITE_POWER - 1, 6402534));
+    assert_eq!(compute_float32(38, 4), (f32::INFINITE_POWER, 0)); // infinity
+    assert_eq!(compute_float32(20, 3402823470000000000), (f32::INFINITE_POWER - 1, 8388607));
 }
 
 #[test]
diff --git a/library/coretests/tests/num/dec2flt/mod.rs b/library/coretests/tests/num/dec2flt/mod.rs
index 874e0ec7093..a9025be5ca7 100644
--- a/library/coretests/tests/num/dec2flt/mod.rs
+++ b/library/coretests/tests/num/dec2flt/mod.rs
@@ -1,5 +1,7 @@
 #![allow(overflowing_literals)]
 
+mod decimal;
+mod decimal_seq;
 mod float;
 mod lemire;
 mod parse;
diff --git a/library/coretests/tests/num/dec2flt/parse.rs b/library/coretests/tests/num/dec2flt/parse.rs
index 4a5d24ba7d5..59be3915052 100644
--- a/library/coretests/tests/num/dec2flt/parse.rs
+++ b/library/coretests/tests/num/dec2flt/parse.rs
@@ -1,9 +1,9 @@
-use core::num::dec2flt::number::Number;
+use core::num::dec2flt::decimal::Decimal;
 use core::num::dec2flt::parse::parse_number;
 use core::num::dec2flt::{dec2flt, pfe_invalid};
 
-fn new_number(e: i64, m: u64) -> Number {
-    Number { exponent: e, mantissa: m, negative: false, many_digits: false }
+fn new_dec(e: i64, m: u64) -> Decimal {
+    Decimal { exponent: e, mantissa: m, negative: false, many_digits: false }
 }
 
 #[test]
@@ -31,23 +31,23 @@ fn invalid_chars() {
     }
 }
 
-fn parse_positive(s: &[u8]) -> Option<Number> {
+fn parse_positive(s: &[u8]) -> Option<Decimal> {
     parse_number(s)
 }
 
 #[test]
 fn valid() {
-    assert_eq!(parse_positive(b"123.456e789"), Some(new_number(786, 123456)));
-    assert_eq!(parse_positive(b"123.456e+789"), Some(new_number(786, 123456)));
-    assert_eq!(parse_positive(b"123.456e-789"), Some(new_number(-792, 123456)));
-    assert_eq!(parse_positive(b".050"), Some(new_number(-3, 50)));
-    assert_eq!(parse_positive(b"999"), Some(new_number(0, 999)));
-    assert_eq!(parse_positive(b"1.e300"), Some(new_number(300, 1)));
-    assert_eq!(parse_positive(b".1e300"), Some(new_number(299, 1)));
-    assert_eq!(parse_positive(b"101e-33"), Some(new_number(-33, 101)));
+    assert_eq!(parse_positive(b"123.456e789"), Some(new_dec(786, 123456)));
+    assert_eq!(parse_positive(b"123.456e+789"), Some(new_dec(786, 123456)));
+    assert_eq!(parse_positive(b"123.456e-789"), Some(new_dec(-792, 123456)));
+    assert_eq!(parse_positive(b".050"), Some(new_dec(-3, 50)));
+    assert_eq!(parse_positive(b"999"), Some(new_dec(0, 999)));
+    assert_eq!(parse_positive(b"1.e300"), Some(new_dec(300, 1)));
+    assert_eq!(parse_positive(b".1e300"), Some(new_dec(299, 1)));
+    assert_eq!(parse_positive(b"101e-33"), Some(new_dec(-33, 101)));
     let zeros = "0".repeat(25);
     let s = format!("1.5e{zeros}");
-    assert_eq!(parse_positive(s.as_bytes()), Some(new_number(-1, 15)));
+    assert_eq!(parse_positive(s.as_bytes()), Some(new_dec(-1, 15)));
 }
 
 macro_rules! assert_float_result_bits_eq {
@@ -58,6 +58,21 @@ macro_rules! assert_float_result_bits_eq {
 }
 
 #[test]
+fn regression() {
+    // These showed up in fuzz tests when the minimum exponent was incorrect.
+    assert_float_result_bits_eq!(
+        0x0,
+        f64,
+        "3313756768023998018398807867233977556112078681253148176737587500333136120852692315608454494981109839693784033457129423181787087843504060087613228932431e-475"
+    );
+    assert_float_result_bits_eq!(
+        0x0,
+        f64,
+        "5298127456259331337220.92759278003098321644501973966679724599271041396379712108366679824365568578569680024083293475291869842408884554511641179110778276695274832779269225510492006696321279587846006535230380114430977056662212751544508159333199129106162019382177820713609e-346"
+    );
+}
+
+#[test]
 fn issue31109() {
     // Regression test for #31109.
     // Ensure the test produces a valid float with the expected bit pattern.
diff --git a/library/coretests/tests/ptr.rs b/library/coretests/tests/ptr.rs
index 0c9f9b338b0..6091926084a 100644
--- a/library/coretests/tests/ptr.rs
+++ b/library/coretests/tests/ptr.rs
@@ -1,6 +1,6 @@
 use core::cell::RefCell;
 use core::marker::Freeze;
-use core::mem::{self, MaybeUninit};
+use core::mem::MaybeUninit;
 use core::num::NonZero;
 use core::ptr;
 use core::ptr::*;
@@ -388,7 +388,7 @@ fn align_offset_various_strides() {
         let mut expected = usize::MAX;
         // Naive but definitely correct way to find the *first* aligned element of stride::<T>.
         for el in 0..align {
-            if (numptr + el * ::std::mem::size_of::<T>()) % align == 0 {
+            if (numptr + el * size_of::<T>()) % align == 0 {
                 expected = el;
                 break;
             }
@@ -398,7 +398,7 @@ fn align_offset_various_strides() {
             eprintln!(
                 "aligning {:p} (with stride of {}) to {}, expected {}, got {}",
                 ptr,
-                ::std::mem::size_of::<T>(),
+                size_of::<T>(),
                 align,
                 expected,
                 got
@@ -525,31 +525,24 @@ fn ptr_metadata() {
     assert_eq!(metadata("foo"), 3_usize);
     assert_eq!(metadata(&[4, 7][..]), 2_usize);
 
-    let dst_tuple: &(bool, [u8]) = &(true, [0x66, 0x6F, 0x6F]);
     let dst_struct: &Pair<bool, [u8]> = &Pair(true, [0x66, 0x6F, 0x6F]);
-    assert_eq!(metadata(dst_tuple), 3_usize);
     assert_eq!(metadata(dst_struct), 3_usize);
     unsafe {
-        let dst_tuple: &(bool, str) = std::mem::transmute(dst_tuple);
         let dst_struct: &Pair<bool, str> = std::mem::transmute(dst_struct);
-        assert_eq!(&dst_tuple.1, "foo");
         assert_eq!(&dst_struct.1, "foo");
-        assert_eq!(metadata(dst_tuple), 3_usize);
         assert_eq!(metadata(dst_struct), 3_usize);
     }
 
     let vtable_1: DynMetadata<dyn Debug> = metadata(&4_u16 as &dyn Debug);
     let vtable_2: DynMetadata<dyn Display> = metadata(&4_u16 as &dyn Display);
     let vtable_3: DynMetadata<dyn Display> = metadata(&4_u32 as &dyn Display);
-    let vtable_4: DynMetadata<dyn Display> = metadata(&(true, 7_u32) as &(bool, dyn Display));
-    let vtable_5: DynMetadata<dyn Display> =
+    let vtable_4: DynMetadata<dyn Display> =
         metadata(&Pair(true, 7_u32) as &Pair<bool, dyn Display>);
     unsafe {
         let address_1: *const () = std::mem::transmute(vtable_1);
         let address_2: *const () = std::mem::transmute(vtable_2);
         let address_3: *const () = std::mem::transmute(vtable_3);
         let address_4: *const () = std::mem::transmute(vtable_4);
-        let address_5: *const () = std::mem::transmute(vtable_5);
         // Different trait => different vtable pointer
         assert_ne!(address_1, address_2);
         // Different erased type => different vtable pointer
@@ -558,7 +551,6 @@ fn ptr_metadata() {
         // This is *not guaranteed*, so we skip it in Miri.
         if !cfg!(miri) {
             assert_eq!(address_3, address_4);
-            assert_eq!(address_3, address_5);
         }
     }
 }
@@ -613,9 +605,9 @@ fn dyn_metadata() {
     let meta = metadata(trait_object);
 
     assert_eq!(meta.size_of(), 64);
-    assert_eq!(meta.size_of(), std::mem::size_of::<Something>());
+    assert_eq!(meta.size_of(), size_of::<Something>());
     assert_eq!(meta.align_of(), 32);
-    assert_eq!(meta.align_of(), std::mem::align_of::<Something>());
+    assert_eq!(meta.align_of(), align_of::<Something>());
     assert_eq!(meta.layout(), std::alloc::Layout::new::<Something>());
 
     assert!(format!("{meta:?}").starts_with("DynMetadata(0x"));
@@ -789,7 +781,7 @@ fn nonnull_tagged_pointer_with_provenance() {
 
     impl<T> TaggedPointer<T> {
         /// The ABI-required minimum alignment of the `P` type.
-        pub const ALIGNMENT: usize = core::mem::align_of::<T>();
+        pub const ALIGNMENT: usize = align_of::<T>();
         /// A mask for data-carrying bits of the address.
         pub const DATA_MASK: usize = !Self::ADDRESS_MASK;
         /// Number of available bits of storage in the address.
@@ -873,7 +865,7 @@ fn test_const_copy_ptr() {
             ptr::copy(
                 &ptr1 as *const _ as *const MaybeUninit<u8>,
                 &mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
-                mem::size_of::<&i32>(),
+                size_of::<&i32>(),
             );
         }
 
@@ -891,7 +883,7 @@ fn test_const_copy_ptr() {
             ptr::copy_nonoverlapping(
                 &ptr1 as *const _ as *const MaybeUninit<u8>,
                 &mut ptr2 as *mut _ as *mut MaybeUninit<u8>,
-                mem::size_of::<&i32>(),
+                size_of::<&i32>(),
             );
         }
 
@@ -936,7 +928,7 @@ fn test_const_swap_ptr() {
         let mut s2 = A(S { ptr: &666, f1: 0, f2: [0; 3] });
 
         // Swap ptr1 and ptr2, as an array.
-        type T = [u8; mem::size_of::<A>()];
+        type T = [u8; size_of::<A>()];
         unsafe {
             ptr::swap(ptr::from_mut(&mut s1).cast::<T>(), ptr::from_mut(&mut s2).cast::<T>());
         }
diff --git a/library/coretests/tests/slice.rs b/library/coretests/tests/slice.rs
index 1c5c8a9ebf2..d17e681480c 100644
--- a/library/coretests/tests/slice.rs
+++ b/library/coretests/tests/slice.rs
@@ -5,8 +5,6 @@ use core::num::NonZero;
 use core::ops::{Range, RangeInclusive};
 use core::slice;
 
-use rand::seq::IndexedRandom;
-
 #[test]
 fn test_position() {
     let b = [1, 2, 3, 5, 5];
@@ -1810,6 +1808,7 @@ fn select_nth_unstable() {
     use core::cmp::Ordering::{Equal, Greater, Less};
 
     use rand::Rng;
+    use rand::seq::IndexedRandom;
 
     let mut rng = crate::test_rng();
 
@@ -2058,15 +2057,13 @@ fn test_align_to_non_trivial() {
 
 #[test]
 fn test_align_to_empty_mid() {
-    use core::mem;
-
     // Make sure that we do not create empty unaligned slices for the mid part, even when the
     // overall slice is too short to contain an aligned address.
     let bytes = [1, 2, 3, 4, 5, 6, 7];
     type Chunk = u32;
     for offset in 0..4 {
         let (_, mid, _) = unsafe { bytes[offset..offset + 1].align_to::<Chunk>() };
-        assert_eq!(mid.as_ptr() as usize % mem::align_of::<Chunk>(), 0);
+        assert_eq!(mid.as_ptr() as usize % align_of::<Chunk>(), 0);
     }
 }
 
diff --git a/library/panic_unwind/src/emcc.rs b/library/panic_unwind/src/emcc.rs
index 1569c26c9de..bad795a019c 100644
--- a/library/panic_unwind/src/emcc.rs
+++ b/library/panic_unwind/src/emcc.rs
@@ -9,7 +9,7 @@
 use alloc::boxed::Box;
 use core::any::Any;
 use core::sync::atomic::{AtomicBool, Ordering};
-use core::{intrinsics, mem, ptr};
+use core::{intrinsics, ptr};
 
 use unwind as uw;
 
@@ -97,7 +97,7 @@ pub(crate) unsafe fn cleanup(ptr: *mut u8) -> Box<dyn Any + Send> {
 
 pub(crate) unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
     unsafe {
-        let exception = __cxa_allocate_exception(mem::size_of::<Exception>()) as *mut Exception;
+        let exception = __cxa_allocate_exception(size_of::<Exception>()) as *mut Exception;
         if exception.is_null() {
             return uw::_URC_FATAL_PHASE1_ERROR as u32;
         }
diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs
index 3a95b940221..3794b56c089 100644
--- a/library/panic_unwind/src/seh.rs
+++ b/library/panic_unwind/src/seh.rs
@@ -49,7 +49,7 @@
 use alloc::boxed::Box;
 use core::any::Any;
 use core::ffi::{c_int, c_uint, c_void};
-use core::mem::{self, ManuallyDrop};
+use core::mem::ManuallyDrop;
 
 // NOTE(nbdd0121): The `canary` field is part of stable ABI.
 #[repr(C)]
@@ -225,7 +225,7 @@ static mut CATCHABLE_TYPE: _CatchableType = _CatchableType {
     properties: 0,
     pType: ptr_t::null(),
     thisDisplacement: _PMD { mdisp: 0, pdisp: -1, vdisp: 0 },
-    sizeOrOffset: mem::size_of::<Exception>() as c_int,
+    sizeOrOffset: size_of::<Exception>() as c_int,
     copyFunction: ptr_t::null(),
 };
 
diff --git a/library/proc_macro/src/bridge/selfless_reify.rs b/library/proc_macro/src/bridge/selfless_reify.rs
index 312a79152e2..b06434a5ffe 100644
--- a/library/proc_macro/src/bridge/selfless_reify.rs
+++ b/library/proc_macro/src/bridge/selfless_reify.rs
@@ -50,7 +50,7 @@ macro_rules! define_reify_functions {
         >(f: F) -> $(extern $abi)? fn($($arg_ty),*) -> $ret_ty {
             // FIXME(eddyb) describe the `F` type (e.g. via `type_name::<F>`) once panic
             // formatting becomes possible in `const fn`.
-            assert!(mem::size_of::<F>() == 0, "selfless_reify: closure must be zero-sized");
+            assert!(size_of::<F>() == 0, "selfless_reify: closure must be zero-sized");
 
             $(extern $abi)? fn wrapper<
                 $($($param,)*)?
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index f4d4894c1bb..0ec167c2d16 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -18,7 +18,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core", public = true }
-compiler_builtins = { version = "=0.1.148" }
+compiler_builtins = { version = "=0.1.151" }
 unwind = { path = "../unwind" }
 hashbrown = { version = "0.15", default-features = false, features = [
     'rustc-dep-of-std',
@@ -35,7 +35,7 @@ miniz_oxide = { version = "0.8.0", optional = true, default-features = false }
 addr2line = { version = "0.24.0", optional = true, default-features = false }
 
 [target.'cfg(not(all(windows, target_env = "msvc")))'.dependencies]
-libc = { version = "0.2.169", default-features = false, features = [
+libc = { version = "0.2.170", default-features = false, features = [
     'rustc-dep-of-std',
 ], public = true }
 
diff --git a/library/std/build.rs b/library/std/build.rs
index 9df35ce3cc8..cedfd7406a1 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -113,7 +113,6 @@ fn main() {
         // Infinite recursion <https://github.com/llvm/llvm-project/issues/97981>
         ("csky", _) => false,
         ("hexagon", _) => false,
-        ("loongarch64", _) => false,
         ("powerpc" | "powerpc64", _) => false,
         ("sparc" | "sparc64", _) => false,
         ("wasm32" | "wasm64", _) => false,
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index 4a071b4e1fa..e62aeb2ede0 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -641,11 +641,6 @@ impl Error for JoinPathsError {
 ///     None => println!("Impossible to get your home dir!"),
 /// }
 /// ```
-#[deprecated(
-    since = "1.29.0",
-    note = "This function's behavior may be unexpected on Windows. \
-            Consider using a crate from crates.io instead."
-)]
 #[must_use]
 #[stable(feature = "env", since = "1.0.0")]
 pub fn home_dir() -> Option<PathBuf> {
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 57e235c3efe..4314c8a0b18 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -2857,9 +2857,11 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 ///
 /// See [`fs::remove_file`] and [`fs::remove_dir`].
 ///
-/// `remove_dir_all` will fail if `remove_dir` or `remove_file` fail on any constituent paths, including the root `path`.
-/// As a result, the directory you are deleting must exist, meaning that this function is not idempotent.
-/// Additionally, `remove_dir_all` will also fail if the `path` is not a directory.
+/// [`remove_dir_all`] will fail if [`remove_dir`] or [`remove_file`] fail on *any* constituent
+/// paths, *including* the root `path`. Consequently,
+///
+/// - The directory you are deleting *must* exist, meaning that this function is *not idempotent*.
+/// - [`remove_dir_all`] will fail if the `path` is *not* a directory.
 ///
 /// Consider ignoring the error if validating the removal is not required for your use case.
 ///
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 38dcd816d26..6dd18e4f4c8 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -1878,7 +1878,7 @@ fn windows_unix_socket_exists() {
         let bytes = socket_path.as_os_str().as_encoded_bytes();
         let bytes = core::slice::from_raw_parts(bytes.as_ptr().cast::<i8>(), bytes.len());
         addr.sun_path[..bytes.len()].copy_from_slice(bytes);
-        let len = mem::size_of_val(&addr) as i32;
+        let len = size_of_val(&addr) as i32;
         let result = c::bind(socket, (&raw const addr).cast::<c::SOCKADDR>(), len);
         c::closesocket(socket);
         assert_eq!(result, 0);
diff --git a/library/std/src/io/error/tests.rs b/library/std/src/io/error/tests.rs
index edac6563478..3e4029768eb 100644
--- a/library/std/src/io/error/tests.rs
+++ b/library/std/src/io/error/tests.rs
@@ -1,6 +1,5 @@
 use super::{Custom, Error, ErrorData, ErrorKind, Repr, SimpleMessage, const_error};
 use crate::assert_matches::assert_matches;
-use crate::mem::size_of;
 use crate::sys::decode_error_kind;
 use crate::sys::os::error_string;
 use crate::{error, fmt};
diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs
index 017862c7f3a..ce46241f8e8 100644
--- a/library/std/src/io/stdio.rs
+++ b/library/std/src/io/stdio.rs
@@ -575,6 +575,11 @@ impl fmt::Debug for StdinLock<'_> {
 /// output stream. Access is also synchronized via a lock and explicit control
 /// over locking is available via the [`lock`] method.
 ///
+/// By default, the handle is line-buffered when connected to a terminal, meaning
+/// it flushes automatically when a newline (`\n`) is encountered. For immediate
+/// output, you can manually call the [`flush`] method. When the handle goes out
+/// of scope, the buffer is automatically flushed.
+///
 /// Created by the [`io::stdout`] method.
 ///
 /// ### Note: Windows Portability Considerations
@@ -590,6 +595,7 @@ impl fmt::Debug for StdinLock<'_> {
 /// standard library or via raw Windows API calls, will fail.
 ///
 /// [`lock`]: Stdout::lock
+/// [`flush`]: Write::flush
 /// [`io::stdout`]: stdout
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Stdout {
@@ -604,6 +610,11 @@ pub struct Stdout {
 /// This handle implements the [`Write`] trait, and is constructed via
 /// the [`Stdout::lock`] method. See its documentation for more.
 ///
+/// By default, the handle is line-buffered when connected to a terminal, meaning
+/// it flushes automatically when a newline (`\n`) is encountered. For immediate
+/// output, you can manually call the [`flush`] method. When the handle goes out
+/// of scope, the buffer is automatically flushed.
+///
 /// ### Note: Windows Portability Considerations
 ///
 /// When operating in a console, the Windows implementation of this stream does not support
@@ -615,6 +626,8 @@ pub struct Stdout {
 /// the contained handle will be null. In such cases, the standard library's `Read` and
 /// `Write` will do nothing and silently succeed. All other I/O operations, via the
 /// standard library or via raw Windows API calls, will fail.
+///
+/// [`flush`]: Write::flush
 #[must_use = "if unused stdout will immediately unlock"]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct StdoutLock<'a> {
@@ -629,6 +642,11 @@ static STDOUT: OnceLock<ReentrantLock<RefCell<LineWriter<StdoutRaw>>>> = OnceLoc
 /// is synchronized via a mutex. If you need more explicit control over
 /// locking, see the [`Stdout::lock`] method.
 ///
+/// By default, the handle is line-buffered when connected to a terminal, meaning
+/// it flushes automatically when a newline (`\n`) is encountered. For immediate
+/// output, you can manually call the [`flush`] method. When the handle goes out
+/// of scope, the buffer is automatically flushed.
+///
 /// ### Note: Windows Portability Considerations
 ///
 /// When operating in a console, the Windows implementation of this stream does not support
@@ -669,6 +687,22 @@ static STDOUT: OnceLock<ReentrantLock<RefCell<LineWriter<StdoutRaw>>>> = OnceLoc
 ///     Ok(())
 /// }
 /// ```
+///
+/// Ensuring output is flushed immediately:
+///
+/// ```no_run
+/// use std::io::{self, Write};
+///
+/// fn main() -> io::Result<()> {
+///     let mut stdout = io::stdout();
+///     stdout.write_all(b"hello, ")?;
+///     stdout.flush()?;                // Manual flush
+///     stdout.write_all(b"world!\n")?; // Automatically flushed
+///     Ok(())
+/// }
+/// ```
+///
+/// [`flush`]: Write::flush
 #[must_use]
 #[stable(feature = "rust1", since = "1.0.0")]
 #[cfg_attr(not(test), rustc_diagnostic_item = "io_stdout")]
diff --git a/library/std/src/os/fd/tests.rs b/library/std/src/os/fd/tests.rs
index b39863644f1..7e9cf038e9a 100644
--- a/library/std/src/os/fd/tests.rs
+++ b/library/std/src/os/fd/tests.rs
@@ -36,7 +36,6 @@ fn test_fd() {
 #[cfg(any(unix, target_os = "wasi"))]
 #[test]
 fn test_niche_optimizations() {
-    use crate::mem::size_of;
     #[cfg(unix)]
     use crate::os::unix::io::{BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
     #[cfg(target_os = "wasi")]
diff --git a/library/std/src/os/unix/io/tests.rs b/library/std/src/os/unix/io/tests.rs
index 84d2a7a1a91..fc147730578 100644
--- a/library/std/src/os/unix/io/tests.rs
+++ b/library/std/src/os/unix/io/tests.rs
@@ -1,4 +1,3 @@
-use crate::mem::size_of;
 use crate::os::unix::io::RawFd;
 
 #[test]
diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs
index 56789f235fd..cb1246db310 100644
--- a/library/std/src/os/unix/net/addr.rs
+++ b/library/std/src/os/unix/net/addr.rs
@@ -94,7 +94,7 @@ impl SocketAddr {
     {
         unsafe {
             let mut addr: libc::sockaddr_un = mem::zeroed();
-            let mut len = mem::size_of::<libc::sockaddr_un>() as libc::socklen_t;
+            let mut len = size_of::<libc::sockaddr_un>() as libc::socklen_t;
             cvt(f((&raw mut addr) as *mut _, &mut len))?;
             SocketAddr::from_parts(addr, len)
         }
diff --git a/library/std/src/os/unix/net/listener.rs b/library/std/src/os/unix/net/listener.rs
index be236317d04..27428c9eb28 100644
--- a/library/std/src/os/unix/net/listener.rs
+++ b/library/std/src/os/unix/net/listener.rs
@@ -177,7 +177,7 @@ impl UnixListener {
     #[stable(feature = "unix_socket", since = "1.10.0")]
     pub fn accept(&self) -> io::Result<(UnixStream, SocketAddr)> {
         let mut storage: libc::sockaddr_un = unsafe { mem::zeroed() };
-        let mut len = mem::size_of_val(&storage) as libc::socklen_t;
+        let mut len = size_of_val(&storage) as libc::socklen_t;
         let sock = self.0.accept((&raw mut storage) as *mut _, &mut len)?;
         let addr = SocketAddr::from_parts(storage, len)?;
         Ok((UnixStream(sock), addr))
diff --git a/library/std/src/os/unix/net/ucred.rs b/library/std/src/os/unix/net/ucred.rs
index e1014a4f296..2dd7d409e48 100644
--- a/library/std/src/os/unix/net/ucred.rs
+++ b/library/std/src/os/unix/net/ucred.rs
@@ -41,15 +41,15 @@ mod impl_linux {
     use libc::{SO_PEERCRED, SOL_SOCKET, c_void, getsockopt, socklen_t, ucred};
 
     use super::UCred;
+    use crate::io;
     use crate::os::unix::io::AsRawFd;
     use crate::os::unix::net::UnixStream;
-    use crate::{io, mem};
 
     pub fn peer_cred(socket: &UnixStream) -> io::Result<UCred> {
-        let ucred_size = mem::size_of::<ucred>();
+        let ucred_size = size_of::<ucred>();
 
         // Trivial sanity checks.
-        assert!(mem::size_of::<u32>() <= mem::size_of::<usize>());
+        assert!(size_of::<u32>() <= size_of::<usize>());
         assert!(ucred_size <= u32::MAX as usize);
 
         let mut ucred_size = ucred_size as socklen_t;
@@ -64,7 +64,7 @@ mod impl_linux {
                 &mut ucred_size,
             );
 
-            if ret == 0 && ucred_size as usize == mem::size_of::<ucred>() {
+            if ret == 0 && ucred_size as usize == size_of::<ucred>() {
                 Ok(UCred { uid: ucred.uid, gid: ucred.gid, pid: Some(ucred.pid) })
             } else {
                 Err(io::Error::last_os_error())
@@ -101,9 +101,9 @@ mod impl_apple {
     use libc::{LOCAL_PEERPID, SOL_LOCAL, c_void, getpeereid, getsockopt, pid_t, socklen_t};
 
     use super::UCred;
+    use crate::io;
     use crate::os::unix::io::AsRawFd;
     use crate::os::unix::net::UnixStream;
-    use crate::{io, mem};
 
     pub fn peer_cred(socket: &UnixStream) -> io::Result<UCred> {
         let mut cred = UCred { uid: 1, gid: 1, pid: None };
@@ -115,7 +115,7 @@ mod impl_apple {
             }
 
             let mut pid: pid_t = 1;
-            let mut pid_size = mem::size_of::<pid_t>() as socklen_t;
+            let mut pid_size = size_of::<pid_t>() as socklen_t;
 
             let ret = getsockopt(
                 socket.as_raw_fd(),
@@ -125,7 +125,7 @@ mod impl_apple {
                 &mut pid_size,
             );
 
-            if ret == 0 && pid_size as usize == mem::size_of::<pid_t>() {
+            if ret == 0 && pid_size as usize == size_of::<pid_t>() {
                 cred.pid = Some(pid);
                 Ok(cred)
             } else {
diff --git a/library/std/src/os/wasi/io/tests.rs b/library/std/src/os/wasi/io/tests.rs
index 418274752b0..c5c6a19a6c8 100644
--- a/library/std/src/os/wasi/io/tests.rs
+++ b/library/std/src/os/wasi/io/tests.rs
@@ -1,4 +1,3 @@
-use crate::mem::size_of;
 use crate::os::wasi::io::RawFd;
 
 #[test]
diff --git a/library/std/src/os/windows/io/tests.rs b/library/std/src/os/windows/io/tests.rs
index 41734e52e8c..029b6f5cd3d 100644
--- a/library/std/src/os/windows/io/tests.rs
+++ b/library/std/src/os/windows/io/tests.rs
@@ -1,6 +1,5 @@
 #[test]
 fn test_niche_optimizations_socket() {
-    use crate::mem::size_of;
     use crate::os::windows::io::{
         BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
     };
diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs
index 201274cf03a..fa65a7c51bf 100644
--- a/library/std/src/os/windows/process.rs
+++ b/library/std/src/os/windows/process.rs
@@ -500,11 +500,7 @@ impl<'a> ProcThreadAttributeListBuilder<'a> {
     /// [1]: <https://learn.microsoft.com/en-us/windows/win32/api/processthreadsapi/nf-processthreadsapi-updateprocthreadattribute#parameters>
     pub fn attribute<T>(self, attribute: usize, value: &'a T) -> Self {
         unsafe {
-            self.raw_attribute(
-                attribute,
-                ptr::addr_of!(*value).cast::<c_void>(),
-                crate::mem::size_of::<T>(),
-            )
+            self.raw_attribute(attribute, ptr::addr_of!(*value).cast::<c_void>(), size_of::<T>())
         }
     }
 
@@ -574,7 +570,7 @@ impl<'a> ProcThreadAttributeListBuilder<'a> {
     ///         .raw_attribute(
     ///             PROC_THREAD_ATTRIBUTE_PSEUDOCONSOLE,
     ///             h_pc as *const c_void,
-    ///             std::mem::size_of::<isize>(),
+    ///             size_of::<isize>(),
     ///         )
     ///         .finish()?
     /// };
diff --git a/library/std/src/os/xous/ffi.rs b/library/std/src/os/xous/ffi.rs
index 1db314e9dda..9394f0a0496 100644
--- a/library/std/src/os/xous/ffi.rs
+++ b/library/std/src/os/xous/ffi.rs
@@ -368,7 +368,7 @@ pub(crate) unsafe fn map_memory<T>(
     let mut a0 = Syscall::MapMemory as usize;
     let mut a1 = phys.map(|p| p.as_ptr() as usize).unwrap_or_default();
     let mut a2 = virt.map(|p| p.as_ptr() as usize).unwrap_or_default();
-    let a3 = count * core::mem::size_of::<T>();
+    let a3 = count * size_of::<T>();
     let a4 = flags.bits();
     let a5 = 0;
     let a6 = 0;
@@ -392,7 +392,7 @@ pub(crate) unsafe fn map_memory<T>(
 
     if result == SyscallResult::MemoryRange as usize {
         let start = core::ptr::with_exposed_provenance_mut::<T>(a1);
-        let len = a2 / core::mem::size_of::<T>();
+        let len = a2 / size_of::<T>();
         let end = unsafe { start.add(len) };
         Ok(unsafe { core::slice::from_raw_parts_mut(start, len) })
     } else if result == SyscallResult::Error as usize {
@@ -409,7 +409,7 @@ pub(crate) unsafe fn map_memory<T>(
 pub(crate) unsafe fn unmap_memory<T>(range: *mut [T]) -> Result<(), Error> {
     let mut a0 = Syscall::UnmapMemory as usize;
     let mut a1 = range.as_mut_ptr() as usize;
-    let a2 = range.len() * core::mem::size_of::<T>();
+    let a2 = range.len() * size_of::<T>();
     let a3 = 0;
     let a4 = 0;
     let a5 = 0;
@@ -455,7 +455,7 @@ pub(crate) unsafe fn update_memory_flags<T>(
 ) -> Result<(), Error> {
     let mut a0 = Syscall::UpdateMemoryFlags as usize;
     let mut a1 = range.as_mut_ptr() as usize;
-    let a2 = range.len() * core::mem::size_of::<T>();
+    let a2 = range.len() * size_of::<T>();
     let a3 = new_flags.bits();
     let a4 = 0; // Process ID is currently None
     let a5 = 0;
diff --git a/library/std/src/os/xous/services/log.rs b/library/std/src/os/xous/services/log.rs
index 1661011ca64..095d4f4a3e7 100644
--- a/library/std/src/os/xous/services/log.rs
+++ b/library/std/src/os/xous/services/log.rs
@@ -7,8 +7,8 @@ use crate::os::xous::ffi::Connection;
 /// `group_or_null([1,2,3,4,5,6,7,8], 1)` on a 32-bit system will return a
 /// `usize` with 5678 packed into it.
 fn group_or_null(data: &[u8], offset: usize) -> usize {
-    let start = offset * core::mem::size_of::<usize>();
-    let mut out_array = [0u8; core::mem::size_of::<usize>()];
+    let start = offset * size_of::<usize>();
+    let mut out_array = [0u8; size_of::<usize>()];
     if start < data.len() {
         for (dest, src) in out_array.iter_mut().zip(&data[start..]) {
             *dest = *src;
diff --git a/library/std/src/sys/alloc/unix.rs b/library/std/src/sys/alloc/unix.rs
index 1af9d766290..a7ac4117ec9 100644
--- a/library/std/src/sys/alloc/unix.rs
+++ b/library/std/src/sys/alloc/unix.rs
@@ -81,7 +81,7 @@ cfg_if::cfg_if! {
             // while others require the alignment to be at least the pointer size (Illumos, macOS).
             // posix_memalign only has one, clear requirement: that the alignment be a multiple of
             // `sizeof(void*)`. Since these are all powers of 2, we can just use max.
-            let align = layout.align().max(crate::mem::size_of::<usize>());
+            let align = layout.align().max(size_of::<usize>());
             let ret = unsafe { libc::posix_memalign(&mut out, align, layout.size()) };
             if ret != 0 { ptr::null_mut() } else { out as *mut u8 }
         }
diff --git a/library/std/src/sys/alloc/windows/tests.rs b/library/std/src/sys/alloc/windows/tests.rs
index 674a3e1d92d..1d5614528b1 100644
--- a/library/std/src/sys/alloc/windows/tests.rs
+++ b/library/std/src/sys/alloc/windows/tests.rs
@@ -1,9 +1,8 @@
 use super::{Header, MIN_ALIGN};
-use crate::mem;
 
 #[test]
 fn alloc_header() {
     // Header must fit in the padding before an aligned pointer
-    assert!(mem::size_of::<Header>() <= MIN_ALIGN);
-    assert!(mem::align_of::<Header>() <= MIN_ALIGN);
+    assert!(size_of::<Header>() <= MIN_ALIGN);
+    assert!(align_of::<Header>() <= MIN_ALIGN);
 }
diff --git a/library/std/src/sys/io/is_terminal/windows.rs b/library/std/src/sys/io/is_terminal/windows.rs
index 3ec18fb47b9..b0c718d71f9 100644
--- a/library/std/src/sys/io/is_terminal/windows.rs
+++ b/library/std/src/sys/io/is_terminal/windows.rs
@@ -1,5 +1,4 @@
 use crate::ffi::c_void;
-use crate::mem::size_of;
 use crate::os::windows::io::{AsHandle, AsRawHandle, BorrowedHandle};
 use crate::sys::c;
 
diff --git a/library/std/src/sys/net/connection/socket.rs b/library/std/src/sys/net/connection/socket.rs
index ddd74b42615..e154cf039ca 100644
--- a/library/std/src/sys/net/connection/socket.rs
+++ b/library/std/src/sys/net/connection/socket.rs
@@ -154,11 +154,11 @@ fn socket_addr_to_c(addr: &SocketAddr) -> (SocketAddrCRepr, c::socklen_t) {
     match addr {
         SocketAddr::V4(a) => {
             let sockaddr = SocketAddrCRepr { v4: socket_addr_v4_to_c(a) };
-            (sockaddr, mem::size_of::<c::sockaddr_in>() as c::socklen_t)
+            (sockaddr, size_of::<c::sockaddr_in>() as c::socklen_t)
         }
         SocketAddr::V6(a) => {
             let sockaddr = SocketAddrCRepr { v6: socket_addr_v6_to_c(a) };
-            (sockaddr, mem::size_of::<c::sockaddr_in6>() as c::socklen_t)
+            (sockaddr, size_of::<c::sockaddr_in6>() as c::socklen_t)
         }
     }
 }
@@ -169,13 +169,13 @@ unsafe fn socket_addr_from_c(
 ) -> io::Result<SocketAddr> {
     match (*storage).ss_family as c_int {
         c::AF_INET => {
-            assert!(len >= mem::size_of::<c::sockaddr_in>());
+            assert!(len >= size_of::<c::sockaddr_in>());
             Ok(SocketAddr::V4(socket_addr_v4_from_c(unsafe {
                 *(storage as *const _ as *const c::sockaddr_in)
             })))
         }
         c::AF_INET6 => {
-            assert!(len >= mem::size_of::<c::sockaddr_in6>());
+            assert!(len >= size_of::<c::sockaddr_in6>());
             Ok(SocketAddr::V6(socket_addr_v6_from_c(unsafe {
                 *(storage as *const _ as *const c::sockaddr_in6)
             })))
@@ -200,7 +200,7 @@ pub fn setsockopt<T>(
             level,
             option_name,
             (&raw const option_value) as *const _,
-            mem::size_of::<T>() as c::socklen_t,
+            size_of::<T>() as c::socklen_t,
         ))?;
         Ok(())
     }
@@ -209,7 +209,7 @@ pub fn setsockopt<T>(
 pub fn getsockopt<T: Copy>(sock: &Socket, level: c_int, option_name: c_int) -> io::Result<T> {
     unsafe {
         let mut option_value: T = mem::zeroed();
-        let mut option_len = mem::size_of::<T>() as c::socklen_t;
+        let mut option_len = size_of::<T>() as c::socklen_t;
         cvt(c::getsockopt(
             sock.as_raw(),
             level,
@@ -227,7 +227,7 @@ where
 {
     unsafe {
         let mut storage: c::sockaddr_storage = mem::zeroed();
-        let mut len = mem::size_of_val(&storage) as c::socklen_t;
+        let mut len = size_of_val(&storage) as c::socklen_t;
         cvt(f((&raw mut storage) as *mut _, &mut len))?;
         socket_addr_from_c(&storage, len as usize)
     }
@@ -561,7 +561,7 @@ impl TcpListener {
         // so we don't need to zero it here.
         // reference: https://linux.die.net/man/2/accept4
         let mut storage: mem::MaybeUninit<c::sockaddr_storage> = mem::MaybeUninit::uninit();
-        let mut len = mem::size_of_val(&storage) as c::socklen_t;
+        let mut len = size_of_val(&storage) as c::socklen_t;
         let sock = self.inner.accept(storage.as_mut_ptr() as *mut _, &mut len)?;
         let addr = unsafe { socket_addr_from_c(storage.as_ptr(), len as usize)? };
         Ok((TcpStream { inner: sock }, addr))
diff --git a/library/std/src/sys/net/connection/socket/hermit.rs b/library/std/src/sys/net/connection/socket/hermit.rs
index e393342ced9..f49821657d9 100644
--- a/library/std/src/sys/net/connection/socket/hermit.rs
+++ b/library/std/src/sys/net/connection/socket/hermit.rs
@@ -183,7 +183,7 @@ impl Socket {
 
     fn recv_from_with_flags(&self, buf: &mut [u8], flags: i32) -> io::Result<(usize, SocketAddr)> {
         let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() };
-        let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t;
+        let mut addrlen = size_of_val(&storage) as netc::socklen_t;
 
         let n = cvt(unsafe {
             netc::recvfrom(
diff --git a/library/std/src/sys/net/connection/socket/solid.rs b/library/std/src/sys/net/connection/socket/solid.rs
index 906bef267b6..94bb605c100 100644
--- a/library/std/src/sys/net/connection/socket/solid.rs
+++ b/library/std/src/sys/net/connection/socket/solid.rs
@@ -244,7 +244,7 @@ impl Socket {
         flags: c_int,
     ) -> io::Result<(usize, SocketAddr)> {
         let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() };
-        let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t;
+        let mut addrlen = size_of_val(&storage) as netc::socklen_t;
 
         let n = cvt(unsafe {
             netc::recvfrom(
diff --git a/library/std/src/sys/net/connection/socket/unix.rs b/library/std/src/sys/net/connection/socket/unix.rs
index 29fb47ddca3..e633cf772c5 100644
--- a/library/std/src/sys/net/connection/socket/unix.rs
+++ b/library/std/src/sys/net/connection/socket/unix.rs
@@ -326,7 +326,7 @@ impl Socket {
         // so we don't need to zero it here.
         // reference: https://linux.die.net/man/2/recvfrom
         let mut storage: mem::MaybeUninit<libc::sockaddr_storage> = mem::MaybeUninit::uninit();
-        let mut addrlen = mem::size_of_val(&storage) as libc::socklen_t;
+        let mut addrlen = size_of_val(&storage) as libc::socklen_t;
 
         let n = cvt(unsafe {
             libc::recvfrom(
diff --git a/library/std/src/sys/net/connection/socket/wasip2.rs b/library/std/src/sys/net/connection/socket/wasip2.rs
index c5034e73dd7..73c25831872 100644
--- a/library/std/src/sys/net/connection/socket/wasip2.rs
+++ b/library/std/src/sys/net/connection/socket/wasip2.rs
@@ -211,7 +211,7 @@ impl Socket {
         flags: c_int,
     ) -> io::Result<(usize, SocketAddr)> {
         let mut storage: netc::sockaddr_storage = unsafe { mem::zeroed() };
-        let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t;
+        let mut addrlen = size_of_val(&storage) as netc::socklen_t;
 
         let n = cvt(unsafe {
             netc::recvfrom(
diff --git a/library/std/src/sys/net/connection/socket/windows.rs b/library/std/src/sys/net/connection/socket/windows.rs
index 428f142dabe..ce975bb2289 100644
--- a/library/std/src/sys/net/connection/socket/windows.rs
+++ b/library/std/src/sys/net/connection/socket/windows.rs
@@ -381,7 +381,7 @@ impl Socket {
         flags: c_int,
     ) -> io::Result<(usize, SocketAddr)> {
         let mut storage = unsafe { mem::zeroed::<c::SOCKADDR_STORAGE>() };
-        let mut addrlen = mem::size_of_val(&storage) as netc::socklen_t;
+        let mut addrlen = size_of_val(&storage) as netc::socklen_t;
         let length = cmp::min(buf.len(), <wrlen_t>::MAX as usize) as wrlen_t;
 
         // On unix when a socket is shut down all further reads return 0, so we
@@ -514,13 +514,13 @@ impl Socket {
 
     // This is used by sys_common code to abstract over Windows and Unix.
     pub fn as_raw(&self) -> c::SOCKET {
-        debug_assert_eq!(mem::size_of::<c::SOCKET>(), mem::size_of::<RawSocket>());
-        debug_assert_eq!(mem::align_of::<c::SOCKET>(), mem::align_of::<RawSocket>());
+        debug_assert_eq!(size_of::<c::SOCKET>(), size_of::<RawSocket>());
+        debug_assert_eq!(align_of::<c::SOCKET>(), align_of::<RawSocket>());
         self.as_inner().as_raw_socket() as c::SOCKET
     }
     pub unsafe fn from_raw(raw: c::SOCKET) -> Self {
-        debug_assert_eq!(mem::size_of::<c::SOCKET>(), mem::size_of::<RawSocket>());
-        debug_assert_eq!(mem::align_of::<c::SOCKET>(), mem::align_of::<RawSocket>());
+        debug_assert_eq!(size_of::<c::SOCKET>(), size_of::<RawSocket>());
+        debug_assert_eq!(align_of::<c::SOCKET>(), align_of::<RawSocket>());
         unsafe { Self::from_raw_socket(raw as RawSocket) }
     }
 }
diff --git a/library/std/src/sys/net/connection/xous/udp.rs b/library/std/src/sys/net/connection/xous/udp.rs
index f35970bc321..c112c04ce94 100644
--- a/library/std/src/sys/net/connection/xous/udp.rs
+++ b/library/std/src/sys/net/connection/xous/udp.rs
@@ -244,7 +244,7 @@ impl UdpSocket {
         // let buf = unsafe {
         //     xous::MemoryRange::new(
         //         &mut tx_req as *mut SendData as usize,
-        //         core::mem::size_of::<SendData>(),
+        //         size_of::<SendData>(),
         //     )
         //     .unwrap()
         // };
diff --git a/library/std/src/sys/pal/itron/thread.rs b/library/std/src/sys/pal/itron/thread.rs
index 04095e1a7cf..d1481f827e1 100644
--- a/library/std/src/sys/pal/itron/thread.rs
+++ b/library/std/src/sys/pal/itron/thread.rs
@@ -80,7 +80,7 @@ const LIFECYCLE_EXITED_OR_FINISHED_OR_JOIN_FINALIZE: usize = usize::MAX;
 // there's no single value for `JOINING`
 
 // 64KiB for 32-bit ISAs, 128KiB for 64-bit ISAs.
-pub const DEFAULT_MIN_STACK_SIZE: usize = 0x4000 * crate::mem::size_of::<usize>();
+pub const DEFAULT_MIN_STACK_SIZE: usize = 0x4000 * size_of::<usize>();
 
 impl Thread {
     /// # Safety
diff --git a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
index 5069ab82ccc..301e3299c05 100644
--- a/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
+++ b/library/std/src/sys/pal/sgx/abi/usercalls/alloc.rs
@@ -63,7 +63,7 @@ unsafe impl<T: UserSafeSized> UserSafeSized for [T; 2] {}
 /// A type that can be represented in memory as one or more `UserSafeSized`s.
 #[unstable(feature = "sgx_platform", issue = "56975")]
 pub unsafe trait UserSafe {
-    /// Equivalent to `mem::align_of::<Self>`.
+    /// Equivalent to `align_of::<Self>`.
     fn align_of() -> usize;
 
     /// Constructs a pointer to `Self` given a memory range in user space.
@@ -120,7 +120,7 @@ pub unsafe trait UserSafe {
         let is_aligned = |p: *const u8| -> bool { p.is_aligned_to(Self::align_of()) };
 
         assert!(is_aligned(ptr as *const u8));
-        assert!(is_user_range(ptr as _, mem::size_of_val(unsafe { &*ptr })));
+        assert!(is_user_range(ptr as _, size_of_val(unsafe { &*ptr })));
         assert!(!ptr.is_null());
     }
 }
@@ -128,11 +128,11 @@ pub unsafe trait UserSafe {
 #[unstable(feature = "sgx_platform", issue = "56975")]
 unsafe impl<T: UserSafeSized> UserSafe for T {
     fn align_of() -> usize {
-        mem::align_of::<T>()
+        align_of::<T>()
     }
 
     unsafe fn from_raw_sized_unchecked(ptr: *mut u8, size: usize) -> *mut Self {
-        assert_eq!(size, mem::size_of::<T>());
+        assert_eq!(size, size_of::<T>());
         ptr as _
     }
 }
@@ -140,7 +140,7 @@ unsafe impl<T: UserSafeSized> UserSafe for T {
 #[unstable(feature = "sgx_platform", issue = "56975")]
 unsafe impl<T: UserSafeSized> UserSafe for [T] {
     fn align_of() -> usize {
-        mem::align_of::<T>()
+        align_of::<T>()
     }
 
     /// # Safety
@@ -155,7 +155,7 @@ unsafe impl<T: UserSafeSized> UserSafe for [T] {
     ///
     /// * the element size is not a factor of the size
     unsafe fn from_raw_sized_unchecked(ptr: *mut u8, size: usize) -> *mut Self {
-        let elem_size = mem::size_of::<T>();
+        let elem_size = size_of::<T>();
         assert_eq!(size % elem_size, 0);
         let len = size / elem_size;
         // SAFETY: The caller must uphold the safety contract for `from_raw_sized_unchecked`
@@ -239,7 +239,7 @@ where
     /// Copies `val` into freshly allocated space in user memory.
     pub fn new_from_enclave(val: &T) -> Self {
         unsafe {
-            let mut user = Self::new_uninit_bytes(mem::size_of_val(val));
+            let mut user = Self::new_uninit_bytes(size_of_val(val));
             user.copy_from_enclave(val);
             user
         }
@@ -277,7 +277,7 @@ where
 {
     /// Allocates space for `T` in user memory.
     pub fn uninitialized() -> Self {
-        Self::new_uninit_bytes(mem::size_of::<T>())
+        Self::new_uninit_bytes(size_of::<T>())
     }
 }
 
@@ -288,7 +288,7 @@ where
 {
     /// Allocates space for a `[T]` of `n` elements in user memory.
     pub fn uninitialized(n: usize) -> Self {
-        Self::new_uninit_bytes(n * mem::size_of::<T>())
+        Self::new_uninit_bytes(n * size_of::<T>())
     }
 
     /// Creates an owned `User<[T]>` from a raw thin pointer and a slice length.
@@ -306,9 +306,7 @@ where
     /// * The pointed-to range does not fit in the address space
     /// * The pointed-to range is not in user memory
     pub unsafe fn from_raw_parts(ptr: *mut T, len: usize) -> Self {
-        User(unsafe {
-            NonNull::new_userref(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()))
-        })
+        User(unsafe { NonNull::new_userref(<[T]>::from_raw_sized(ptr as _, len * size_of::<T>())) })
     }
 }
 
@@ -326,7 +324,7 @@ where
 // `<*const u8>::align_offset` aren't _guaranteed_ to compute the largest
 // possible middle region, and as such can't be used.
 fn u64_align_to_guaranteed(ptr: *const u8, mut len: usize) -> (usize, usize, usize) {
-    const QWORD_SIZE: usize = mem::size_of::<u64>();
+    const QWORD_SIZE: usize = size_of::<u64>();
 
     let offset = ptr as usize % QWORD_SIZE;
 
@@ -532,11 +530,11 @@ where
     /// the source. This can happen for dynamically-sized types such as slices.
     pub fn copy_from_enclave(&mut self, val: &T) {
         unsafe {
-            assert_eq!(mem::size_of_val(val), mem::size_of_val(&*self.0.get()));
+            assert_eq!(size_of_val(val), size_of_val(&*self.0.get()));
             copy_to_userspace(
                 val as *const T as *const u8,
                 self.0.get() as *mut T as *mut u8,
-                mem::size_of_val(val),
+                size_of_val(val),
             );
         }
     }
@@ -548,11 +546,11 @@ where
     /// the source. This can happen for dynamically-sized types such as slices.
     pub fn copy_to_enclave(&self, dest: &mut T) {
         unsafe {
-            assert_eq!(mem::size_of_val(dest), mem::size_of_val(&*self.0.get()));
+            assert_eq!(size_of_val(dest), size_of_val(&*self.0.get()));
             copy_from_userspace(
                 self.0.get() as *const T as *const u8,
                 dest as *mut T as *mut u8,
-                mem::size_of_val(dest),
+                size_of_val(dest),
             );
         }
     }
@@ -577,7 +575,7 @@ where
     pub fn to_enclave(&self) -> T {
         unsafe {
             let mut data = mem::MaybeUninit::uninit();
-            copy_from_userspace(self.0.get() as _, data.as_mut_ptr() as _, mem::size_of::<T>());
+            copy_from_userspace(self.0.get() as _, data.as_mut_ptr() as _, size_of::<T>());
             data.assume_init()
         }
     }
@@ -602,9 +600,7 @@ where
     /// * The pointed-to range is not in user memory
     pub unsafe fn from_raw_parts<'a>(ptr: *const T, len: usize) -> &'a Self {
         // SAFETY: The caller must uphold the safety contract for `from_raw_parts`.
-        unsafe {
-            &*(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *const Self)
-        }
+        unsafe { &*(<[T]>::from_raw_sized(ptr as _, len * size_of::<T>()).as_ptr() as *const Self) }
     }
 
     /// Creates a `&mut UserRef<[T]>` from a raw thin pointer and a slice length.
@@ -624,7 +620,7 @@ where
     pub unsafe fn from_raw_parts_mut<'a>(ptr: *mut T, len: usize) -> &'a mut Self {
         // SAFETY: The caller must uphold the safety contract for `from_raw_parts_mut`.
         unsafe {
-            &mut *(<[T]>::from_raw_sized(ptr as _, len * mem::size_of::<T>()).as_ptr() as *mut Self)
+            &mut *(<[T]>::from_raw_sized(ptr as _, len * size_of::<T>()).as_ptr() as *mut Self)
         }
     }
 
@@ -744,7 +740,7 @@ where
     fn drop(&mut self) {
         unsafe {
             let ptr = (*self.0.as_ptr()).0.get();
-            super::free(ptr as _, mem::size_of_val(&mut *ptr), T::align_of());
+            super::free(ptr as _, size_of_val(&mut *ptr), T::align_of());
         }
     }
 }
diff --git a/library/std/src/sys/pal/uefi/args.rs b/library/std/src/sys/pal/uefi/args.rs
index bdf6f5a0c1c..0c29caf2db6 100644
--- a/library/std/src/sys/pal/uefi/args.rs
+++ b/library/std/src/sys/pal/uefi/args.rs
@@ -4,7 +4,6 @@ use super::helpers;
 use crate::env::current_exe;
 use crate::ffi::OsString;
 use crate::iter::Iterator;
-use crate::mem::size_of;
 use crate::{fmt, vec};
 
 pub struct Args {
diff --git a/library/std/src/sys/pal/uefi/helpers.rs b/library/std/src/sys/pal/uefi/helpers.rs
index cb6aacd0063..0a2a8f5ef67 100644
--- a/library/std/src/sys/pal/uefi/helpers.rs
+++ b/library/std/src/sys/pal/uefi/helpers.rs
@@ -10,12 +10,12 @@
 //! - More information about protocols can be found [here](https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/3_foundation/36_protocols_and_handles)
 
 use r_efi::efi::{self, Guid};
-use r_efi::protocols::{device_path, device_path_to_text, shell};
+use r_efi::protocols::{device_path, device_path_to_text, service_binding, shell};
 
 use crate::ffi::{OsStr, OsString};
 use crate::io::{self, const_error};
 use crate::marker::PhantomData;
-use crate::mem::{MaybeUninit, size_of};
+use crate::mem::MaybeUninit;
 use crate::os::uefi::env::boot_services;
 use crate::os::uefi::ffi::{OsStrExt, OsStringExt};
 use crate::os::uefi::{self};
@@ -500,3 +500,62 @@ pub(crate) fn get_device_path_from_map(map: &Path) -> io::Result<BorrowedDeviceP
 
     Ok(BorrowedDevicePath::new(protocol))
 }
+
+/// Helper for UEFI Protocols which are created and destroyed using
+/// [EFI_SERVICE_BINDING_PROTCOL](https://uefi.org/specs/UEFI/2.11/11_Protocols_UEFI_Driver_Model.html#efi-service-binding-protocol)
+pub(crate) struct ServiceProtocol {
+    service_guid: r_efi::efi::Guid,
+    handle: NonNull<crate::ffi::c_void>,
+    child_handle: NonNull<crate::ffi::c_void>,
+}
+
+impl ServiceProtocol {
+    #[expect(dead_code)]
+    pub(crate) fn open(service_guid: r_efi::efi::Guid) -> io::Result<Self> {
+        let handles = locate_handles(service_guid)?;
+
+        for handle in handles {
+            if let Ok(protocol) = open_protocol::<service_binding::Protocol>(handle, service_guid) {
+                let Ok(child_handle) = Self::create_child(protocol) else {
+                    continue;
+                };
+
+                return Ok(Self { service_guid, handle, child_handle });
+            }
+        }
+
+        Err(io::const_error!(io::ErrorKind::NotFound, "no service binding protocol found"))
+    }
+
+    #[expect(dead_code)]
+    pub(crate) fn child_handle(&self) -> NonNull<crate::ffi::c_void> {
+        self.child_handle
+    }
+
+    fn create_child(
+        sbp: NonNull<service_binding::Protocol>,
+    ) -> io::Result<NonNull<crate::ffi::c_void>> {
+        let mut child_handle: r_efi::efi::Handle = crate::ptr::null_mut();
+        // SAFETY: A new handle is allocated if a pointer to NULL is passed.
+        let r = unsafe { ((*sbp.as_ptr()).create_child)(sbp.as_ptr(), &mut child_handle) };
+
+        if r.is_error() {
+            Err(crate::io::Error::from_raw_os_error(r.as_usize()))
+        } else {
+            NonNull::new(child_handle)
+                .ok_or(const_error!(io::ErrorKind::Other, "null child handle"))
+        }
+    }
+}
+
+impl Drop for ServiceProtocol {
+    fn drop(&mut self) {
+        if let Ok(sbp) = open_protocol::<service_binding::Protocol>(self.handle, self.service_guid)
+        {
+            // SAFETY: Child handle must be allocated by the current service binding protocol.
+            let _ = unsafe {
+                ((*sbp.as_ptr()).destroy_child)(sbp.as_ptr(), self.child_handle.as_ptr())
+            };
+        }
+    }
+}
diff --git a/library/std/src/sys/pal/uefi/process.rs b/library/std/src/sys/pal/uefi/process.rs
index a47c8dbcaaa..1203d51e531 100644
--- a/library/std/src/sys/pal/uefi/process.rs
+++ b/library/std/src/sys/pal/uefi/process.rs
@@ -490,7 +490,7 @@ mod uefi_command_internal {
                 helpers::open_protocol(self.handle, loaded_image::PROTOCOL_GUID).unwrap();
 
             let len = args.len();
-            let args_size: u32 = (len * crate::mem::size_of::<u16>()).try_into().unwrap();
+            let args_size: u32 = (len * size_of::<u16>()).try_into().unwrap();
             let ptr = Box::into_raw(args).as_mut_ptr();
 
             unsafe {
@@ -757,7 +757,7 @@ mod uefi_command_internal {
 }
 
 /// Create a map of environment variable changes. Allows efficient setting and rolling back of
-/// enviroment variable changes.
+/// environment variable changes.
 ///
 /// Entry: (Old Value, New Value)
 fn env_changes(env: &CommandEnv) -> Option<BTreeMap<EnvKey, (Option<OsString>, Option<OsString>)>> {
diff --git a/library/std/src/sys/pal/uefi/tests.rs b/library/std/src/sys/pal/uefi/tests.rs
index 5eb36da922b..38658cc4e9a 100644
--- a/library/std/src/sys/pal/uefi/tests.rs
+++ b/library/std/src/sys/pal/uefi/tests.rs
@@ -16,7 +16,7 @@ fn align() {
             if *j <= 8 {
                 assert_eq!(align_size(i, *j), i);
             } else {
-                assert!(align_size(i, *j) > i + std::mem::size_of::<*mut ()>());
+                assert!(align_size(i, *j) > i + size_of::<*mut ()>());
             }
         }
     }
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index 3df460e38b7..20ba915af13 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -1505,7 +1505,7 @@ impl File {
                     self.as_raw_fd(),
                     (&raw const attrlist).cast::<libc::c_void>().cast_mut(),
                     buf.as_ptr().cast::<libc::c_void>().cast_mut(),
-                    num_times * mem::size_of::<libc::timespec>(),
+                    num_times * size_of::<libc::timespec>(),
                     0
                 ) })?;
                 Ok(())
@@ -1660,7 +1660,7 @@ impl fmt::Debug for File {
         fn get_path(fd: c_int) -> Option<PathBuf> {
             let info = Box::<libc::kinfo_file>::new_zeroed();
             let mut info = unsafe { info.assume_init() };
-            info.kf_structsize = mem::size_of::<libc::kinfo_file>() as libc::c_int;
+            info.kf_structsize = size_of::<libc::kinfo_file>() as libc::c_int;
             let n = unsafe { libc::fcntl(fd, libc::F_KINFO, &mut *info) };
             if n == -1 {
                 return None;
diff --git a/library/std/src/sys/pal/unix/futex.rs b/library/std/src/sys/pal/unix/futex.rs
index d4551dd6a38..87ba13ca932 100644
--- a/library/std/src/sys/pal/unix/futex.rs
+++ b/library/std/src/sys/pal/unix/futex.rs
@@ -58,7 +58,7 @@ pub fn futex_wait(futex: &AtomicU32, expected: u32, timeout: Option<Duration>) -
                         _clockid: libc::CLOCK_MONOTONIC as u32,
                     });
                     let umtx_timeout_ptr = umtx_timeout.as_ref().map_or(null(), |t| t as *const _);
-                    let umtx_timeout_size = umtx_timeout.as_ref().map_or(0, |t| crate::mem::size_of_val(t));
+                    let umtx_timeout_size = umtx_timeout.as_ref().map_or(0, |t| size_of_val(t));
                     libc::_umtx_op(
                         futex as *const AtomicU32 as *mut _,
                         libc::UMTX_OP_WAIT_UINT_PRIVATE,
diff --git a/library/std/src/sys/pal/unix/process/process_common.rs b/library/std/src/sys/pal/unix/process/process_common.rs
index 342818ac911..0ea9db211b3 100644
--- a/library/std/src/sys/pal/unix/process/process_common.rs
+++ b/library/std/src/sys/pal/unix/process/process_common.rs
@@ -43,10 +43,7 @@ cfg_if::cfg_if! {
 
         #[allow(dead_code)]
         pub unsafe fn sigaddset(set: *mut libc::sigset_t, signum: libc::c_int) -> libc::c_int {
-            use crate::{
-                mem::{align_of, size_of},
-                slice,
-            };
+            use crate::slice;
             use libc::{c_ulong, sigset_t};
 
             // The implementations from bionic (android libc) type pun `sigset_t` as an
diff --git a/library/std/src/sys/pal/unix/process/process_fuchsia.rs b/library/std/src/sys/pal/unix/process/process_fuchsia.rs
index 4ddc96356b9..05c9ace470e 100644
--- a/library/std/src/sys/pal/unix/process/process_fuchsia.rs
+++ b/library/std/src/sys/pal/unix/process/process_fuchsia.rs
@@ -179,7 +179,7 @@ impl Process {
                 self.handle.raw(),
                 ZX_INFO_PROCESS,
                 (&raw mut proc_info) as *mut libc::c_void,
-                mem::size_of::<zx_info_process_t>(),
+                size_of::<zx_info_process_t>(),
                 &mut actual,
                 &mut avail,
             ))?;
@@ -216,7 +216,7 @@ impl Process {
                 self.handle.raw(),
                 ZX_INFO_PROCESS,
                 (&raw mut proc_info) as *mut libc::c_void,
-                mem::size_of::<zx_info_process_t>(),
+                size_of::<zx_info_process_t>(),
                 &mut actual,
                 &mut avail,
             ))?;
diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs
index 1f3abd4cc12..25d9e935332 100644
--- a/library/std/src/sys/pal/unix/process/process_unix.rs
+++ b/library/std/src/sys/pal/unix/process/process_unix.rs
@@ -410,6 +410,7 @@ impl Command {
 
     #[cfg(not(any(
         target_os = "freebsd",
+        target_os = "illumos",
         all(target_os = "linux", target_env = "gnu"),
         all(target_os = "linux", target_env = "musl"),
         target_os = "nto",
@@ -427,6 +428,7 @@ impl Command {
     // directly.
     #[cfg(any(
         target_os = "freebsd",
+        target_os = "illumos",
         all(target_os = "linux", target_env = "gnu"),
         all(target_os = "linux", target_env = "musl"),
         target_os = "nto",
@@ -584,6 +586,10 @@ impl Command {
         fn get_posix_spawn_addchdir() -> Option<PosixSpawnAddChdirFn> {
             use crate::sys::weak::weak;
 
+            // POSIX.1-2024 standardizes this function:
+            // https://pubs.opengroup.org/onlinepubs/9799919799/functions/posix_spawn_file_actions_addchdir.html.
+            // The _np version is more widely available, though, so try that first.
+
             weak! {
                 fn posix_spawn_file_actions_addchdir_np(
                     *mut libc::posix_spawn_file_actions_t,
@@ -591,7 +597,16 @@ impl Command {
                 ) -> libc::c_int
             }
 
-            posix_spawn_file_actions_addchdir_np.get()
+            weak! {
+                fn posix_spawn_file_actions_addchdir(
+                    *mut libc::posix_spawn_file_actions_t,
+                    *const libc::c_char
+                ) -> libc::c_int
+            }
+
+            posix_spawn_file_actions_addchdir_np
+                .get()
+                .or_else(|| posix_spawn_file_actions_addchdir.get())
         }
 
         /// Get the function pointer for adding a chdir action to a
@@ -799,7 +814,7 @@ impl Command {
 
             let fds: [c_int; 1] = [pidfd as RawFd];
 
-            const SCM_MSG_LEN: usize = mem::size_of::<[c_int; 1]>();
+            const SCM_MSG_LEN: usize = size_of::<[c_int; 1]>();
 
             #[repr(C)]
             union Cmsg {
@@ -818,7 +833,7 @@ impl Command {
 
             // only attach cmsg if we successfully acquired the pidfd
             if pidfd >= 0 {
-                msg.msg_controllen = mem::size_of_val(&cmsg.buf) as _;
+                msg.msg_controllen = size_of_val(&cmsg.buf) as _;
                 msg.msg_control = (&raw mut cmsg.buf) as *mut _;
 
                 let hdr = CMSG_FIRSTHDR((&raw mut msg) as *mut _);
@@ -850,7 +865,7 @@ impl Command {
         use crate::sys::cvt_r;
 
         unsafe {
-            const SCM_MSG_LEN: usize = mem::size_of::<[c_int; 1]>();
+            const SCM_MSG_LEN: usize = size_of::<[c_int; 1]>();
 
             #[repr(C)]
             union Cmsg {
@@ -865,7 +880,7 @@ impl Command {
 
             msg.msg_iov = (&raw mut iov) as *mut _;
             msg.msg_iovlen = 1;
-            msg.msg_controllen = mem::size_of::<Cmsg>() as _;
+            msg.msg_controllen = size_of::<Cmsg>() as _;
             msg.msg_control = (&raw mut cmsg) as *mut _;
 
             match cvt_r(|| libc::recvmsg(sock.as_raw(), &mut msg, libc::MSG_CMSG_CLOEXEC)) {
diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs
index 43ece63457f..0ecccdc8812 100644
--- a/library/std/src/sys/pal/unix/stack_overflow.rs
+++ b/library/std/src/sys/pal/unix/stack_overflow.rs
@@ -426,7 +426,7 @@ mod imp {
             use crate::sys::weak::dlsym;
             dlsym!(fn sysctlbyname(*const libc::c_char, *mut libc::c_void, *mut libc::size_t, *const libc::c_void, libc::size_t) -> libc::c_int);
             let mut guard: usize = 0;
-            let mut size = mem::size_of_val(&guard);
+            let mut size = size_of_val(&guard);
             let oid = c"security.bsd.stack_guard_page";
             match sysctlbyname.get() {
                 Some(fcn) if unsafe {
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 3dedc8d1257..11f6998cac1 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -372,7 +372,7 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
                 quota = cgroups::quota().max(1);
                 let mut set: libc::cpu_set_t = unsafe { mem::zeroed() };
                 unsafe {
-                    if libc::sched_getaffinity(0, mem::size_of::<libc::cpu_set_t>(), &mut set) == 0 {
+                    if libc::sched_getaffinity(0, size_of::<libc::cpu_set_t>(), &mut set) == 0 {
                         let count = libc::CPU_COUNT(&set) as usize;
                         let count = count.min(quota);
 
@@ -412,7 +412,7 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
                         libc::CPU_LEVEL_WHICH,
                         libc::CPU_WHICH_PID,
                         -1,
-                        mem::size_of::<libc::cpuset_t>(),
+                        size_of::<libc::cpuset_t>(),
                         &mut set,
                     ) == 0 {
                         let count = libc::CPU_COUNT(&set) as usize;
@@ -447,7 +447,7 @@ pub fn available_parallelism() -> io::Result<NonZero<usize>> {
             }
 
             let mut cpus: libc::c_uint = 0;
-            let mut cpus_size = crate::mem::size_of_val(&cpus);
+            let mut cpus_size = size_of_val(&cpus);
 
             unsafe {
                 cpus = libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as libc::c_uint;
diff --git a/library/std/src/sys/pal/unix/weak.rs b/library/std/src/sys/pal/unix/weak.rs
index 5a37598f438..7ec4787f1ea 100644
--- a/library/std/src/sys/pal/unix/weak.rs
+++ b/library/std/src/sys/pal/unix/weak.rs
@@ -123,7 +123,7 @@ impl<F> DlsymWeak<F> {
     // Cold because it should only happen during first-time initialization.
     #[cold]
     unsafe fn initialize(&self) -> Option<F> {
-        assert_eq!(mem::size_of::<F>(), mem::size_of::<*mut libc::c_void>());
+        assert_eq!(size_of::<F>(), size_of::<*mut libc::c_void>());
 
         let val = fetch(self.name);
         // This synchronizes with the acquire fence in `get`.
diff --git a/library/std/src/sys/pal/wasi/fd.rs b/library/std/src/sys/pal/wasi/fd.rs
index 19b60157e2e..4b3dd1ce49e 100644
--- a/library/std/src/sys/pal/wasi/fd.rs
+++ b/library/std/src/sys/pal/wasi/fd.rs
@@ -14,8 +14,8 @@ pub struct WasiFd {
 }
 
 fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] {
-    assert_eq!(mem::size_of::<IoSliceMut<'_>>(), mem::size_of::<wasi::Iovec>());
-    assert_eq!(mem::align_of::<IoSliceMut<'_>>(), mem::align_of::<wasi::Iovec>());
+    assert_eq!(size_of::<IoSliceMut<'_>>(), size_of::<wasi::Iovec>());
+    assert_eq!(align_of::<IoSliceMut<'_>>(), align_of::<wasi::Iovec>());
     // SAFETY: `IoSliceMut` and `IoVec` have exactly the same memory layout.
     // We decorate our `IoSliceMut` with `repr(transparent)` (see `io.rs`), and
     // `crate::io::IoSliceMut` is a `repr(transparent)` wrapper around our type, so this is
@@ -24,8 +24,8 @@ fn iovec<'a>(a: &'a mut [IoSliceMut<'_>]) -> &'a [wasi::Iovec] {
 }
 
 fn ciovec<'a>(a: &'a [IoSlice<'_>]) -> &'a [wasi::Ciovec] {
-    assert_eq!(mem::size_of::<IoSlice<'_>>(), mem::size_of::<wasi::Ciovec>());
-    assert_eq!(mem::align_of::<IoSlice<'_>>(), mem::align_of::<wasi::Ciovec>());
+    assert_eq!(size_of::<IoSlice<'_>>(), size_of::<wasi::Ciovec>());
+    assert_eq!(align_of::<IoSlice<'_>>(), align_of::<wasi::Ciovec>());
     // SAFETY: `IoSlice` and `CIoVec` have exactly the same memory layout.
     // We decorate our `IoSlice` with `repr(transparent)` (see `io.rs`), and
     // `crate::io::IoSlice` is a `repr(transparent)` wrapper around our type, so this is
diff --git a/library/std/src/sys/pal/wasi/fs.rs b/library/std/src/sys/pal/wasi/fs.rs
index 39978346d73..6d7d125fc4d 100644
--- a/library/std/src/sys/pal/wasi/fs.rs
+++ b/library/std/src/sys/pal/wasi/fs.rs
@@ -209,7 +209,7 @@ impl Iterator for ReadDir {
             }
             ReadDirState::ProcessEntry { buf, next_read_offset, offset } => {
                 let contents = &buf[*offset..];
-                const DIRENT_SIZE: usize = crate::mem::size_of::<wasi::Dirent>();
+                const DIRENT_SIZE: usize = size_of::<wasi::Dirent>();
                 if contents.len() >= DIRENT_SIZE {
                     let (dirent, data) = contents.split_at(DIRENT_SIZE);
                     let dirent =
diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs
index 0ae02369410..c85b03d4a89 100644
--- a/library/std/src/sys/pal/wasi/thread.rs
+++ b/library/std/src/sys/pal/wasi/thread.rs
@@ -13,16 +13,15 @@ cfg_if::cfg_if! {
         // Add a few symbols not in upstream `libc` just yet.
         mod libc {
             pub use crate::ffi;
-            pub use crate::mem;
             pub use libc::*;
 
             // defined in wasi-libc
             // https://github.com/WebAssembly/wasi-libc/blob/a6f871343313220b76009827ed0153586361c0d5/libc-top-half/musl/include/alltypes.h.in#L108
             #[repr(C)]
             union pthread_attr_union {
-                __i: [ffi::c_int; if mem::size_of::<ffi::c_long>() == 8 { 14 } else { 9 }],
-                __vi: [ffi::c_int; if mem::size_of::<ffi::c_long>() == 8 { 14 } else { 9 }],
-                __s: [ffi::c_ulong; if mem::size_of::<ffi::c_long>() == 8 { 7 } else { 9 }],
+                __i: [ffi::c_int; if size_of::<ffi::c_long>() == 8 { 14 } else { 9 }],
+                __vi: [ffi::c_int; if size_of::<ffi::c_long>() == 8 { 14 } else { 9 }],
+                __s: [ffi::c_ulong; if size_of::<ffi::c_long>() == 8 { 7 } else { 9 }],
             }
 
             #[repr(C)]
diff --git a/library/std/src/sys/pal/windows/api.rs b/library/std/src/sys/pal/windows/api.rs
index ebe207fde93..6b5f9aeace2 100644
--- a/library/std/src/sys/pal/windows/api.rs
+++ b/library/std/src/sys/pal/windows/api.rs
@@ -137,7 +137,7 @@ pub const fn to_utf16<const UTF16_LEN: usize>(s: &str) -> [u16; UTF16_LEN] {
 /// use frequent `as` casts. This is risky because they are too powerful.
 /// For example, the following will compile today:
 ///
-/// `std::mem::size_of::<u64> as u32`
+/// `size_of::<u64> as u32`
 ///
 /// Note that `size_of` is never actually called, instead a function pointer is
 /// converted to a `u32`. Clippy would warn about this but, alas, it's not run
@@ -147,7 +147,7 @@ const fn win32_size_of<T: Sized>() -> u32 {
     // Uses a trait to workaround restriction on using generic types in inner items.
     trait Win32SizeOf: Sized {
         const WIN32_SIZE_OF: u32 = {
-            let size = core::mem::size_of::<Self>();
+            let size = size_of::<Self>();
             assert!(size <= u32::MAX as usize);
             size as u32
         };
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index 4fbdc839939..40b2bed73c0 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -6,7 +6,7 @@
 #![allow(clippy::style)]
 
 use core::ffi::{CStr, c_uint, c_ulong, c_ushort, c_void};
-use core::{mem, ptr};
+use core::ptr;
 
 mod windows_sys;
 pub use windows_sys::*;
@@ -39,7 +39,7 @@ pub fn nt_success(status: NTSTATUS) -> bool {
 
 impl UNICODE_STRING {
     pub fn from_ref(slice: &[u16]) -> Self {
-        let len = mem::size_of_val(slice);
+        let len = size_of_val(slice);
         Self { Length: len as _, MaximumLength: len as _, Buffer: slice.as_ptr() as _ }
     }
 }
@@ -47,7 +47,7 @@ impl UNICODE_STRING {
 impl Default for OBJECT_ATTRIBUTES {
     fn default() -> Self {
         Self {
-            Length: mem::size_of::<Self>() as _,
+            Length: size_of::<Self>() as _,
             RootDirectory: ptr::null_mut(),
             ObjectName: ptr::null_mut(),
             Attributes: 0,
diff --git a/library/std/src/sys/pal/windows/fs.rs b/library/std/src/sys/pal/windows/fs.rs
index 623a7d89ba5..17dc3e5c257 100644
--- a/library/std/src/sys/pal/windows/fs.rs
+++ b/library/std/src/sys/pal/windows/fs.rs
@@ -477,7 +477,7 @@ impl File {
                     self.handle.as_raw_handle(),
                     c::FileAttributeTagInfo,
                     (&raw mut attr_tag).cast(),
-                    mem::size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(),
+                    size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(),
                 ))?;
                 if attr_tag.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
                     reparse_tag = attr_tag.ReparseTag;
@@ -504,7 +504,7 @@ impl File {
     pub fn file_attr(&self) -> io::Result<FileAttr> {
         unsafe {
             let mut info: c::FILE_BASIC_INFO = mem::zeroed();
-            let size = mem::size_of_val(&info);
+            let size = size_of_val(&info);
             cvt(c::GetFileInformationByHandleEx(
                 self.handle.as_raw_handle(),
                 c::FileBasicInfo,
@@ -536,7 +536,7 @@ impl File {
                 file_index: None,
             };
             let mut info: c::FILE_STANDARD_INFO = mem::zeroed();
-            let size = mem::size_of_val(&info);
+            let size = size_of_val(&info);
             cvt(c::GetFileInformationByHandleEx(
                 self.handle.as_raw_handle(),
                 c::FileStandardInfo,
@@ -551,7 +551,7 @@ impl File {
                     self.handle.as_raw_handle(),
                     c::FileAttributeTagInfo,
                     (&raw mut attr_tag).cast(),
-                    mem::size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(),
+                    size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(),
                 ))?;
                 if attr_tag.FileAttributes & c::FILE_ATTRIBUTE_REPARSE_POINT != 0 {
                     attr.reparse_tag = attr_tag.ReparseTag;
@@ -649,7 +649,7 @@ impl File {
                     ptr::null_mut(),
                 )
             })?;
-            const _: () = assert!(core::mem::align_of::<c::REPARSE_DATA_BUFFER>() <= 8);
+            const _: () = assert!(align_of::<c::REPARSE_DATA_BUFFER>() <= 8);
             Ok((bytes, space.0.as_mut_ptr().cast::<c::REPARSE_DATA_BUFFER>()))
         }
     }
@@ -753,7 +753,7 @@ impl File {
     fn basic_info(&self) -> io::Result<c::FILE_BASIC_INFO> {
         unsafe {
             let mut info: c::FILE_BASIC_INFO = mem::zeroed();
-            let size = mem::size_of_val(&info);
+            let size = size_of_val(&info);
             cvt(c::GetFileInformationByHandleEx(
                 self.handle.as_raw_handle(),
                 c::FileBasicInfo,
@@ -886,7 +886,6 @@ impl<'a> DirBuffIter<'a> {
 impl<'a> Iterator for DirBuffIter<'a> {
     type Item = (Cow<'a, [u16]>, bool);
     fn next(&mut self) -> Option<Self::Item> {
-        use crate::mem::size_of;
         let buffer = &self.buffer?[self.cursor..];
 
         // Get the name and next entry from the buffer.
@@ -1249,8 +1248,8 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
     // Therefore we need to make sure to not allocate less than
     // size_of::<c::FILE_RENAME_INFO>() bytes, which would be the case with
     // 0 or 1 character paths + a null byte.
-    let struct_size = mem::size_of::<c::FILE_RENAME_INFO>()
-        .max(mem::offset_of!(c::FILE_RENAME_INFO, FileName) + new.len() * mem::size_of::<u16>());
+    let struct_size = size_of::<c::FILE_RENAME_INFO>()
+        .max(mem::offset_of!(c::FILE_RENAME_INFO, FileName) + new.len() * size_of::<u16>());
 
     let struct_size: u32 = struct_size.try_into().unwrap();
 
@@ -1282,7 +1281,7 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
                     handle.as_raw_handle(),
                     c::FileAttributeTagInfo,
                     file_attribute_tag_info.as_mut_ptr().cast(),
-                    mem::size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(),
+                    size_of::<c::FILE_ATTRIBUTE_TAG_INFO>().try_into().unwrap(),
                 ))
             };
 
@@ -1321,11 +1320,9 @@ pub fn rename(old: &Path, new: &Path) -> io::Result<()> {
     }
     .unwrap_or_else(|| create_file(0, 0))?;
 
-    let layout = core::alloc::Layout::from_size_align(
-        struct_size as _,
-        mem::align_of::<c::FILE_RENAME_INFO>(),
-    )
-    .unwrap();
+    let layout =
+        core::alloc::Layout::from_size_align(struct_size as _, align_of::<c::FILE_RENAME_INFO>())
+            .unwrap();
 
     let file_rename_info = unsafe { alloc(layout) } as *mut c::FILE_RENAME_INFO;
 
diff --git a/library/std/src/sys/pal/windows/futex.rs b/library/std/src/sys/pal/windows/futex.rs
index 38afb8c043b..aebf638239c 100644
--- a/library/std/src/sys/pal/windows/futex.rs
+++ b/library/std/src/sys/pal/windows/futex.rs
@@ -1,10 +1,10 @@
 use core::ffi::c_void;
+use core::ptr;
 use core::sync::atomic::{
     AtomicBool, AtomicI8, AtomicI16, AtomicI32, AtomicI64, AtomicIsize, AtomicPtr, AtomicU8,
     AtomicU16, AtomicU32, AtomicU64, AtomicUsize,
 };
 use core::time::Duration;
-use core::{mem, ptr};
 
 use super::api::{self, WinError};
 use crate::sys::{c, dur2timeout};
@@ -61,7 +61,7 @@ pub fn wait_on_address<W: Waitable>(
 ) -> bool {
     unsafe {
         let addr = ptr::from_ref(address).cast::<c_void>();
-        let size = mem::size_of::<W>();
+        let size = size_of::<W>();
         let compare_addr = (&raw const compare).cast::<c_void>();
         let timeout = timeout.map(dur2timeout).unwrap_or(c::INFINITE);
         c::WaitOnAddress(addr, compare_addr, size, timeout) == c::TRUE
diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs
index a8f6617c9dc..8521cf4162f 100644
--- a/library/std/src/sys/pal/windows/pipe.rs
+++ b/library/std/src/sys/pal/windows/pipe.rs
@@ -151,7 +151,7 @@ pub fn anon_pipe(ours_readable: bool, their_handle_inheritable: bool) -> io::Res
         opts.write(ours_readable);
         opts.read(!ours_readable);
         opts.share_mode(0);
-        let size = mem::size_of::<c::SECURITY_ATTRIBUTES>();
+        let size = size_of::<c::SECURITY_ATTRIBUTES>();
         let mut sa = c::SECURITY_ATTRIBUTES {
             nLength: size as u32,
             lpSecurityDescriptor: ptr::null_mut(),
diff --git a/library/std/src/sys/pal/windows/process.rs b/library/std/src/sys/pal/windows/process.rs
index 6eff471f386..c57ff355d12 100644
--- a/library/std/src/sys/pal/windows/process.rs
+++ b/library/std/src/sys/pal/windows/process.rs
@@ -24,7 +24,7 @@ use crate::sys::pipe::{self, AnonPipe};
 use crate::sys::{cvt, path, stdio};
 use crate::sys_common::IntoInner;
 use crate::sys_common::process::{CommandEnv, CommandEnvs};
-use crate::{cmp, env, fmt, mem, ptr};
+use crate::{cmp, env, fmt, ptr};
 
 ////////////////////////////////////////////////////////////////////////////////
 // Command
@@ -355,7 +355,7 @@ impl Command {
         let mut si_ex;
 
         if let Some(proc_thread_attribute_list) = proc_thread_attribute_list {
-            si.cb = mem::size_of::<c::STARTUPINFOEXW>() as u32;
+            si.cb = size_of::<c::STARTUPINFOEXW>() as u32;
             flags |= c::EXTENDED_STARTUPINFO_PRESENT;
 
             si_ex = c::STARTUPINFOEXW {
@@ -367,7 +367,7 @@ impl Command {
             };
             si_ptr = (&raw mut si_ex) as _;
         } else {
-            si.cb = mem::size_of::<c::STARTUPINFOW>() as u32;
+            si.cb = size_of::<c::STARTUPINFOW>() as u32;
             si_ptr = (&raw mut si) as _;
         }
 
@@ -599,7 +599,7 @@ impl Stdio {
             // permissions as well as the ability to be inherited to child
             // processes (as this is about to be inherited).
             Stdio::Null => {
-                let size = mem::size_of::<c::SECURITY_ATTRIBUTES>();
+                let size = size_of::<c::SECURITY_ATTRIBUTES>();
                 let mut sa = c::SECURITY_ATTRIBUTES {
                     nLength: size as u32,
                     lpSecurityDescriptor: ptr::null_mut(),
diff --git a/library/std/src/sys/pal/windows/stdio.rs b/library/std/src/sys/pal/windows/stdio.rs
index 1b245991aa7..58d3406e138 100644
--- a/library/std/src/sys/pal/windows/stdio.rs
+++ b/library/std/src/sys/pal/windows/stdio.rs
@@ -359,7 +359,7 @@ fn read_u16s(handle: c::HANDLE, buf: &mut [MaybeUninit<u16>]) -> io::Result<usiz
     const CTRL_Z: u16 = 0x1A;
     const CTRL_Z_MASK: u32 = 1 << CTRL_Z;
     let input_control = c::CONSOLE_READCONSOLE_CONTROL {
-        nLength: crate::mem::size_of::<c::CONSOLE_READCONSOLE_CONTROL>() as u32,
+        nLength: size_of::<c::CONSOLE_READCONSOLE_CONTROL>() as u32,
         nInitialChars: 0,
         dwCtrlWakeupMask: CTRL_Z_MASK,
         dwControlKeyState: 0,
diff --git a/library/std/src/sys/pal/xous/stdio.rs b/library/std/src/sys/pal/xous/stdio.rs
index dfd47a1775a..71736145221 100644
--- a/library/std/src/sys/pal/xous/stdio.rs
+++ b/library/std/src/sys/pal/xous/stdio.rs
@@ -87,7 +87,7 @@ pub struct PanicWriter {
 
 impl io::Write for PanicWriter {
     fn write(&mut self, s: &[u8]) -> core::result::Result<usize, io::Error> {
-        for c in s.chunks(core::mem::size_of::<usize>() * 4) {
+        for c in s.chunks(size_of::<usize>() * 4) {
             // Text is grouped into 4x `usize` words. The id is 1100 plus
             // the number of characters in this message.
             // Ignore errors since we're already panicking.
diff --git a/library/std/src/sys/pal/zkvm/mod.rs b/library/std/src/sys/pal/zkvm/mod.rs
index 054c867f90d..8d8fe321f66 100644
--- a/library/std/src/sys/pal/zkvm/mod.rs
+++ b/library/std/src/sys/pal/zkvm/mod.rs
@@ -8,7 +8,7 @@
 //! will likely change over time.
 #![forbid(unsafe_op_in_unsafe_fn)]
 
-const WORD_SIZE: usize = core::mem::size_of::<u32>();
+const WORD_SIZE: usize = size_of::<u32>();
 
 pub mod abi;
 #[path = "../zkvm/args.rs"]
diff --git a/library/std/src/sys/personality/dwarf/eh.rs b/library/std/src/sys/personality/dwarf/eh.rs
index 778d8686f02..ef5112ad74f 100644
--- a/library/std/src/sys/personality/dwarf/eh.rs
+++ b/library/std/src/sys/personality/dwarf/eh.rs
@@ -12,7 +12,7 @@
 #![allow(non_upper_case_globals)]
 #![allow(unused)]
 
-use core::{mem, ptr};
+use core::ptr;
 
 use super::DwarfReader;
 
@@ -245,8 +245,7 @@ unsafe fn read_encoded_pointer(
         DW_EH_PE_datarel => (*context.get_data_start)(),
         // aligned means the value is aligned to the size of a pointer
         DW_EH_PE_aligned => {
-            reader.ptr =
-                reader.ptr.with_addr(round_up(reader.ptr.addr(), mem::size_of::<*const u8>())?);
+            reader.ptr = reader.ptr.with_addr(round_up(reader.ptr.addr(), size_of::<*const u8>())?);
             core::ptr::null()
         }
         _ => return Err(()),
diff --git a/library/std/src/sys/personality/dwarf/mod.rs b/library/std/src/sys/personality/dwarf/mod.rs
index 5c52d96c4ca..2bc91951b49 100644
--- a/library/std/src/sys/personality/dwarf/mod.rs
+++ b/library/std/src/sys/personality/dwarf/mod.rs
@@ -12,8 +12,6 @@ mod tests;
 
 pub mod eh;
 
-use core::mem;
-
 pub struct DwarfReader {
     pub ptr: *const u8,
 }
@@ -29,7 +27,7 @@ impl DwarfReader {
     pub unsafe fn read<T: Copy>(&mut self) -> T {
         unsafe {
             let result = self.ptr.cast::<T>().read_unaligned();
-            self.ptr = self.ptr.byte_add(mem::size_of::<T>());
+            self.ptr = self.ptr.byte_add(size_of::<T>());
             result
         }
     }
diff --git a/library/std/src/sys/thread_local/key/xous.rs b/library/std/src/sys/thread_local/key/xous.rs
index 55ac5b20e1a..48dfe17ab32 100644
--- a/library/std/src/sys/thread_local/key/xous.rs
+++ b/library/std/src/sys/thread_local/key/xous.rs
@@ -85,7 +85,7 @@ fn tls_table() -> &'static mut [*mut u8] {
 
     if !tp.is_null() {
         return unsafe {
-            core::slice::from_raw_parts_mut(tp, TLS_MEMORY_SIZE / core::mem::size_of::<*mut u8>())
+            core::slice::from_raw_parts_mut(tp, TLS_MEMORY_SIZE / size_of::<*mut u8>())
         };
     }
     // If the TP register is `0`, then this thread hasn't initialized
@@ -94,7 +94,7 @@ fn tls_table() -> &'static mut [*mut u8] {
         map_memory(
             None,
             None,
-            TLS_MEMORY_SIZE / core::mem::size_of::<*mut u8>(),
+            TLS_MEMORY_SIZE / size_of::<*mut u8>(),
             MemoryFlags::R | MemoryFlags::W,
         )
         .expect("Unable to allocate memory for thread local storage")
@@ -177,11 +177,8 @@ pub unsafe fn destroy_tls() {
 
     // Finally, free the TLS array
     unsafe {
-        unmap_memory(core::slice::from_raw_parts_mut(
-            tp,
-            TLS_MEMORY_SIZE / core::mem::size_of::<usize>(),
-        ))
-        .unwrap()
+        unmap_memory(core::slice::from_raw_parts_mut(tp, TLS_MEMORY_SIZE / size_of::<usize>()))
+            .unwrap()
     };
 }
 
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
index ff45e82bd9c..06c347af181 100644
--- a/library/std/src/thread/tests.rs
+++ b/library/std/src/thread/tests.rs
@@ -1,12 +1,12 @@
 use super::Builder;
 use crate::any::Any;
 use crate::panic::panic_any;
+use crate::result;
 use crate::sync::atomic::{AtomicBool, Ordering};
 use crate::sync::mpsc::{Sender, channel};
 use crate::sync::{Arc, Barrier};
 use crate::thread::{self, Scope, ThreadId};
 use crate::time::{Duration, Instant};
-use crate::{mem, result};
 
 // !!! These tests are dangerous. If something is buggy, they will hang, !!!
 // !!! instead of exiting cleanly. This might wedge the buildbots.       !!!
@@ -327,7 +327,7 @@ fn sleep_ms_smoke() {
 
 #[test]
 fn test_size_of_option_thread_id() {
-    assert_eq!(mem::size_of::<Option<ThreadId>>(), mem::size_of::<ThreadId>());
+    assert_eq!(size_of::<Option<ThreadId>>(), size_of::<ThreadId>());
 }
 
 #[test]
diff --git a/library/stdarch b/library/stdarch
-Subproject 684de0d6fef708cae08214fef9643dd9ec7296e
+Subproject 9426bb56586c6ae4095a2dcbd66c570253e6fb3
diff --git a/library/unwind/src/unwinding.rs b/library/unwind/src/unwinding.rs
index 1b94005ab6c..fa8a8c38583 100644
--- a/library/unwind/src/unwinding.rs
+++ b/library/unwind/src/unwinding.rs
@@ -39,9 +39,9 @@ pub type _Unwind_Exception_Class = u64;
 pub type _Unwind_Word = *const u8;
 pub type _Unwind_Ptr = *const u8;
 
-pub const unwinder_private_data_size: usize = core::mem::size_of::<UnwindException>()
-    - core::mem::size_of::<_Unwind_Exception_Class>()
-    - core::mem::size_of::<_Unwind_Exception_Cleanup_Fn>();
+pub const unwinder_private_data_size: usize = size_of::<UnwindException>()
+    - size_of::<_Unwind_Exception_Class>()
+    - size_of::<_Unwind_Exception_Cleanup_Fn>();
 
 pub type _Unwind_Exception_Cleanup_Fn =
     Option<extern "C" fn(unwind_code: _Unwind_Reason_Code, exception: *mut _Unwind_Exception)>;
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index e3f58d97cbc..c3b25646439 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -292,7 +292,7 @@ v(
 v("release-channel", "rust.channel", "the name of the release channel to build")
 v(
     "release-description",
-    "rust.description",
+    "build.description",
     "optional descriptive string for version output",
 )
 v("dist-compression-formats", None, "List of compression formats to use")
diff --git a/src/bootstrap/src/bin/main.rs b/src/bootstrap/src/bin/main.rs
index 38b380e3db8..6f6aaa878ef 100644
--- a/src/bootstrap/src/bin/main.rs
+++ b/src/bootstrap/src/bin/main.rs
@@ -70,11 +70,12 @@ fn main() {
     }
 
     // check_version warnings are not printed during setup, or during CI
-    let changelog_suggestion = if matches!(config.cmd, Subcommand::Setup { .. }) || CiEnv::is_ci() {
-        None
-    } else {
-        check_version(&config)
-    };
+    let changelog_suggestion =
+        if matches!(config.cmd, Subcommand::Setup { .. }) || CiEnv::is_ci() || config.dry_run() {
+            None
+        } else {
+            check_version(&config)
+        };
 
     // NOTE: Since `./configure` generates a `config.toml`, distro maintainers will see the
     // changelog warning, not the `x.py setup` message.
@@ -187,7 +188,7 @@ fn check_version(config: &Config) -> Option<String> {
             "update `config.toml` to use `change-id = {latest_change_id}` instead"
         ));
 
-        if io::stdout().is_terminal() && !config.dry_run() {
+        if io::stdout().is_terminal() {
             t!(fs::write(warned_id_path, latest_change_id.to_string()));
         }
     } else {
diff --git a/src/bootstrap/src/bin/rustc.rs b/src/bootstrap/src/bin/rustc.rs
index 61045067592..d8cae02456c 100644
--- a/src/bootstrap/src/bin/rustc.rs
+++ b/src/bootstrap/src/bin/rustc.rs
@@ -349,7 +349,7 @@ fn format_rusage_data(child: Child) -> Option<String> {
     let mut kernel_filetime = Default::default();
     let mut kernel_time = Default::default();
     let mut memory_counters = PROCESS_MEMORY_COUNTERS::default();
-    let memory_counters_size = std::mem::size_of_val(&memory_counters);
+    let memory_counters_size = size_of_val(&memory_counters);
 
     unsafe {
         GetProcessTimes(
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index d645d922ef4..78219500737 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -994,7 +994,9 @@ impl Step for Rustc {
     fn make_run(run: RunConfig<'_>) {
         let crates = run.cargo_crates_in_set();
         run.builder.ensure(Rustc {
-            compiler: run.builder.compiler(run.builder.top_stage, run.build_triple()),
+            compiler: run
+                .builder
+                .compiler(run.builder.top_stage.saturating_sub(1), run.build_triple()),
             target: run.target,
             crates,
         });
@@ -1911,7 +1913,7 @@ impl Step for Assemble {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(Assemble {
-            target_compiler: run.builder.compiler(run.builder.top_stage + 1, run.target),
+            target_compiler: run.builder.compiler(run.builder.top_stage, run.target),
         });
     }
 
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index 26b3e0b701c..0296346009f 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -421,7 +421,11 @@ impl Step for Rustc {
 
             if let Some(ra_proc_macro_srv) = builder.ensure_if_default(
                 tool::RustAnalyzerProcMacroSrv {
-                    compiler: builder.compiler(compiler.stage, builder.config.build),
+                    compiler: builder.compiler_for(
+                        compiler.stage,
+                        builder.config.build,
+                        compiler.host,
+                    ),
                     target: compiler.host,
                 },
                 builder.kind,
@@ -771,7 +775,11 @@ impl Step for Analysis {
             // Find the actual compiler (handling the full bootstrap option) which
             // produced the save-analysis data because that data isn't copied
             // through the sysroot uplifting.
-            compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+            compiler: run.builder.compiler_for(
+                run.builder.top_stage,
+                run.builder.config.build,
+                run.target,
+            ),
             target: run.target,
         });
     }
@@ -1116,7 +1124,11 @@ impl Step for Cargo {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(Cargo {
-            compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+            compiler: run.builder.compiler_for(
+                run.builder.top_stage,
+                run.builder.config.build,
+                run.target,
+            ),
             target: run.target,
         });
     }
@@ -1161,7 +1173,11 @@ impl Step for Rls {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(Rls {
-            compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+            compiler: run.builder.compiler_for(
+                run.builder.top_stage,
+                run.builder.config.build,
+                run.target,
+            ),
             target: run.target,
         });
     }
@@ -1199,7 +1215,11 @@ impl Step for RustAnalyzer {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(RustAnalyzer {
-            compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+            compiler: run.builder.compiler_for(
+                run.builder.top_stage,
+                run.builder.config.build,
+                run.target,
+            ),
             target: run.target,
         });
     }
@@ -1237,7 +1257,11 @@ impl Step for Clippy {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(Clippy {
-            compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+            compiler: run.builder.compiler_for(
+                run.builder.top_stage,
+                run.builder.config.build,
+                run.target,
+            ),
             target: run.target,
         });
     }
@@ -1280,7 +1304,11 @@ impl Step for Miri {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(Miri {
-            compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+            compiler: run.builder.compiler_for(
+                run.builder.top_stage,
+                run.builder.config.build,
+                run.target,
+            ),
             target: run.target,
         });
     }
@@ -1414,7 +1442,11 @@ impl Step for Rustfmt {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(Rustfmt {
-            compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+            compiler: run.builder.compiler_for(
+                run.builder.top_stage,
+                run.builder.config.build,
+                run.target,
+            ),
             target: run.target,
         });
     }
@@ -1464,7 +1496,7 @@ impl Step for Extended {
     fn run(self, builder: &Builder<'_>) {
         let target = self.target;
         let stage = self.stage;
-        let compiler = builder.compiler(self.stage, self.host);
+        let compiler = builder.compiler_for(self.stage, self.host, self.target);
 
         builder.info(&format!("Dist extended stage{} ({})", compiler.stage, target));
 
@@ -2112,8 +2144,7 @@ pub fn maybe_install_llvm_target(builder: &Builder<'_>, target: TargetSelection,
     ),
 )]
 pub fn maybe_install_llvm_runtime(builder: &Builder<'_>, target: TargetSelection, sysroot: &Path) {
-    let dst_libdir =
-        sysroot.join(builder.sysroot_libdir_relative(Compiler { stage: 1, host: target }));
+    let dst_libdir = sysroot.join(builder.sysroot_libdir_relative(Compiler::new(1, target)));
     // We do not need to copy LLVM files into the sysroot if it is not
     // dynamically linked; it is already included into librustc_llvm
     // statically.
@@ -2228,7 +2259,11 @@ impl Step for LlvmBitcodeLinker {
 
     fn make_run(run: RunConfig<'_>) {
         run.builder.ensure(LlvmBitcodeLinker {
-            compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.build),
+            compiler: run.builder.compiler_for(
+                run.builder.top_stage,
+                run.builder.config.build,
+                run.target,
+            ),
             target: run.target,
         });
     }
@@ -2464,3 +2499,30 @@ impl Step for ReproducibleArtifacts {
         if added_anything { Some(tarball.generate()) } else { None }
     }
 }
+
+/// Tarball containing a prebuilt version of the libgccjit library,
+/// needed as a dependency for the GCC codegen backend (similarly to the LLVM
+/// backend needing a prebuilt libLLVM).
+#[derive(Clone, Debug, Eq, Hash, PartialEq)]
+pub struct Gcc {
+    pub target: TargetSelection,
+}
+
+impl Step for Gcc {
+    type Output = GeneratedTarball;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.alias("gcc")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(Gcc { target: run.target });
+    }
+
+    fn run(self, builder: &Builder<'_>) -> Self::Output {
+        let tarball = Tarball::new(builder, "gcc", &self.target.triple);
+        let output = builder.ensure(super::gcc::Gcc { target: self.target });
+        tarball.add_file(output.libgccjit, ".", 0o644);
+        tarball.generate()
+    }
+}
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index c9fa2e9ba96..4b7c8d5770e 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -90,7 +90,7 @@ impl Step for CrateBootstrap {
         );
 
         let crate_name = path.rsplit_once('/').unwrap().1;
-        run_cargo_test(cargo, &[], &[], crate_name, crate_name, bootstrap_host, builder);
+        run_cargo_test(cargo, &[], &[], crate_name, bootstrap_host, builder);
     }
 }
 
@@ -140,15 +140,7 @@ You can skip linkcheck with --skip src/tools/linkchecker"
             SourceType::InTree,
             &[],
         );
-        run_cargo_test(
-            cargo,
-            &[],
-            &[],
-            "linkchecker",
-            "linkchecker self tests",
-            bootstrap_host,
-            builder,
-        );
+        run_cargo_test(cargo, &[], &[], "linkchecker self tests", bootstrap_host, builder);
 
         if builder.doc_tests == DocTests::No {
             return;
@@ -337,7 +329,7 @@ impl Step for Cargo {
         );
 
         // NOTE: can't use `run_cargo_test` because we need to overwrite `PATH`
-        let mut cargo = prepare_cargo_test(cargo, &[], &[], "cargo", self.host, builder);
+        let mut cargo = prepare_cargo_test(cargo, &[], &[], self.host, builder);
 
         // Don't run cross-compile tests, we may not have cross-compiled libstd libs
         // available.
@@ -423,7 +415,7 @@ impl Step for RustAnalyzer {
         cargo.env("SKIP_SLOW_TESTS", "1");
 
         cargo.add_rustc_lib_path(builder);
-        run_cargo_test(cargo, &[], &[], "rust-analyzer", "rust-analyzer", host, builder);
+        run_cargo_test(cargo, &[], &[], "rust-analyzer", host, builder);
     }
 }
 
@@ -472,7 +464,7 @@ impl Step for Rustfmt {
 
         cargo.add_rustc_lib_path(builder);
 
-        run_cargo_test(cargo, &[], &[], "rustfmt", "rustfmt", host, builder);
+        run_cargo_test(cargo, &[], &[], "rustfmt", host, builder);
     }
 }
 
@@ -588,7 +580,7 @@ impl Step for Miri {
 
         // We can NOT use `run_cargo_test` since Miri's integration tests do not use the usual test
         // harness and therefore do not understand the flags added by `add_flags_and_try_run_test`.
-        let mut cargo = prepare_cargo_test(cargo, &[], &[], "miri", host, builder);
+        let mut cargo = prepare_cargo_test(cargo, &[], &[], host, builder);
 
         // miri tests need to know about the stage sysroot
         cargo.env("MIRI_SYSROOT", &miri_sysroot);
@@ -736,7 +728,7 @@ impl Step for CompiletestTest {
             &[],
         );
         cargo.allow_features("test");
-        run_cargo_test(cargo, &[], &[], "compiletest", "compiletest self test", host, builder);
+        run_cargo_test(cargo, &[], &[], "compiletest self test", host, builder);
     }
 }
 
@@ -797,7 +789,7 @@ impl Step for Clippy {
         cargo.env("HOST_LIBS", host_libs);
 
         cargo.add_rustc_lib_path(builder);
-        let cargo = prepare_cargo_test(cargo, &[], &[], "clippy", host, builder);
+        let cargo = prepare_cargo_test(cargo, &[], &[], host, builder);
 
         let _guard = builder.msg_sysroot_tool(Kind::Test, compiler.stage, "clippy", host, host);
 
@@ -1242,59 +1234,6 @@ macro_rules! test {
     };
 }
 
-#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, Ord, PartialOrd)]
-pub struct RunMakeSupport {
-    pub compiler: Compiler,
-    pub target: TargetSelection,
-}
-
-impl Step for RunMakeSupport {
-    type Output = PathBuf;
-    const DEFAULT: bool = true;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.never()
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple());
-        run.builder.ensure(RunMakeSupport { compiler, target: run.build_triple() });
-    }
-
-    /// Builds run-make-support and returns the path to the resulting rlib.
-    fn run(self, builder: &Builder<'_>) -> PathBuf {
-        builder.ensure(compile::Std::new(self.compiler, self.target));
-
-        let cargo = tool::prepare_tool_cargo(
-            builder,
-            self.compiler,
-            Mode::ToolStd,
-            self.target,
-            Kind::Build,
-            "src/tools/run-make-support",
-            SourceType::InTree,
-            &[],
-        );
-
-        let _guard = builder.msg_tool(
-            Kind::Build,
-            Mode::ToolStd,
-            "run-make-support",
-            self.compiler.stage,
-            &self.compiler.host,
-            &self.target,
-        );
-        cargo.into_cmd().run(builder);
-
-        let lib_name = "librun_make_support.rlib";
-        let lib = builder.tools_dir(self.compiler).join(lib_name);
-
-        let cargo_out = builder.cargo_out(self.compiler, Mode::ToolStd, self.target).join(lib_name);
-        builder.copy_link(&cargo_out, &lib);
-        lib
-    }
-}
-
 /// Runs `cargo test` on the `src/tools/run-make-support` crate.
 /// That crate is used by run-make tests.
 #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -1330,15 +1269,7 @@ impl Step for CrateRunMakeSupport {
             &[],
         );
         cargo.allow_features("test");
-        run_cargo_test(
-            cargo,
-            &[],
-            &[],
-            "run-make-support",
-            "run-make-support self test",
-            host,
-            builder,
-        );
+        run_cargo_test(cargo, &[], &[], "run-make-support self test", host, builder);
     }
 }
 
@@ -1375,7 +1306,7 @@ impl Step for CrateBuildHelper {
             &[],
         );
         cargo.allow_features("test");
-        run_cargo_test(cargo, &[], &[], "build_helper", "build_helper self test", host, builder);
+        run_cargo_test(cargo, &[], &[], "build_helper self test", host, builder);
     }
 }
 
@@ -1446,40 +1377,7 @@ test!(Pretty {
     only_hosts: true,
 });
 
-/// Special-handling is needed for `run-make`, so don't use `test!` for defining `RunMake`
-/// tests.
-#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-pub struct RunMake {
-    pub compiler: Compiler,
-    pub target: TargetSelection,
-}
-
-impl Step for RunMake {
-    type Output = ();
-    const DEFAULT: bool = true;
-    const ONLY_HOSTS: bool = false;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.suite_path("tests/run-make")
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        let compiler = run.builder.compiler(run.builder.top_stage, run.build_triple());
-        run.builder.ensure(RunMakeSupport { compiler, target: run.build_triple() });
-        run.builder.ensure(RunMake { compiler, target: run.target });
-    }
-
-    fn run(self, builder: &Builder<'_>) {
-        builder.ensure(Compiletest {
-            compiler: self.compiler,
-            target: self.target,
-            mode: "run-make",
-            suite: "run-make",
-            path: "tests/run-make",
-            compare_mode: None,
-        });
-    }
-}
+test!(RunMake { path: "tests/run-make", mode: "run-make", suite: "run-make", default: true });
 
 test!(Assembly { path: "tests/assembly", mode: "assembly", suite: "assembly", default: true });
 
@@ -1722,6 +1620,9 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
                 host: target,
             });
         }
+        if suite == "run-make" {
+            builder.tool_exe(Tool::RunMakeSupport);
+        }
 
         // Also provide `rust_test_helpers` for the host.
         builder.ensure(TestHelpers { target: compiler.host });
@@ -1774,6 +1675,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
             };
 
             cmd.arg("--cargo-path").arg(cargo_path);
+
+            // We need to pass the compiler that was used to compile run-make-support,
+            // because we have to use the same compiler to compile rmake.rs recipes.
+            let stage0_rustc_path = builder.compiler(0, compiler.host);
+            cmd.arg("--stage0-rustc-path").arg(builder.rustc(stage0_rustc_path));
         }
 
         // Avoid depending on rustdoc when we don't need it.
@@ -2585,13 +2491,12 @@ fn run_cargo_test<'a>(
     cargo: builder::Cargo,
     libtest_args: &[&str],
     crates: &[String],
-    primary_crate: &str,
     description: impl Into<Option<&'a str>>,
     target: TargetSelection,
     builder: &Builder<'_>,
 ) -> bool {
     let compiler = cargo.compiler();
-    let mut cargo = prepare_cargo_test(cargo, libtest_args, crates, primary_crate, target, builder);
+    let mut cargo = prepare_cargo_test(cargo, libtest_args, crates, target, builder);
     let _time = helpers::timeit(builder);
     let _group = description.into().and_then(|what| {
         builder.msg_sysroot_tool(Kind::Test, compiler.stage, what, compiler.host, target)
@@ -2615,7 +2520,6 @@ fn prepare_cargo_test(
     cargo: builder::Cargo,
     libtest_args: &[&str],
     crates: &[String],
-    primary_crate: &str,
     target: TargetSelection,
     builder: &Builder<'_>,
 ) -> BootstrapCommand {
@@ -2645,13 +2549,6 @@ fn prepare_cargo_test(
             cargo.arg("--doc");
         }
         DocTests::No => {
-            let krate = &builder
-                .crates
-                .get(primary_crate)
-                .unwrap_or_else(|| panic!("missing crate {primary_crate}"));
-            if krate.has_lib {
-                cargo.arg("--lib");
-            }
             cargo.args(["--bins", "--examples", "--tests", "--benches"]);
         }
         DocTests::Yes => {}
@@ -2826,15 +2723,15 @@ impl Step for Crate {
             _ => panic!("can only test libraries"),
         };
 
-        run_cargo_test(
-            cargo,
-            &[],
-            &self.crates,
-            &self.crates[0],
-            &*crate_description(&self.crates),
-            target,
-            builder,
-        );
+        let mut crates = self.crates.clone();
+        // The core crate can't directly be tested. We could silently
+        // ignore it, but adding it's own test crate is less confusing
+        // for users. We still keep core itself for doctests.
+        if crates.iter().any(|crate_| crate_ == "core") {
+            crates.push("coretests".to_owned());
+        }
+
+        run_cargo_test(cargo, &[], &crates, &*crate_description(&self.crates), target, builder);
     }
 }
 
@@ -2927,15 +2824,7 @@ impl Step for CrateRustdoc {
         dylib_path.insert(0, PathBuf::from(&*libdir));
         cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
 
-        run_cargo_test(
-            cargo,
-            &[],
-            &["rustdoc:0.0.0".to_string()],
-            "rustdoc",
-            "rustdoc",
-            target,
-            builder,
-        );
+        run_cargo_test(cargo, &[], &["rustdoc:0.0.0".to_string()], "rustdoc", target, builder);
     }
 }
 
@@ -2992,7 +2881,6 @@ impl Step for CrateRustdocJsonTypes {
             libtest_args,
             &["rustdoc-json-types".to_string()],
             "rustdoc-json-types",
-            "rustdoc-json-types",
             target,
             builder,
         );
@@ -3172,7 +3060,7 @@ impl Step for Bootstrap {
 
         // bootstrap tests are racy on directory creation so just run them one at a time.
         // Since there's not many this shouldn't be a problem.
-        run_cargo_test(cargo, &["--test-threads=1"], &[], "bootstrap", None, host, builder);
+        run_cargo_test(cargo, &["--test-threads=1"], &[], None, host, builder);
     }
 
     fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
@@ -3297,7 +3185,7 @@ impl Step for RustInstaller {
             bootstrap_host,
             bootstrap_host,
         );
-        run_cargo_test(cargo, &[], &[], "installer", None, bootstrap_host, builder);
+        run_cargo_test(cargo, &[], &[], None, bootstrap_host, builder);
 
         // We currently don't support running the test.sh script outside linux(?) environments.
         // Eventually this should likely migrate to #[test]s in rust-installer proper rather than a
@@ -3688,7 +3576,7 @@ impl Step for TestFloatParse {
             &[],
         );
 
-        run_cargo_test(cargo_test, &[], &[], crate_name, crate_name, bootstrap_host, builder);
+        run_cargo_test(cargo_test, &[], &[], crate_name, bootstrap_host, builder);
 
         // Run the actual parse tests.
         let mut cargo_run = 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 39acb646dff..65633c9ea7c 100644
--- a/src/bootstrap/src/core/build_steps/tool.rs
+++ b/src/bootstrap/src/core/build_steps/tool.rs
@@ -35,6 +35,12 @@ pub enum SourceType {
 }
 
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
+pub enum ToolArtifactKind {
+    Binary,
+    Library,
+}
+
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
 struct ToolBuild {
     compiler: Compiler,
     target: TargetSelection,
@@ -47,6 +53,8 @@ struct ToolBuild {
     allow_features: &'static str,
     /// Additional arguments to pass to the `cargo` invocation.
     cargo_args: Vec<String>,
+    /// Whether the tool builds a binary or a library.
+    artifact_kind: ToolArtifactKind,
 }
 
 impl Builder<'_> {
@@ -79,7 +87,7 @@ impl Builder<'_> {
 /// for using this type as `type Output = ToolBuildResult;`
 #[derive(Clone)]
 pub struct ToolBuildResult {
-    /// Executable path of the corresponding tool that was built.
+    /// Artifact path of the corresponding tool that was built.
     pub tool_path: PathBuf,
     /// Compiler used to build the tool. For non-`ToolRustc` tools this is equal to `target_compiler`.
     /// For `ToolRustc` this is one stage before of the `target_compiler`.
@@ -179,8 +187,14 @@ impl Step for ToolBuild {
             if tool == "tidy" {
                 tool = "rust-tidy";
             }
-            let tool_path =
-                copy_link_tool_bin(builder, self.compiler, self.target, self.mode, tool);
+            let tool_path = match self.artifact_kind {
+                ToolArtifactKind::Binary => {
+                    copy_link_tool_bin(builder, self.compiler, self.target, self.mode, tool)
+                }
+                ToolArtifactKind::Library => builder
+                    .cargo_out(self.compiler, self.mode, self.target)
+                    .join(format!("lib{tool}.rlib")),
+            };
 
             ToolBuildResult { tool_path, build_compiler: self.compiler, target_compiler }
         }
@@ -234,23 +248,32 @@ pub fn prepare_tool_cargo(
     cargo.env("CFG_VERSION", builder.rust_version());
     cargo.env("CFG_RELEASE_NUM", &builder.version);
     cargo.env("DOC_RUST_LANG_ORG_CHANNEL", builder.doc_rust_lang_org_channel());
+
     if let Some(ref ver_date) = builder.rust_info().commit_date() {
         cargo.env("CFG_VER_DATE", ver_date);
     }
+
     if let Some(ref ver_hash) = builder.rust_info().sha() {
         cargo.env("CFG_VER_HASH", ver_hash);
     }
 
+    if let Some(description) = &builder.config.description {
+        cargo.env("CFG_VER_DESCRIPTION", description);
+    }
+
     let info = GitInfo::new(builder.config.omit_git_hash, &dir);
     if let Some(sha) = info.sha() {
         cargo.env("CFG_COMMIT_HASH", sha);
     }
+
     if let Some(sha_short) = info.sha_short() {
         cargo.env("CFG_SHORT_COMMIT_HASH", sha_short);
     }
+
     if let Some(date) = info.commit_date() {
         cargo.env("CFG_COMMIT_DATE", date);
     }
+
     if !features.is_empty() {
         cargo.arg("--features").arg(features.join(", "));
     }
@@ -299,6 +322,8 @@ pub(crate) fn get_tool_rustc_compiler(
     if builder.download_rustc() && target_compiler.stage == 1 {
         // We already have the stage 1 compiler, we don't need to cut the stage.
         builder.compiler(target_compiler.stage, builder.config.build)
+    } else if target_compiler.is_forced_compiler() {
+        target_compiler
     } else {
         // Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise
         // we'd have stageN/bin/rustc and stageN/bin/$rustc_tool be effectively different stage
@@ -330,6 +355,7 @@ macro_rules! bootstrap_tool {
         $(,is_unstable_tool = $unstable:expr)*
         $(,allow_features = $allow_features:expr)?
         $(,submodules = $submodules:expr)?
+        $(,artifact_kind = $artifact_kind:expr)?
         ;
     )+) => {
         #[derive(PartialEq, Eq, Clone)]
@@ -389,6 +415,7 @@ macro_rules! bootstrap_tool {
                         builder.require_submodule(submodule, None);
                     }
                 )*
+
                 builder.ensure(ToolBuild {
                     compiler: self.compiler,
                     target: self.target,
@@ -407,7 +434,12 @@ macro_rules! bootstrap_tool {
                     },
                     extra_features: vec![],
                     allow_features: concat!($($allow_features)*),
-                    cargo_args: vec![]
+                    cargo_args: vec![],
+                    artifact_kind: if false $(|| $artifact_kind == ToolArtifactKind::Library)* {
+                        ToolArtifactKind::Library
+                    } else {
+                        ToolArtifactKind::Binary
+                    }
                 })
             }
         }
@@ -445,51 +477,14 @@ bootstrap_tool!(
     WasmComponentLd, "src/tools/wasm-component-ld", "wasm-component-ld", is_unstable_tool = true, allow_features = "min_specialization";
     UnicodeTableGenerator, "src/tools/unicode-table-generator", "unicode-table-generator";
     FeaturesStatusDump, "src/tools/features-status-dump", "features-status-dump";
+    OptimizedDist, "src/tools/opt-dist", "opt-dist", submodules = &["src/tools/rustc-perf"];
+    RunMakeSupport, "src/tools/run-make-support", "run_make_support", artifact_kind = ToolArtifactKind::Library;
 );
 
 /// These are the submodules that are required for rustbook to work due to
 /// depending on mdbook plugins.
 pub static SUBMODULES_FOR_RUSTBOOK: &[&str] = &["src/doc/book", "src/doc/reference"];
 
-#[derive(Debug, Clone, Hash, PartialEq, Eq)]
-pub struct OptimizedDist {
-    pub compiler: Compiler,
-    pub target: TargetSelection,
-}
-
-impl Step for OptimizedDist {
-    type Output = ToolBuildResult;
-
-    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
-        run.path("src/tools/opt-dist")
-    }
-
-    fn make_run(run: RunConfig<'_>) {
-        run.builder.ensure(OptimizedDist {
-            compiler: run.builder.compiler(0, run.builder.config.build),
-            target: run.target,
-        });
-    }
-
-    fn run(self, builder: &Builder<'_>) -> ToolBuildResult {
-        // We need to ensure the rustc-perf submodule is initialized when building opt-dist since
-        // the tool requires it to be in place to run.
-        builder.require_submodule("src/tools/rustc-perf", None);
-
-        builder.ensure(ToolBuild {
-            compiler: self.compiler,
-            target: self.target,
-            tool: "opt-dist",
-            mode: Mode::ToolBootstrap,
-            path: "src/tools/opt-dist",
-            source_type: SourceType::InTree,
-            extra_features: Vec::new(),
-            allow_features: "",
-            cargo_args: Vec::new(),
-        })
-    }
-}
-
 /// The [rustc-perf](https://github.com/rust-lang/rustc-perf) benchmark suite, which is added
 /// as a submodule at `src/tools/rustc-perf`.
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
@@ -529,6 +524,7 @@ impl Step for RustcPerf {
             // Only build the collector package, which is used for benchmarking through
             // a CLI.
             cargo_args: vec!["-p".to_string(), "collector".to_string()],
+            artifact_kind: ToolArtifactKind::Binary,
         };
         let res = builder.ensure(tool.clone());
         // We also need to symlink the `rustc-fake` binary to the corresponding directory,
@@ -586,6 +582,7 @@ impl Step for ErrorIndex {
             extra_features: Vec::new(),
             allow_features: "",
             cargo_args: Vec::new(),
+            artifact_kind: ToolArtifactKind::Binary,
         })
     }
 }
@@ -621,6 +618,7 @@ impl Step for RemoteTestServer {
             extra_features: Vec::new(),
             allow_features: "",
             cargo_args: Vec::new(),
+            artifact_kind: ToolArtifactKind::Binary,
         })
     }
 }
@@ -725,6 +723,7 @@ impl Step for Rustdoc {
                 extra_features,
                 allow_features: "",
                 cargo_args: Vec::new(),
+                artifact_kind: ToolArtifactKind::Binary,
             });
 
         // don't create a stage0-sysroot/bin directory.
@@ -779,6 +778,7 @@ impl Step for Cargo {
             extra_features: Vec::new(),
             allow_features: "",
             cargo_args: Vec::new(),
+            artifact_kind: ToolArtifactKind::Binary,
         })
     }
 }
@@ -827,6 +827,7 @@ impl Step for LldWrapper {
             extra_features: Vec::new(),
             allow_features: "",
             cargo_args: Vec::new(),
+            artifact_kind: ToolArtifactKind::Binary,
         });
 
         let libdir_bin = builder.sysroot_target_bindir(self.target_compiler, target);
@@ -887,6 +888,7 @@ impl Step for RustAnalyzer {
             source_type: SourceType::InTree,
             allow_features: RustAnalyzer::ALLOW_FEATURES,
             cargo_args: Vec::new(),
+            artifact_kind: ToolArtifactKind::Binary,
         })
     }
 }
@@ -931,6 +933,7 @@ impl Step for RustAnalyzerProcMacroSrv {
             source_type: SourceType::InTree,
             allow_features: RustAnalyzer::ALLOW_FEATURES,
             cargo_args: Vec::new(),
+            artifact_kind: ToolArtifactKind::Binary,
         });
 
         // Copy `rust-analyzer-proc-macro-srv` to `<sysroot>/libexec/`
@@ -985,6 +988,7 @@ impl Step for LlvmBitcodeLinker {
             extra_features: self.extra_features,
             allow_features: "",
             cargo_args: Vec::new(),
+            artifact_kind: ToolArtifactKind::Binary,
         });
 
         if tool_result.target_compiler.stage > 0 {
@@ -1164,6 +1168,7 @@ fn run_tool_build_step(
             source_type: SourceType::InTree,
             allow_features: "",
             cargo_args: vec![],
+            artifact_kind: ToolArtifactKind::Binary,
         });
 
     // FIXME: This should just be an if-let-chain, but those are unstable.
@@ -1242,6 +1247,7 @@ impl Step for TestFloatParse {
             extra_features: Vec::new(),
             allow_features: "",
             cargo_args: Vec::new(),
+            artifact_kind: ToolArtifactKind::Binary,
         })
     }
 }
diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs
index c8e2856bdc8..801894e9ff1 100644
--- a/src/bootstrap/src/core/builder/mod.rs
+++ b/src/bootstrap/src/core/builder/mod.rs
@@ -1072,6 +1072,7 @@ impl<'a> Builder<'a> {
                 dist::PlainSourceTarball,
                 dist::BuildManifest,
                 dist::ReproducibleArtifacts,
+                dist::Gcc
             ),
             Kind::Install => describe!(
                 install::Docs,
@@ -1234,7 +1235,7 @@ impl<'a> Builder<'a> {
         ),
     )]
     pub fn compiler(&self, stage: u32, host: TargetSelection) -> Compiler {
-        self.ensure(compile::Assemble { target_compiler: Compiler { stage, host } })
+        self.ensure(compile::Assemble { target_compiler: Compiler::new(stage, host) })
     }
 
     /// Similar to `compiler`, except handles the full-bootstrap option to
@@ -1272,7 +1273,7 @@ impl<'a> Builder<'a> {
         target: TargetSelection,
     ) -> Compiler {
         #![allow(clippy::let_and_return)]
-        let resolved_compiler = if self.build.force_use_stage2(stage) {
+        let mut resolved_compiler = if self.build.force_use_stage2(stage) {
             trace!(target: "COMPILER_FOR", ?stage, "force_use_stage2");
             self.compiler(2, self.config.build)
         } else if self.build.force_use_stage1(stage, target) {
@@ -1282,6 +1283,11 @@ impl<'a> Builder<'a> {
             trace!(target: "COMPILER_FOR", ?stage, ?host, "no force, fallback to `compiler()`");
             self.compiler(stage, host)
         };
+
+        if stage != resolved_compiler.stage {
+            resolved_compiler.forced_compiler(true);
+        }
+
         trace!(target: "COMPILER_FOR", ?resolved_compiler);
         resolved_compiler
     }
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 0eaa89792bd..63a1bbc24f1 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -71,7 +71,7 @@ fn check_cli<const N: usize>(paths: [&str; N]) {
 macro_rules! std {
     ($host:ident => $target:ident, stage = $stage:literal) => {
         compile::Std::new(
-            Compiler { host: TargetSelection::from_user($host), stage: $stage },
+            Compiler::new($stage, TargetSelection::from_user($host)),
             TargetSelection::from_user($target),
         )
     };
@@ -84,7 +84,7 @@ macro_rules! doc_std {
 macro_rules! rustc {
     ($host:ident => $target:ident, stage = $stage:literal) => {
         compile::Rustc::new(
-            Compiler { host: TargetSelection::from_user($host), stage: $stage },
+            Compiler::new($stage, TargetSelection::from_user($host)),
             TargetSelection::from_user($target),
         )
     };
@@ -296,7 +296,7 @@ mod defaults {
             first(cache.all::<tool::Rustdoc>()),
             // Recall that rustdoc stages are off-by-one
             // - this is the compiler it's _linked_ to, not built with.
-            &[tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }],
+            &[tool::Rustdoc { compiler: Compiler::new(1, a) }],
         );
         assert_eq!(
             first(cache.all::<compile::Rustc>()),
@@ -319,7 +319,7 @@ mod defaults {
             first(cache.all::<tool::Rustdoc>()),
             // This is the beta rustdoc.
             // Add an assert here to make sure this is the only rustdoc built.
-            &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } }],
+            &[tool::Rustdoc { compiler: Compiler::new(0, a) }],
         );
         assert!(cache.all::<compile::Rustc>().is_empty());
     }
@@ -352,16 +352,16 @@ mod defaults {
         assert_eq!(
             first(cache.all::<compile::Assemble>()),
             &[
-                compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
-                compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
-                compile::Assemble { target_compiler: Compiler { host: b, stage: 1 } },
+                compile::Assemble { target_compiler: Compiler::new(0, a) },
+                compile::Assemble { target_compiler: Compiler::new(1, a) },
+                compile::Assemble { target_compiler: Compiler::new(1, b) },
             ]
         );
         assert_eq!(
             first(cache.all::<tool::Rustdoc>()),
             &[
-                tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } },
-                tool::Rustdoc { compiler: Compiler { host: b, stage: 1 } },
+                tool::Rustdoc { compiler: Compiler::new(1, a) },
+                tool::Rustdoc { compiler: Compiler::new(1, b) },
             ],
         );
         assert_eq!(
@@ -386,14 +386,14 @@ mod defaults {
         assert_eq!(first(cache.all::<doc::ErrorIndex>()), &[doc::ErrorIndex { target: a },]);
         assert_eq!(
             first(cache.all::<tool::ErrorIndex>()),
-            &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 0 } }]
+            &[tool::ErrorIndex { compiler: Compiler::new(0, a) }]
         );
         // docs should be built with the beta compiler, not with the stage0 artifacts.
         // recall that rustdoc is off-by-one: `stage` is the compiler rustdoc is _linked_ to,
         // not the one it was built by.
         assert_eq!(
             first(cache.all::<tool::Rustdoc>()),
-            &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },]
+            &[tool::Rustdoc { compiler: Compiler::new(0, a) },]
         );
     }
 }
@@ -418,17 +418,17 @@ mod dist {
         assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: a },]);
         assert_eq!(
             first(cache.all::<dist::Rustc>()),
-            &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },]
+            &[dist::Rustc { compiler: Compiler::new(2, a) },]
         );
         assert_eq!(
             first(cache.all::<dist::Std>()),
-            &[dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },]
+            &[dist::Std { compiler: Compiler::new(1, a), target: a },]
         );
         assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
         // Make sure rustdoc is only built once.
         assert_eq!(
             first(cache.all::<tool::Rustdoc>()),
-            &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },]
+            &[tool::Rustdoc { compiler: Compiler::new(2, a) },]
         );
     }
 
@@ -450,13 +450,13 @@ mod dist {
         );
         assert_eq!(
             first(cache.all::<dist::Rustc>()),
-            &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },]
+            &[dist::Rustc { compiler: Compiler::new(2, a) },]
         );
         assert_eq!(
             first(cache.all::<dist::Std>()),
             &[
-                dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
-                dist::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
+                dist::Std { compiler: Compiler::new(1, a), target: a },
+                dist::Std { compiler: Compiler::new(2, a), target: b },
             ]
         );
         assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
@@ -483,15 +483,15 @@ mod dist {
         assert_eq!(
             first(cache.all::<dist::Rustc>()),
             &[
-                dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
-                dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
+                dist::Rustc { compiler: Compiler::new(2, a) },
+                dist::Rustc { compiler: Compiler::new(2, b) },
             ]
         );
         assert_eq!(
             first(cache.all::<dist::Std>()),
             &[
-                dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
-                dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
+                dist::Std { compiler: Compiler::new(1, a), target: a },
+                dist::Std { compiler: Compiler::new(1, a), target: b },
             ]
         );
         assert_eq!(
@@ -519,13 +519,12 @@ mod dist {
 
         assert_eq!(
             first(cache.all::<dist::Rustc>()),
-            &[dist::Rustc { compiler: Compiler { host: b, stage: 2 } },]
+            &[dist::Rustc { compiler: Compiler::new(2, b) },]
         );
         assert_eq!(
             first(cache.all::<compile::Rustc>()),
             &[
                 rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
-                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
                 rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
             ]
         );
@@ -556,16 +555,16 @@ mod dist {
         assert_eq!(
             first(cache.all::<dist::Rustc>()),
             &[
-                dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
-                dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
+                dist::Rustc { compiler: Compiler::new(2, a) },
+                dist::Rustc { compiler: Compiler::new(2, b) },
             ]
         );
         assert_eq!(
             first(cache.all::<dist::Std>()),
             &[
-                dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
-                dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
-                dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
+                dist::Std { compiler: Compiler::new(1, a), target: a },
+                dist::Std { compiler: Compiler::new(1, a), target: b },
+                dist::Std { compiler: Compiler::new(2, a), target: c },
             ]
         );
         assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
@@ -583,7 +582,7 @@ mod dist {
         assert_eq!(first(cache.all::<dist::Mingw>()), &[dist::Mingw { host: c },]);
         assert_eq!(
             first(cache.all::<dist::Std>()),
-            &[dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c },]
+            &[dist::Std { compiler: Compiler::new(2, a), target: c },]
         );
     }
 
@@ -608,15 +607,15 @@ mod dist {
         assert_eq!(
             first(cache.all::<dist::Rustc>()),
             &[
-                dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
-                dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
+                dist::Rustc { compiler: Compiler::new(2, a) },
+                dist::Rustc { compiler: Compiler::new(2, b) },
             ]
         );
         assert_eq!(
             first(cache.all::<dist::Std>()),
             &[
-                dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
-                dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
+                dist::Std { compiler: Compiler::new(1, a), target: a },
+                dist::Std { compiler: Compiler::new(1, a), target: b },
             ]
         );
         assert_eq!(first(cache.all::<dist::Src>()), &[dist::Src]);
@@ -633,10 +632,10 @@ mod dist {
         assert_eq!(
             first(cache.all::<compile::Assemble>()),
             &[
-                compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
-                compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
-                compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
-                compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } },
+                compile::Assemble { target_compiler: Compiler::new(0, a) },
+                compile::Assemble { target_compiler: Compiler::new(1, a) },
+                compile::Assemble { target_compiler: Compiler::new(2, a) },
+                compile::Assemble { target_compiler: Compiler::new(2, b) },
             ]
         );
     }
@@ -653,6 +652,20 @@ mod dist {
             &["compiler/rustc".into(), "library".into()],
         );
 
+        assert_eq!(builder.config.stage, 2);
+
+        // `compile::Rustc` includes one-stage-off compiler information as the target compiler
+        // artifacts get copied from there to the target stage sysroot.
+        // For example, `stage2/bin/rustc` gets copied from the `stage1-rustc` build directory.
+        assert_eq!(
+            first(builder.cache.all::<compile::Rustc>()),
+            &[
+                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
+                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
+                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
+            ]
+        );
+
         assert_eq!(
             first(builder.cache.all::<compile::Std>()),
             &[
@@ -664,15 +677,22 @@ mod dist {
                 std!(TEST_TRIPLE_1 => TEST_TRIPLE_3, stage = 2),
             ]
         );
-        assert_eq!(builder.cache.all::<compile::Assemble>().len(), 5);
+
         assert_eq!(
-            first(builder.cache.all::<compile::Rustc>()),
+            first(builder.cache.all::<compile::Assemble>()),
             &[
-                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 0),
-                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 1),
-                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_1, stage = 2),
-                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 1),
-                rustc!(TEST_TRIPLE_1 => TEST_TRIPLE_2, stage = 2),
+                compile::Assemble {
+                    target_compiler: Compiler::new(0, TargetSelection::from_user(TEST_TRIPLE_1),)
+                },
+                compile::Assemble {
+                    target_compiler: Compiler::new(1, TargetSelection::from_user(TEST_TRIPLE_1),)
+                },
+                compile::Assemble {
+                    target_compiler: Compiler::new(2, TargetSelection::from_user(TEST_TRIPLE_1),)
+                },
+                compile::Assemble {
+                    target_compiler: Compiler::new(2, TargetSelection::from_user(TEST_TRIPLE_2),)
+                },
             ]
         );
     }
@@ -714,9 +734,9 @@ mod dist {
         assert_eq!(
             first(builder.cache.all::<compile::Assemble>()),
             &[
-                compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
-                compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
-                compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
+                compile::Assemble { target_compiler: Compiler::new(0, a) },
+                compile::Assemble { target_compiler: Compiler::new(1, a) },
+                compile::Assemble { target_compiler: Compiler::new(2, a) },
             ]
         );
         assert_eq!(
@@ -765,7 +785,7 @@ mod dist {
         assert_eq!(
             first(builder.cache.all::<test::Crate>()),
             &[test::Crate {
-                compiler: Compiler { host, stage: 0 },
+                compiler: Compiler::new(0, host),
                 target: host,
                 mode: crate::Mode::Std,
                 crates: vec!["std".to_owned()],
@@ -791,13 +811,13 @@ mod dist {
         );
         assert_eq!(
             first(builder.cache.all::<tool::ErrorIndex>()),
-            &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }]
+            &[tool::ErrorIndex { compiler: Compiler::new(1, a) }]
         );
         // This is actually stage 1, but Rustdoc::run swaps out the compiler with
         // stage minus 1 if --stage is not 0. Very confusing!
         assert_eq!(
             first(builder.cache.all::<tool::Rustdoc>()),
-            &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },]
+            &[tool::Rustdoc { compiler: Compiler::new(2, a) },]
         );
     }
 
@@ -837,7 +857,7 @@ mod dist {
         );
         assert_eq!(
             first(builder.cache.all::<tool::ErrorIndex>()),
-            &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }]
+            &[tool::ErrorIndex { compiler: Compiler::new(1, a) }]
         );
         // Unfortunately rustdoc is built twice. Once from stage1 for compiletest
         // (and other things), and once from stage0 for std crates. Ideally it
@@ -853,9 +873,9 @@ mod dist {
         assert_eq!(
             first(builder.cache.all::<tool::Rustdoc>()),
             &[
-                tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },
-                tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } },
-                tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },
+                tool::Rustdoc { compiler: Compiler::new(0, a) },
+                tool::Rustdoc { compiler: Compiler::new(1, a) },
+                tool::Rustdoc { compiler: Compiler::new(2, a) },
             ]
         );
     }
@@ -871,7 +891,7 @@ mod sysroot_target_dirs {
         let build = Build::new(configure("build", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]));
         let builder = Builder::new(&build);
         let target_triple_1 = TargetSelection::from_user(TEST_TRIPLE_1);
-        let compiler = Compiler { stage: 1, host: target_triple_1 };
+        let compiler = Compiler::new(1, target_triple_1);
         let target_triple_2 = TargetSelection::from_user(TEST_TRIPLE_2);
         let actual = builder.sysroot_target_libdir(compiler, target_triple_2);
 
@@ -891,7 +911,7 @@ mod sysroot_target_dirs {
         let build = Build::new(configure("build", &[TEST_TRIPLE_1], &[TEST_TRIPLE_1]));
         let builder = Builder::new(&build);
         let target_triple_1 = TargetSelection::from_user(TEST_TRIPLE_1);
-        let compiler = Compiler { stage: 1, host: target_triple_1 };
+        let compiler = Compiler::new(1, target_triple_1);
         let target_triple_2 = TargetSelection::from_user(TEST_TRIPLE_2);
         let actual = builder.sysroot_target_bindir(compiler, target_triple_2);
 
@@ -1095,13 +1115,13 @@ fn test_get_tool_rustc_compiler() {
 
     let target_triple_1 = TargetSelection::from_user(TEST_TRIPLE_1);
 
-    let compiler = Compiler { stage: 2, host: target_triple_1 };
-    let expected = Compiler { stage: 1, host: target_triple_1 };
+    let compiler = Compiler::new(2, target_triple_1);
+    let expected = Compiler::new(1, target_triple_1);
     let actual = tool::get_tool_rustc_compiler(&builder, compiler);
     assert_eq!(expected, actual);
 
-    let compiler = Compiler { stage: 1, host: target_triple_1 };
-    let expected = Compiler { stage: 0, host: target_triple_1 };
+    let compiler = Compiler::new(1, target_triple_1);
+    let expected = Compiler::new(0, target_triple_1);
     let actual = tool::get_tool_rustc_compiler(&builder, compiler);
     assert_eq!(expected, actual);
 
@@ -1110,8 +1130,8 @@ fn test_get_tool_rustc_compiler() {
     let build = Build::new(config);
     let builder = Builder::new(&build);
 
-    let compiler = Compiler { stage: 1, host: target_triple_1 };
-    let expected = Compiler { stage: 1, host: target_triple_1 };
+    let compiler = Compiler::new(1, target_triple_1);
+    let expected = Compiler::new(1, target_triple_1);
     let actual = tool::get_tool_rustc_compiler(&builder, compiler);
     assert_eq!(expected, actual);
 }
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index d0e0ed50ad8..ac24da9f86b 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -894,6 +894,7 @@ define_config! {
     #[derive(Default)]
     struct Build {
         build: Option<String> = "build",
+        description: Option<String> = "description",
         host: Option<Vec<String>> = "host",
         target: Option<Vec<String>> = "target",
         build_dir: Option<String> = "build-dir",
@@ -1176,6 +1177,7 @@ define_config! {
         incremental: Option<bool> = "incremental",
         default_linker: Option<String> = "default-linker",
         channel: Option<String> = "channel",
+        // FIXME: Remove this field at Q2 2025, it has been replaced by build.description
         description: Option<String> = "description",
         musl_root: Option<String> = "musl-root",
         rpath: Option<bool> = "rpath",
@@ -1583,6 +1585,7 @@ impl Config {
         config.change_id = toml.change_id.inner;
 
         let Build {
+            mut description,
             build,
             host,
             target,
@@ -1831,7 +1834,7 @@ impl Config {
                 randomize_layout,
                 default_linker,
                 channel: _, // already handled above
-                description,
+                description: rust_description,
                 musl_root,
                 rpath,
                 verbose_tests,
@@ -1924,7 +1927,12 @@ impl Config {
             set(&mut config.jemalloc, jemalloc);
             set(&mut config.test_compare_mode, test_compare_mode);
             set(&mut config.backtrace, backtrace);
-            config.description = description;
+            if rust_description.is_some() {
+                eprintln!(
+                    "Warning: rust.description is deprecated. Use build.description instead."
+                );
+            }
+            description = description.or(rust_description);
             set(&mut config.rust_dist_src, dist_src);
             set(&mut config.verbose_tests, verbose_tests);
             // in the case "false" is set explicitly, do not overwrite the command line args
@@ -1990,6 +1998,7 @@ impl Config {
         }
 
         config.reproducible_artifacts = flags.reproducible_artifact;
+        config.description = description;
 
         // We need to override `rust.channel` if it's manually specified when using the CI rustc.
         // This is because if the compiler uses a different channel than the one specified in config.toml,
diff --git a/src/bootstrap/src/core/metadata.rs b/src/bootstrap/src/core/metadata.rs
index 01cbf662940..2706aba5ffc 100644
--- a/src/bootstrap/src/core/metadata.rs
+++ b/src/bootstrap/src/core/metadata.rs
@@ -28,7 +28,6 @@ struct Package {
     source: Option<String>,
     manifest_path: String,
     dependencies: Vec<Dependency>,
-    targets: Vec<Target>,
     features: BTreeMap<String, Vec<String>>,
 }
 
@@ -40,11 +39,6 @@ struct Dependency {
     source: Option<String>,
 }
 
-#[derive(Debug, Deserialize)]
-struct Target {
-    kind: Vec<String>,
-}
-
 /// Collects and stores package metadata of each workspace members into `build`,
 /// by executing `cargo metadata` commands.
 pub fn build(build: &mut Build) {
@@ -59,12 +53,10 @@ pub fn build(build: &mut Build) {
                 .filter(|dep| dep.source.is_none())
                 .map(|dep| dep.name)
                 .collect();
-            let has_lib = package.targets.iter().any(|t| t.kind.iter().any(|k| k == "lib"));
             let krate = Crate {
                 name: name.clone(),
                 deps,
                 path,
-                has_lib,
                 features: package.features.keys().cloned().collect(),
             };
             let relative_path = krate.local_path(build);
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 351e67f6702..788c8bbdc84 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -92,10 +92,27 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
 /// Each compiler has a `stage` that it is associated with and a `host` that
 /// corresponds to the platform the compiler runs on. This structure is used as
 /// a parameter to many methods below.
-#[derive(Eq, PartialOrd, Ord, PartialEq, Clone, Copy, Hash, Debug)]
+#[derive(Eq, PartialOrd, Ord, Clone, Copy, Debug)]
 pub struct Compiler {
     stage: u32,
     host: TargetSelection,
+    /// Indicates whether `compiler_for` was used to force a specific compiler stage.
+    /// This field is ignored in `Hash` and `PartialEq` implementations as only the `stage`
+    /// and `host` fields are relevant for those.
+    forced_compiler: bool,
+}
+
+impl std::hash::Hash for Compiler {
+    fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
+        self.stage.hash(state);
+        self.host.hash(state);
+    }
+}
+
+impl PartialEq for Compiler {
+    fn eq(&self, other: &Self) -> bool {
+        self.stage == other.stage && self.host == other.host
+    }
 }
 
 #[derive(PartialEq, Eq, Copy, Clone, Debug)]
@@ -185,7 +202,6 @@ struct Crate {
     name: String,
     deps: HashSet<String>,
     path: PathBuf,
-    has_lib: bool,
     features: Vec<String>,
 }
 
@@ -1964,6 +1980,14 @@ fn chmod(path: &Path, perms: u32) {
 fn chmod(_path: &Path, _perms: u32) {}
 
 impl Compiler {
+    pub fn new(stage: u32, host: TargetSelection) -> Self {
+        Self { stage, host, forced_compiler: false }
+    }
+
+    pub fn forced_compiler(&mut self, forced_compiler: bool) {
+        self.forced_compiler = forced_compiler;
+    }
+
     pub fn with_stage(mut self, stage: u32) -> Compiler {
         self.stage = stage;
         self
@@ -1973,6 +1997,11 @@ impl Compiler {
     pub fn is_snapshot(&self, build: &Build) -> bool {
         self.stage == 0 && self.host == build.build
     }
+
+    /// Indicates whether `compiler_for` was used to force a specific compiler stage.
+    pub fn is_forced_compiler(&self) -> bool {
+        self.forced_compiler
+    }
 }
 
 fn envify(s: &str) -> String {
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 5f49c50c5ad..425ffdccad5 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -365,4 +365,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "`rust.channel` now supports \"auto-detect\" to load the channel from `src/ci/channel`",
     },
+    ChangeInfo {
+        change_id: 137723,
+        severity: ChangeSeverity::Info,
+        summary: "The rust.description option has moved to build.description and rust.description is now deprecated.",
+    },
 ];
diff --git a/src/bootstrap/src/utils/job.rs b/src/bootstrap/src/utils/job.rs
index 10efed130d6..a60e889fd57 100644
--- a/src/bootstrap/src/utils/job.rs
+++ b/src/bootstrap/src/utils/job.rs
@@ -42,7 +42,7 @@ pub unsafe fn setup(build: &mut crate::Build) {
 #[cfg(windows)]
 mod for_windows {
     use std::ffi::c_void;
-    use std::{io, mem};
+    use std::io;
 
     use windows::Win32::Foundation::CloseHandle;
     use windows::Win32::System::Diagnostics::Debug::{
@@ -82,7 +82,7 @@ mod for_windows {
             job,
             JobObjectExtendedLimitInformation,
             &info as *const _ as *const c_void,
-            mem::size_of_val(&info) as u32,
+            size_of_val(&info) as u32,
         );
         assert!(r.is_ok(), "{}", io::Error::last_os_error());
 
diff --git a/src/bootstrap/src/utils/metrics.rs b/src/bootstrap/src/utils/metrics.rs
index b51fd490535..57766fd63fb 100644
--- a/src/bootstrap/src/utils/metrics.rs
+++ b/src/bootstrap/src/utils/metrics.rs
@@ -200,6 +200,14 @@ impl BuildMetrics {
             }
         };
         invocations.push(JsonInvocation {
+            // The command-line invocation with which bootstrap was invoked.
+            // Skip the first argument, as it is a potentially long absolute
+            // path that is not interesting.
+            cmdline: std::env::args_os()
+                .skip(1)
+                .map(|arg| arg.to_string_lossy().to_string())
+                .collect::<Vec<_>>()
+                .join(" "),
             start_time: state
                 .invocation_start
                 .duration_since(SystemTime::UNIX_EPOCH)
diff --git a/src/build_helper/src/git.rs b/src/build_helper/src/git.rs
index 3ef9c7ac35e..9f778a2fd77 100644
--- a/src/build_helper/src/git.rs
+++ b/src/build_helper/src/git.rs
@@ -129,7 +129,7 @@ pub fn get_closest_merge_commit(
         git.current_dir(git_dir);
     }
 
-    let channel = include_str!("../../ci/channel");
+    let channel = include_str!("../../ci/channel").trim();
 
     let merge_base = {
         if CiEnv::is_ci() &&
diff --git a/src/build_helper/src/metrics.rs b/src/build_helper/src/metrics.rs
index 538c33e9b15..eb306550fc4 100644
--- a/src/build_helper/src/metrics.rs
+++ b/src/build_helper/src/metrics.rs
@@ -1,3 +1,5 @@
+use std::time::Duration;
+
 use serde_derive::{Deserialize, Serialize};
 
 #[derive(Serialize, Deserialize)]
@@ -12,6 +14,8 @@ pub struct JsonRoot {
 #[derive(Serialize, Deserialize)]
 #[serde(rename_all = "snake_case")]
 pub struct JsonInvocation {
+    // Remembers the command-line invocation with which bootstrap was invoked.
+    pub cmdline: String,
     // Unix timestamp in seconds
     //
     // This is necessary to easily correlate this invocation with logs or other data.
@@ -98,3 +102,87 @@ fn null_as_f64_nan<'de, D: serde::Deserializer<'de>>(d: D) -> Result<f64, D::Err
     use serde::Deserialize as _;
     Option::<f64>::deserialize(d).map(|f| f.unwrap_or(f64::NAN))
 }
+
+/// Represents a single bootstrap step, with the accumulated duration of all its children.
+#[derive(Clone, Debug)]
+pub struct BuildStep {
+    pub r#type: String,
+    pub children: Vec<BuildStep>,
+    pub duration: Duration,
+}
+
+impl BuildStep {
+    /// Create a `BuildStep` representing a single invocation of bootstrap.
+    /// The most important thing is that the build step aggregates the
+    /// durations of all children, so that it can be easily accessed.
+    pub fn from_invocation(invocation: &JsonInvocation) -> Self {
+        fn parse(node: &JsonNode) -> Option<BuildStep> {
+            match node {
+                JsonNode::RustbuildStep {
+                    type_: kind,
+                    children,
+                    duration_excluding_children_sec,
+                    ..
+                } => {
+                    let children: Vec<_> = children.into_iter().filter_map(parse).collect();
+                    let children_duration = children.iter().map(|c| c.duration).sum::<Duration>();
+                    Some(BuildStep {
+                        r#type: kind.to_string(),
+                        children,
+                        duration: children_duration
+                            + Duration::from_secs_f64(*duration_excluding_children_sec),
+                    })
+                }
+                JsonNode::TestSuite(_) => None,
+            }
+        }
+
+        let duration = Duration::from_secs_f64(invocation.duration_including_children_sec);
+        let children: Vec<_> = invocation.children.iter().filter_map(parse).collect();
+        Self { r#type: "total".to_string(), children, duration }
+    }
+
+    pub fn find_all_by_type(&self, r#type: &str) -> Vec<&Self> {
+        let mut result = Vec::new();
+        self.find_by_type(r#type, &mut result);
+        result
+    }
+
+    fn find_by_type<'a>(&'a self, r#type: &str, result: &mut Vec<&'a Self>) {
+        if self.r#type == r#type {
+            result.push(self);
+        }
+        for child in &self.children {
+            child.find_by_type(r#type, result);
+        }
+    }
+}
+
+/// Writes build steps into a nice indented table.
+pub fn format_build_steps(root: &BuildStep) -> String {
+    use std::fmt::Write;
+
+    let mut substeps: Vec<(u32, &BuildStep)> = Vec::new();
+
+    fn visit<'a>(step: &'a BuildStep, level: u32, substeps: &mut Vec<(u32, &'a BuildStep)>) {
+        substeps.push((level, step));
+        for child in &step.children {
+            visit(child, level + 1, substeps);
+        }
+    }
+
+    visit(root, 0, &mut substeps);
+
+    let mut output = String::new();
+    for (level, step) in substeps {
+        let label = format!(
+            "{}{}",
+            ".".repeat(level as usize),
+            // Bootstrap steps can be generic and thus contain angle brackets (<...>).
+            // However, Markdown interprets these as HTML, so we need to escap ethem.
+            step.r#type.replace('<', "&lt;").replace('>', "&gt;")
+        );
+        writeln!(output, "{label:.<65}{:>8.2}s", step.duration.as_secs_f64()).unwrap();
+    }
+    output
+}
diff --git a/src/ci/citool/Cargo.lock b/src/ci/citool/Cargo.lock
index 39b6b44da64..46343a7b86e 100644
--- a/src/ci/citool/Cargo.lock
+++ b/src/ci/citool/Cargo.lock
@@ -3,6 +3,12 @@
 version = 4
 
 [[package]]
+name = "adler2"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "512761e0bb2578dd7380c6baaa0f4ce03e84f95e960231d1dec8bf4d7d6e2627"
+
+[[package]]
 name = "anstream"
 version = "0.6.18"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -38,7 +44,7 @@ version = "1.1.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
 dependencies = [
- "windows-sys",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -49,7 +55,7 @@ checksum = "ca3534e77181a9cc07539ad51f2141fe32f6c3ffd4df76db8ad92346b003ae4e"
 dependencies = [
  "anstyle",
  "once_cell",
- "windows-sys",
+ "windows-sys 0.59.0",
 ]
 
 [[package]]
@@ -59,15 +65,53 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04"
 
 [[package]]
+name = "base64"
+version = "0.22.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
+
+[[package]]
+name = "build_helper"
+version = "0.1.0"
+dependencies = [
+ "serde",
+ "serde_derive",
+]
+
+[[package]]
+name = "bytes"
+version = "1.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9"
+
+[[package]]
+name = "cc"
+version = "1.2.16"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
+dependencies = [
+ "shlex",
+]
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
 name = "citool"
 version = "0.1.0"
 dependencies = [
  "anyhow",
+ "build_helper",
  "clap",
+ "csv",
  "insta",
  "serde",
  "serde_json",
  "serde_yaml",
+ "ureq",
 ]
 
 [[package]]
@@ -125,7 +169,95 @@ dependencies = [
  "encode_unicode",
  "libc",
  "once_cell",
- "windows-sys",
+ "windows-sys 0.59.0",
+]
+
+[[package]]
+name = "cookie"
+version = "0.18.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747"
+dependencies = [
+ "percent-encoding",
+ "time",
+ "version_check",
+]
+
+[[package]]
+name = "cookie_store"
+version = "0.21.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2eac901828f88a5241ee0600950ab981148a18f2f756900ffba1b125ca6a3ef9"
+dependencies = [
+ "cookie",
+ "document-features",
+ "idna",
+ "indexmap",
+ "log",
+ "serde",
+ "serde_derive",
+ "serde_json",
+ "time",
+ "url",
+]
+
+[[package]]
+name = "crc32fast"
+version = "1.4.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
+dependencies = [
+ "cfg-if",
+]
+
+[[package]]
+name = "csv"
+version = "1.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "acdc4883a9c96732e4733212c01447ebd805833b7275a73ca3ee080fd77afdaf"
+dependencies = [
+ "csv-core",
+ "itoa",
+ "ryu",
+ "serde",
+]
+
+[[package]]
+name = "csv-core"
+version = "0.1.12"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7d02f3b0da4c6504f86e9cd789d8dbafab48c2321be74e9987593de5a894d93d"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
+name = "deranged"
+version = "0.3.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
+dependencies = [
+ "powerfmt",
+]
+
+[[package]]
+name = "displaydoc"
+version = "0.2.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "document-features"
+version = "0.2.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95249b50c6c185bee49034bcb378a49dc2b5dff0be90ff6616d31d64febab05d"
+dependencies = [
+ "litrs",
 ]
 
 [[package]]
@@ -141,6 +273,42 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
 
 [[package]]
+name = "flate2"
+version = "1.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "11faaf5a5236997af9848be0bef4db95824b1d534ebc64d0f0c6cf3e67bd38dc"
+dependencies = [
+ "crc32fast",
+ "miniz_oxide",
+]
+
+[[package]]
+name = "fnv"
+version = "1.0.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
+
+[[package]]
+name = "form_urlencoded"
+version = "1.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e13624c2627564efccf4934284bdd98cbaa14e79b0b5a141218e507b3a823456"
+dependencies = [
+ "percent-encoding",
+]
+
+[[package]]
+name = "getrandom"
+version = "0.2.15"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
+dependencies = [
+ "cfg-if",
+ "libc",
+ "wasi",
+]
+
+[[package]]
 name = "hashbrown"
 version = "0.15.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -153,6 +321,162 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
 
 [[package]]
+name = "http"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea"
+dependencies = [
+ "bytes",
+ "fnv",
+ "itoa",
+]
+
+[[package]]
+name = "httparse"
+version = "1.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
+
+[[package]]
+name = "icu_collections"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db2fa452206ebee18c4b5c2274dbf1de17008e874b4dc4f0aea9d01ca79e4526"
+dependencies = [
+ "displaydoc",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13acbb8371917fc971be86fc8057c41a64b521c184808a698c02acc242dbf637"
+dependencies = [
+ "displaydoc",
+ "litemap",
+ "tinystr",
+ "writeable",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid_transform"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "01d11ac35de8e40fdeda00d9e1e9d92525f3f9d887cdd7aa81d727596788b54e"
+dependencies = [
+ "displaydoc",
+ "icu_locid",
+ "icu_locid_transform_data",
+ "icu_provider",
+ "tinystr",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_locid_transform_data"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fdc8ff3388f852bede6b579ad4e978ab004f139284d7b28715f773507b946f6e"
+
+[[package]]
+name = "icu_normalizer"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "19ce3e0da2ec68599d193c93d088142efd7f9c5d6fc9b803774855747dc6a84f"
+dependencies = [
+ "displaydoc",
+ "icu_collections",
+ "icu_normalizer_data",
+ "icu_properties",
+ "icu_provider",
+ "smallvec",
+ "utf16_iter",
+ "utf8_iter",
+ "write16",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_normalizer_data"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f8cafbf7aa791e9b22bec55a167906f9e1215fd475cd22adfcf660e03e989516"
+
+[[package]]
+name = "icu_properties"
+version = "1.5.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "93d6020766cfc6302c15dbbc9c8778c37e62c14427cb7f6e601d849e092aeef5"
+dependencies = [
+ "displaydoc",
+ "icu_collections",
+ "icu_locid_transform",
+ "icu_properties_data",
+ "icu_provider",
+ "tinystr",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_properties_data"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "67a8effbc3dd3e4ba1afa8ad918d5684b8868b3b26500753effea8d2eed19569"
+
+[[package]]
+name = "icu_provider"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6ed421c8a8ef78d3e2dbc98a973be2f3770cb42b606e3ab18d6237c4dfde68d9"
+dependencies = [
+ "displaydoc",
+ "icu_locid",
+ "icu_provider_macros",
+ "stable_deref_trait",
+ "tinystr",
+ "writeable",
+ "yoke",
+ "zerofrom",
+ "zerovec",
+]
+
+[[package]]
+name = "icu_provider_macros"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "idna"
+version = "1.0.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "686f825264d630750a544639377bae737628043f20d38bbc029e8f29ea968a7e"
+dependencies = [
+ "idna_adapter",
+ "smallvec",
+ "utf8_iter",
+]
+
+[[package]]
+name = "idna_adapter"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "daca1df1c957320b2cf139ac61e7bd64fed304c5040df000a745aa1de3b4ef71"
+dependencies = [
+ "icu_normalizer",
+ "icu_properties",
+]
+
+[[package]]
 name = "indexmap"
 version = "2.7.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -200,18 +524,57 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
 
 [[package]]
+name = "litemap"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "23fb14cb19457329c82206317a5663005a4d404783dc74f4252769b0d5f42856"
+
+[[package]]
+name = "litrs"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4ce301924b7887e9d637144fdade93f9dfff9b60981d4ac161db09720d39aa5"
+
+[[package]]
+name = "log"
+version = "0.4.26"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
+
+[[package]]
 name = "memchr"
 version = "2.7.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
 
 [[package]]
+name = "miniz_oxide"
+version = "0.8.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e3e04debbb59698c15bacbb6d93584a8c0ca9cc3213cb423d31f760d8843ce5"
+dependencies = [
+ "adler2",
+]
+
+[[package]]
+name = "num-conv"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
+
+[[package]]
 name = "once_cell"
 version = "1.20.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e"
 
 [[package]]
+name = "percent-encoding"
+version = "2.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e3148f5046208a5d56bcfc03053e3ca6334e51da8dfb19b6cdc8b306fae3283e"
+
+[[package]]
 name = "pin-project"
 version = "1.1.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -232,6 +595,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "powerfmt"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
+
+[[package]]
 name = "proc-macro2"
 version = "1.0.93"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -250,6 +619,61 @@ dependencies = [
 ]
 
 [[package]]
+name = "ring"
+version = "0.17.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da5349ae27d3887ca812fb375b45a4fbb36d8d12d2df394968cd86e35683fe73"
+dependencies = [
+ "cc",
+ "cfg-if",
+ "getrandom",
+ "libc",
+ "untrusted",
+ "windows-sys 0.52.0",
+]
+
+[[package]]
+name = "rustls"
+version = "0.23.23"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395"
+dependencies = [
+ "log",
+ "once_cell",
+ "ring",
+ "rustls-pki-types",
+ "rustls-webpki",
+ "subtle",
+ "zeroize",
+]
+
+[[package]]
+name = "rustls-pemfile"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dce314e5fee3f39953d46bb63bb8a46d40c2f8fb7cc5a3b6cab2bde9721d6e50"
+dependencies = [
+ "rustls-pki-types",
+]
+
+[[package]]
+name = "rustls-pki-types"
+version = "1.11.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
+
+[[package]]
+name = "rustls-webpki"
+version = "0.102.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
+dependencies = [
+ "ring",
+ "rustls-pki-types",
+ "untrusted",
+]
+
+[[package]]
 name = "ryu"
 version = "1.0.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -301,18 +725,42 @@ dependencies = [
 ]
 
 [[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
 name = "similar"
 version = "2.7.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bbbb5d9659141646ae647b42fe094daf6c6192d1620870b449d9557f748b2daa"
 
 [[package]]
+name = "smallvec"
+version = "1.14.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
+
+[[package]]
+name = "stable_deref_trait"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
+
+[[package]]
 name = "strsim"
 version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f"
 
 [[package]]
+name = "subtle"
+version = "2.6.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292"
+
+[[package]]
 name = "syn"
 version = "2.0.98"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -324,6 +772,58 @@ dependencies = [
 ]
 
 [[package]]
+name = "synstructure"
+version = "0.13.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "time"
+version = "0.3.38"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bb041120f25f8fbe8fd2dbe4671c7c2ed74d83be2e7a77529bf7e0790ae3f472"
+dependencies = [
+ "deranged",
+ "itoa",
+ "num-conv",
+ "powerfmt",
+ "serde",
+ "time-core",
+ "time-macros",
+]
+
+[[package]]
+name = "time-core"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "765c97a5b985b7c11d7bc27fa927dc4fe6af3a6dfb021d28deb60d3bf51e76ef"
+
+[[package]]
+name = "time-macros"
+version = "0.2.20"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e8093bc3e81c3bc5f7879de09619d06c9a5a5e45ca44dfeeb7225bae38005c5c"
+dependencies = [
+ "num-conv",
+ "time-core",
+]
+
+[[package]]
+name = "tinystr"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9117f5d4db391c1cf6927e7bea3db74b9a1c1add8f7eda9ffd5364f40f57b82f"
+dependencies = [
+ "displaydoc",
+ "zerovec",
+]
+
+[[package]]
 name = "unicode-ident"
 version = "1.0.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -336,12 +836,110 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
 
 [[package]]
+name = "untrusted"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1"
+
+[[package]]
+name = "ureq"
+version = "3.0.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "06f78313c985f2fba11100dd06d60dd402d0cabb458af4d94791b8e09c025323"
+dependencies = [
+ "base64",
+ "cookie_store",
+ "flate2",
+ "log",
+ "percent-encoding",
+ "rustls",
+ "rustls-pemfile",
+ "rustls-pki-types",
+ "serde",
+ "serde_json",
+ "ureq-proto",
+ "utf-8",
+ "webpki-roots",
+]
+
+[[package]]
+name = "ureq-proto"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "64adb55464bad1ab1aa9229133d0d59d2f679180f4d15f0d9debe616f541f25e"
+dependencies = [
+ "base64",
+ "http",
+ "httparse",
+ "log",
+]
+
+[[package]]
+name = "url"
+version = "2.5.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "32f8b686cadd1473f4bd0117a5d28d36b1ade384ea9b5069a1c40aefed7fda60"
+dependencies = [
+ "form_urlencoded",
+ "idna",
+ "percent-encoding",
+]
+
+[[package]]
+name = "utf-8"
+version = "0.7.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
+
+[[package]]
+name = "utf16_iter"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c8232dd3cdaed5356e0f716d285e4b40b932ac434100fe9b7e0e8e935b9e6246"
+
+[[package]]
+name = "utf8_iter"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
+
+[[package]]
 name = "utf8parse"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
 
 [[package]]
+name = "version_check"
+version = "0.9.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
+
+[[package]]
+name = "wasi"
+version = "0.11.0+wasi-snapshot-preview1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
+
+[[package]]
+name = "webpki-roots"
+version = "0.26.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9"
+dependencies = [
+ "rustls-pki-types",
+]
+
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets",
+]
+
+[[package]]
 name = "windows-sys"
 version = "0.59.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -413,3 +1011,88 @@ name = "windows_x86_64_msvc"
 version = "0.52.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
+
+[[package]]
+name = "write16"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d1890f4022759daae28ed4fe62859b1236caebfc61ede2f63ed4e695f3f6d936"
+
+[[package]]
+name = "writeable"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
+
+[[package]]
+name = "yoke"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "120e6aef9aa629e3d4f52dc8cc43a015c7724194c97dfaf45180d2daf2b77f40"
+dependencies = [
+ "serde",
+ "stable_deref_trait",
+ "yoke-derive",
+ "zerofrom",
+]
+
+[[package]]
+name = "yoke-derive"
+version = "0.7.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zerofrom"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5"
+dependencies = [
+ "zerofrom-derive",
+]
+
+[[package]]
+name = "zerofrom-derive"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+ "synstructure",
+]
+
+[[package]]
+name = "zeroize"
+version = "1.8.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ced3678a2879b30306d323f4542626697a464a97c0a07c9aebf7ebca65cd4dde"
+
+[[package]]
+name = "zerovec"
+version = "0.10.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "aa2b893d79df23bfb12d5461018d408ea19dfafe76c2c7ef6d4eba614f8ff079"
+dependencies = [
+ "yoke",
+ "zerofrom",
+ "zerovec-derive",
+]
+
+[[package]]
+name = "zerovec-derive"
+version = "0.10.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
diff --git a/src/ci/citool/Cargo.toml b/src/ci/citool/Cargo.toml
index e77c67c7147..c486f2977a1 100644
--- a/src/ci/citool/Cargo.toml
+++ b/src/ci/citool/Cargo.toml
@@ -6,9 +6,13 @@ edition = "2021"
 [dependencies]
 anyhow = "1"
 clap = { version = "4.5", features = ["derive"] }
+csv = "1"
 serde = { version = "1", features = ["derive"] }
 serde_yaml = "0.9"
 serde_json = "1"
+ureq = { version = "3", features = ["json"] }
+
+build_helper = { path = "../../build_helper" }
 
 [dev-dependencies]
 insta = "1"
@@ -17,3 +21,7 @@ insta = "1"
 # If this is omitted, cargo will look for a workspace elsewhere.
 # We want to avoid this, since citool is independent of the other crates.
 [workspace]
+
+# Make compilation faster
+[profile.dev]
+debug = 0
diff --git a/src/ci/citool/src/cpu_usage.rs b/src/ci/citool/src/cpu_usage.rs
new file mode 100644
index 00000000000..fa9a1203f41
--- /dev/null
+++ b/src/ci/citool/src/cpu_usage.rs
@@ -0,0 +1,24 @@
+use std::path::Path;
+
+/// Loads CPU usage records from a CSV generated by the `src/ci/scripts/collect-cpu-stats.sh`
+/// script.
+pub fn load_cpu_usage(path: &Path) -> anyhow::Result<Vec<f64>> {
+    let reader = csv::ReaderBuilder::new().flexible(true).from_path(path)?;
+
+    let mut entries = vec![];
+    for row in reader.into_records() {
+        let row = row?;
+        let cols = row.into_iter().collect::<Vec<&str>>();
+
+        // The log might contain incomplete rows or some Python exception
+        if cols.len() == 2 {
+            if let Ok(idle) = cols[1].parse::<f64>() {
+                entries.push(100.0 - idle);
+            } else {
+                eprintln!("Warning: cannot parse CPU CSV entry {}", cols[1]);
+            }
+        }
+    }
+
+    Ok(entries)
+}
diff --git a/src/ci/citool/src/datadog.rs b/src/ci/citool/src/datadog.rs
new file mode 100644
index 00000000000..837257420d6
--- /dev/null
+++ b/src/ci/citool/src/datadog.rs
@@ -0,0 +1,43 @@
+use anyhow::Context;
+
+use crate::utils::load_env_var;
+
+/// Uploads a custom CI pipeline metric to Datadog.
+/// Expects to be executed from within the context of a GitHub Actions job.
+pub fn upload_datadog_metric(name: &str, value: f64) -> anyhow::Result<()> {
+    let datadog_api_key = load_env_var("DATADOG_API_KEY")?;
+    let github_server_url = load_env_var("GITHUB_SERVER_URL")?;
+    let github_repository = load_env_var("GITHUB_REPOSITORY")?;
+    let github_run_id = load_env_var("GITHUB_RUN_ID")?;
+    let github_run_attempt = load_env_var("GITHUB_RUN_ATTEMPT")?;
+    let github_job = load_env_var("GITHUB_JOB")?;
+    let dd_github_job_name = load_env_var("DD_GITHUB_JOB_NAME")?;
+
+    // This API endpoint is not documented in Datadog's API reference currently.
+    // It was reverse-engineered from the `datadog-ci measure` npm command.
+    ureq::post("https://api.datadoghq.com/api/v2/ci/pipeline/metrics")
+        .header("DD-API-KEY", datadog_api_key)
+        .send_json(serde_json::json!({
+            "data": {
+                "attributes": {
+                    "ci_env": {
+                        "GITHUB_SERVER_URL": github_server_url,
+                        "GITHUB_REPOSITORY": github_repository,
+                        "GITHUB_RUN_ID": github_run_id,
+                        "GITHUB_RUN_ATTEMPT": github_run_attempt,
+                        "GITHUB_JOB": github_job,
+                        "DD_GITHUB_JOB_NAME": dd_github_job_name
+                    },
+                    // Job level
+                    "ci_level": 1,
+                    "metrics": {
+                        name: value
+                    },
+                    "provider": "github"
+                },
+                "type": "ci_custom_metric"
+            }
+        }))
+        .context("cannot send metric to DataDog")?;
+    Ok(())
+}
diff --git a/src/ci/citool/src/main.rs b/src/ci/citool/src/main.rs
index ad9cc8b82a6..16edd681886 100644
--- a/src/ci/citool/src/main.rs
+++ b/src/ci/citool/src/main.rs
@@ -1,3 +1,8 @@
+mod cpu_usage;
+mod datadog;
+mod metrics;
+mod utils;
+
 use std::collections::BTreeMap;
 use std::path::{Path, PathBuf};
 use std::process::Command;
@@ -6,6 +11,11 @@ use anyhow::Context;
 use clap::Parser;
 use serde_yaml::Value;
 
+use crate::cpu_usage::load_cpu_usage;
+use crate::datadog::upload_datadog_metric;
+use crate::metrics::postprocess_metrics;
+use crate::utils::load_env_var;
+
 const CI_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/..");
 const DOCKER_DIRECTORY: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../docker");
 const JOBS_YML_PATH: &str = concat!(env!("CARGO_MANIFEST_DIR"), "/../github-actions/jobs.yml");
@@ -71,7 +81,7 @@ impl JobDatabase {
 }
 
 fn load_job_db(path: &Path) -> anyhow::Result<JobDatabase> {
-    let db = read_to_string(path)?;
+    let db = utils::read_to_string(path)?;
     let mut db: Value = serde_yaml::from_str(&db)?;
 
     // We need to expand merge keys (<<), because serde_yaml can't deal with them
@@ -144,10 +154,6 @@ impl GitHubContext {
     }
 }
 
-fn load_env_var(name: &str) -> anyhow::Result<String> {
-    std::env::var(name).with_context(|| format!("Cannot find variable {name}"))
-}
-
 fn load_github_ctx() -> anyhow::Result<GitHubContext> {
     let event_name = load_env_var("GITHUB_EVENT_NAME")?;
     let commit_message =
@@ -176,6 +182,10 @@ fn yaml_map_to_json(map: &BTreeMap<String, Value>) -> BTreeMap<String, serde_jso
         .collect()
 }
 
+/// Maximum number of custom try jobs that can be requested in a single
+/// `@bors try` request.
+const MAX_TRY_JOBS_COUNT: usize = 20;
+
 fn calculate_jobs(
     run_type: &RunType,
     db: &JobDatabase,
@@ -185,9 +195,9 @@ fn calculate_jobs(
         RunType::PullRequest => (db.pr_jobs.clone(), "PR", &db.envs.pr_env),
         RunType::TryJob { custom_jobs } => {
             let jobs = if let Some(custom_jobs) = custom_jobs {
-                if custom_jobs.len() > 10 {
+                if custom_jobs.len() > MAX_TRY_JOBS_COUNT {
                     return Err(anyhow::anyhow!(
-                        "It is only possible to schedule up to 10 custom jobs, received {} custom jobs",
+                        "It is only possible to schedule up to {MAX_TRY_JOBS_COUNT} custom jobs, received {} custom jobs",
                         custom_jobs.len()
                     ));
                 }
@@ -321,6 +331,18 @@ fn run_workflow_locally(db: JobDatabase, job_type: JobType, name: String) -> any
     if !result.success() { Err(anyhow::anyhow!("Job failed")) } else { Ok(()) }
 }
 
+fn upload_ci_metrics(cpu_usage_csv: &Path) -> anyhow::Result<()> {
+    let usage = load_cpu_usage(cpu_usage_csv).context("Cannot load CPU usage from input CSV")?;
+    eprintln!("CPU usage\n{usage:?}");
+
+    let avg = if !usage.is_empty() { usage.iter().sum::<f64>() / usage.len() as f64 } else { 0.0 };
+    eprintln!("CPU usage average: {avg}");
+
+    upload_datadog_metric("avg-cpu-usage", avg).context("Cannot upload Datadog metric")?;
+
+    Ok(())
+}
+
 #[derive(clap::Parser)]
 enum Args {
     /// Calculate a list of jobs that should be executed on CI.
@@ -338,6 +360,19 @@ enum Args {
         #[clap(long = "type", default_value = "auto")]
         job_type: JobType,
     },
+    /// Postprocess the metrics.json file generated by bootstrap.
+    PostprocessMetrics {
+        /// Path to the metrics.json file
+        metrics_path: PathBuf,
+        /// Path to a file where the postprocessed metrics summary will be stored.
+        /// Usually, this will be GITHUB_STEP_SUMMARY on CI.
+        summary_path: PathBuf,
+    },
+    /// Upload CI metrics to Datadog.
+    UploadBuildMetrics {
+        /// Path to a CSV containing the CI job CPU usage.
+        cpu_usage_csv: PathBuf,
+    },
 }
 
 #[derive(clap::ValueEnum, Clone)]
@@ -358,7 +393,7 @@ fn main() -> anyhow::Result<()> {
             let jobs_path = jobs_file.as_deref().unwrap_or(default_jobs_file);
             let gh_ctx = load_github_ctx()
                 .context("Cannot load environment variables from GitHub Actions")?;
-            let channel = read_to_string(Path::new(CI_DIRECTORY).join("channel"))
+            let channel = utils::read_to_string(Path::new(CI_DIRECTORY).join("channel"))
                 .context("Cannot read channel file")?
                 .trim()
                 .to_string();
@@ -367,14 +402,15 @@ fn main() -> anyhow::Result<()> {
                 .context("Failed to calculate job matrix")?;
         }
         Args::RunJobLocally { job_type, name } => {
-            run_workflow_locally(load_db(default_jobs_file)?, job_type, name)?
+            run_workflow_locally(load_db(default_jobs_file)?, job_type, name)?;
+        }
+        Args::UploadBuildMetrics { cpu_usage_csv } => {
+            upload_ci_metrics(&cpu_usage_csv)?;
+        }
+        Args::PostprocessMetrics { metrics_path, summary_path } => {
+            postprocess_metrics(&metrics_path, &summary_path)?;
         }
     }
 
     Ok(())
 }
-
-fn read_to_string<P: AsRef<Path>>(path: P) -> anyhow::Result<String> {
-    let error = format!("Cannot read file {:?}", path.as_ref());
-    std::fs::read_to_string(path).context(error)
-}
diff --git a/src/ci/citool/src/metrics.rs b/src/ci/citool/src/metrics.rs
new file mode 100644
index 00000000000..2386413ed6b
--- /dev/null
+++ b/src/ci/citool/src/metrics.rs
@@ -0,0 +1,164 @@
+use std::collections::BTreeMap;
+use std::fs::File;
+use std::io::Write;
+use std::path::Path;
+
+use anyhow::Context;
+use build_helper::metrics::{
+    BuildStep, JsonNode, JsonRoot, TestOutcome, TestSuite, TestSuiteMetadata, format_build_steps,
+};
+
+pub fn postprocess_metrics(metrics_path: &Path, summary_path: &Path) -> anyhow::Result<()> {
+    let metrics = load_metrics(metrics_path)?;
+
+    let mut file = File::options()
+        .append(true)
+        .create(true)
+        .open(summary_path)
+        .with_context(|| format!("Cannot open summary file at {summary_path:?}"))?;
+
+    if !metrics.invocations.is_empty() {
+        writeln!(file, "# Bootstrap steps")?;
+        record_bootstrap_step_durations(&metrics, &mut file)?;
+        record_test_suites(&metrics, &mut file)?;
+    }
+
+    Ok(())
+}
+
+fn record_bootstrap_step_durations(metrics: &JsonRoot, file: &mut File) -> anyhow::Result<()> {
+    for invocation in &metrics.invocations {
+        let step = BuildStep::from_invocation(invocation);
+        let table = format_build_steps(&step);
+        eprintln!("Step `{}`\n{table}\n", invocation.cmdline);
+        writeln!(
+            file,
+            r"<details>
+<summary>{}</summary>
+<pre><code>{table}</code></pre>
+</details>
+",
+            invocation.cmdline
+        )?;
+    }
+    eprintln!("Recorded {} bootstrap invocation(s)", metrics.invocations.len());
+
+    Ok(())
+}
+
+fn record_test_suites(metrics: &JsonRoot, file: &mut File) -> anyhow::Result<()> {
+    let suites = get_test_suites(&metrics);
+
+    if !suites.is_empty() {
+        let aggregated = aggregate_test_suites(&suites);
+        let table = render_table(aggregated);
+        writeln!(file, "\n# Test results\n")?;
+        writeln!(file, "{table}")?;
+    } else {
+        eprintln!("No test suites found in metrics");
+    }
+
+    Ok(())
+}
+
+fn render_table(suites: BTreeMap<String, TestSuiteRecord>) -> String {
+    use std::fmt::Write;
+
+    let mut table = "| Test suite | Passed ✅ | Ignored 🚫 | Failed  ❌ |\n".to_string();
+    writeln!(table, "|:------|------:|------:|------:|").unwrap();
+
+    fn write_row(
+        buffer: &mut String,
+        name: &str,
+        record: &TestSuiteRecord,
+        surround: &str,
+    ) -> std::fmt::Result {
+        let TestSuiteRecord { passed, ignored, failed } = record;
+        let total = (record.passed + record.ignored + record.failed) as f64;
+        let passed_pct = ((*passed as f64) / total) * 100.0;
+        let ignored_pct = ((*ignored as f64) / total) * 100.0;
+        let failed_pct = ((*failed as f64) / total) * 100.0;
+
+        write!(buffer, "| {surround}{name}{surround} |")?;
+        write!(buffer, " {surround}{passed} ({passed_pct:.0}%){surround} |")?;
+        write!(buffer, " {surround}{ignored} ({ignored_pct:.0}%){surround} |")?;
+        writeln!(buffer, " {surround}{failed} ({failed_pct:.0}%){surround} |")?;
+
+        Ok(())
+    }
+
+    let mut total = TestSuiteRecord::default();
+    for (name, record) in suites {
+        write_row(&mut table, &name, &record, "").unwrap();
+        total.passed += record.passed;
+        total.ignored += record.ignored;
+        total.failed += record.failed;
+    }
+    write_row(&mut table, "Total", &total, "**").unwrap();
+    table
+}
+
+#[derive(Default)]
+struct TestSuiteRecord {
+    passed: u64,
+    ignored: u64,
+    failed: u64,
+}
+
+fn aggregate_test_suites(suites: &[&TestSuite]) -> BTreeMap<String, TestSuiteRecord> {
+    let mut records: BTreeMap<String, TestSuiteRecord> = BTreeMap::new();
+    for suite in suites {
+        let name = match &suite.metadata {
+            TestSuiteMetadata::CargoPackage { crates, stage, .. } => {
+                format!("{} (stage {stage})", crates.join(", "))
+            }
+            TestSuiteMetadata::Compiletest { suite, stage, .. } => {
+                format!("{suite} (stage {stage})")
+            }
+        };
+        let record = records.entry(name).or_default();
+        for test in &suite.tests {
+            match test.outcome {
+                TestOutcome::Passed => {
+                    record.passed += 1;
+                }
+                TestOutcome::Failed => {
+                    record.failed += 1;
+                }
+                TestOutcome::Ignored { .. } => {
+                    record.ignored += 1;
+                }
+            }
+        }
+    }
+    records
+}
+
+fn get_test_suites(metrics: &JsonRoot) -> Vec<&TestSuite> {
+    fn visit_test_suites<'a>(nodes: &'a [JsonNode], suites: &mut Vec<&'a TestSuite>) {
+        for node in nodes {
+            match node {
+                JsonNode::RustbuildStep { children, .. } => {
+                    visit_test_suites(&children, suites);
+                }
+                JsonNode::TestSuite(suite) => {
+                    suites.push(&suite);
+                }
+            }
+        }
+    }
+
+    let mut suites = vec![];
+    for invocation in &metrics.invocations {
+        visit_test_suites(&invocation.children, &mut suites);
+    }
+    suites
+}
+
+fn load_metrics(path: &Path) -> anyhow::Result<JsonRoot> {
+    let metrics = std::fs::read_to_string(path)
+        .with_context(|| format!("Cannot read JSON metrics from {path:?}"))?;
+    let metrics: JsonRoot = serde_json::from_str(&metrics)
+        .with_context(|| format!("Cannot deserialize JSON metrics from {path:?}"))?;
+    Ok(metrics)
+}
diff --git a/src/ci/citool/src/utils.rs b/src/ci/citool/src/utils.rs
new file mode 100644
index 00000000000..9cc220987bd
--- /dev/null
+++ b/src/ci/citool/src/utils.rs
@@ -0,0 +1,11 @@
+use std::path::Path;
+
+use anyhow::Context;
+
+pub fn load_env_var(name: &str) -> anyhow::Result<String> {
+    std::env::var(name).with_context(|| format!("Cannot find environment variable `{name}`"))
+}
+
+pub fn read_to_string<P: AsRef<Path>>(path: P) -> anyhow::Result<String> {
+    std::fs::read_to_string(&path).with_context(|| format!("Cannot read file {:?}", path.as_ref()))
+}
diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md
index a1a3a1c37ce..20b6f7d10ef 100644
--- a/src/ci/docker/README.md
+++ b/src/ci/docker/README.md
@@ -11,12 +11,12 @@ the [`jobs.yml`](../github-actions/jobs.yml) file.
 To run a specific CI job locally, you can use the `citool` Rust crate:
 
 ```
-cargo --manifest-path src/ci/citool/Cargo.toml run run-local <job-name>
+cargo run --manifest-path src/ci/citool/Cargo.toml run-local <job-name>
 ```
 
 For example, to run the `x86_64-gnu-llvm-18-1` job:
 ```
-cargo --manifest-path src/ci/citool/Cargo.toml run run-local x86_64-gnu-llvm-18-1
+cargo run --manifest-path src/ci/citool/Cargo.toml run-local x86_64-gnu-llvm-18-1
 ```
 
 The job will output artifacts in an `obj/<image-name>` dir at the root of a repository. Note
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
index 0b4682ac32b..f54ecef1e30 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-linux/Dockerfile
@@ -101,7 +101,7 @@ ENV SCRIPT python3 ../x.py build --set rust.debug=true opt-dist && \
     ./build/$HOSTS/stage0-tools-bin/opt-dist linux-ci -- python3 ../x.py dist \
     --host $HOSTS --target $HOSTS \
     --include-default-paths \
-    build-manifest bootstrap
+    build-manifest bootstrap gcc
 ENV CARGO_TARGET_X86_64_UNKNOWN_LINUX_GNU_LINKER=clang
 
 # This is the only builder which will create source tarballs
diff --git a/src/ci/docker/scripts/rfl-build.sh b/src/ci/docker/scripts/rfl-build.sh
index 573821c3e59..ea8066d95e0 100755
--- a/src/ci/docker/scripts/rfl-build.sh
+++ b/src/ci/docker/scripts/rfl-build.sh
@@ -8,16 +8,10 @@ LINUX_VERSION=v6.14-rc3
 ../x.py build --stage 2 library rustdoc clippy rustfmt
 ../x.py build --stage 0 cargo
 
-# Install rustup so that we can use the built toolchain easily, and also
-# install bindgen in an easy way.
-curl --proto '=https' --tlsv1.2 -sSf -o rustup.sh https://sh.rustup.rs
-sh rustup.sh -y --default-toolchain none
+BUILD_DIR=$(realpath ./build/x86_64-unknown-linux-gnu)
 
-source /cargo/env
-
-BUILD_DIR=$(realpath ./build)
-rustup toolchain link local "${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage2
-rustup default local
+# Provide path to rustc, rustdoc, clippy-driver and rustfmt to RfL
+export PATH=${PATH}:${BUILD_DIR}/stage2/bin
 
 mkdir -p rfl
 cd rfl
@@ -33,10 +27,14 @@ git -C linux fetch --depth 1 origin ${LINUX_VERSION}
 git -C linux checkout FETCH_HEAD
 
 # Install bindgen
-"${BUILD_DIR}"/x86_64-unknown-linux-gnu/stage0/bin/cargo install \
+"${BUILD_DIR}"/stage0/bin/cargo install \
   --version $(linux/scripts/min-tool-version.sh bindgen) \
+  --root ${BUILD_DIR}/bindgen \
   bindgen-cli
 
+# Provide path to bindgen to RfL
+export PATH=${PATH}:${BUILD_DIR}/bindgen/bin
+
 # Configure Rust for Linux
 cat <<EOF > linux/kernel/configs/rfl-for-rust-ci.config
 # CONFIG_WERROR is not set
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index bbcc01a0c29..6b88c26e3a2 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -54,7 +54,7 @@ runners:
     <<: *base-job
 
   - &job-aarch64-linux-8c
-    os: ubuntu-22.04-arm64-8core-32gb
+    os: ubuntu-24.04-arm64-8core-32gb
     <<: *base-job
 envs:
   env-x86_64-apple-tests: &env-x86_64-apple-tests
diff --git a/src/ci/package-lock.json b/src/ci/package-lock.json
deleted file mode 100644
index 6bbdc6adcfd..00000000000
--- a/src/ci/package-lock.json
+++ /dev/null
@@ -1,5004 +0,0 @@
-{
-  "name": "ci",
-  "lockfileVersion": 3,
-  "requires": true,
-  "packages": {
-    "": {
-      "dependencies": {
-        "@datadog/datadog-ci": "^2.45.1"
-      }
-    },
-    "node_modules/@aws-crypto/crc32": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@aws-crypto/crc32/-/crc32-5.2.0.tgz",
-      "integrity": "sha512-nLbCWqQNgUiwwtFsen1AdzAtvuLRsQS8rYgMuxCrdKf9kOssamGLuPwyTY9wyYblNr9+1XM8v6zoDTPPSIeANg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-crypto/util": "^5.2.0",
-        "@aws-sdk/types": "^3.222.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-crypto/sha256-browser": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-browser/-/sha256-browser-5.2.0.tgz",
-      "integrity": "sha512-AXfN/lGotSQwu6HNcEsIASo7kWXZ5HYWvfOmSNKDsEqC4OashTp8alTmaz+F7TC2L083SFv5RdB+qU3Vs1kZqw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-crypto/sha256-js": "^5.2.0",
-        "@aws-crypto/supports-web-crypto": "^5.2.0",
-        "@aws-crypto/util": "^5.2.0",
-        "@aws-sdk/types": "^3.222.0",
-        "@aws-sdk/util-locate-window": "^3.0.0",
-        "@smithy/util-utf8": "^2.0.0",
-        "tslib": "^2.6.2"
-      }
-    },
-    "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/is-array-buffer": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
-      "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-buffer-from": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
-      "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/is-array-buffer": "^2.2.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@aws-crypto/sha256-browser/node_modules/@smithy/util-utf8": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
-      "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/util-buffer-from": "^2.2.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@aws-crypto/sha256-js": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@aws-crypto/sha256-js/-/sha256-js-5.2.0.tgz",
-      "integrity": "sha512-FFQQyu7edu4ufvIZ+OadFpHHOt+eSTBaYaki44c+akjg7qZg9oOQeLlk77F6tSYqjDAFClrHJk9tMf0HdVyOvA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-crypto/util": "^5.2.0",
-        "@aws-sdk/types": "^3.222.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-crypto/supports-web-crypto": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@aws-crypto/supports-web-crypto/-/supports-web-crypto-5.2.0.tgz",
-      "integrity": "sha512-iAvUotm021kM33eCdNfwIN//F77/IADDSs58i+MDaOqFrVjZo9bAal0NK7HurRuWLLpF1iLX7gbWrjHjeo+YFg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^2.6.2"
-      }
-    },
-    "node_modules/@aws-crypto/util": {
-      "version": "5.2.0",
-      "resolved": "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz",
-      "integrity": "sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/types": "^3.222.0",
-        "@smithy/util-utf8": "^2.0.0",
-        "tslib": "^2.6.2"
-      }
-    },
-    "node_modules/@aws-crypto/util/node_modules/@smithy/is-array-buffer": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-2.2.0.tgz",
-      "integrity": "sha512-GGP3O9QFD24uGeAXYUjwSTXARoqpZykHadOmA8G5vfJPK0/DC67qa//0qvqrJzL1xc8WQWX7/yc7fwudjPHPhA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@aws-crypto/util/node_modules/@smithy/util-buffer-from": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-2.2.0.tgz",
-      "integrity": "sha512-IJdWBbTcMQ6DA0gdNhh/BwrLkDR+ADW5Kr1aZmd4k3DIF6ezMV4R2NIAmT08wQJ3yUK82thHWmC/TnK/wpMMIA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/is-array-buffer": "^2.2.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@aws-crypto/util/node_modules/@smithy/util-utf8": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-2.3.0.tgz",
-      "integrity": "sha512-R8Rdn8Hy72KKcebgLiv8jQcQkXoLMOGGv5uI1/k0l+snqkOzQ1R0ChUBCxWMlBsFMekWjq0wRudIweFs7sKT5A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/util-buffer-from": "^2.2.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-cloudwatch-logs": {
-      "version": "3.703.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-cloudwatch-logs/-/client-cloudwatch-logs-3.703.0.tgz",
-      "integrity": "sha512-KkLMwrNhkLZr3OCRWakJY16OF8pUZCoexxZkWzHfR/Pw3WBcDtBMEiEO13P6oHlGAn1VvIDxxMBSxeg/89xyJA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-crypto/sha256-browser": "5.2.0",
-        "@aws-crypto/sha256-js": "5.2.0",
-        "@aws-sdk/client-sso-oidc": "3.699.0",
-        "@aws-sdk/client-sts": "3.699.0",
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/credential-provider-node": "3.699.0",
-        "@aws-sdk/middleware-host-header": "3.696.0",
-        "@aws-sdk/middleware-logger": "3.696.0",
-        "@aws-sdk/middleware-recursion-detection": "3.696.0",
-        "@aws-sdk/middleware-user-agent": "3.696.0",
-        "@aws-sdk/region-config-resolver": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@aws-sdk/util-endpoints": "3.696.0",
-        "@aws-sdk/util-user-agent-browser": "3.696.0",
-        "@aws-sdk/util-user-agent-node": "3.696.0",
-        "@smithy/config-resolver": "^3.0.12",
-        "@smithy/core": "^2.5.3",
-        "@smithy/eventstream-serde-browser": "^3.0.13",
-        "@smithy/eventstream-serde-config-resolver": "^3.0.10",
-        "@smithy/eventstream-serde-node": "^3.0.12",
-        "@smithy/fetch-http-handler": "^4.1.1",
-        "@smithy/hash-node": "^3.0.10",
-        "@smithy/invalid-dependency": "^3.0.10",
-        "@smithy/middleware-content-length": "^3.0.12",
-        "@smithy/middleware-endpoint": "^3.2.3",
-        "@smithy/middleware-retry": "^3.0.27",
-        "@smithy/middleware-serde": "^3.0.10",
-        "@smithy/middleware-stack": "^3.0.10",
-        "@smithy/node-config-provider": "^3.1.11",
-        "@smithy/node-http-handler": "^3.3.1",
-        "@smithy/protocol-http": "^4.1.7",
-        "@smithy/smithy-client": "^3.4.4",
-        "@smithy/types": "^3.7.1",
-        "@smithy/url-parser": "^3.0.10",
-        "@smithy/util-base64": "^3.0.0",
-        "@smithy/util-body-length-browser": "^3.0.0",
-        "@smithy/util-body-length-node": "^3.0.0",
-        "@smithy/util-defaults-mode-browser": "^3.0.27",
-        "@smithy/util-defaults-mode-node": "^3.0.27",
-        "@smithy/util-endpoints": "^2.1.6",
-        "@smithy/util-middleware": "^3.0.10",
-        "@smithy/util-retry": "^3.0.10",
-        "@smithy/util-utf8": "^3.0.0",
-        "@types/uuid": "^9.0.1",
-        "tslib": "^2.6.2",
-        "uuid": "^9.0.1"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-cloudwatch-logs/node_modules/@smithy/util-retry": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz",
-      "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/service-error-classification": "^3.0.11",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-cognito-identity": {
-      "version": "3.699.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-cognito-identity/-/client-cognito-identity-3.699.0.tgz",
-      "integrity": "sha512-9tFt+we6AIvj/f1+nrLHuCWcQmyfux5gcBSOy9d9+zIG56YxGEX7S9TaZnybogpVV8A0BYWml36WvIHS9QjIpA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-crypto/sha256-browser": "5.2.0",
-        "@aws-crypto/sha256-js": "5.2.0",
-        "@aws-sdk/client-sso-oidc": "3.699.0",
-        "@aws-sdk/client-sts": "3.699.0",
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/credential-provider-node": "3.699.0",
-        "@aws-sdk/middleware-host-header": "3.696.0",
-        "@aws-sdk/middleware-logger": "3.696.0",
-        "@aws-sdk/middleware-recursion-detection": "3.696.0",
-        "@aws-sdk/middleware-user-agent": "3.696.0",
-        "@aws-sdk/region-config-resolver": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@aws-sdk/util-endpoints": "3.696.0",
-        "@aws-sdk/util-user-agent-browser": "3.696.0",
-        "@aws-sdk/util-user-agent-node": "3.696.0",
-        "@smithy/config-resolver": "^3.0.12",
-        "@smithy/core": "^2.5.3",
-        "@smithy/fetch-http-handler": "^4.1.1",
-        "@smithy/hash-node": "^3.0.10",
-        "@smithy/invalid-dependency": "^3.0.10",
-        "@smithy/middleware-content-length": "^3.0.12",
-        "@smithy/middleware-endpoint": "^3.2.3",
-        "@smithy/middleware-retry": "^3.0.27",
-        "@smithy/middleware-serde": "^3.0.10",
-        "@smithy/middleware-stack": "^3.0.10",
-        "@smithy/node-config-provider": "^3.1.11",
-        "@smithy/node-http-handler": "^3.3.1",
-        "@smithy/protocol-http": "^4.1.7",
-        "@smithy/smithy-client": "^3.4.4",
-        "@smithy/types": "^3.7.1",
-        "@smithy/url-parser": "^3.0.10",
-        "@smithy/util-base64": "^3.0.0",
-        "@smithy/util-body-length-browser": "^3.0.0",
-        "@smithy/util-body-length-node": "^3.0.0",
-        "@smithy/util-defaults-mode-browser": "^3.0.27",
-        "@smithy/util-defaults-mode-node": "^3.0.27",
-        "@smithy/util-endpoints": "^2.1.6",
-        "@smithy/util-middleware": "^3.0.10",
-        "@smithy/util-retry": "^3.0.10",
-        "@smithy/util-utf8": "^3.0.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-cognito-identity/node_modules/@smithy/util-retry": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz",
-      "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/service-error-classification": "^3.0.11",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-iam": {
-      "version": "3.699.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-iam/-/client-iam-3.699.0.tgz",
-      "integrity": "sha512-JBVcmkGaV7tW/mEntqt6KdkhsyYU2oIMUbkNHJextKqu6odSkuB1mN70TgctwFP8x2LDgFzvT6WcWVCKc/g3Ng==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-crypto/sha256-browser": "5.2.0",
-        "@aws-crypto/sha256-js": "5.2.0",
-        "@aws-sdk/client-sso-oidc": "3.699.0",
-        "@aws-sdk/client-sts": "3.699.0",
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/credential-provider-node": "3.699.0",
-        "@aws-sdk/middleware-host-header": "3.696.0",
-        "@aws-sdk/middleware-logger": "3.696.0",
-        "@aws-sdk/middleware-recursion-detection": "3.696.0",
-        "@aws-sdk/middleware-user-agent": "3.696.0",
-        "@aws-sdk/region-config-resolver": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@aws-sdk/util-endpoints": "3.696.0",
-        "@aws-sdk/util-user-agent-browser": "3.696.0",
-        "@aws-sdk/util-user-agent-node": "3.696.0",
-        "@smithy/config-resolver": "^3.0.12",
-        "@smithy/core": "^2.5.3",
-        "@smithy/fetch-http-handler": "^4.1.1",
-        "@smithy/hash-node": "^3.0.10",
-        "@smithy/invalid-dependency": "^3.0.10",
-        "@smithy/middleware-content-length": "^3.0.12",
-        "@smithy/middleware-endpoint": "^3.2.3",
-        "@smithy/middleware-retry": "^3.0.27",
-        "@smithy/middleware-serde": "^3.0.10",
-        "@smithy/middleware-stack": "^3.0.10",
-        "@smithy/node-config-provider": "^3.1.11",
-        "@smithy/node-http-handler": "^3.3.1",
-        "@smithy/protocol-http": "^4.1.7",
-        "@smithy/smithy-client": "^3.4.4",
-        "@smithy/types": "^3.7.1",
-        "@smithy/url-parser": "^3.0.10",
-        "@smithy/util-base64": "^3.0.0",
-        "@smithy/util-body-length-browser": "^3.0.0",
-        "@smithy/util-body-length-node": "^3.0.0",
-        "@smithy/util-defaults-mode-browser": "^3.0.27",
-        "@smithy/util-defaults-mode-node": "^3.0.27",
-        "@smithy/util-endpoints": "^2.1.6",
-        "@smithy/util-middleware": "^3.0.10",
-        "@smithy/util-retry": "^3.0.10",
-        "@smithy/util-utf8": "^3.0.0",
-        "@smithy/util-waiter": "^3.1.9",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-iam/node_modules/@smithy/util-retry": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz",
-      "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/service-error-classification": "^3.0.11",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-lambda": {
-      "version": "3.699.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-lambda/-/client-lambda-3.699.0.tgz",
-      "integrity": "sha512-K9TGvQB8hkjwNhfWSfYllUpttqxTcd78ShSRCIhlcwzzsmQphET10xEb0Tm1k8sqriSQ+CiVOFSkX78gqoHzBg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-crypto/sha256-browser": "5.2.0",
-        "@aws-crypto/sha256-js": "5.2.0",
-        "@aws-sdk/client-sso-oidc": "3.699.0",
-        "@aws-sdk/client-sts": "3.699.0",
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/credential-provider-node": "3.699.0",
-        "@aws-sdk/middleware-host-header": "3.696.0",
-        "@aws-sdk/middleware-logger": "3.696.0",
-        "@aws-sdk/middleware-recursion-detection": "3.696.0",
-        "@aws-sdk/middleware-user-agent": "3.696.0",
-        "@aws-sdk/region-config-resolver": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@aws-sdk/util-endpoints": "3.696.0",
-        "@aws-sdk/util-user-agent-browser": "3.696.0",
-        "@aws-sdk/util-user-agent-node": "3.696.0",
-        "@smithy/config-resolver": "^3.0.12",
-        "@smithy/core": "^2.5.3",
-        "@smithy/eventstream-serde-browser": "^3.0.13",
-        "@smithy/eventstream-serde-config-resolver": "^3.0.10",
-        "@smithy/eventstream-serde-node": "^3.0.12",
-        "@smithy/fetch-http-handler": "^4.1.1",
-        "@smithy/hash-node": "^3.0.10",
-        "@smithy/invalid-dependency": "^3.0.10",
-        "@smithy/middleware-content-length": "^3.0.12",
-        "@smithy/middleware-endpoint": "^3.2.3",
-        "@smithy/middleware-retry": "^3.0.27",
-        "@smithy/middleware-serde": "^3.0.10",
-        "@smithy/middleware-stack": "^3.0.10",
-        "@smithy/node-config-provider": "^3.1.11",
-        "@smithy/node-http-handler": "^3.3.1",
-        "@smithy/protocol-http": "^4.1.7",
-        "@smithy/smithy-client": "^3.4.4",
-        "@smithy/types": "^3.7.1",
-        "@smithy/url-parser": "^3.0.10",
-        "@smithy/util-base64": "^3.0.0",
-        "@smithy/util-body-length-browser": "^3.0.0",
-        "@smithy/util-body-length-node": "^3.0.0",
-        "@smithy/util-defaults-mode-browser": "^3.0.27",
-        "@smithy/util-defaults-mode-node": "^3.0.27",
-        "@smithy/util-endpoints": "^2.1.6",
-        "@smithy/util-middleware": "^3.0.10",
-        "@smithy/util-retry": "^3.0.10",
-        "@smithy/util-stream": "^3.3.1",
-        "@smithy/util-utf8": "^3.0.0",
-        "@smithy/util-waiter": "^3.1.9",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-lambda/node_modules/@smithy/util-retry": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz",
-      "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/service-error-classification": "^3.0.11",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-sfn": {
-      "version": "3.699.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sfn/-/client-sfn-3.699.0.tgz",
-      "integrity": "sha512-66/+rOMVvjKRhKDDsrxtfRzXXsAfVu/RbhxPYepcVhO+0/ii6DL2uQCeNhMN3+MPg+HWX695H5RyBVJ6QGli8w==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-crypto/sha256-browser": "5.2.0",
-        "@aws-crypto/sha256-js": "5.2.0",
-        "@aws-sdk/client-sso-oidc": "3.699.0",
-        "@aws-sdk/client-sts": "3.699.0",
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/credential-provider-node": "3.699.0",
-        "@aws-sdk/middleware-host-header": "3.696.0",
-        "@aws-sdk/middleware-logger": "3.696.0",
-        "@aws-sdk/middleware-recursion-detection": "3.696.0",
-        "@aws-sdk/middleware-user-agent": "3.696.0",
-        "@aws-sdk/region-config-resolver": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@aws-sdk/util-endpoints": "3.696.0",
-        "@aws-sdk/util-user-agent-browser": "3.696.0",
-        "@aws-sdk/util-user-agent-node": "3.696.0",
-        "@smithy/config-resolver": "^3.0.12",
-        "@smithy/core": "^2.5.3",
-        "@smithy/fetch-http-handler": "^4.1.1",
-        "@smithy/hash-node": "^3.0.10",
-        "@smithy/invalid-dependency": "^3.0.10",
-        "@smithy/middleware-content-length": "^3.0.12",
-        "@smithy/middleware-endpoint": "^3.2.3",
-        "@smithy/middleware-retry": "^3.0.27",
-        "@smithy/middleware-serde": "^3.0.10",
-        "@smithy/middleware-stack": "^3.0.10",
-        "@smithy/node-config-provider": "^3.1.11",
-        "@smithy/node-http-handler": "^3.3.1",
-        "@smithy/protocol-http": "^4.1.7",
-        "@smithy/smithy-client": "^3.4.4",
-        "@smithy/types": "^3.7.1",
-        "@smithy/url-parser": "^3.0.10",
-        "@smithy/util-base64": "^3.0.0",
-        "@smithy/util-body-length-browser": "^3.0.0",
-        "@smithy/util-body-length-node": "^3.0.0",
-        "@smithy/util-defaults-mode-browser": "^3.0.27",
-        "@smithy/util-defaults-mode-node": "^3.0.27",
-        "@smithy/util-endpoints": "^2.1.6",
-        "@smithy/util-middleware": "^3.0.10",
-        "@smithy/util-retry": "^3.0.10",
-        "@smithy/util-utf8": "^3.0.0",
-        "@types/uuid": "^9.0.1",
-        "tslib": "^2.6.2",
-        "uuid": "^9.0.1"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-sfn/node_modules/@smithy/util-retry": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz",
-      "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/service-error-classification": "^3.0.11",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-sso": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso/-/client-sso-3.696.0.tgz",
-      "integrity": "sha512-q5TTkd08JS0DOkHfUL853tuArf7NrPeqoS5UOvqJho8ibV9Ak/a/HO4kNvy9Nj3cib/toHYHsQIEtecUPSUUrQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-crypto/sha256-browser": "5.2.0",
-        "@aws-crypto/sha256-js": "5.2.0",
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/middleware-host-header": "3.696.0",
-        "@aws-sdk/middleware-logger": "3.696.0",
-        "@aws-sdk/middleware-recursion-detection": "3.696.0",
-        "@aws-sdk/middleware-user-agent": "3.696.0",
-        "@aws-sdk/region-config-resolver": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@aws-sdk/util-endpoints": "3.696.0",
-        "@aws-sdk/util-user-agent-browser": "3.696.0",
-        "@aws-sdk/util-user-agent-node": "3.696.0",
-        "@smithy/config-resolver": "^3.0.12",
-        "@smithy/core": "^2.5.3",
-        "@smithy/fetch-http-handler": "^4.1.1",
-        "@smithy/hash-node": "^3.0.10",
-        "@smithy/invalid-dependency": "^3.0.10",
-        "@smithy/middleware-content-length": "^3.0.12",
-        "@smithy/middleware-endpoint": "^3.2.3",
-        "@smithy/middleware-retry": "^3.0.27",
-        "@smithy/middleware-serde": "^3.0.10",
-        "@smithy/middleware-stack": "^3.0.10",
-        "@smithy/node-config-provider": "^3.1.11",
-        "@smithy/node-http-handler": "^3.3.1",
-        "@smithy/protocol-http": "^4.1.7",
-        "@smithy/smithy-client": "^3.4.4",
-        "@smithy/types": "^3.7.1",
-        "@smithy/url-parser": "^3.0.10",
-        "@smithy/util-base64": "^3.0.0",
-        "@smithy/util-body-length-browser": "^3.0.0",
-        "@smithy/util-body-length-node": "^3.0.0",
-        "@smithy/util-defaults-mode-browser": "^3.0.27",
-        "@smithy/util-defaults-mode-node": "^3.0.27",
-        "@smithy/util-endpoints": "^2.1.6",
-        "@smithy/util-middleware": "^3.0.10",
-        "@smithy/util-retry": "^3.0.10",
-        "@smithy/util-utf8": "^3.0.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-sso-oidc": {
-      "version": "3.699.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sso-oidc/-/client-sso-oidc-3.699.0.tgz",
-      "integrity": "sha512-u8a1GorY5D1l+4FQAf4XBUC1T10/t7neuwT21r0ymrtMFSK2a9QqVHKMoLkvavAwyhJnARSBM9/UQC797PFOFw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-crypto/sha256-browser": "5.2.0",
-        "@aws-crypto/sha256-js": "5.2.0",
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/credential-provider-node": "3.699.0",
-        "@aws-sdk/middleware-host-header": "3.696.0",
-        "@aws-sdk/middleware-logger": "3.696.0",
-        "@aws-sdk/middleware-recursion-detection": "3.696.0",
-        "@aws-sdk/middleware-user-agent": "3.696.0",
-        "@aws-sdk/region-config-resolver": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@aws-sdk/util-endpoints": "3.696.0",
-        "@aws-sdk/util-user-agent-browser": "3.696.0",
-        "@aws-sdk/util-user-agent-node": "3.696.0",
-        "@smithy/config-resolver": "^3.0.12",
-        "@smithy/core": "^2.5.3",
-        "@smithy/fetch-http-handler": "^4.1.1",
-        "@smithy/hash-node": "^3.0.10",
-        "@smithy/invalid-dependency": "^3.0.10",
-        "@smithy/middleware-content-length": "^3.0.12",
-        "@smithy/middleware-endpoint": "^3.2.3",
-        "@smithy/middleware-retry": "^3.0.27",
-        "@smithy/middleware-serde": "^3.0.10",
-        "@smithy/middleware-stack": "^3.0.10",
-        "@smithy/node-config-provider": "^3.1.11",
-        "@smithy/node-http-handler": "^3.3.1",
-        "@smithy/protocol-http": "^4.1.7",
-        "@smithy/smithy-client": "^3.4.4",
-        "@smithy/types": "^3.7.1",
-        "@smithy/url-parser": "^3.0.10",
-        "@smithy/util-base64": "^3.0.0",
-        "@smithy/util-body-length-browser": "^3.0.0",
-        "@smithy/util-body-length-node": "^3.0.0",
-        "@smithy/util-defaults-mode-browser": "^3.0.27",
-        "@smithy/util-defaults-mode-node": "^3.0.27",
-        "@smithy/util-endpoints": "^2.1.6",
-        "@smithy/util-middleware": "^3.0.10",
-        "@smithy/util-retry": "^3.0.10",
-        "@smithy/util-utf8": "^3.0.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      },
-      "peerDependencies": {
-        "@aws-sdk/client-sts": "^3.699.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-sso-oidc/node_modules/@smithy/util-retry": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz",
-      "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/service-error-classification": "^3.0.11",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-sso/node_modules/@smithy/util-retry": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz",
-      "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/service-error-classification": "^3.0.11",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-sts": {
-      "version": "3.699.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/client-sts/-/client-sts-3.699.0.tgz",
-      "integrity": "sha512-++lsn4x2YXsZPIzFVwv3fSUVM55ZT0WRFmPeNilYIhZClxHLmVAWKH4I55cY9ry60/aTKYjzOXkWwyBKGsGvQg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-crypto/sha256-browser": "5.2.0",
-        "@aws-crypto/sha256-js": "5.2.0",
-        "@aws-sdk/client-sso-oidc": "3.699.0",
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/credential-provider-node": "3.699.0",
-        "@aws-sdk/middleware-host-header": "3.696.0",
-        "@aws-sdk/middleware-logger": "3.696.0",
-        "@aws-sdk/middleware-recursion-detection": "3.696.0",
-        "@aws-sdk/middleware-user-agent": "3.696.0",
-        "@aws-sdk/region-config-resolver": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@aws-sdk/util-endpoints": "3.696.0",
-        "@aws-sdk/util-user-agent-browser": "3.696.0",
-        "@aws-sdk/util-user-agent-node": "3.696.0",
-        "@smithy/config-resolver": "^3.0.12",
-        "@smithy/core": "^2.5.3",
-        "@smithy/fetch-http-handler": "^4.1.1",
-        "@smithy/hash-node": "^3.0.10",
-        "@smithy/invalid-dependency": "^3.0.10",
-        "@smithy/middleware-content-length": "^3.0.12",
-        "@smithy/middleware-endpoint": "^3.2.3",
-        "@smithy/middleware-retry": "^3.0.27",
-        "@smithy/middleware-serde": "^3.0.10",
-        "@smithy/middleware-stack": "^3.0.10",
-        "@smithy/node-config-provider": "^3.1.11",
-        "@smithy/node-http-handler": "^3.3.1",
-        "@smithy/protocol-http": "^4.1.7",
-        "@smithy/smithy-client": "^3.4.4",
-        "@smithy/types": "^3.7.1",
-        "@smithy/url-parser": "^3.0.10",
-        "@smithy/util-base64": "^3.0.0",
-        "@smithy/util-body-length-browser": "^3.0.0",
-        "@smithy/util-body-length-node": "^3.0.0",
-        "@smithy/util-defaults-mode-browser": "^3.0.27",
-        "@smithy/util-defaults-mode-node": "^3.0.27",
-        "@smithy/util-endpoints": "^2.1.6",
-        "@smithy/util-middleware": "^3.0.10",
-        "@smithy/util-retry": "^3.0.10",
-        "@smithy/util-utf8": "^3.0.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/client-sts/node_modules/@smithy/util-retry": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz",
-      "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/service-error-classification": "^3.0.11",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/core": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/core/-/core-3.696.0.tgz",
-      "integrity": "sha512-3c9III1k03DgvRZWg8vhVmfIXPG6hAciN9MzQTzqGngzWAELZF/WONRTRQuDFixVtarQatmLHYVw/atGeA2Byw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/core": "^2.5.3",
-        "@smithy/node-config-provider": "^3.1.11",
-        "@smithy/property-provider": "^3.1.9",
-        "@smithy/protocol-http": "^4.1.7",
-        "@smithy/signature-v4": "^4.2.2",
-        "@smithy/smithy-client": "^3.4.4",
-        "@smithy/types": "^3.7.1",
-        "@smithy/util-middleware": "^3.0.10",
-        "fast-xml-parser": "4.4.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/core/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/core/node_modules/fast-xml-parser": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.4.1.tgz",
-      "integrity": "sha512-xkjOecfnKGkSsOwtZ5Pz7Us/T6mrbPQrq0nh+aCO5V9nk5NLWmasAHumTKjiPJPWANe+kAZ84Jc8ooJkzZ88Sw==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/NaturalIntelligence"
-        },
-        {
-          "type": "paypal",
-          "url": "https://paypal.me/naturalintelligence"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "strnum": "^1.0.5"
-      },
-      "bin": {
-        "fxparser": "src/cli/cli.js"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-cognito-identity": {
-      "version": "3.699.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-cognito-identity/-/credential-provider-cognito-identity-3.699.0.tgz",
-      "integrity": "sha512-iuaTnudaBfEET+o444sDwf71Awe6UiZfH+ipUPmswAi2jZDwdFF1nxMKDEKL8/LV5WpXsdKSfwgS0RQeupURew==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/client-cognito-identity": "3.699.0",
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/property-provider": "^3.1.9",
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-cognito-identity/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-env": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-env/-/credential-provider-env-3.696.0.tgz",
-      "integrity": "sha512-T9iMFnJL7YTlESLpVFT3fg1Lkb1lD+oiaIC8KMpepb01gDUBIpj9+Y+pA/cgRWW0yRxmkDXNazAE2qQTVFGJzA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/property-provider": "^3.1.9",
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-env/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-http": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-http/-/credential-provider-http-3.696.0.tgz",
-      "integrity": "sha512-GV6EbvPi2eq1+WgY/o2RFA3P7HGmnkIzCNmhwtALFlqMroLYWKE7PSeHw66Uh1dFQeVESn0/+hiUNhu1mB0emA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/fetch-http-handler": "^4.1.1",
-        "@smithy/node-http-handler": "^3.3.1",
-        "@smithy/property-provider": "^3.1.9",
-        "@smithy/protocol-http": "^4.1.7",
-        "@smithy/smithy-client": "^3.4.4",
-        "@smithy/types": "^3.7.1",
-        "@smithy/util-stream": "^3.3.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-http/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-ini": {
-      "version": "3.699.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-ini/-/credential-provider-ini-3.699.0.tgz",
-      "integrity": "sha512-dXmCqjJnKmG37Q+nLjPVu22mNkrGHY8hYoOt3Jo9R2zr5MYV7s/NHsCHr+7E+BZ+tfZYLRPeB1wkpTeHiEcdRw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/credential-provider-env": "3.696.0",
-        "@aws-sdk/credential-provider-http": "3.696.0",
-        "@aws-sdk/credential-provider-process": "3.696.0",
-        "@aws-sdk/credential-provider-sso": "3.699.0",
-        "@aws-sdk/credential-provider-web-identity": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/credential-provider-imds": "^3.2.6",
-        "@smithy/property-provider": "^3.1.9",
-        "@smithy/shared-ini-file-loader": "^3.1.10",
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      },
-      "peerDependencies": {
-        "@aws-sdk/client-sts": "^3.699.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-ini/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-node": {
-      "version": "3.699.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-node/-/credential-provider-node-3.699.0.tgz",
-      "integrity": "sha512-MmEmNDo1bBtTgRmdNfdQksXu4uXe66s0p1hi1YPrn1h59Q605eq/xiWbGL6/3KdkViH6eGUuABeV2ODld86ylg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/credential-provider-env": "3.696.0",
-        "@aws-sdk/credential-provider-http": "3.696.0",
-        "@aws-sdk/credential-provider-ini": "3.699.0",
-        "@aws-sdk/credential-provider-process": "3.696.0",
-        "@aws-sdk/credential-provider-sso": "3.699.0",
-        "@aws-sdk/credential-provider-web-identity": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/credential-provider-imds": "^3.2.6",
-        "@smithy/property-provider": "^3.1.9",
-        "@smithy/shared-ini-file-loader": "^3.1.10",
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-node/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-process": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-process/-/credential-provider-process-3.696.0.tgz",
-      "integrity": "sha512-mL1RcFDe9sfmyU5K1nuFkO8UiJXXxLX4JO1gVaDIOvPqwStpUAwi3A1BoeZhWZZNQsiKI810RnYGo0E0WB/hUA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/property-provider": "^3.1.9",
-        "@smithy/shared-ini-file-loader": "^3.1.10",
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-process/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-sso": {
-      "version": "3.699.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-sso/-/credential-provider-sso-3.699.0.tgz",
-      "integrity": "sha512-Ekp2cZG4pl9D8+uKWm4qO1xcm8/MeiI8f+dnlZm8aQzizeC+aXYy9GyoclSf6daK8KfRPiRfM7ZHBBL5dAfdMA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/client-sso": "3.696.0",
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/token-providers": "3.699.0",
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/property-provider": "^3.1.9",
-        "@smithy/shared-ini-file-loader": "^3.1.10",
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-sso/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-web-identity": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-provider-web-identity/-/credential-provider-web-identity-3.696.0.tgz",
-      "integrity": "sha512-XJ/CVlWChM0VCoc259vWguFUjJDn/QwDqHwbx+K9cg3v6yrqXfK5ai+p/6lx0nQpnk4JzPVeYYxWRpaTsGC9rg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/property-provider": "^3.1.9",
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      },
-      "peerDependencies": {
-        "@aws-sdk/client-sts": "^3.696.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-provider-web-identity/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-providers": {
-      "version": "3.699.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/credential-providers/-/credential-providers-3.699.0.tgz",
-      "integrity": "sha512-jBjOntl9zN9Nvb0jmbMGRbiTzemDz64ij7W6BDavxBJRZpRoNeN0QCz6RolkCyXnyUJjo5mF2unY2wnv00A+LQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/client-cognito-identity": "3.699.0",
-        "@aws-sdk/client-sso": "3.696.0",
-        "@aws-sdk/client-sts": "3.699.0",
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/credential-provider-cognito-identity": "3.699.0",
-        "@aws-sdk/credential-provider-env": "3.696.0",
-        "@aws-sdk/credential-provider-http": "3.696.0",
-        "@aws-sdk/credential-provider-ini": "3.699.0",
-        "@aws-sdk/credential-provider-node": "3.699.0",
-        "@aws-sdk/credential-provider-process": "3.696.0",
-        "@aws-sdk/credential-provider-sso": "3.699.0",
-        "@aws-sdk/credential-provider-web-identity": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/credential-provider-imds": "^3.2.6",
-        "@smithy/property-provider": "^3.1.9",
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/credential-providers/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/middleware-host-header": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-host-header/-/middleware-host-header-3.696.0.tgz",
-      "integrity": "sha512-zELJp9Ta2zkX7ELggMN9qMCgekqZhFC5V2rOr4hJDEb/Tte7gpfKSObAnw/3AYiVqt36sjHKfdkoTsuwGdEoDg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/protocol-http": "^4.1.7",
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/middleware-logger": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-logger/-/middleware-logger-3.696.0.tgz",
-      "integrity": "sha512-KhkHt+8AjCxcR/5Zp3++YPJPpFQzxpr+jmONiT/Jw2yqnSngZ0Yspm5wGoRx2hS1HJbyZNuaOWEGuJoxLeBKfA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/middleware-recursion-detection": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-recursion-detection/-/middleware-recursion-detection-3.696.0.tgz",
-      "integrity": "sha512-si/maV3Z0hH7qa99f9ru2xpS5HlfSVcasRlNUXKSDm611i7jFMWwGNLUOXFAOLhXotPX5G3Z6BLwL34oDeBMug==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/protocol-http": "^4.1.7",
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/middleware-user-agent": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/middleware-user-agent/-/middleware-user-agent-3.696.0.tgz",
-      "integrity": "sha512-Lvyj8CTyxrHI6GHd2YVZKIRI5Fmnugt3cpJo0VrKKEgK5zMySwEZ1n4dqPK6czYRWKd5+WnYHYAuU+Wdk6Jsjw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/core": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@aws-sdk/util-endpoints": "3.696.0",
-        "@smithy/core": "^2.5.3",
-        "@smithy/protocol-http": "^4.1.7",
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/region-config-resolver": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/region-config-resolver/-/region-config-resolver-3.696.0.tgz",
-      "integrity": "sha512-7EuH142lBXjI8yH6dVS/CZeiK/WZsmb/8zP6bQbVYpMrppSTgB3MzZZdxVZGzL5r8zPQOU10wLC4kIMy0qdBVQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/node-config-provider": "^3.1.11",
-        "@smithy/types": "^3.7.1",
-        "@smithy/util-config-provider": "^3.0.0",
-        "@smithy/util-middleware": "^3.0.10",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/token-providers": {
-      "version": "3.699.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/token-providers/-/token-providers-3.699.0.tgz",
-      "integrity": "sha512-kuiEW9DWs7fNos/SM+y58HCPhcIzm1nEZLhe2/7/6+TvAYLuEWURYsbK48gzsxXlaJ2k/jGY3nIsA7RptbMOwA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/property-provider": "^3.1.9",
-        "@smithy/shared-ini-file-loader": "^3.1.10",
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      },
-      "peerDependencies": {
-        "@aws-sdk/client-sso-oidc": "^3.699.0"
-      }
-    },
-    "node_modules/@aws-sdk/token-providers/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/types": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/types/-/types-3.696.0.tgz",
-      "integrity": "sha512-9rTvUJIAj5d3//U5FDPWGJ1nFJLuWb30vugGOrWk7aNZ6y9tuA3PI7Cc9dP8WEXKVyK1vuuk8rSFP2iqXnlgrw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/util-endpoints": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/util-endpoints/-/util-endpoints-3.696.0.tgz",
-      "integrity": "sha512-T5s0IlBVX+gkb9g/I6CLt4yAZVzMSiGnbUqWihWsHvQR1WOoIcndQy/Oz/IJXT9T2ipoy7a80gzV6a5mglrioA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/types": "^3.7.1",
-        "@smithy/util-endpoints": "^2.1.6",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/util-locate-window": {
-      "version": "3.693.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/util-locate-window/-/util-locate-window-3.693.0.tgz",
-      "integrity": "sha512-ttrag6haJLWABhLqtg1Uf+4LgHWIMOVSYL+VYZmAp2v4PUGOwWmWQH0Zk8RM7YuQcLfH/EoR72/Yxz6A4FKcuw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@aws-sdk/util-user-agent-browser": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-browser/-/util-user-agent-browser-3.696.0.tgz",
-      "integrity": "sha512-Z5rVNDdmPOe6ELoM5AhF/ja5tSjbe6ctSctDPb0JdDf4dT0v2MfwhJKzXju2RzX8Es/77Glh7MlaXLE0kCB9+Q==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/types": "^3.7.1",
-        "bowser": "^2.11.0",
-        "tslib": "^2.6.2"
-      }
-    },
-    "node_modules/@aws-sdk/util-user-agent-node": {
-      "version": "3.696.0",
-      "resolved": "https://registry.npmjs.org/@aws-sdk/util-user-agent-node/-/util-user-agent-node-3.696.0.tgz",
-      "integrity": "sha512-KhKqcfyXIB0SCCt+qsu4eJjsfiOrNzK5dCV7RAW2YIpp+msxGUUX0NdRE9rkzjiv+3EMktgJm3eEIS+yxtlVdQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/middleware-user-agent": "3.696.0",
-        "@aws-sdk/types": "3.696.0",
-        "@smithy/node-config-provider": "^3.1.11",
-        "@smithy/types": "^3.7.1",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      },
-      "peerDependencies": {
-        "aws-crt": ">=1.0.0"
-      },
-      "peerDependenciesMeta": {
-        "aws-crt": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@datadog/datadog-ci": {
-      "version": "2.45.1",
-      "resolved": "https://registry.npmjs.org/@datadog/datadog-ci/-/datadog-ci-2.45.1.tgz",
-      "integrity": "sha512-na4c4UuhT2jGFTOh+/uUVGR0CVj7c2B6Q7pRp9AMxb6NF2o3McjnSFJzmVc7YFdZwr+eHXeKXKf6bEYw/PjNWw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-sdk/client-cloudwatch-logs": "^3.624.0",
-        "@aws-sdk/client-iam": "^3.624.0",
-        "@aws-sdk/client-lambda": "^3.624.0",
-        "@aws-sdk/client-sfn": "^3.624.0",
-        "@aws-sdk/core": "^3.624.0",
-        "@aws-sdk/credential-provider-ini": "^3.624.0",
-        "@aws-sdk/credential-providers": "^3.624.0",
-        "@google-cloud/logging": "^11.1.0",
-        "@google-cloud/run": "^1.4.0",
-        "@smithy/property-provider": "^2.0.12",
-        "@smithy/util-retry": "^2.0.4",
-        "@types/datadog-metrics": "0.6.1",
-        "ajv": "^8.12.0",
-        "ajv-formats": "^2.1.1",
-        "async-retry": "1.3.1",
-        "axios": "^1.7.4",
-        "chalk": "3.0.0",
-        "clipanion": "^3.2.1",
-        "datadog-metrics": "0.9.3",
-        "deep-extend": "0.6.0",
-        "deep-object-diff": "^1.1.9",
-        "fast-levenshtein": "^3.0.0",
-        "fast-xml-parser": "^4.4.1",
-        "form-data": "4.0.0",
-        "fuzzy": "^0.1.3",
-        "glob": "^7.1.4",
-        "google-auth-library": "^9.12.0",
-        "inquirer": "^8.2.5",
-        "inquirer-checkbox-plus-prompt": "^1.4.2",
-        "js-yaml": "3.13.1",
-        "jszip": "^3.10.1",
-        "ora": "5.4.1",
-        "proxy-agent": "^6.4.0",
-        "rimraf": "^3.0.2",
-        "semver": "^7.5.3",
-        "simple-git": "3.16.0",
-        "ssh2": "^1.15.0",
-        "ssh2-streams": "0.4.10",
-        "sshpk": "1.16.1",
-        "terminal-link": "2.1.1",
-        "tiny-async-pool": "^2.1.0",
-        "typanion": "^3.14.0",
-        "uuid": "^9.0.0",
-        "ws": "^7.5.10",
-        "xml2js": "0.5.0",
-        "yamux-js": "0.1.2"
-      },
-      "bin": {
-        "datadog-ci": "dist/cli.js"
-      },
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/@google-cloud/common": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/@google-cloud/common/-/common-5.0.2.tgz",
-      "integrity": "sha512-V7bmBKYQyu0eVG2BFejuUjlBt+zrya6vtsKdY+JxMM/dNntPF41vZ9+LhOshEUH01zOHEqBSvI7Dad7ZS6aUeA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@google-cloud/projectify": "^4.0.0",
-        "@google-cloud/promisify": "^4.0.0",
-        "arrify": "^2.0.1",
-        "duplexify": "^4.1.1",
-        "extend": "^3.0.2",
-        "google-auth-library": "^9.0.0",
-        "html-entities": "^2.5.2",
-        "retry-request": "^7.0.0",
-        "teeny-request": "^9.0.0"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@google-cloud/logging": {
-      "version": "11.2.0",
-      "resolved": "https://registry.npmjs.org/@google-cloud/logging/-/logging-11.2.0.tgz",
-      "integrity": "sha512-Ma94jvuoMpbgNniwtelOt8w82hxK62FuOXZonEv0Hyk3B+/YVuLG/SWNyY9yMso/RXnPEc1fP2qo9kDrjf/b2w==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@google-cloud/common": "^5.0.0",
-        "@google-cloud/paginator": "^5.0.0",
-        "@google-cloud/projectify": "^4.0.0",
-        "@google-cloud/promisify": "^4.0.0",
-        "@opentelemetry/api": "^1.7.0",
-        "arrify": "^2.0.1",
-        "dot-prop": "^6.0.0",
-        "eventid": "^2.0.0",
-        "extend": "^3.0.2",
-        "gcp-metadata": "^6.0.0",
-        "google-auth-library": "^9.0.0",
-        "google-gax": "^4.0.3",
-        "on-finished": "^2.3.0",
-        "pumpify": "^2.0.1",
-        "stream-events": "^1.0.5",
-        "uuid": "^9.0.0"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@google-cloud/paginator": {
-      "version": "5.0.2",
-      "resolved": "https://registry.npmjs.org/@google-cloud/paginator/-/paginator-5.0.2.tgz",
-      "integrity": "sha512-DJS3s0OVH4zFDB1PzjxAsHqJT6sKVbRwwML0ZBP9PbU7Yebtu/7SWMRzvO2J3nUi9pRNITCfu4LJeooM2w4pjg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "arrify": "^2.0.0",
-        "extend": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@google-cloud/projectify": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/@google-cloud/projectify/-/projectify-4.0.0.tgz",
-      "integrity": "sha512-MmaX6HeSvyPbWGwFq7mXdo0uQZLGBYCwziiLIGq5JVX+/bdI3SAq6bP98trV5eTWfLuvsMcIC1YJOF2vfteLFA==",
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@google-cloud/promisify": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/@google-cloud/promisify/-/promisify-4.0.0.tgz",
-      "integrity": "sha512-Orxzlfb9c67A15cq2JQEyVc7wEsmFBmHjZWZYQMUyJ1qivXyMwdyNOs9odi79hze+2zqdTtu1E19IM/FtqZ10g==",
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/@google-cloud/run": {
-      "version": "1.5.0",
-      "resolved": "https://registry.npmjs.org/@google-cloud/run/-/run-1.5.0.tgz",
-      "integrity": "sha512-Ct0ZIuicd2O6fJHv7Lbwl4CcCWKK7NjACvUc4pOJVbKo75B5proOa7/9TrXVpI6oWu1n7EFx1s8xsavYHLxRAg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "google-gax": "^4.0.3"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@grpc/grpc-js": {
-      "version": "1.12.4",
-      "resolved": "https://registry.npmjs.org/@grpc/grpc-js/-/grpc-js-1.12.4.tgz",
-      "integrity": "sha512-NBhrxEWnFh0FxeA0d//YP95lRFsSx2TNLEUQg4/W+5f/BMxcCjgOOIT24iD+ZB/tZw057j44DaIxja7w4XMrhg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@grpc/proto-loader": "^0.7.13",
-        "@js-sdsl/ordered-map": "^4.4.2"
-      },
-      "engines": {
-        "node": ">=12.10.0"
-      }
-    },
-    "node_modules/@grpc/proto-loader": {
-      "version": "0.7.13",
-      "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.7.13.tgz",
-      "integrity": "sha512-AiXO/bfe9bmxBjxxtYxFAXGZvMaN5s8kO+jBHAJCON8rJoB5YS/D6X7ZNc6XQkuHNmyl4CYaMI1fJ/Gn27RGGw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "lodash.camelcase": "^4.3.0",
-        "long": "^5.0.0",
-        "protobufjs": "^7.2.5",
-        "yargs": "^17.7.2"
-      },
-      "bin": {
-        "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js"
-      },
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/@js-sdsl/ordered-map": {
-      "version": "4.4.2",
-      "resolved": "https://registry.npmjs.org/@js-sdsl/ordered-map/-/ordered-map-4.4.2.tgz",
-      "integrity": "sha512-iUKgm52T8HOE/makSxjqoWhe95ZJA1/G1sYsGev2JDKUSS14KAgg1LHb+Ba+IPow0xflbnSkOsZcO08C7w1gYw==",
-      "license": "MIT",
-      "funding": {
-        "type": "opencollective",
-        "url": "https://opencollective.com/js-sdsl"
-      }
-    },
-    "node_modules/@kwsites/file-exists": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@kwsites/file-exists/-/file-exists-1.1.1.tgz",
-      "integrity": "sha512-m9/5YGR18lIwxSFDwfE3oA7bWuq9kdau6ugN4H2rJeyhFQZcG9AgSHkQtSD15a8WvTgfz9aikZMrKPHvbpqFiw==",
-      "license": "MIT",
-      "dependencies": {
-        "debug": "^4.1.1"
-      }
-    },
-    "node_modules/@kwsites/file-exists/node_modules/debug": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
-      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/@kwsites/file-exists/node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "license": "MIT"
-    },
-    "node_modules/@kwsites/promise-deferred": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/@kwsites/promise-deferred/-/promise-deferred-1.1.1.tgz",
-      "integrity": "sha512-GaHYm+c0O9MjZRu0ongGBRbinu8gVAMd2UZjji6jVmqKtZluZnptXGWhz1E8j8D2HJ3f/yMxKAUC0b+57wncIw==",
-      "license": "MIT"
-    },
-    "node_modules/@opentelemetry/api": {
-      "version": "1.9.0",
-      "resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.0.tgz",
-      "integrity": "sha512-3giAOQvZiH5F9bMlMiv8+GSPMeqg0dbaeo58/0SlA9sxSqZhnUtxzX9/2FzyhS9sWQf5S0GJE0AKBrFqjpeYcg==",
-      "license": "Apache-2.0",
-      "engines": {
-        "node": ">=8.0.0"
-      }
-    },
-    "node_modules/@protobufjs/aspromise": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz",
-      "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/@protobufjs/base64": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz",
-      "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/@protobufjs/codegen": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz",
-      "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/@protobufjs/eventemitter": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz",
-      "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/@protobufjs/fetch": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz",
-      "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==",
-      "license": "BSD-3-Clause",
-      "dependencies": {
-        "@protobufjs/aspromise": "^1.1.1",
-        "@protobufjs/inquire": "^1.1.0"
-      }
-    },
-    "node_modules/@protobufjs/float": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz",
-      "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/@protobufjs/inquire": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz",
-      "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/@protobufjs/path": {
-      "version": "1.1.2",
-      "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz",
-      "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/@protobufjs/pool": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz",
-      "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/@protobufjs/utf8": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz",
-      "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/@smithy/abort-controller": {
-      "version": "3.1.9",
-      "resolved": "https://registry.npmjs.org/@smithy/abort-controller/-/abort-controller-3.1.9.tgz",
-      "integrity": "sha512-yiW0WI30zj8ZKoSYNx90no7ugVn3khlyH/z5W8qtKBtVE6awRALbhSG+2SAHA1r6bO/6M9utxYKVZ3PCJ1rWxw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/config-resolver": {
-      "version": "3.0.13",
-      "resolved": "https://registry.npmjs.org/@smithy/config-resolver/-/config-resolver-3.0.13.tgz",
-      "integrity": "sha512-Gr/qwzyPaTL1tZcq8WQyHhTZREER5R1Wytmz4WnVGL4onA3dNk6Btll55c8Vr58pLdvWZmtG8oZxJTw3t3q7Jg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/node-config-provider": "^3.1.12",
-        "@smithy/types": "^3.7.2",
-        "@smithy/util-config-provider": "^3.0.0",
-        "@smithy/util-middleware": "^3.0.11",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/core": {
-      "version": "2.5.5",
-      "resolved": "https://registry.npmjs.org/@smithy/core/-/core-2.5.5.tgz",
-      "integrity": "sha512-G8G/sDDhXA7o0bOvkc7bgai6POuSld/+XhNnWAbpQTpLv2OZPvyqQ58tLPPlz0bSNsXktldDDREIv1LczFeNEw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/middleware-serde": "^3.0.11",
-        "@smithy/protocol-http": "^4.1.8",
-        "@smithy/types": "^3.7.2",
-        "@smithy/util-body-length-browser": "^3.0.0",
-        "@smithy/util-middleware": "^3.0.11",
-        "@smithy/util-stream": "^3.3.2",
-        "@smithy/util-utf8": "^3.0.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/credential-provider-imds": {
-      "version": "3.2.8",
-      "resolved": "https://registry.npmjs.org/@smithy/credential-provider-imds/-/credential-provider-imds-3.2.8.tgz",
-      "integrity": "sha512-ZCY2yD0BY+K9iMXkkbnjo+08T2h8/34oHd0Jmh6BZUSZwaaGlGCyBT/3wnS7u7Xl33/EEfN4B6nQr3Gx5bYxgw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/node-config-provider": "^3.1.12",
-        "@smithy/property-provider": "^3.1.11",
-        "@smithy/types": "^3.7.2",
-        "@smithy/url-parser": "^3.0.11",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/credential-provider-imds/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/eventstream-codec": {
-      "version": "3.1.10",
-      "resolved": "https://registry.npmjs.org/@smithy/eventstream-codec/-/eventstream-codec-3.1.10.tgz",
-      "integrity": "sha512-323B8YckSbUH0nMIpXn7HZsAVKHYHFUODa8gG9cHo0ySvA1fr5iWaNT+iIL0UCqUzG6QPHA3BSsBtRQou4mMqQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@aws-crypto/crc32": "5.2.0",
-        "@smithy/types": "^3.7.2",
-        "@smithy/util-hex-encoding": "^3.0.0",
-        "tslib": "^2.6.2"
-      }
-    },
-    "node_modules/@smithy/eventstream-serde-browser": {
-      "version": "3.0.14",
-      "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-browser/-/eventstream-serde-browser-3.0.14.tgz",
-      "integrity": "sha512-kbrt0vjOIihW3V7Cqj1SXQvAI5BR8SnyQYsandva0AOR307cXAc+IhPngxIPslxTLfxwDpNu0HzCAq6g42kCPg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/eventstream-serde-universal": "^3.0.13",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/eventstream-serde-config-resolver": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-config-resolver/-/eventstream-serde-config-resolver-3.0.11.tgz",
-      "integrity": "sha512-P2pnEp4n75O+QHjyO7cbw/vsw5l93K/8EWyjNCAAybYwUmj3M+hjSQZ9P5TVdUgEG08ueMAP5R4FkuSkElZ5tQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/eventstream-serde-node": {
-      "version": "3.0.13",
-      "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-node/-/eventstream-serde-node-3.0.13.tgz",
-      "integrity": "sha512-zqy/9iwbj8Wysmvi7Lq7XFLeDgjRpTbCfwBhJa8WbrylTAHiAu6oQTwdY7iu2lxigbc9YYr9vPv5SzYny5tCXQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/eventstream-serde-universal": "^3.0.13",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/eventstream-serde-universal": {
-      "version": "3.0.13",
-      "resolved": "https://registry.npmjs.org/@smithy/eventstream-serde-universal/-/eventstream-serde-universal-3.0.13.tgz",
-      "integrity": "sha512-L1Ib66+gg9uTnqp/18Gz4MDpJPKRE44geOjOQ2SVc0eiaO5l255ADziATZgjQjqumC7yPtp1XnjHlF1srcwjKw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/eventstream-codec": "^3.1.10",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/fetch-http-handler": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/@smithy/fetch-http-handler/-/fetch-http-handler-4.1.2.tgz",
-      "integrity": "sha512-R7rU7Ae3ItU4rC0c5mB2sP5mJNbCfoDc8I5XlYjIZnquyUwec7fEo78F6DA3SmgJgkU1qTMcZJuGblxZsl10ZA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/protocol-http": "^4.1.8",
-        "@smithy/querystring-builder": "^3.0.11",
-        "@smithy/types": "^3.7.2",
-        "@smithy/util-base64": "^3.0.0",
-        "tslib": "^2.6.2"
-      }
-    },
-    "node_modules/@smithy/hash-node": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/hash-node/-/hash-node-3.0.11.tgz",
-      "integrity": "sha512-emP23rwYyZhQBvklqTtwetkQlqbNYirDiEEwXl2v0GYWMnCzxst7ZaRAnWuy28njp5kAH54lvkdG37MblZzaHA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "@smithy/util-buffer-from": "^3.0.0",
-        "@smithy/util-utf8": "^3.0.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/invalid-dependency": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/invalid-dependency/-/invalid-dependency-3.0.11.tgz",
-      "integrity": "sha512-NuQmVPEJjUX6c+UELyVz8kUx8Q539EDeNwbRyu4IIF8MeV7hUtq1FB3SHVyki2u++5XLMFqngeMKk7ccspnNyQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      }
-    },
-    "node_modules/@smithy/is-array-buffer": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@smithy/is-array-buffer/-/is-array-buffer-3.0.0.tgz",
-      "integrity": "sha512-+Fsu6Q6C4RSJiy81Y8eApjEB5gVtM+oFKTffg+jSuwtvomJJrhUJBu2zS8wjXSgH/g1MKEWrzyChTBe6clb5FQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/middleware-content-length": {
-      "version": "3.0.13",
-      "resolved": "https://registry.npmjs.org/@smithy/middleware-content-length/-/middleware-content-length-3.0.13.tgz",
-      "integrity": "sha512-zfMhzojhFpIX3P5ug7jxTjfUcIPcGjcQYzB9t+rv0g1TX7B0QdwONW+ATouaLoD7h7LOw/ZlXfkq4xJ/g2TrIw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/protocol-http": "^4.1.8",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/middleware-endpoint": {
-      "version": "3.2.5",
-      "resolved": "https://registry.npmjs.org/@smithy/middleware-endpoint/-/middleware-endpoint-3.2.5.tgz",
-      "integrity": "sha512-VhJNs/s/lyx4weiZdXSloBgoLoS8osV0dKIain8nGmx7of3QFKu5BSdEuk1z/U8x9iwes1i+XCiNusEvuK1ijg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/core": "^2.5.5",
-        "@smithy/middleware-serde": "^3.0.11",
-        "@smithy/node-config-provider": "^3.1.12",
-        "@smithy/shared-ini-file-loader": "^3.1.12",
-        "@smithy/types": "^3.7.2",
-        "@smithy/url-parser": "^3.0.11",
-        "@smithy/util-middleware": "^3.0.11",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/middleware-retry": {
-      "version": "3.0.29",
-      "resolved": "https://registry.npmjs.org/@smithy/middleware-retry/-/middleware-retry-3.0.29.tgz",
-      "integrity": "sha512-/FfI/N2tIVCG9escHYLLABJlNHbO1gWFSdMlvbPOTV+Y+Aa8Q1FuS7Yaghb8NUfFmGYjkbeIu3bnbta6KbarsA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/node-config-provider": "^3.1.12",
-        "@smithy/protocol-http": "^4.1.8",
-        "@smithy/service-error-classification": "^3.0.11",
-        "@smithy/smithy-client": "^3.4.6",
-        "@smithy/types": "^3.7.2",
-        "@smithy/util-middleware": "^3.0.11",
-        "@smithy/util-retry": "^3.0.11",
-        "tslib": "^2.6.2",
-        "uuid": "^9.0.1"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/middleware-retry/node_modules/@smithy/util-retry": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-3.0.11.tgz",
-      "integrity": "sha512-hJUC6W7A3DQgaee3Hp9ZFcOxVDZzmBIRBPlUAk8/fSOEl7pE/aX7Dci0JycNOnm9Mfr0KV2XjIlUOcGWXQUdVQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/service-error-classification": "^3.0.11",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/middleware-serde": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/middleware-serde/-/middleware-serde-3.0.11.tgz",
-      "integrity": "sha512-KzPAeySp/fOoQA82TpnwItvX8BBURecpx6ZMu75EZDkAcnPtO6vf7q4aH5QHs/F1s3/snQaSFbbUMcFFZ086Mw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/middleware-stack": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/middleware-stack/-/middleware-stack-3.0.11.tgz",
-      "integrity": "sha512-1HGo9a6/ikgOMrTrWL/WiN9N8GSVYpuRQO5kjstAq4CvV59bjqnh7TbdXGQ4vxLD3xlSjfBjq5t1SOELePsLnA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/node-config-provider": {
-      "version": "3.1.12",
-      "resolved": "https://registry.npmjs.org/@smithy/node-config-provider/-/node-config-provider-3.1.12.tgz",
-      "integrity": "sha512-O9LVEu5J/u/FuNlZs+L7Ikn3lz7VB9hb0GtPT9MQeiBmtK8RSY3ULmsZgXhe6VAlgTw0YO+paQx4p8xdbs43vQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/property-provider": "^3.1.11",
-        "@smithy/shared-ini-file-loader": "^3.1.12",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/node-config-provider/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/node-http-handler": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/@smithy/node-http-handler/-/node-http-handler-3.3.2.tgz",
-      "integrity": "sha512-t4ng1DAd527vlxvOfKFYEe6/QFBcsj7WpNlWTyjorwXXcKw3XlltBGbyHfSJ24QT84nF+agDha9tNYpzmSRZPA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/abort-controller": "^3.1.9",
-        "@smithy/protocol-http": "^4.1.8",
-        "@smithy/querystring-builder": "^3.0.11",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/property-provider": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-2.2.0.tgz",
-      "integrity": "sha512-+xiil2lFhtTRzXkx8F053AV46QnIw6e7MV8od5Mi68E1ICOjCeCHw2XfLnDEUHnT9WGUIkwcqavXjfwuJbGlpg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^2.12.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@smithy/property-provider/node_modules/@smithy/types": {
-      "version": "2.12.0",
-      "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz",
-      "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@smithy/protocol-http": {
-      "version": "4.1.8",
-      "resolved": "https://registry.npmjs.org/@smithy/protocol-http/-/protocol-http-4.1.8.tgz",
-      "integrity": "sha512-hmgIAVyxw1LySOwkgMIUN0kjN8TG9Nc85LJeEmEE/cNEe2rkHDUWhnJf2gxcSRFLWsyqWsrZGw40ROjUogg+Iw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/querystring-builder": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/querystring-builder/-/querystring-builder-3.0.11.tgz",
-      "integrity": "sha512-u+5HV/9uJaeLj5XTb6+IEF/dokWWkEqJ0XiaRRogyREmKGUgZnNecLucADLdauWFKUNbQfulHFEZEdjwEBjXRg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "@smithy/util-uri-escape": "^3.0.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/querystring-parser": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/querystring-parser/-/querystring-parser-3.0.11.tgz",
-      "integrity": "sha512-Je3kFvCsFMnso1ilPwA7GtlbPaTixa3WwC+K21kmMZHsBEOZYQaqxcMqeFFoU7/slFjKDIpiiPydvdJm8Q/MCw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/service-error-classification": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-3.0.11.tgz",
-      "integrity": "sha512-QnYDPkyewrJzCyaeI2Rmp7pDwbUETe+hU8ADkXmgNusO1bgHBH7ovXJiYmba8t0fNfJx75fE8dlM6SEmZxheog==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/shared-ini-file-loader": {
-      "version": "3.1.12",
-      "resolved": "https://registry.npmjs.org/@smithy/shared-ini-file-loader/-/shared-ini-file-loader-3.1.12.tgz",
-      "integrity": "sha512-1xKSGI+U9KKdbG2qDvIR9dGrw3CNx+baqJfyr0igKEpjbHL5stsqAesYBzHChYHlelWtb87VnLWlhvfCz13H8Q==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/signature-v4": {
-      "version": "4.2.4",
-      "resolved": "https://registry.npmjs.org/@smithy/signature-v4/-/signature-v4-4.2.4.tgz",
-      "integrity": "sha512-5JWeMQYg81TgU4cG+OexAWdvDTs5JDdbEZx+Qr1iPbvo91QFGzjy0IkXAKaXUHqmKUJgSHK0ZxnCkgZpzkeNTA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/is-array-buffer": "^3.0.0",
-        "@smithy/protocol-http": "^4.1.8",
-        "@smithy/types": "^3.7.2",
-        "@smithy/util-hex-encoding": "^3.0.0",
-        "@smithy/util-middleware": "^3.0.11",
-        "@smithy/util-uri-escape": "^3.0.0",
-        "@smithy/util-utf8": "^3.0.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/smithy-client": {
-      "version": "3.4.6",
-      "resolved": "https://registry.npmjs.org/@smithy/smithy-client/-/smithy-client-3.4.6.tgz",
-      "integrity": "sha512-j/WYdfzdx4asqb0YZch1rb6Y5OQcuTdXY7xnEMtc05diB5jfLQQtys9J/2lzmGKri9m9mUBrcnNTv3jbXvtk7A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/core": "^2.5.5",
-        "@smithy/middleware-endpoint": "^3.2.5",
-        "@smithy/middleware-stack": "^3.0.11",
-        "@smithy/protocol-http": "^4.1.8",
-        "@smithy/types": "^3.7.2",
-        "@smithy/util-stream": "^3.3.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/types": {
-      "version": "3.7.2",
-      "resolved": "https://registry.npmjs.org/@smithy/types/-/types-3.7.2.tgz",
-      "integrity": "sha512-bNwBYYmN8Eh9RyjS1p2gW6MIhSO2rl7X9QeLM8iTdcGRP+eDiIWDt66c9IysCc22gefKszZv+ubV9qZc7hdESg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/url-parser": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/url-parser/-/url-parser-3.0.11.tgz",
-      "integrity": "sha512-TmlqXkSk8ZPhfc+SQutjmFr5FjC0av3GZP4B/10caK1SbRwe/v+Wzu/R6xEKxoNqL+8nY18s1byiy6HqPG37Aw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/querystring-parser": "^3.0.11",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      }
-    },
-    "node_modules/@smithy/util-base64": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-base64/-/util-base64-3.0.0.tgz",
-      "integrity": "sha512-Kxvoh5Qtt0CDsfajiZOCpJxgtPHXOKwmM+Zy4waD43UoEMA+qPxxa98aE/7ZhdnBFZFXMOiBR5xbcaMhLtznQQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/util-buffer-from": "^3.0.0",
-        "@smithy/util-utf8": "^3.0.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/util-body-length-browser": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-body-length-browser/-/util-body-length-browser-3.0.0.tgz",
-      "integrity": "sha512-cbjJs2A1mLYmqmyVl80uoLTJhAcfzMOyPgjwAYusWKMdLeNtzmMz9YxNl3/jRLoxSS3wkqkf0jwNdtXWtyEBaQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^2.6.2"
-      }
-    },
-    "node_modules/@smithy/util-body-length-node": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-body-length-node/-/util-body-length-node-3.0.0.tgz",
-      "integrity": "sha512-Tj7pZ4bUloNUP6PzwhN7K386tmSmEET9QtQg0TgdNOnxhZvCssHji+oZTUIuzxECRfG8rdm2PMw2WCFs6eIYkA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/util-buffer-from": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-buffer-from/-/util-buffer-from-3.0.0.tgz",
-      "integrity": "sha512-aEOHCgq5RWFbP+UDPvPot26EJHjOC+bRgse5A8V3FSShqd5E5UN4qc7zkwsvJPPAVsf73QwYcHN1/gt/rtLwQA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/is-array-buffer": "^3.0.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/util-config-provider": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-config-provider/-/util-config-provider-3.0.0.tgz",
-      "integrity": "sha512-pbjk4s0fwq3Di/ANL+rCvJMKM5bzAQdE5S/6RL5NXgMExFAi6UgQMPOm5yPaIWPpr+EOXKXRonJ3FoxKf4mCJQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/util-defaults-mode-browser": {
-      "version": "3.0.29",
-      "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-browser/-/util-defaults-mode-browser-3.0.29.tgz",
-      "integrity": "sha512-7k0kOfDjnSM44GG74UnjEixtHmtF/do6pCNEvp1DQlFjktEz8pv06p9RSjxp2J3Lv6I3+Ba9FLfurpFeBv+Pvw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/property-provider": "^3.1.11",
-        "@smithy/smithy-client": "^3.4.6",
-        "@smithy/types": "^3.7.2",
-        "bowser": "^2.11.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/@smithy/util-defaults-mode-browser/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/util-defaults-mode-node": {
-      "version": "3.0.29",
-      "resolved": "https://registry.npmjs.org/@smithy/util-defaults-mode-node/-/util-defaults-mode-node-3.0.29.tgz",
-      "integrity": "sha512-lu8jaXAt1TIVkTAKMuGdZwWQ1L03iV/n8WPbY5hdjcNqLg2ysp5DqiINmtuLL8EgzDv1TXvKDaBAN+9bGH4sEQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/config-resolver": "^3.0.13",
-        "@smithy/credential-provider-imds": "^3.2.8",
-        "@smithy/node-config-provider": "^3.1.12",
-        "@smithy/property-provider": "^3.1.11",
-        "@smithy/smithy-client": "^3.4.6",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">= 10.0.0"
-      }
-    },
-    "node_modules/@smithy/util-defaults-mode-node/node_modules/@smithy/property-provider": {
-      "version": "3.1.11",
-      "resolved": "https://registry.npmjs.org/@smithy/property-provider/-/property-provider-3.1.11.tgz",
-      "integrity": "sha512-I/+TMc4XTQ3QAjXfOcUWbSS073oOEAxgx4aZy8jHaf8JQnRkq2SZWw8+PfDtBvLUjcGMdxl+YwtzWe6i5uhL/A==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/util-endpoints": {
-      "version": "2.1.7",
-      "resolved": "https://registry.npmjs.org/@smithy/util-endpoints/-/util-endpoints-2.1.7.tgz",
-      "integrity": "sha512-tSfcqKcN/Oo2STEYCABVuKgJ76nyyr6skGl9t15hs+YaiU06sgMkN7QYjo0BbVw+KT26zok3IzbdSOksQ4YzVw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/node-config-provider": "^3.1.12",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/util-hex-encoding": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-hex-encoding/-/util-hex-encoding-3.0.0.tgz",
-      "integrity": "sha512-eFndh1WEK5YMUYvy3lPlVmYY/fZcQE1D8oSf41Id2vCeIkKJXPcYDCZD+4+xViI6b1XSd7tE+s5AmXzz5ilabQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/util-middleware": {
-      "version": "3.0.11",
-      "resolved": "https://registry.npmjs.org/@smithy/util-middleware/-/util-middleware-3.0.11.tgz",
-      "integrity": "sha512-dWpyc1e1R6VoXrwLoLDd57U1z6CwNSdkM69Ie4+6uYh2GC7Vg51Qtan7ITzczuVpqezdDTKJGJB95fFvvjU/ow==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/util-retry": {
-      "version": "2.2.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-retry/-/util-retry-2.2.0.tgz",
-      "integrity": "sha512-q9+pAFPTfftHXRytmZ7GzLFFrEGavqapFc06XxzZFcSIGERXMerXxCitjOG1prVDR9QdjqotF40SWvbqcCpf8g==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/service-error-classification": "^2.1.5",
-        "@smithy/types": "^2.12.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">= 14.0.0"
-      }
-    },
-    "node_modules/@smithy/util-retry/node_modules/@smithy/service-error-classification": {
-      "version": "2.1.5",
-      "resolved": "https://registry.npmjs.org/@smithy/service-error-classification/-/service-error-classification-2.1.5.tgz",
-      "integrity": "sha512-uBDTIBBEdAQryvHdc5W8sS5YX7RQzF683XrHePVdFmAgKiMofU15FLSM0/HU03hKTnazdNRFa0YHS7+ArwoUSQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/types": "^2.12.0"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@smithy/util-retry/node_modules/@smithy/types": {
-      "version": "2.12.0",
-      "resolved": "https://registry.npmjs.org/@smithy/types/-/types-2.12.0.tgz",
-      "integrity": "sha512-QwYgloJ0sVNBeBuBs65cIkTbfzV/Q6ZNPCJ99EICFEdJYG50nGIY/uYXp+TbsdJReIuPr0a0kXmCvren3MbRRw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/@smithy/util-stream": {
-      "version": "3.3.2",
-      "resolved": "https://registry.npmjs.org/@smithy/util-stream/-/util-stream-3.3.2.tgz",
-      "integrity": "sha512-sInAqdiVeisUGYAv/FrXpmJ0b4WTFmciTRqzhb7wVuem9BHvhIG7tpiYHLDWrl2stOokNZpTTGqz3mzB2qFwXg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/fetch-http-handler": "^4.1.2",
-        "@smithy/node-http-handler": "^3.3.2",
-        "@smithy/types": "^3.7.2",
-        "@smithy/util-base64": "^3.0.0",
-        "@smithy/util-buffer-from": "^3.0.0",
-        "@smithy/util-hex-encoding": "^3.0.0",
-        "@smithy/util-utf8": "^3.0.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/util-uri-escape": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-uri-escape/-/util-uri-escape-3.0.0.tgz",
-      "integrity": "sha512-LqR7qYLgZTD7nWLBecUi4aqolw8Mhza9ArpNEQ881MJJIU2sE5iHCK6TdyqqzcDLy0OPe10IY4T8ctVdtynubg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/util-utf8": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-utf8/-/util-utf8-3.0.0.tgz",
-      "integrity": "sha512-rUeT12bxFnplYDe815GXbq/oixEGHfRFFtcTF3YdDi/JaENIM6aSYYLJydG83UNzLXeRI5K8abYd/8Sp/QM0kA==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/util-buffer-from": "^3.0.0",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@smithy/util-waiter": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/@smithy/util-waiter/-/util-waiter-3.2.0.tgz",
-      "integrity": "sha512-PpjSboaDUE6yl+1qlg3Si57++e84oXdWGbuFUSAciXsVfEZJJJupR2Nb0QuXHiunt2vGR+1PTizOMvnUPaG2Qg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@smithy/abort-controller": "^3.1.9",
-        "@smithy/types": "^3.7.2",
-        "tslib": "^2.6.2"
-      },
-      "engines": {
-        "node": ">=16.0.0"
-      }
-    },
-    "node_modules/@tootallnate/once": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz",
-      "integrity": "sha512-XCuKFP5PS55gnMVu3dty8KPatLqUoy/ZYzDzAGCQ8JNFCkLXzmI7vNHCR+XpbZaMWQK/vQubr7PkYq8g470J/A==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/@tootallnate/quickjs-emscripten": {
-      "version": "0.23.0",
-      "resolved": "https://registry.npmjs.org/@tootallnate/quickjs-emscripten/-/quickjs-emscripten-0.23.0.tgz",
-      "integrity": "sha512-C5Mc6rdnsaJDjO3UpGW/CQTHtCKaYlScZTly4JIu97Jxo/odCiH0ITnDXSJPTOrEKk/ycSZ0AOgTmkDtkOsvIA==",
-      "license": "MIT"
-    },
-    "node_modules/@types/caseless": {
-      "version": "0.12.5",
-      "resolved": "https://registry.npmjs.org/@types/caseless/-/caseless-0.12.5.tgz",
-      "integrity": "sha512-hWtVTC2q7hc7xZ/RLbxapMvDMgUnDvKvMOpKal4DrMyfGBUfB1oKaZlIRr6mJL+If3bAP6sV/QneGzF6tJjZDg==",
-      "license": "MIT"
-    },
-    "node_modules/@types/datadog-metrics": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/@types/datadog-metrics/-/datadog-metrics-0.6.1.tgz",
-      "integrity": "sha512-p6zVpfmNcXwtcXjgpz7do/fKyfndGhU5sGJVtb5Gn5PvLDiQUAgD0mI/itf/99sBi9DRxeyhFQ9dQF6OxxQNbA==",
-      "license": "MIT"
-    },
-    "node_modules/@types/long": {
-      "version": "4.0.2",
-      "resolved": "https://registry.npmjs.org/@types/long/-/long-4.0.2.tgz",
-      "integrity": "sha512-MqTGEo5bj5t157U6fA/BiDynNkn0YknVdh48CMPkTSpFTVmvao5UQmm7uEF6xBEo7qIMAlY/JSleYaE6VOdpaA==",
-      "license": "MIT"
-    },
-    "node_modules/@types/node": {
-      "version": "22.10.1",
-      "resolved": "https://registry.npmjs.org/@types/node/-/node-22.10.1.tgz",
-      "integrity": "sha512-qKgsUwfHZV2WCWLAnVP1JqnpE6Im6h3Y0+fYgMTasNQ7V++CBX5OT1as0g0f+OyubbFqhf6XVNIsmN4IIhEgGQ==",
-      "license": "MIT",
-      "dependencies": {
-        "undici-types": "~6.20.0"
-      }
-    },
-    "node_modules/@types/request": {
-      "version": "2.48.12",
-      "resolved": "https://registry.npmjs.org/@types/request/-/request-2.48.12.tgz",
-      "integrity": "sha512-G3sY+NpsA9jnwm0ixhAFQSJ3Q9JkpLZpJbI3GMv0mIAT0y3mRabYeINzal5WOChIiaTEGQYlHOKgkaM9EisWHw==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/caseless": "*",
-        "@types/node": "*",
-        "@types/tough-cookie": "*",
-        "form-data": "^2.5.0"
-      }
-    },
-    "node_modules/@types/request/node_modules/form-data": {
-      "version": "2.5.2",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.5.2.tgz",
-      "integrity": "sha512-GgwY0PS7DbXqajuGf4OYlsrIu3zgxD6Vvql43IBhm6MahqA5SK/7mwhtNj2AdH2z35YR34ujJ7BN+3fFC3jP5Q==",
-      "license": "MIT",
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.6",
-        "mime-types": "^2.1.12",
-        "safe-buffer": "^5.2.1"
-      },
-      "engines": {
-        "node": ">= 0.12"
-      }
-    },
-    "node_modules/@types/tough-cookie": {
-      "version": "4.0.5",
-      "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.5.tgz",
-      "integrity": "sha512-/Ad8+nIOV7Rl++6f1BdKxFSMgmoqEoYbHRpPcx3JEfv8VRsQe9Z4mCXeJBzxs7mbHY/XOZZuXlRNfhpVPbs6ZA==",
-      "license": "MIT"
-    },
-    "node_modules/@types/uuid": {
-      "version": "9.0.8",
-      "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz",
-      "integrity": "sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==",
-      "license": "MIT"
-    },
-    "node_modules/abort-controller": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
-      "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
-      "license": "MIT",
-      "dependencies": {
-        "event-target-shim": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=6.5"
-      }
-    },
-    "node_modules/agent-base": {
-      "version": "7.1.3",
-      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
-      "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/ajv": {
-      "version": "8.17.1",
-      "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
-      "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==",
-      "license": "MIT",
-      "dependencies": {
-        "fast-deep-equal": "^3.1.3",
-        "fast-uri": "^3.0.1",
-        "json-schema-traverse": "^1.0.0",
-        "require-from-string": "^2.0.2"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/sponsors/epoberezkin"
-      }
-    },
-    "node_modules/ajv-formats": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
-      "integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
-      "license": "MIT",
-      "dependencies": {
-        "ajv": "^8.0.0"
-      },
-      "peerDependencies": {
-        "ajv": "^8.0.0"
-      },
-      "peerDependenciesMeta": {
-        "ajv": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/ansi-escapes": {
-      "version": "4.3.2",
-      "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-4.3.2.tgz",
-      "integrity": "sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==",
-      "license": "MIT",
-      "dependencies": {
-        "type-fest": "^0.21.3"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/ansi-regex": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-      "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/ansi-styles": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-      "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
-      "license": "MIT",
-      "dependencies": {
-        "color-convert": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/ansi-styles?sponsor=1"
-      }
-    },
-    "node_modules/argparse": {
-      "version": "1.0.10",
-      "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
-      "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
-      "license": "MIT",
-      "dependencies": {
-        "sprintf-js": "~1.0.2"
-      }
-    },
-    "node_modules/arrify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/arrify/-/arrify-2.0.1.tgz",
-      "integrity": "sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/asn1": {
-      "version": "0.2.6",
-      "resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.6.tgz",
-      "integrity": "sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==",
-      "license": "MIT",
-      "dependencies": {
-        "safer-buffer": "~2.1.0"
-      }
-    },
-    "node_modules/assert-plus": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
-      "integrity": "sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
-    "node_modules/ast-types": {
-      "version": "0.13.4",
-      "resolved": "https://registry.npmjs.org/ast-types/-/ast-types-0.13.4.tgz",
-      "integrity": "sha512-x1FCFnFifvYDDzTaLII71vG5uvDwgtmDTEVWAxrgeiR8VjMONcCXJx7E+USjDtHlwFmt9MysbqgF9b9Vjr6w+w==",
-      "license": "MIT",
-      "dependencies": {
-        "tslib": "^2.0.1"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/async-retry": {
-      "version": "1.3.1",
-      "resolved": "https://registry.npmjs.org/async-retry/-/async-retry-1.3.1.tgz",
-      "integrity": "sha512-aiieFW/7h3hY0Bq5d+ktDBejxuwR78vRu9hDUdR8rNhSaQ29VzPL4AoIRG7D/c7tdenwOcKvgPM6tIxB3cB6HA==",
-      "license": "MIT",
-      "dependencies": {
-        "retry": "0.12.0"
-      }
-    },
-    "node_modules/asynckit": {
-      "version": "0.4.0",
-      "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
-      "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
-      "license": "MIT"
-    },
-    "node_modules/axios": {
-      "version": "1.7.9",
-      "resolved": "https://registry.npmjs.org/axios/-/axios-1.7.9.tgz",
-      "integrity": "sha512-LhLcE7Hbiryz8oMDdDptSrWowmB4Bl6RCt6sIJKpRB4XtVf0iEgewX3au/pJqm+Py1kCASkb/FFKjxQaLtxJvw==",
-      "license": "MIT",
-      "dependencies": {
-        "follow-redirects": "^1.15.6",
-        "form-data": "^4.0.0",
-        "proxy-from-env": "^1.1.0"
-      }
-    },
-    "node_modules/balanced-match": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-      "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
-      "license": "MIT"
-    },
-    "node_modules/base64-js": {
-      "version": "1.5.1",
-      "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz",
-      "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "license": "MIT"
-    },
-    "node_modules/basic-ftp": {
-      "version": "5.0.5",
-      "resolved": "https://registry.npmjs.org/basic-ftp/-/basic-ftp-5.0.5.tgz",
-      "integrity": "sha512-4Bcg1P8xhUuqcii/S0Z9wiHIrQVPMermM1any+MX5GeGD7faD3/msQUDGLol9wOcz4/jbg/WJnGqoJF6LiBdtg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
-    "node_modules/bcrypt-pbkdf": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
-      "integrity": "sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==",
-      "license": "BSD-3-Clause",
-      "dependencies": {
-        "tweetnacl": "^0.14.3"
-      }
-    },
-    "node_modules/bignumber.js": {
-      "version": "9.1.2",
-      "resolved": "https://registry.npmjs.org/bignumber.js/-/bignumber.js-9.1.2.tgz",
-      "integrity": "sha512-2/mKyZH9K85bzOEfhXDBFZTGd1CTs+5IHpeFQo9luiBG7hghdC851Pj2WAhb6E3R6b9tZj/XKhbg4fum+Kepug==",
-      "license": "MIT",
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/bl": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
-      "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
-      "license": "MIT",
-      "dependencies": {
-        "buffer": "^5.5.0",
-        "inherits": "^2.0.4",
-        "readable-stream": "^3.4.0"
-      }
-    },
-    "node_modules/bowser": {
-      "version": "2.11.0",
-      "resolved": "https://registry.npmjs.org/bowser/-/bowser-2.11.0.tgz",
-      "integrity": "sha512-AlcaJBi/pqqJBIQ8U9Mcpc9i8Aqxn88Skv5d+xBX006BY5u8N3mGLHa5Lgppa7L/HfwgwLgZ6NYs+Ag6uUmJRA==",
-      "license": "MIT"
-    },
-    "node_modules/brace-expansion": {
-      "version": "1.1.11",
-      "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-      "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "license": "MIT",
-      "dependencies": {
-        "balanced-match": "^1.0.0",
-        "concat-map": "0.0.1"
-      }
-    },
-    "node_modules/buffer": {
-      "version": "5.7.1",
-      "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
-      "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "base64-js": "^1.3.1",
-        "ieee754": "^1.1.13"
-      }
-    },
-    "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==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/buildcheck": {
-      "version": "0.0.6",
-      "resolved": "https://registry.npmjs.org/buildcheck/-/buildcheck-0.0.6.tgz",
-      "integrity": "sha512-8f9ZJCUXyT1M35Jx7MkBgmBMo3oHTTBIPLiY9xyL0pl3T5RwcPEY8cUHr5LBNfu/fk6c2T4DJZuVM/8ZZT2D2A==",
-      "optional": true,
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
-    "node_modules/chalk": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz",
-      "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/chardet": {
-      "version": "0.7.0",
-      "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz",
-      "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==",
-      "license": "MIT"
-    },
-    "node_modules/cli-cursor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz",
-      "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==",
-      "license": "MIT",
-      "dependencies": {
-        "restore-cursor": "^3.1.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/cli-spinners": {
-      "version": "2.9.2",
-      "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
-      "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/cli-width": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz",
-      "integrity": "sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==",
-      "license": "ISC",
-      "engines": {
-        "node": ">= 10"
-      }
-    },
-    "node_modules/clipanion": {
-      "version": "3.2.1",
-      "resolved": "https://registry.npmjs.org/clipanion/-/clipanion-3.2.1.tgz",
-      "integrity": "sha512-dYFdjLb7y1ajfxQopN05mylEpK9ZX0sO1/RfMXdfmwjlIsPkbh4p7A682x++zFPLDCo1x3p82dtljHf5cW2LKA==",
-      "license": "MIT",
-      "workspaces": [
-        "website"
-      ],
-      "dependencies": {
-        "typanion": "^3.8.0"
-      },
-      "peerDependencies": {
-        "typanion": "*"
-      }
-    },
-    "node_modules/cliui": {
-      "version": "8.0.1",
-      "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
-      "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
-      "license": "ISC",
-      "dependencies": {
-        "string-width": "^4.2.0",
-        "strip-ansi": "^6.0.1",
-        "wrap-ansi": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/cliui/node_modules/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==",
-      "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/clone": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz",
-      "integrity": "sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.8"
-      }
-    },
-    "node_modules/color-convert": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
-      "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
-      "license": "MIT",
-      "dependencies": {
-        "color-name": "~1.1.4"
-      },
-      "engines": {
-        "node": ">=7.0.0"
-      }
-    },
-    "node_modules/color-name": {
-      "version": "1.1.4",
-      "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-      "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
-      "license": "MIT"
-    },
-    "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==",
-      "license": "MIT",
-      "dependencies": {
-        "delayed-stream": "~1.0.0"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/concat-map": {
-      "version": "0.0.1",
-      "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
-      "license": "MIT"
-    },
-    "node_modules/core-util-is": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
-      "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
-      "license": "MIT"
-    },
-    "node_modules/cpu-features": {
-      "version": "0.0.10",
-      "resolved": "https://registry.npmjs.org/cpu-features/-/cpu-features-0.0.10.tgz",
-      "integrity": "sha512-9IkYqtX3YHPCzoVg1Py+o9057a3i0fp7S530UWokCSaFVTc7CwXPRiOjRjBQQ18ZCNafx78YfnG+HALxtVmOGA==",
-      "hasInstallScript": true,
-      "optional": true,
-      "dependencies": {
-        "buildcheck": "~0.0.6",
-        "nan": "^2.19.0"
-      },
-      "engines": {
-        "node": ">=10.0.0"
-      }
-    },
-    "node_modules/dashdash": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
-      "integrity": "sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==",
-      "license": "MIT",
-      "dependencies": {
-        "assert-plus": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=0.10"
-      }
-    },
-    "node_modules/data-uri-to-buffer": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-6.0.2.tgz",
-      "integrity": "sha512-7hvf7/GW8e86rW0ptuwS3OcBGDjIi6SZva7hCyWC0yYry2cOPmLIjXAUHI6DK2HsnwJd9ifmt57i8eV2n4YNpw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/datadog-metrics": {
-      "version": "0.9.3",
-      "resolved": "https://registry.npmjs.org/datadog-metrics/-/datadog-metrics-0.9.3.tgz",
-      "integrity": "sha512-BVsBX2t+4yA3tHs7DnB5H01cHVNiGJ/bHA8y6JppJDyXG7s2DLm6JaozPGpgsgVGd42Is1CHRG/yMDQpt877Xg==",
-      "license": "MIT",
-      "dependencies": {
-        "debug": "3.1.0",
-        "dogapi": "2.8.4"
-      }
-    },
-    "node_modules/debug": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
-      "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "2.0.0"
-      }
-    },
-    "node_modules/deep-extend": {
-      "version": "0.6.0",
-      "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
-      "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=4.0.0"
-      }
-    },
-    "node_modules/deep-object-diff": {
-      "version": "1.1.9",
-      "resolved": "https://registry.npmjs.org/deep-object-diff/-/deep-object-diff-1.1.9.tgz",
-      "integrity": "sha512-Rn+RuwkmkDwCi2/oXOFS9Gsr5lJZu/yTGpK7wAaAIE75CC+LCGEZHpY6VQJa/RoJcrmaA/docWJZvYohlNkWPA==",
-      "license": "MIT"
-    },
-    "node_modules/defaults": {
-      "version": "1.0.4",
-      "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.4.tgz",
-      "integrity": "sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==",
-      "license": "MIT",
-      "dependencies": {
-        "clone": "^1.0.2"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/degenerator": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/degenerator/-/degenerator-5.0.1.tgz",
-      "integrity": "sha512-TllpMR/t0M5sqCXfj85i4XaAzxmS5tVA16dqvdkMwGmzI+dXLXnw3J+3Vdv7VKw+ThlTMboK6i9rnZ6Nntj5CQ==",
-      "license": "MIT",
-      "dependencies": {
-        "ast-types": "^0.13.4",
-        "escodegen": "^2.1.0",
-        "esprima": "^4.0.1"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/delayed-stream": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
-      "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.4.0"
-      }
-    },
-    "node_modules/dogapi": {
-      "version": "2.8.4",
-      "resolved": "https://registry.npmjs.org/dogapi/-/dogapi-2.8.4.tgz",
-      "integrity": "sha512-065fsvu5dB0o4+ENtLjZILvXMClDNH/yA9H6L8nsdcNiz9l0Hzpn7aQaCOPYXxqyzq4CRPOdwkFXUjDOXfRGbg==",
-      "license": "MIT",
-      "dependencies": {
-        "extend": "^3.0.2",
-        "json-bigint": "^1.0.0",
-        "lodash": "^4.17.21",
-        "minimist": "^1.2.5",
-        "rc": "^1.2.8"
-      },
-      "bin": {
-        "dogapi": "bin/dogapi"
-      }
-    },
-    "node_modules/dot-prop": {
-      "version": "6.0.1",
-      "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-6.0.1.tgz",
-      "integrity": "sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==",
-      "license": "MIT",
-      "dependencies": {
-        "is-obj": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/duplexify": {
-      "version": "4.1.3",
-      "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.3.tgz",
-      "integrity": "sha512-M3BmBhwJRZsSx38lZyhE53Csddgzl5R7xGJNk7CVddZD6CcmwMCH8J+7AprIrQKH7TonKxaCjcv27Qmf+sQ+oA==",
-      "license": "MIT",
-      "dependencies": {
-        "end-of-stream": "^1.4.1",
-        "inherits": "^2.0.3",
-        "readable-stream": "^3.1.1",
-        "stream-shift": "^1.0.2"
-      }
-    },
-    "node_modules/ecc-jsbn": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
-      "integrity": "sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==",
-      "license": "MIT",
-      "dependencies": {
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.1.0"
-      }
-    },
-    "node_modules/ecc-jsbn/node_modules/jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
-      "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==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "node_modules/ee-first": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
-      "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
-      "license": "MIT"
-    },
-    "node_modules/emoji-regex": {
-      "version": "8.0.0",
-      "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-      "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
-      "license": "MIT"
-    },
-    "node_modules/end-of-stream": {
-      "version": "1.4.4",
-      "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
-      "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
-      "license": "MIT",
-      "dependencies": {
-        "once": "^1.4.0"
-      }
-    },
-    "node_modules/escalade": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
-      "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "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==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/escodegen": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/escodegen/-/escodegen-2.1.0.tgz",
-      "integrity": "sha512-2NlIDTwUWJN0mRPQOdtQBzbUHvdGY2P1VXSyU83Q3xKxM7WHX2Ql8dKq782Q9TgQUNOLEzEYu9bzLNj1q88I5w==",
-      "license": "BSD-2-Clause",
-      "dependencies": {
-        "esprima": "^4.0.1",
-        "estraverse": "^5.2.0",
-        "esutils": "^2.0.2"
-      },
-      "bin": {
-        "escodegen": "bin/escodegen.js",
-        "esgenerate": "bin/esgenerate.js"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "optionalDependencies": {
-        "source-map": "~0.6.1"
-      }
-    },
-    "node_modules/esprima": {
-      "version": "4.0.1",
-      "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
-      "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
-      "license": "BSD-2-Clause",
-      "bin": {
-        "esparse": "bin/esparse.js",
-        "esvalidate": "bin/esvalidate.js"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/estraverse": {
-      "version": "5.3.0",
-      "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-      "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-      "license": "BSD-2-Clause",
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "node_modules/esutils": {
-      "version": "2.0.3",
-      "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
-      "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
-      "license": "BSD-2-Clause",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/event-target-shim": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
-      "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/eventid": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/eventid/-/eventid-2.0.1.tgz",
-      "integrity": "sha512-sPNTqiMokAvV048P2c9+foqVJzk49o6d4e0D/sq5jog3pw+4kBgyR0gaM1FM7Mx6Kzd9dztesh9oYz1LWWOpzw==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "uuid": "^8.0.0"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/eventid/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==",
-      "license": "MIT",
-      "bin": {
-        "uuid": "dist/bin/uuid"
-      }
-    },
-    "node_modules/extend": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
-      "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
-      "license": "MIT"
-    },
-    "node_modules/external-editor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.1.0.tgz",
-      "integrity": "sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==",
-      "license": "MIT",
-      "dependencies": {
-        "chardet": "^0.7.0",
-        "iconv-lite": "^0.4.24",
-        "tmp": "^0.0.33"
-      },
-      "engines": {
-        "node": ">=4"
-      }
-    },
-    "node_modules/fast-deep-equal": {
-      "version": "3.1.3",
-      "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
-      "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-      "license": "MIT"
-    },
-    "node_modules/fast-levenshtein": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-3.0.0.tgz",
-      "integrity": "sha512-hKKNajm46uNmTlhHSyZkmToAc56uZJwYq7yrciZjqOxnlfQwERDQJmHPUp7m1m9wx8vgOe8IaCKZ5Kv2k1DdCQ==",
-      "license": "MIT",
-      "dependencies": {
-        "fastest-levenshtein": "^1.0.7"
-      }
-    },
-    "node_modules/fast-uri": {
-      "version": "3.0.3",
-      "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz",
-      "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/fast-xml-parser": {
-      "version": "4.5.0",
-      "resolved": "https://registry.npmjs.org/fast-xml-parser/-/fast-xml-parser-4.5.0.tgz",
-      "integrity": "sha512-/PlTQCI96+fZMAOLMZK4CWG1ItCbfZ/0jx7UIJFChPNrx7tcEgerUgWbeieCM9MfHInUDyK8DWYZ+YrywDJuTg==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/NaturalIntelligence"
-        },
-        {
-          "type": "paypal",
-          "url": "https://paypal.me/naturalintelligence"
-        }
-      ],
-      "license": "MIT",
-      "dependencies": {
-        "strnum": "^1.0.5"
-      },
-      "bin": {
-        "fxparser": "src/cli/cli.js"
-      }
-    },
-    "node_modules/fastest-levenshtein": {
-      "version": "1.0.16",
-      "resolved": "https://registry.npmjs.org/fastest-levenshtein/-/fastest-levenshtein-1.0.16.tgz",
-      "integrity": "sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 4.9.1"
-      }
-    },
-    "node_modules/figures": {
-      "version": "3.2.0",
-      "resolved": "https://registry.npmjs.org/figures/-/figures-3.2.0.tgz",
-      "integrity": "sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==",
-      "license": "MIT",
-      "dependencies": {
-        "escape-string-regexp": "^1.0.5"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/follow-redirects": {
-      "version": "1.15.9",
-      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
-      "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
-      "funding": [
-        {
-          "type": "individual",
-          "url": "https://github.com/sponsors/RubenVerborgh"
-        }
-      ],
-      "license": "MIT",
-      "engines": {
-        "node": ">=4.0"
-      },
-      "peerDependenciesMeta": {
-        "debug": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/form-data": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz",
-      "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==",
-      "license": "MIT",
-      "dependencies": {
-        "asynckit": "^0.4.0",
-        "combined-stream": "^1.0.8",
-        "mime-types": "^2.1.12"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/fs.realpath": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-      "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
-      "license": "ISC"
-    },
-    "node_modules/fuzzy": {
-      "version": "0.1.3",
-      "resolved": "https://registry.npmjs.org/fuzzy/-/fuzzy-0.1.3.tgz",
-      "integrity": "sha512-/gZffu4ykarLrCiP3Ygsa86UAo1E5vEVlvTrpkKywXSbP9Xhln3oSp9QSV57gEq3JFFpGJ4GZ+5zdEp3FcUh4w==",
-      "engines": {
-        "node": ">= 0.6.0"
-      }
-    },
-    "node_modules/gaxios": {
-      "version": "6.7.1",
-      "resolved": "https://registry.npmjs.org/gaxios/-/gaxios-6.7.1.tgz",
-      "integrity": "sha512-LDODD4TMYx7XXdpwxAVRAIAuB0bzv0s+ywFonY46k126qzQHT9ygyoa9tncmOiQmmDrik65UYsEkv3lbfqQ3yQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "extend": "^3.0.2",
-        "https-proxy-agent": "^7.0.1",
-        "is-stream": "^2.0.0",
-        "node-fetch": "^2.6.9",
-        "uuid": "^9.0.1"
-      },
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/gcp-metadata": {
-      "version": "6.1.0",
-      "resolved": "https://registry.npmjs.org/gcp-metadata/-/gcp-metadata-6.1.0.tgz",
-      "integrity": "sha512-Jh/AIwwgaxan+7ZUUmRLCjtchyDiqh4KjBJ5tW3plBZb5iL/BPcso8A5DlzeD9qlw0duCamnNdpFjxwaT0KyKg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "gaxios": "^6.0.0",
-        "json-bigint": "^1.0.0"
-      },
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/get-caller-file": {
-      "version": "2.0.5",
-      "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
-      "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
-      "license": "ISC",
-      "engines": {
-        "node": "6.* || 8.* || >= 10.*"
-      }
-    },
-    "node_modules/get-uri": {
-      "version": "6.0.4",
-      "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-6.0.4.tgz",
-      "integrity": "sha512-E1b1lFFLvLgak2whF2xDBcOy6NLVGZBqqjJjsIhvopKfWWEi64pLVTWWehV8KlLerZkfNTA95sTe2OdJKm1OzQ==",
-      "license": "MIT",
-      "dependencies": {
-        "basic-ftp": "^5.0.2",
-        "data-uri-to-buffer": "^6.0.2",
-        "debug": "^4.3.4"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/get-uri/node_modules/debug": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
-      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/get-uri/node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "license": "MIT"
-    },
-    "node_modules/getpass": {
-      "version": "0.1.7",
-      "resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
-      "integrity": "sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==",
-      "license": "MIT",
-      "dependencies": {
-        "assert-plus": "^1.0.0"
-      }
-    },
-    "node_modules/glob": {
-      "version": "7.2.3",
-      "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-      "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
-      "deprecated": "Glob versions prior to v9 are no longer supported",
-      "license": "ISC",
-      "dependencies": {
-        "fs.realpath": "^1.0.0",
-        "inflight": "^1.0.4",
-        "inherits": "2",
-        "minimatch": "^3.1.1",
-        "once": "^1.3.0",
-        "path-is-absolute": "^1.0.0"
-      },
-      "engines": {
-        "node": "*"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/google-auth-library": {
-      "version": "9.15.0",
-      "resolved": "https://registry.npmjs.org/google-auth-library/-/google-auth-library-9.15.0.tgz",
-      "integrity": "sha512-7ccSEJFDFO7exFbO6NRyC+xH8/mZ1GZGG2xxx9iHxZWcjUjJpjWxIMw3cofAKcueZ6DATiukmmprD7yavQHOyQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "base64-js": "^1.3.0",
-        "ecdsa-sig-formatter": "^1.0.11",
-        "gaxios": "^6.1.1",
-        "gcp-metadata": "^6.1.0",
-        "gtoken": "^7.0.0",
-        "jws": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/google-gax": {
-      "version": "4.4.1",
-      "resolved": "https://registry.npmjs.org/google-gax/-/google-gax-4.4.1.tgz",
-      "integrity": "sha512-Phyp9fMfA00J3sZbJxbbB4jC55b7DBjE3F6poyL3wKMEBVKA79q6BGuHcTiM28yOzVql0NDbRL8MLLh8Iwk9Dg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "@grpc/grpc-js": "^1.10.9",
-        "@grpc/proto-loader": "^0.7.13",
-        "@types/long": "^4.0.0",
-        "abort-controller": "^3.0.0",
-        "duplexify": "^4.0.0",
-        "google-auth-library": "^9.3.0",
-        "node-fetch": "^2.7.0",
-        "object-hash": "^3.0.0",
-        "proto3-json-serializer": "^2.0.2",
-        "protobufjs": "^7.3.2",
-        "retry-request": "^7.0.0",
-        "uuid": "^9.0.1"
-      },
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/gtoken": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/gtoken/-/gtoken-7.1.0.tgz",
-      "integrity": "sha512-pCcEwRi+TKpMlxAQObHDQ56KawURgyAf6jtIY046fJ5tIv3zDe/LEIubckAO8fj6JnAxLdmWkUfNyulQ2iKdEw==",
-      "license": "MIT",
-      "dependencies": {
-        "gaxios": "^6.0.0",
-        "jws": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/has-flag": {
-      "version": "4.0.0",
-      "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-      "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/html-entities": {
-      "version": "2.5.2",
-      "resolved": "https://registry.npmjs.org/html-entities/-/html-entities-2.5.2.tgz",
-      "integrity": "sha512-K//PSRMQk4FZ78Kyau+mZurHn3FH0Vwr+H36eE0rPbeYkRRi9YxceYPhuN60UwWorxyKHhqoAJl2OFKa4BVtaA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/mdevils"
-        },
-        {
-          "type": "patreon",
-          "url": "https://patreon.com/mdevils"
-        }
-      ],
-      "license": "MIT"
-    },
-    "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==",
-      "license": "MIT",
-      "dependencies": {
-        "agent-base": "^7.1.0",
-        "debug": "^4.3.4"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/http-proxy-agent/node_modules/debug": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
-      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/http-proxy-agent/node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "license": "MIT"
-    },
-    "node_modules/https-proxy-agent": {
-      "version": "7.0.6",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
-      "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
-      "license": "MIT",
-      "dependencies": {
-        "agent-base": "^7.1.2",
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/https-proxy-agent/node_modules/debug": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
-      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/https-proxy-agent/node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "license": "MIT"
-    },
-    "node_modules/iconv-lite": {
-      "version": "0.4.24",
-      "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz",
-      "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==",
-      "license": "MIT",
-      "dependencies": {
-        "safer-buffer": ">= 2.1.2 < 3"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/ieee754": {
-      "version": "1.2.1",
-      "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
-      "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/immediate": {
-      "version": "3.0.6",
-      "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
-      "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
-      "license": "MIT"
-    },
-    "node_modules/inflight": {
-      "version": "1.0.6",
-      "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-      "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
-      "deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
-      "license": "ISC",
-      "dependencies": {
-        "once": "^1.3.0",
-        "wrappy": "1"
-      }
-    },
-    "node_modules/inherits": {
-      "version": "2.0.4",
-      "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
-      "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-      "license": "ISC"
-    },
-    "node_modules/ini": {
-      "version": "1.3.8",
-      "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
-      "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
-      "license": "ISC"
-    },
-    "node_modules/inquirer": {
-      "version": "8.2.6",
-      "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-8.2.6.tgz",
-      "integrity": "sha512-M1WuAmb7pn9zdFRtQYk26ZBoY043Sse0wVDdk4Bppr+JOXyQYybdtvK+l9wUibhtjdjvtoiNy8tk+EgsYIUqKg==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-escapes": "^4.2.1",
-        "chalk": "^4.1.1",
-        "cli-cursor": "^3.1.0",
-        "cli-width": "^3.0.0",
-        "external-editor": "^3.0.3",
-        "figures": "^3.0.0",
-        "lodash": "^4.17.21",
-        "mute-stream": "0.0.8",
-        "ora": "^5.4.1",
-        "run-async": "^2.4.0",
-        "rxjs": "^7.5.5",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0",
-        "through": "^2.3.6",
-        "wrap-ansi": "^6.0.1"
-      },
-      "engines": {
-        "node": ">=12.0.0"
-      }
-    },
-    "node_modules/inquirer-checkbox-plus-prompt": {
-      "version": "1.4.2",
-      "resolved": "https://registry.npmjs.org/inquirer-checkbox-plus-prompt/-/inquirer-checkbox-plus-prompt-1.4.2.tgz",
-      "integrity": "sha512-W8/NL9x5A81Oq9ZfbYW5c1LuwtAhc/oB/u9YZZejna0pqrajj27XhnUHygJV0Vn5TvcDy1VJcD2Ld9kTk40dvg==",
-      "license": "MIT",
-      "dependencies": {
-        "chalk": "4.1.2",
-        "cli-cursor": "^3.1.0",
-        "figures": "^3.0.0",
-        "lodash": "^4.17.5",
-        "rxjs": "^6.6.7"
-      },
-      "peerDependencies": {
-        "inquirer": "< 9.x"
-      }
-    },
-    "node_modules/inquirer-checkbox-plus-prompt/node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
-      }
-    },
-    "node_modules/inquirer-checkbox-plus-prompt/node_modules/rxjs": {
-      "version": "6.6.7",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz",
-      "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^1.9.0"
-      },
-      "engines": {
-        "npm": ">=2.0.0"
-      }
-    },
-    "node_modules/inquirer-checkbox-plus-prompt/node_modules/tslib": {
-      "version": "1.14.1",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
-      "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
-      "license": "0BSD"
-    },
-    "node_modules/inquirer/node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
-      }
-    },
-    "node_modules/ip-address": {
-      "version": "9.0.5",
-      "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-9.0.5.tgz",
-      "integrity": "sha512-zHtQzGojZXTwZTHQqra+ETKd4Sn3vgi7uBmlPoXVWZqYvuKmtI0l/VZTjqGmJY9x88GGOaZ9+G9ES8hC4T4X8g==",
-      "license": "MIT",
-      "dependencies": {
-        "jsbn": "1.1.0",
-        "sprintf-js": "^1.1.3"
-      },
-      "engines": {
-        "node": ">= 12"
-      }
-    },
-    "node_modules/ip-address/node_modules/sprintf-js": {
-      "version": "1.1.3",
-      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz",
-      "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/is-fullwidth-code-point": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
-      "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/is-interactive": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-1.0.0.tgz",
-      "integrity": "sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/is-obj": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
-      "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/is-stream": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
-      "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/is-unicode-supported": {
-      "version": "0.1.0",
-      "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-0.1.0.tgz",
-      "integrity": "sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/isarray": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
-      "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
-      "license": "MIT"
-    },
-    "node_modules/js-yaml": {
-      "version": "3.13.1",
-      "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
-      "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
-      "license": "MIT",
-      "dependencies": {
-        "argparse": "^1.0.7",
-        "esprima": "^4.0.0"
-      },
-      "bin": {
-        "js-yaml": "bin/js-yaml.js"
-      }
-    },
-    "node_modules/jsbn": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-1.1.0.tgz",
-      "integrity": "sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==",
-      "license": "MIT"
-    },
-    "node_modules/json-bigint": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/json-bigint/-/json-bigint-1.0.0.tgz",
-      "integrity": "sha512-SiPv/8VpZuWbvLSMtTDU8hEfrZWg/mH/nV/b4o0CYbSxu1UIQPLdwKOCIyLQX+VIPO5vrLX3i8qtqFyhdPSUSQ==",
-      "license": "MIT",
-      "dependencies": {
-        "bignumber.js": "^9.0.0"
-      }
-    },
-    "node_modules/json-schema-traverse": {
-      "version": "1.0.0",
-      "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
-      "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
-      "license": "MIT"
-    },
-    "node_modules/jszip": {
-      "version": "3.10.1",
-      "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
-      "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
-      "license": "(MIT OR GPL-3.0-or-later)",
-      "dependencies": {
-        "lie": "~3.3.0",
-        "pako": "~1.0.2",
-        "readable-stream": "~2.3.6",
-        "setimmediate": "^1.0.5"
-      }
-    },
-    "node_modules/jszip/node_modules/readable-stream": {
-      "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
-      "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
-      "license": "MIT",
-      "dependencies": {
-        "core-util-is": "~1.0.0",
-        "inherits": "~2.0.3",
-        "isarray": "~1.0.0",
-        "process-nextick-args": "~2.0.0",
-        "safe-buffer": "~5.1.1",
-        "string_decoder": "~1.1.1",
-        "util-deprecate": "~1.0.1"
-      }
-    },
-    "node_modules/jszip/node_modules/safe-buffer": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-      "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-      "license": "MIT"
-    },
-    "node_modules/jszip/node_modules/string_decoder": {
-      "version": "1.1.1",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
-      "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
-      "license": "MIT",
-      "dependencies": {
-        "safe-buffer": "~5.1.0"
-      }
-    },
-    "node_modules/jwa": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/jwa/-/jwa-2.0.0.tgz",
-      "integrity": "sha512-jrZ2Qx916EA+fq9cEAeCROWPTfCwi1IVHqT2tapuqLEVVDKFDENFw1oL+MwrTvH6msKxsd1YTDVw6uKEcsrLEA==",
-      "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==",
-      "license": "MIT",
-      "dependencies": {
-        "jwa": "^2.0.0",
-        "safe-buffer": "^5.0.1"
-      }
-    },
-    "node_modules/lie": {
-      "version": "3.3.0",
-      "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
-      "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
-      "license": "MIT",
-      "dependencies": {
-        "immediate": "~3.0.5"
-      }
-    },
-    "node_modules/lodash": {
-      "version": "4.17.21",
-      "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz",
-      "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==",
-      "license": "MIT"
-    },
-    "node_modules/lodash.camelcase": {
-      "version": "4.3.0",
-      "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
-      "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
-      "license": "MIT"
-    },
-    "node_modules/log-symbols": {
-      "version": "4.1.0",
-      "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.1.0.tgz",
-      "integrity": "sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==",
-      "license": "MIT",
-      "dependencies": {
-        "chalk": "^4.1.0",
-        "is-unicode-supported": "^0.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/log-symbols/node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
-      }
-    },
-    "node_modules/long": {
-      "version": "5.2.3",
-      "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz",
-      "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==",
-      "license": "Apache-2.0"
-    },
-    "node_modules/lru-cache": {
-      "version": "7.18.3",
-      "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
-      "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
-      "license": "ISC",
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "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==",
-      "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==",
-      "license": "MIT",
-      "dependencies": {
-        "mime-db": "1.52.0"
-      },
-      "engines": {
-        "node": ">= 0.6"
-      }
-    },
-    "node_modules/mimic-fn": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
-      "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=6"
-      }
-    },
-    "node_modules/minimatch": {
-      "version": "3.1.2",
-      "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-      "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
-      "license": "ISC",
-      "dependencies": {
-        "brace-expansion": "^1.1.7"
-      },
-      "engines": {
-        "node": "*"
-      }
-    },
-    "node_modules/minimist": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
-      "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
-      "license": "MIT",
-      "funding": {
-        "url": "https://github.com/sponsors/ljharb"
-      }
-    },
-    "node_modules/ms": {
-      "version": "2.0.0",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
-      "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
-      "license": "MIT"
-    },
-    "node_modules/mute-stream": {
-      "version": "0.0.8",
-      "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
-      "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
-      "license": "ISC"
-    },
-    "node_modules/nan": {
-      "version": "2.22.0",
-      "resolved": "https://registry.npmjs.org/nan/-/nan-2.22.0.tgz",
-      "integrity": "sha512-nbajikzWTMwsW+eSsNm3QwlOs7het9gGJU5dDZzRTQGk03vyBOauxgI4VakDzE0PtsGTmXPsXTbbjVhRwR5mpw==",
-      "license": "MIT",
-      "optional": true
-    },
-    "node_modules/netmask": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/netmask/-/netmask-2.0.2.tgz",
-      "integrity": "sha512-dBpDMdxv9Irdq66304OLfEmQ9tbNRFnFTuZiLo+bD+r332bBmMJ8GBLXklIXXgxd3+v9+KUnZaUR5PJMa75Gsg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 0.4.0"
-      }
-    },
-    "node_modules/node-fetch": {
-      "version": "2.7.0",
-      "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
-      "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
-      "license": "MIT",
-      "dependencies": {
-        "whatwg-url": "^5.0.0"
-      },
-      "engines": {
-        "node": "4.x || >=6.0.0"
-      },
-      "peerDependencies": {
-        "encoding": "^0.1.0"
-      },
-      "peerDependenciesMeta": {
-        "encoding": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/object-hash": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/object-hash/-/object-hash-3.0.0.tgz",
-      "integrity": "sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/on-finished": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
-      "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
-      "license": "MIT",
-      "dependencies": {
-        "ee-first": "1.1.1"
-      },
-      "engines": {
-        "node": ">= 0.8"
-      }
-    },
-    "node_modules/once": {
-      "version": "1.4.0",
-      "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
-      "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
-      "license": "ISC",
-      "dependencies": {
-        "wrappy": "1"
-      }
-    },
-    "node_modules/onetime": {
-      "version": "5.1.2",
-      "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
-      "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
-      "license": "MIT",
-      "dependencies": {
-        "mimic-fn": "^2.1.0"
-      },
-      "engines": {
-        "node": ">=6"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/ora": {
-      "version": "5.4.1",
-      "resolved": "https://registry.npmjs.org/ora/-/ora-5.4.1.tgz",
-      "integrity": "sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==",
-      "license": "MIT",
-      "dependencies": {
-        "bl": "^4.1.0",
-        "chalk": "^4.1.0",
-        "cli-cursor": "^3.1.0",
-        "cli-spinners": "^2.5.0",
-        "is-interactive": "^1.0.0",
-        "is-unicode-supported": "^0.1.0",
-        "log-symbols": "^4.1.0",
-        "strip-ansi": "^6.0.0",
-        "wcwidth": "^1.0.1"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/ora/node_modules/chalk": {
-      "version": "4.1.2",
-      "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-      "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.1.0",
-        "supports-color": "^7.1.0"
-      },
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/chalk/chalk?sponsor=1"
-      }
-    },
-    "node_modules/os-tmpdir": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz",
-      "integrity": "sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/pac-proxy-agent": {
-      "version": "7.1.0",
-      "resolved": "https://registry.npmjs.org/pac-proxy-agent/-/pac-proxy-agent-7.1.0.tgz",
-      "integrity": "sha512-Z5FnLVVZSnX7WjBg0mhDtydeRZ1xMcATZThjySQUHqr+0ksP8kqaw23fNKkaaN/Z8gwLUs/W7xdl0I75eP2Xyw==",
-      "license": "MIT",
-      "dependencies": {
-        "@tootallnate/quickjs-emscripten": "^0.23.0",
-        "agent-base": "^7.1.2",
-        "debug": "^4.3.4",
-        "get-uri": "^6.0.1",
-        "http-proxy-agent": "^7.0.0",
-        "https-proxy-agent": "^7.0.6",
-        "pac-resolver": "^7.0.1",
-        "socks-proxy-agent": "^8.0.5"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/pac-proxy-agent/node_modules/debug": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
-      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/pac-proxy-agent/node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "license": "MIT"
-    },
-    "node_modules/pac-resolver": {
-      "version": "7.0.1",
-      "resolved": "https://registry.npmjs.org/pac-resolver/-/pac-resolver-7.0.1.tgz",
-      "integrity": "sha512-5NPgf87AT2STgwa2ntRMr45jTKrYBGkVU36yT0ig/n/GMAa3oPqhZfIQ2kMEimReg0+t9kZViDVZ83qfVUlckg==",
-      "license": "MIT",
-      "dependencies": {
-        "degenerator": "^5.0.0",
-        "netmask": "^2.0.2"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/pako": {
-      "version": "1.0.11",
-      "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
-      "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
-      "license": "(MIT AND Zlib)"
-    },
-    "node_modules/path-is-absolute": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-      "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/process-nextick-args": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
-      "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
-      "license": "MIT"
-    },
-    "node_modules/proto3-json-serializer": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz",
-      "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "protobufjs": "^7.2.5"
-      },
-      "engines": {
-        "node": ">=14.0.0"
-      }
-    },
-    "node_modules/protobufjs": {
-      "version": "7.4.0",
-      "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz",
-      "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==",
-      "hasInstallScript": true,
-      "license": "BSD-3-Clause",
-      "dependencies": {
-        "@protobufjs/aspromise": "^1.1.2",
-        "@protobufjs/base64": "^1.1.2",
-        "@protobufjs/codegen": "^2.0.4",
-        "@protobufjs/eventemitter": "^1.1.0",
-        "@protobufjs/fetch": "^1.1.0",
-        "@protobufjs/float": "^1.0.2",
-        "@protobufjs/inquire": "^1.1.0",
-        "@protobufjs/path": "^1.1.2",
-        "@protobufjs/pool": "^1.1.0",
-        "@protobufjs/utf8": "^1.1.0",
-        "@types/node": ">=13.7.0",
-        "long": "^5.0.0"
-      },
-      "engines": {
-        "node": ">=12.0.0"
-      }
-    },
-    "node_modules/proxy-agent": {
-      "version": "6.5.0",
-      "resolved": "https://registry.npmjs.org/proxy-agent/-/proxy-agent-6.5.0.tgz",
-      "integrity": "sha512-TmatMXdr2KlRiA2CyDu8GqR8EjahTG3aY3nXjdzFyoZbmB8hrBsTyMezhULIXKnC0jpfjlmiZ3+EaCzoInSu/A==",
-      "license": "MIT",
-      "dependencies": {
-        "agent-base": "^7.1.2",
-        "debug": "^4.3.4",
-        "http-proxy-agent": "^7.0.1",
-        "https-proxy-agent": "^7.0.6",
-        "lru-cache": "^7.14.1",
-        "pac-proxy-agent": "^7.1.0",
-        "proxy-from-env": "^1.1.0",
-        "socks-proxy-agent": "^8.0.5"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/proxy-agent/node_modules/debug": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
-      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/proxy-agent/node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "license": "MIT"
-    },
-    "node_modules/proxy-from-env": {
-      "version": "1.1.0",
-      "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
-      "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==",
-      "license": "MIT"
-    },
-    "node_modules/pump": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
-      "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
-      "license": "MIT",
-      "dependencies": {
-        "end-of-stream": "^1.1.0",
-        "once": "^1.3.1"
-      }
-    },
-    "node_modules/pumpify": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/pumpify/-/pumpify-2.0.1.tgz",
-      "integrity": "sha512-m7KOje7jZxrmutanlkS1daj1dS6z6BgslzOXmcSEpIlCxM3VJH7lG5QLeck/6hgF6F4crFf01UtQmNsJfweTAw==",
-      "license": "MIT",
-      "dependencies": {
-        "duplexify": "^4.1.1",
-        "inherits": "^2.0.3",
-        "pump": "^3.0.0"
-      }
-    },
-    "node_modules/rc": {
-      "version": "1.2.8",
-      "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
-      "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
-      "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
-      "dependencies": {
-        "deep-extend": "^0.6.0",
-        "ini": "~1.3.0",
-        "minimist": "^1.2.0",
-        "strip-json-comments": "~2.0.1"
-      },
-      "bin": {
-        "rc": "cli.js"
-      }
-    },
-    "node_modules/readable-stream": {
-      "version": "3.6.2",
-      "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
-      "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
-      "license": "MIT",
-      "dependencies": {
-        "inherits": "^2.0.3",
-        "string_decoder": "^1.1.1",
-        "util-deprecate": "^1.0.1"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/require-directory": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
-      "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/require-from-string": {
-      "version": "2.0.2",
-      "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
-      "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/restore-cursor": {
-      "version": "3.1.0",
-      "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
-      "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
-      "license": "MIT",
-      "dependencies": {
-        "onetime": "^5.1.0",
-        "signal-exit": "^3.0.2"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/retry": {
-      "version": "0.12.0",
-      "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
-      "integrity": "sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 4"
-      }
-    },
-    "node_modules/retry-request": {
-      "version": "7.0.2",
-      "resolved": "https://registry.npmjs.org/retry-request/-/retry-request-7.0.2.tgz",
-      "integrity": "sha512-dUOvLMJ0/JJYEn8NrpOaGNE7X3vpI5XlZS/u0ANjqtcZVKnIxP7IgCFwrKTxENw29emmwug53awKtaMm4i9g5w==",
-      "license": "MIT",
-      "dependencies": {
-        "@types/request": "^2.48.8",
-        "extend": "^3.0.2",
-        "teeny-request": "^9.0.0"
-      },
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/rimraf": {
-      "version": "3.0.2",
-      "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-      "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
-      "deprecated": "Rimraf versions prior to v4 are no longer supported",
-      "license": "ISC",
-      "dependencies": {
-        "glob": "^7.1.3"
-      },
-      "bin": {
-        "rimraf": "bin.js"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/isaacs"
-      }
-    },
-    "node_modules/run-async": {
-      "version": "2.4.1",
-      "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.4.1.tgz",
-      "integrity": "sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.12.0"
-      }
-    },
-    "node_modules/rxjs": {
-      "version": "7.8.1",
-      "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.8.1.tgz",
-      "integrity": "sha512-AA3TVj+0A2iuIoQkWEK/tqFjBq2j+6PO6Y0zJcvzLAFhEFIO3HL0vls9hWLncZbAAbK0mar7oZ4V079I/qPMxg==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "tslib": "^2.1.0"
-      }
-    },
-    "node_modules/safe-buffer": {
-      "version": "5.2.1",
-      "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
-      "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
-      "funding": [
-        {
-          "type": "github",
-          "url": "https://github.com/sponsors/feross"
-        },
-        {
-          "type": "patreon",
-          "url": "https://www.patreon.com/feross"
-        },
-        {
-          "type": "consulting",
-          "url": "https://feross.org/support"
-        }
-      ],
-      "license": "MIT"
-    },
-    "node_modules/safer-buffer": {
-      "version": "2.1.2",
-      "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-      "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
-      "license": "MIT"
-    },
-    "node_modules/sax": {
-      "version": "1.4.1",
-      "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
-      "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
-      "license": "ISC"
-    },
-    "node_modules/semver": {
-      "version": "7.6.3",
-      "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz",
-      "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==",
-      "license": "ISC",
-      "bin": {
-        "semver": "bin/semver.js"
-      },
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/setimmediate": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/setimmediate/-/setimmediate-1.0.5.tgz",
-      "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
-      "license": "MIT"
-    },
-    "node_modules/signal-exit": {
-      "version": "3.0.7",
-      "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
-      "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
-      "license": "ISC"
-    },
-    "node_modules/simple-git": {
-      "version": "3.16.0",
-      "resolved": "https://registry.npmjs.org/simple-git/-/simple-git-3.16.0.tgz",
-      "integrity": "sha512-zuWYsOLEhbJRWVxpjdiXl6eyAyGo/KzVW+KFhhw9MqEEJttcq+32jTWSGyxTdf9e/YCohxRE+9xpWFj9FdiJNw==",
-      "license": "MIT",
-      "dependencies": {
-        "@kwsites/file-exists": "^1.1.1",
-        "@kwsites/promise-deferred": "^1.1.1",
-        "debug": "^4.3.4"
-      },
-      "funding": {
-        "type": "github",
-        "url": "https://github.com/steveukx/git-js?sponsor=1"
-      }
-    },
-    "node_modules/simple-git/node_modules/debug": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
-      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/simple-git/node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "license": "MIT"
-    },
-    "node_modules/smart-buffer": {
-      "version": "4.2.0",
-      "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz",
-      "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==",
-      "license": "MIT",
-      "engines": {
-        "node": ">= 6.0.0",
-        "npm": ">= 3.0.0"
-      }
-    },
-    "node_modules/socks": {
-      "version": "2.8.3",
-      "resolved": "https://registry.npmjs.org/socks/-/socks-2.8.3.tgz",
-      "integrity": "sha512-l5x7VUUWbjVFbafGLxPWkYsHIhEvmF85tbIeFZWc8ZPtoMyybuEhL7Jye/ooC4/d48FgOjSJXgsF/AJPYCW8Zw==",
-      "license": "MIT",
-      "dependencies": {
-        "ip-address": "^9.0.5",
-        "smart-buffer": "^4.2.0"
-      },
-      "engines": {
-        "node": ">= 10.0.0",
-        "npm": ">= 3.0.0"
-      }
-    },
-    "node_modules/socks-proxy-agent": {
-      "version": "8.0.5",
-      "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-8.0.5.tgz",
-      "integrity": "sha512-HehCEsotFqbPW9sJ8WVYB6UbmIMv7kUUORIF2Nncq4VQvBfNBLibW9YZR5dlYCSUhwcD628pRllm7n+E+YTzJw==",
-      "license": "MIT",
-      "dependencies": {
-        "agent-base": "^7.1.2",
-        "debug": "^4.3.4",
-        "socks": "^2.8.3"
-      },
-      "engines": {
-        "node": ">= 14"
-      }
-    },
-    "node_modules/socks-proxy-agent/node_modules/debug": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
-      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/socks-proxy-agent/node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "license": "MIT"
-    },
-    "node_modules/source-map": {
-      "version": "0.6.1",
-      "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
-      "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
-      "license": "BSD-3-Clause",
-      "optional": true,
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/sprintf-js": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
-      "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==",
-      "license": "BSD-3-Clause"
-    },
-    "node_modules/ssh2": {
-      "version": "1.16.0",
-      "resolved": "https://registry.npmjs.org/ssh2/-/ssh2-1.16.0.tgz",
-      "integrity": "sha512-r1X4KsBGedJqo7h8F5c4Ybpcr5RjyP+aWIG007uBPRjmdQWfEiVLzSK71Zji1B9sKxwaCvD8y8cwSkYrlLiRRg==",
-      "hasInstallScript": true,
-      "dependencies": {
-        "asn1": "^0.2.6",
-        "bcrypt-pbkdf": "^1.0.2"
-      },
-      "engines": {
-        "node": ">=10.16.0"
-      },
-      "optionalDependencies": {
-        "cpu-features": "~0.0.10",
-        "nan": "^2.20.0"
-      }
-    },
-    "node_modules/ssh2-streams": {
-      "version": "0.4.10",
-      "resolved": "https://registry.npmjs.org/ssh2-streams/-/ssh2-streams-0.4.10.tgz",
-      "integrity": "sha512-8pnlMjvnIZJvmTzUIIA5nT4jr2ZWNNVHwyXfMGdRJbug9TpI3kd99ffglgfSWqujVv/0gxwMsDn9j9RVst8yhQ==",
-      "dependencies": {
-        "asn1": "~0.2.0",
-        "bcrypt-pbkdf": "^1.0.2",
-        "streamsearch": "~0.1.2"
-      },
-      "engines": {
-        "node": ">=5.2.0"
-      }
-    },
-    "node_modules/sshpk": {
-      "version": "1.16.1",
-      "resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
-      "integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
-      "license": "MIT",
-      "dependencies": {
-        "asn1": "~0.2.3",
-        "assert-plus": "^1.0.0",
-        "bcrypt-pbkdf": "^1.0.0",
-        "dashdash": "^1.12.0",
-        "ecc-jsbn": "~0.1.1",
-        "getpass": "^0.1.1",
-        "jsbn": "~0.1.0",
-        "safer-buffer": "^2.0.2",
-        "tweetnacl": "~0.14.0"
-      },
-      "bin": {
-        "sshpk-conv": "bin/sshpk-conv",
-        "sshpk-sign": "bin/sshpk-sign",
-        "sshpk-verify": "bin/sshpk-verify"
-      },
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/sshpk/node_modules/jsbn": {
-      "version": "0.1.1",
-      "resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
-      "integrity": "sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==",
-      "license": "MIT"
-    },
-    "node_modules/stream-events": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/stream-events/-/stream-events-1.0.5.tgz",
-      "integrity": "sha512-E1GUzBSgvct8Jsb3v2X15pjzN1tYebtbLaMg+eBOUOAxgbLoSbT2NS91ckc5lJD1KfLjId+jXJRgo0qnV5Nerg==",
-      "license": "MIT",
-      "dependencies": {
-        "stubs": "^3.0.0"
-      }
-    },
-    "node_modules/stream-shift": {
-      "version": "1.0.3",
-      "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.3.tgz",
-      "integrity": "sha512-76ORR0DO1o1hlKwTbi/DM3EXWGf3ZJYO8cXX5RJwnul2DEg2oyoZyjLNoQM8WsvZiFKCRfC1O0J7iCvie3RZmQ==",
-      "license": "MIT"
-    },
-    "node_modules/streamsearch": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/streamsearch/-/streamsearch-0.1.2.tgz",
-      "integrity": "sha512-jos8u++JKm0ARcSUTAZXOVC0mSox7Bhn6sBgty73P1f3JGf7yG2clTbBNHUdde/kdvP2FESam+vM6l8jBrNxHA==",
-      "engines": {
-        "node": ">=0.8.0"
-      }
-    },
-    "node_modules/string_decoder": {
-      "version": "1.3.0",
-      "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz",
-      "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==",
-      "license": "MIT",
-      "dependencies": {
-        "safe-buffer": "~5.2.0"
-      }
-    },
-    "node_modules/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==",
-      "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",
-      "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-regex": "^5.0.1"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/strip-json-comments": {
-      "version": "2.0.1",
-      "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
-      "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=0.10.0"
-      }
-    },
-    "node_modules/strnum": {
-      "version": "1.0.5",
-      "resolved": "https://registry.npmjs.org/strnum/-/strnum-1.0.5.tgz",
-      "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA==",
-      "license": "MIT"
-    },
-    "node_modules/stubs": {
-      "version": "3.0.0",
-      "resolved": "https://registry.npmjs.org/stubs/-/stubs-3.0.0.tgz",
-      "integrity": "sha512-PdHt7hHUJKxvTCgbKX9C1V/ftOcjJQgz8BZwNfV5c4B6dcGqlpelTbJ999jBGZ2jYiPAwcX5dP6oBwVlBlUbxw==",
-      "license": "MIT"
-    },
-    "node_modules/supports-color": {
-      "version": "7.2.0",
-      "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-      "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
-      "license": "MIT",
-      "dependencies": {
-        "has-flag": "^4.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/supports-hyperlinks": {
-      "version": "2.3.0",
-      "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-2.3.0.tgz",
-      "integrity": "sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==",
-      "license": "MIT",
-      "dependencies": {
-        "has-flag": "^4.0.0",
-        "supports-color": "^7.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "node_modules/teeny-request": {
-      "version": "9.0.0",
-      "resolved": "https://registry.npmjs.org/teeny-request/-/teeny-request-9.0.0.tgz",
-      "integrity": "sha512-resvxdc6Mgb7YEThw6G6bExlXKkv6+YbuzGg9xuXxSgxJF7Ozs+o8Y9+2R3sArdWdW8nOokoQb1yrpFB0pQK2g==",
-      "license": "Apache-2.0",
-      "dependencies": {
-        "http-proxy-agent": "^5.0.0",
-        "https-proxy-agent": "^5.0.0",
-        "node-fetch": "^2.6.9",
-        "stream-events": "^1.0.5",
-        "uuid": "^9.0.0"
-      },
-      "engines": {
-        "node": ">=14"
-      }
-    },
-    "node_modules/teeny-request/node_modules/agent-base": {
-      "version": "6.0.2",
-      "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
-      "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
-      "license": "MIT",
-      "dependencies": {
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 6.0.0"
-      }
-    },
-    "node_modules/teeny-request/node_modules/debug": {
-      "version": "4.4.0",
-      "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
-      "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
-      "license": "MIT",
-      "dependencies": {
-        "ms": "^2.1.3"
-      },
-      "engines": {
-        "node": ">=6.0"
-      },
-      "peerDependenciesMeta": {
-        "supports-color": {
-          "optional": true
-        }
-      }
-    },
-    "node_modules/teeny-request/node_modules/http-proxy-agent": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-5.0.0.tgz",
-      "integrity": "sha512-n2hY8YdoRE1i7r6M0w9DIw5GgZN0G25P8zLCRQ8rjXtTU3vsNFBI/vWK/UIeE6g5MUUz6avwAPXmL6Fy9D/90w==",
-      "license": "MIT",
-      "dependencies": {
-        "@tootallnate/once": "2",
-        "agent-base": "6",
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/teeny-request/node_modules/https-proxy-agent": {
-      "version": "5.0.1",
-      "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
-      "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
-      "license": "MIT",
-      "dependencies": {
-        "agent-base": "6",
-        "debug": "4"
-      },
-      "engines": {
-        "node": ">= 6"
-      }
-    },
-    "node_modules/teeny-request/node_modules/ms": {
-      "version": "2.1.3",
-      "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
-      "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
-      "license": "MIT"
-    },
-    "node_modules/terminal-link": {
-      "version": "2.1.1",
-      "resolved": "https://registry.npmjs.org/terminal-link/-/terminal-link-2.1.1.tgz",
-      "integrity": "sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-escapes": "^4.2.1",
-        "supports-hyperlinks": "^2.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/through": {
-      "version": "2.3.8",
-      "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
-      "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
-      "license": "MIT"
-    },
-    "node_modules/tiny-async-pool": {
-      "version": "2.1.0",
-      "resolved": "https://registry.npmjs.org/tiny-async-pool/-/tiny-async-pool-2.1.0.tgz",
-      "integrity": "sha512-ltAHPh/9k0STRQqaoUX52NH4ZQYAJz24ZAEwf1Zm+HYg3l9OXTWeqWKyYsHu40wF/F0rxd2N2bk5sLvX2qlSvg==",
-      "license": "MIT"
-    },
-    "node_modules/tmp": {
-      "version": "0.0.33",
-      "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz",
-      "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==",
-      "license": "MIT",
-      "dependencies": {
-        "os-tmpdir": "~1.0.2"
-      },
-      "engines": {
-        "node": ">=0.6.0"
-      }
-    },
-    "node_modules/tr46": {
-      "version": "0.0.3",
-      "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
-      "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
-      "license": "MIT"
-    },
-    "node_modules/tslib": {
-      "version": "2.8.1",
-      "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
-      "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
-      "license": "0BSD"
-    },
-    "node_modules/tweetnacl": {
-      "version": "0.14.5",
-      "resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
-      "integrity": "sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==",
-      "license": "Unlicense"
-    },
-    "node_modules/typanion": {
-      "version": "3.14.0",
-      "resolved": "https://registry.npmjs.org/typanion/-/typanion-3.14.0.tgz",
-      "integrity": "sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==",
-      "license": "MIT",
-      "workspaces": [
-        "website"
-      ]
-    },
-    "node_modules/type-fest": {
-      "version": "0.21.3",
-      "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.21.3.tgz",
-      "integrity": "sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==",
-      "license": "(MIT OR CC0-1.0)",
-      "engines": {
-        "node": ">=10"
-      },
-      "funding": {
-        "url": "https://github.com/sponsors/sindresorhus"
-      }
-    },
-    "node_modules/undici-types": {
-      "version": "6.20.0",
-      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
-      "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
-      "license": "MIT"
-    },
-    "node_modules/util-deprecate": {
-      "version": "1.0.2",
-      "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
-      "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
-      "license": "MIT"
-    },
-    "node_modules/uuid": {
-      "version": "9.0.1",
-      "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz",
-      "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==",
-      "funding": [
-        "https://github.com/sponsors/broofa",
-        "https://github.com/sponsors/ctavan"
-      ],
-      "license": "MIT",
-      "bin": {
-        "uuid": "dist/bin/uuid"
-      }
-    },
-    "node_modules/wcwidth": {
-      "version": "1.0.1",
-      "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz",
-      "integrity": "sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==",
-      "license": "MIT",
-      "dependencies": {
-        "defaults": "^1.0.3"
-      }
-    },
-    "node_modules/webidl-conversions": {
-      "version": "3.0.1",
-      "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
-      "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
-      "license": "BSD-2-Clause"
-    },
-    "node_modules/whatwg-url": {
-      "version": "5.0.0",
-      "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
-      "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
-      "license": "MIT",
-      "dependencies": {
-        "tr46": "~0.0.3",
-        "webidl-conversions": "^3.0.0"
-      }
-    },
-    "node_modules/wrap-ansi": {
-      "version": "6.2.0",
-      "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-6.2.0.tgz",
-      "integrity": "sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==",
-      "license": "MIT",
-      "dependencies": {
-        "ansi-styles": "^4.0.0",
-        "string-width": "^4.1.0",
-        "strip-ansi": "^6.0.0"
-      },
-      "engines": {
-        "node": ">=8"
-      }
-    },
-    "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==",
-      "license": "ISC"
-    },
-    "node_modules/ws": {
-      "version": "7.5.10",
-      "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.10.tgz",
-      "integrity": "sha512-+dbF1tHwZpXcbOJdVOkzLDxZP1ailvSxM6ZweXTegylPny803bFhA+vqBYw4s31NSAk4S2Qz+AKXK9a4wkdjcQ==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=8.3.0"
-      },
-      "peerDependencies": {
-        "bufferutil": "^4.0.1",
-        "utf-8-validate": "^5.0.2"
-      },
-      "peerDependenciesMeta": {
-        "bufferutil": {
-          "optional": true
-        },
-        "utf-8-validate": {
-          "optional": 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==",
-      "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",
-      "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
-      "license": "MIT",
-      "engines": {
-        "node": ">=4.0"
-      }
-    },
-    "node_modules/y18n": {
-      "version": "5.0.8",
-      "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
-      "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
-      "license": "ISC",
-      "engines": {
-        "node": ">=10"
-      }
-    },
-    "node_modules/yamux-js": {
-      "version": "0.1.2",
-      "resolved": "https://registry.npmjs.org/yamux-js/-/yamux-js-0.1.2.tgz",
-      "integrity": "sha512-bhsPlPZ9xB4Dawyf6nkS58u4F3IvGCaybkEKGnneUeepcI7MPoG3Tt6SaKCU5x/kP2/2w20Qm/GqbpwAM16vYw==",
-      "license": "MIT"
-    },
-    "node_modules/yargs": {
-      "version": "17.7.2",
-      "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
-      "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
-      "license": "MIT",
-      "dependencies": {
-        "cliui": "^8.0.1",
-        "escalade": "^3.1.1",
-        "get-caller-file": "^2.0.5",
-        "require-directory": "^2.1.1",
-        "string-width": "^4.2.3",
-        "y18n": "^5.0.5",
-        "yargs-parser": "^21.1.1"
-      },
-      "engines": {
-        "node": ">=12"
-      }
-    },
-    "node_modules/yargs-parser": {
-      "version": "21.1.1",
-      "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
-      "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
-      "license": "ISC",
-      "engines": {
-        "node": ">=12"
-      }
-    }
-  }
-}
diff --git a/src/ci/package.json b/src/ci/package.json
deleted file mode 100644
index 91f21e5531e..00000000000
--- a/src/ci/package.json
+++ /dev/null
@@ -1,5 +0,0 @@
-{
-  "dependencies": {
-    "@datadog/datadog-ci": "^2.45.1"
-  }
-}
diff --git a/src/ci/scripts/upload-build-metrics.py b/src/ci/scripts/upload-build-metrics.py
deleted file mode 100644
index 915ba953984..00000000000
--- a/src/ci/scripts/upload-build-metrics.py
+++ /dev/null
@@ -1,86 +0,0 @@
-"""
-This script postprocesses data gathered during a CI run, computes certain metrics
-from them, and uploads these metrics to DataDog.
-
-This script is expected to be executed from within a GitHub Actions job.
-
-It expects the following environment variables:
-- DATADOG_SITE: path to the DataDog API endpoint
-- DATADOG_API_KEY: DataDog API token
-- DD_GITHUB_JOB_NAME: Name of the current GitHub Actions job
-
-It expects the presence of a binary called `datadog-ci` inside `node_modules`.
-It can be installed with `npm ci` at `src/ci`.
-
-Usage:
-```bash
-$ python3 upload-build-metrics.py <path-to-CPU-usage-CSV>
-```
-
-`path-to-CPU-usage-CSV` is a path to a CSV generated by the `src/ci/cpu-usage-over-time.py` script.
-"""
-
-import argparse
-import csv
-import os
-import subprocess
-import sys
-from pathlib import Path
-from typing import List
-
-
-def load_cpu_usage(path: Path) -> List[float]:
-    usage = []
-    with open(path) as f:
-        reader = csv.reader(f, delimiter=",")
-        for row in reader:
-            # The log might contain incomplete rows or some Python exception
-            if len(row) == 2:
-                try:
-                    idle = float(row[1])
-                    usage.append(100.0 - idle)
-                except ValueError:
-                    pass
-    return usage
-
-
-def upload_datadog_measure(name: str, value: float):
-    """
-    Uploads a single numeric metric for the current GitHub Actions job to DataDog.
-    """
-    print(f"Metric {name}: {value:.4f}")
-
-    cmd = "npx"
-    if os.getenv("GITHUB_ACTIONS") is not None and sys.platform.lower().startswith(
-        "win"
-    ):
-        # Due to weird interaction of MSYS2 and Python, we need to use an absolute path,
-        # and also specify the ".cmd" at the end. See https://github.com/rust-lang/rust/pull/125771.
-        cmd = "C:\\Program Files\\nodejs\\npx.cmd"
-
-    subprocess.run(
-        [
-            cmd,
-            "datadog-ci",
-            "measure",
-            "--level",
-            "job",
-            "--measures",
-            f"{name}:{value}",
-        ],
-        check=False,
-    )
-
-
-if __name__ == "__main__":
-    parser = argparse.ArgumentParser(prog="DataDog metric uploader")
-    parser.add_argument("cpu-usage-history-csv")
-    args = parser.parse_args()
-
-    build_usage_csv = vars(args)["cpu-usage-history-csv"]
-    usage_timeseries = load_cpu_usage(Path(build_usage_csv))
-    if len(usage_timeseries) > 0:
-        avg_cpu_usage = sum(usage_timeseries) / len(usage_timeseries)
-    else:
-        avg_cpu_usage = 0
-    upload_datadog_measure("avg-cpu-usage", avg_cpu_usage)
diff --git a/src/doc/rustc-dev-guide/src/parallel-rustc.md b/src/doc/rustc-dev-guide/src/parallel-rustc.md
index c5b70706a81..690fb19c9f5 100644
--- a/src/doc/rustc-dev-guide/src/parallel-rustc.md
+++ b/src/doc/rustc-dev-guide/src/parallel-rustc.md
@@ -46,10 +46,8 @@ are implemented differently depending on whether `parallel-compiler` is true.
 
 | data structure                   | parallel                                            | non-parallel |
 | -------------------------------- | --------------------------------------------------- | ------------ |
-| OnceCell                         | std::sync::OnceLock                                 | std::cell::OnceCell |
 | Lock\<T> | (parking_lot::Mutex\<T>) | (std::cell::RefCell) |
 | RwLock\<T> | (parking_lot::RwLock\<T>) | (std::cell::RefCell) |
-| MTRef<'a, T> | &'a T | &'a mut T |
 | MTLock\<T> | (Lock\<T>) | (T) |
 | ReadGuard | parking_lot::RwLockReadGuard | std::cell::Ref |
 | MappedReadGuard | parking_lot::MappedRwLockReadGuard | std::cell::Ref |
diff --git a/src/doc/rustc-dev-guide/src/tests/compiletest.md b/src/doc/rustc-dev-guide/src/tests/compiletest.md
index 459c082906e..2905e470fab 100644
--- a/src/doc/rustc-dev-guide/src/tests/compiletest.md
+++ b/src/doc/rustc-dev-guide/src/tests/compiletest.md
@@ -74,8 +74,7 @@ The following test suites are available, with links for more information:
 
 ### General purpose test suite
 
-[`run-make`](#run-make-tests) are general purpose tests using Rust programs (or
-Makefiles (legacy)).
+[`run-make`](#run-make-tests) are general purpose tests using Rust programs.
 
 ### Rustdoc test suites
 
@@ -396,14 +395,6 @@ your test, causing separate files to be generated for 32bit and 64bit systems.
 
 ### `run-make` tests
 
-> **Note on phasing out `Makefile`s**
-> 
-> We are planning to migrate all existing Makefile-based `run-make` tests
-> to Rust programs. You should not be adding new Makefile-based `run-make`
-> tests.
->
-> See <https://github.com/rust-lang/rust/issues/121876>.
-
 The tests in [`tests/run-make`] are general-purpose tests using Rust *recipes*,
 which are small programs (`rmake.rs`) allowing arbitrary Rust code such as
 `rustc` invocations, and is supported by a [`run_make_support`] library. Using
@@ -424,11 +415,6 @@ Compiletest directives like `//@ only-<target>` or `//@ ignore-<target>` are
 supported in `rmake.rs`, like in UI tests. However, revisions or building
 auxiliary via directives are not currently supported.
 
-Two `run-make` tests are ported over to Rust recipes as examples:
-
-- <https://github.com/rust-lang/rust/tree/master/tests/run-make/CURRENT_RUSTC_VERSION>
-- <https://github.com/rust-lang/rust/tree/master/tests/run-make/a-b-a-linker-guard>
-
 #### Quickly check if `rmake.rs` tests can be compiled
 
 You can quickly check if `rmake.rs` tests can be compiled without having to
@@ -481,20 +467,6 @@ Then add a corresponding entry to `"rust-analyzer.linkedProjects"`
 ],
 ```
 
-#### Using Makefiles (legacy)
-
-<div class="warning">
-You should avoid writing new Makefile-based `run-make` tests.
-</div>
-
-Each test should be in a separate directory with a `Makefile` indicating the
-commands to run.
-
-There is a [`tools.mk`] Makefile which you can include which provides a bunch of
-utilities to make it easier to run commands and compare outputs. Take a look at
-some of the other tests for some examples on how to get started.
-
-[`tools.mk`]: https://github.com/rust-lang/rust/blob/master/tests/run-make/tools.mk
 [`tests/run-make`]: https://github.com/rust-lang/rust/tree/master/tests/run-make
 [`run_make_support`]: https://github.com/rust-lang/rust/tree/master/src/tools/run-make-support
 
diff --git a/src/doc/rustc-dev-guide/src/tests/directives.md b/src/doc/rustc-dev-guide/src/tests/directives.md
index 00bb2bc4dbb..14f18a7ecf7 100644
--- a/src/doc/rustc-dev-guide/src/tests/directives.md
+++ b/src/doc/rustc-dev-guide/src/tests/directives.md
@@ -6,10 +6,7 @@
 FIXME(jieyouxu) completely revise this chapter.
 -->
 
-Directives are special comments that tell compiletest how to build and interpret
-a test. They must appear before the Rust source in the test. They may also
-appear in `rmake.rs` or legacy Makefiles for [run-make
-tests](compiletest.md#run-make-tests).
+Directives are special comments that tell compiletest how to build and interpret a test. They must appear before the Rust source in the test. They may also appear in `rmake.rs` [run-make tests](compiletest.md#run-make-tests).
 
 They are normally put after the short comment that explains the point of this
 test. Compiletest test suites use `//@` to signal that a comment is a directive.
@@ -142,6 +139,7 @@ Some examples of `X` in `ignore-X` or `only-X`:
   matches that target as well as the emscripten targets.
 - Pointer width: `32bit`, `64bit`
 - Endianness: `endian-big`
+- Binary format: `elf`
 - Stage: `stage0`, `stage1`, `stage2`
 - Channel: `stable`, `beta`
 - When cross compiling: `cross-compile`
@@ -221,8 +219,6 @@ The following directives will check LLVM support:
     [`aarch64-gnu-debug`]), which only runs a
     subset of `run-make` tests. Other tests with this directive will not
     run at all, which is usually not what you want.
-  - Notably, the [`aarch64-gnu-debug`] CI job *currently* only runs `run-make`
-    tests which additionally contain `clang` in their test name.
 
 See also [Debuginfo tests](compiletest.md#debuginfo-tests) for directives for
 ignoring debuggers.
diff --git a/src/doc/rustc-dev-guide/src/tests/running.md b/src/doc/rustc-dev-guide/src/tests/running.md
index 6ce65092389..9ddf0afee0c 100644
--- a/src/doc/rustc-dev-guide/src/tests/running.md
+++ b/src/doc/rustc-dev-guide/src/tests/running.md
@@ -238,30 +238,6 @@ This is much faster, but doesn't always work. For example, some tests include
 directives that specify specific compiler flags, or which rely on other crates,
 and they may not run the same without those options.
 
-## Running `run-make` tests
-
-### Windows
-
-Running the `run-make` test suite on Windows is a currently bit more involved.
-There are numerous prerequisites and environmental requirements:
-
-- Install msys2: <https://www.msys2.org/>
-- Specify `MSYS2_PATH_TYPE=inherit` in `msys2.ini` in the msys2 installation directory, run the
-  following with `MSYS2 MSYS`:
-  - `pacman -Syuu`
-  - `pacman -S make`
-  - `pacman -S diffutils`
-  - `pacman -S binutils`
-  - `./x test run-make` (`./x test tests/run-make` doesn't work)
-
-There is [on-going work][port-run-make] to not rely on `Makefile`s in the
-run-make test suite. Once this work is completed, you can run the entire
-`run-make` test suite on native Windows inside `cmd` or `PowerShell` without
-needing to install and use MSYS2. As of <!--date-check --> Oct 2024, it is
-already possible to run the vast majority of the `run-make` test suite outside
-of MSYS2, but there will be failures for the tests that still use `Makefile`s
-due to not finding `make`.
-
 ## Running tests on a remote machine
 
 Tests may be run on a remote machine (e.g. to test builds for a different
@@ -406,4 +382,3 @@ If you encounter bugs or problems, don't hesitate to open issues on the
 repository](https://github.com/rust-lang/rustc_codegen_gcc/).
 
 [`tests/ui`]: https://github.com/rust-lang/rust/tree/master/tests/ui
-[port-run-make]: https://github.com/rust-lang/rust/issues/121876
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 6c7cdec3480..b1d7e5421c1 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -50,6 +50,7 @@
     - [\*-linux-ohos](platform-support/openharmony.md)
     - [\*-hurd-gnu](platform-support/hurd.md)
     - [aarch64-unknown-teeos](platform-support/aarch64-unknown-teeos.md)
+    - [avr-none](platform-support/avr-none.md)
     - [\*-espidf](platform-support/esp-idf.md)
     - [\*-unknown-fuchsia](platform-support/fuchsia.md)
     - [\*-unknown-trusty](platform-support/trusty.md)
@@ -68,6 +69,7 @@
     - [mipsisa\*r6\*-unknown-linux-gnu\*](platform-support/mips-release-6.md)
     - [nvptx64-nvidia-cuda](platform-support/nvptx64-nvidia-cuda.md)
     - [powerpc-unknown-openbsd](platform-support/powerpc-unknown-openbsd.md)
+    - [powerpc-unknown-linux-gnuspe](platform-support/powerpc-unknown-linux-gnuspe.md)
     - [powerpc-unknown-linux-muslspe](platform-support/powerpc-unknown-linux-muslspe.md)
     - [powerpc64-ibm-aix](platform-support/aix.md)
     - [powerpc64le-unknown-linux-musl](platform-support/powerpc64le-unknown-linux-musl.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index c4e5c1aac2f..84440a5ab78 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -301,7 +301,7 @@ target | std | host | notes
 [`armv8r-none-eabihf`](platform-support/armv8r-none-eabihf.md) | * |  | Bare Armv8-R, hardfloat
 [`armv7a-nuttx-eabi`](platform-support/nuttx.md) | ✓ |  | ARMv7-A with NuttX
 [`armv7a-nuttx-eabihf`](platform-support/nuttx.md) | ✓ |  | ARMv7-A with NuttX, hardfloat
-`avr-none` | * |  | AVR; requires `-Zbuild-std=core` and `-Ctarget-cpu=...`
+[`avr-none`](platform-support/avr-none.md) | * |  | AVR; requires `-Zbuild-std=core` and `-Ctarget-cpu=...`
 `bpfeb-unknown-none` | * |  | BPF (big endian)
 `bpfel-unknown-none` | * |  | BPF (little endian)
 `csky-unknown-linux-gnuabiv2` | ✓ |  | C-SKY abiv2 Linux (little endian)
@@ -348,9 +348,9 @@ target | std | host | notes
 [`mipsisa64r6el-unknown-linux-gnuabi64`](platform-support/mips-release-6.md) | ✓ | ✓ | 64-bit MIPS Release 6 Little Endian
 `msp430-none-elf` | * |  | 16-bit MSP430 microcontrollers
 [`powerpc-unknown-freebsd`](platform-support/freebsd.md) | ? |   | PowerPC FreeBSD
-`powerpc-unknown-linux-gnuspe` | ✓ |  | PowerPC SPE Linux
+[`powerpc-unknown-linux-gnuspe`](platform-support/powerpc-unknown-linux-gnuspe.md) | ✓ |  | PowerPC SPE Linux
 `powerpc-unknown-linux-musl` | ? |  | PowerPC Linux with musl 1.2.3
-[`powerpc-unknown-linux-muslspe`](platform-support/powerpc-unknown-linux-muslspe.md) | ? |  | PowerPC SPE Linux
+[`powerpc-unknown-linux-muslspe`](platform-support/powerpc-unknown-linux-muslspe.md) | ? |  | PowerPC SPE Linux with musl 1.2.3
 [`powerpc-unknown-netbsd`](platform-support/netbsd.md) | ✓ | ✓ | NetBSD 32-bit powerpc systems
 [`powerpc-unknown-openbsd`](platform-support/powerpc-unknown-openbsd.md) | * |  |
 [`powerpc-wrs-vxworks`](platform-support/vxworks.md) | ✓ |  |
diff --git a/src/doc/rustc/src/platform-support/powerpc-unknown-linux-gnuspe.md b/src/doc/rustc/src/platform-support/powerpc-unknown-linux-gnuspe.md
new file mode 100644
index 00000000000..a9983a14111
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/powerpc-unknown-linux-gnuspe.md
@@ -0,0 +1,20 @@
+# powerpc-unknown-linux-gnuspe
+
+**Tier: 3**
+
+`powerpc-unknown-linux-gnuspe` is a target for Linux on 32-bit PowerPC
+processors that implement the Signal Processing Engine (SPE), such as e500, and
+uses a different ABI than standard `powerpc-unknown-linux-gnu`.
+When building for other 32-bit PowerPC processors, use
+`powerpc-unknown-linux-gnu` instead.
+
+See also [Debian Wiki](https://wiki.debian.org/PowerPCSPEPort) for details on
+this platform, and [ABI reference](https://web.archive.org/web/20120608163804/https://www.power.org/resources/downloads/Power-Arch-32-bit-ABI-supp-1.0-Unified.pdf)
+for details on SPE ABI.
+
+Note that support for PowerPC SPE by GCC was [removed in GCC 9](https://gcc.gnu.org/gcc-8/changes.html),
+so recent GCC cannot be used as linker/compiler for this target.
+
+## Target maintainers
+
+There are currently no formally documented target maintainers.
diff --git a/src/doc/rustc/src/platform-support/powerpc-unknown-linux-muslspe.md b/src/doc/rustc/src/platform-support/powerpc-unknown-linux-muslspe.md
index 4c416b51929..6b62e9ddba1 100644
--- a/src/doc/rustc/src/platform-support/powerpc-unknown-linux-muslspe.md
+++ b/src/doc/rustc/src/platform-support/powerpc-unknown-linux-muslspe.md
@@ -2,9 +2,11 @@
 
 **Tier: 3**
 
-This target is very similar to already existing ones like `powerpc_unknown_linux_musl` and `powerpc_unknown_linux_gnuspe`.
+This target is very similar to already existing ones like `powerpc-unknown-linux-musl` and `powerpc-unknown-linux-gnuspe`.
 This one has PowerPC SPE support for musl. Unfortunately, the last supported gcc version with PowerPC SPE is 8.4.0.
 
+See also [platform support documentation of `powerpc-unknown-linux-gnuspe`](powerpc-unknown-linux-gnuspe.md) for information about PowerPC SPE.
+
 ## Target maintainers
 
 - [@BKPepe](https://github.com/BKPepe)
diff --git a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md
index b57083980d2..dda2a50c33d 100644
--- a/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md
+++ b/src/doc/rustc/src/platform-support/riscv64gc-unknown-linux-gnu.md
@@ -65,7 +65,7 @@ section below.
 
 A RISC-V toolchain can be obtained for Windows/Mac/Linux from the
 [`riscv-gnu-toolchain`](https://github.com/riscv-collab/riscv-gnu-toolchain)
-repostory. Binaries are available via
+repository. Binaries are available via
 [embecosm](https://www.embecosm.com/resources/tool-chain-downloads/#riscv-linux),
 and may also be available from your OS's package manager.
 
diff --git a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md
index bfdb579cd35..b2f59732801 100644
--- a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md
+++ b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024-structural.md
@@ -9,12 +9,32 @@ The tracking issue for this feature is: [#123076]
 This feature is incomplete and not yet intended for general use.
 
 This implements experimental, Edition-dependent match ergonomics under consideration for inclusion
-in Rust.
-For more information, see the corresponding typing rules for [Editions 2021 and earlier] and for
-[Editions 2024 and later].
+in Rust, allowing `&` patterns in more places. For example:
+```rust,edition2024
+#![feature(ref_pat_eat_one_layer_2024_structural)]
+#![allow(incomplete_features)]
+#
+# // Tests type equality in a way that avoids coercing `&&T` or `&mut T` to `&T`.
+# trait Eq<T> {}
+# impl<T> Eq<T> for T {}
+# fn has_type<T>(_: impl Eq<T>) {}
+
+// `&` can match against a `ref` binding mode instead of a reference type:
+let (x, &y) = &(0, 1);
+has_type::<&u8>(x);
+has_type::<u8>(y);
+
+// `&` can match against `&mut` references:
+let &z = &mut 2;
+has_type::<u8>(z);
+```
+
+For specifics, see the corresponding typing rules for [Editions 2021 and earlier] and for
+[Editions 2024 and later]. For more information on binding modes, see [The Rust Reference].
 
 For alternative experimental match ergonomics, see the feature
 [`ref_pat_eat_one_layer_2024`](./ref-pat-eat-one-layer-2024.md).
 
 [Editions 2021 and earlier]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAQIBAQEBAAAAAAAAAAAAAAAAAAA%3D&mode=rules&do_cmp=false
 [Editions 2024 and later]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAgEBAQEBAgIAAAAAAAAAAAAAAAA%3D&mode=rules&do_cmp=false
+[The Rust Reference]: https://doc.rust-lang.org/reference/patterns.html#binding-modes
diff --git a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md
index 0c90cec0dbd..f7c85eec2d2 100644
--- a/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md
+++ b/src/doc/unstable-book/src/language-features/ref-pat-eat-one-layer-2024.md
@@ -9,12 +9,33 @@ The tracking issue for this feature is: [#123076]
 This feature is incomplete and not yet intended for general use.
 
 This implements experimental, Edition-dependent match ergonomics under consideration for inclusion
-in Rust.
-For more information, see the corresponding typing rules for [Editions 2021 and earlier] and for
-[Editions 2024 and later].
+in Rust, allowing `&` patterns in more places. For example:
+
+```rust,edition2024
+#![feature(ref_pat_eat_one_layer_2024)]
+#![allow(incomplete_features)]
+#
+# // Tests type equality in a way that avoids coercing `&&T` or `&mut T` to `&T`.
+# trait Eq<T> {}
+# impl<T> Eq<T> for T {}
+# fn has_type<T>(_: impl Eq<T>) {}
+
+// `&` can match against a `ref` binding mode instead of a reference type:
+let (x, &y) = &(0, 1);
+has_type::<&u8>(x);
+has_type::<u8>(y);
+
+// `&` can match against `&mut` references:
+let &z = &mut 2;
+has_type::<u8>(z);
+```
+
+For specifics, see the corresponding typing rules for [Editions 2021 and earlier] and for
+[Editions 2024 and later]. For more information on binding modes, see [The Rust Reference].
 
 For alternative experimental match ergonomics, see the feature
 [`ref_pat_eat_one_layer_2024_structural`](./ref-pat-eat-one-layer-2024-structural.md).
 
 [Editions 2021 and earlier]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAQIBAQABAAAAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false
 [Editions 2024 and later]: https://nadrieril.github.io/typing-rust-patterns/?compare=false&opts1=AQEBAAABAQABAgIAAQEBAAEBAAABAAA%3D&mode=rules&do_cmp=false
+[The Rust Reference]: https://doc.rust-lang.org/reference/patterns.html#binding-modes
diff --git a/src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md b/src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md
deleted file mode 100644
index 310c8d96294..00000000000
--- a/src/doc/unstable-book/src/language-features/unsized-tuple-coercion.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# `unsized_tuple_coercion`
-
-The tracking issue for this feature is: [#42877]
-
-[#42877]: https://github.com/rust-lang/rust/issues/42877
-
-------------------------
-
-This is a part of [RFC0401]. According to the RFC, there should be an implementation like this:
-
-```rust,ignore (partial-example)
-impl<..., T, U: ?Sized> Unsized<(..., U)> for (..., T) where T: Unsized<U> {}
-```
-
-This implementation is currently gated behind `#[feature(unsized_tuple_coercion)]` to avoid insta-stability. Therefore you can use it like this:
-
-```rust
-#![feature(unsized_tuple_coercion)]
-
-fn main() {
-    let x : ([i32; 3], [i32; 3]) = ([1, 2, 3], [4, 5, 6]);
-    let y : &([i32; 3], [i32]) = &x;
-    assert_eq!(y.1[0], 4);
-}
-```
-
-[RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
diff --git a/src/etc/htmldocck.py b/src/etc/htmldocck.py
index d6b594aca71..06fc6518e3b 100755
--- a/src/etc/htmldocck.py
+++ b/src/etc/htmldocck.py
@@ -297,10 +297,24 @@ LINE_PATTERN = re.compile(
     re.X | re.UNICODE,
 )
 
+DEPRECATED_LINE_PATTERN = re.compile(
+    r"""
+    //\s+@
+""",
+    re.X | re.UNICODE,
+)
+
 
 def get_commands(template):
     with io.open(template, encoding="utf-8") as f:
         for lineno, line in concat_multi_lines(f):
+            if DEPRECATED_LINE_PATTERN.search(line):
+                print_err(
+                    lineno,
+                    line,
+                    "Deprecated command syntax, replace `// @` with `//@ `",
+                )
+                continue
             m = LINE_PATTERN.search(line)
             if not m:
                 continue
diff --git a/src/etc/pre-push.sh b/src/etc/pre-push.sh
index 6f86c7ab8a4..7bacc943f25 100755
--- a/src/etc/pre-push.sh
+++ b/src/etc/pre-push.sh
@@ -7,6 +7,20 @@
 
 set -Euo pipefail
 
+# Check if the push is doing anything other than deleting remote branches
+SKIP=true
+while read LOCAL_REF LOCAL_SHA REMOTE_REF REMOTE_SHA; do
+    if [[ "$LOCAL_REF" != "(delete)" || \
+          "$LOCAL_SHA" != "0000000000000000000000000000000000000000" ]]; then
+        SKIP=false
+    fi
+done
+
+if $SKIP; then
+    echo "Skipping tidy check for branch deletion"
+    exit 0
+fi
+
 ROOT_DIR="$(git rev-parse --show-toplevel)"
 
 echo "Running pre-push script $ROOT_DIR/x test tidy"
diff --git a/src/etc/test-float-parse/src/gen/exhaustive.rs b/src/etc/test-float-parse/src/gen/exhaustive.rs
index 5d4b6df8e59..01458fb0b60 100644
--- a/src/etc/test-float-parse/src/gen/exhaustive.rs
+++ b/src/etc/test-float-parse/src/gen/exhaustive.rs
@@ -13,13 +13,12 @@ impl<F: Float> Generator<F> for Exhaustive<F>
 where
     RangeInclusive<F::Int>: Iterator<Item = F::Int>,
 {
-    const NAME: &'static str = "exhaustive";
     const SHORT_NAME: &'static str = "exhaustive";
 
     type WriteCtx = F;
 
     fn total_tests() -> u64 {
-        F::Int::MAX.try_into().unwrap_or(u64::MAX)
+        1u64.checked_shl(F::Int::BITS).expect("More than u64::MAX tests")
     }
 
     fn new() -> Self {
diff --git a/src/etc/test-float-parse/src/gen/fuzz.rs b/src/etc/test-float-parse/src/gen/fuzz.rs
index 0c63e8aae26..7fc999d1671 100644
--- a/src/etc/test-float-parse/src/gen/fuzz.rs
+++ b/src/etc/test-float-parse/src/gen/fuzz.rs
@@ -49,7 +49,6 @@ impl<F: Float> Generator<F> for Fuzz<F>
 where
     Standard: Distribution<<F as Float>::Int>,
 {
-    const NAME: &'static str = "fuzz";
     const SHORT_NAME: &'static str = "fuzz";
 
     type WriteCtx = F;
diff --git a/src/etc/test-float-parse/src/gen/sparse.rs b/src/etc/test-float-parse/src/gen/sparse.rs
index 389b71056a3..72b65d4ce7f 100644
--- a/src/etc/test-float-parse/src/gen/sparse.rs
+++ b/src/etc/test-float-parse/src/gen/sparse.rs
@@ -35,7 +35,6 @@ impl<F: Float> Generator<F> for FewOnesInt<F>
 where
     <F::Int as TryFrom<u128>>::Error: std::fmt::Debug,
 {
-    const NAME: &'static str = "few ones int";
     const SHORT_NAME: &'static str = "few ones int";
 
     type WriteCtx = F::Int;
diff --git a/src/etc/test-float-parse/src/lib.rs b/src/etc/test-float-parse/src/lib.rs
index 3c71b0dc32e..def66398d9f 100644
--- a/src/etc/test-float-parse/src/lib.rs
+++ b/src/etc/test-float-parse/src/lib.rs
@@ -2,19 +2,19 @@ mod traits;
 mod ui;
 mod validate;
 
-use std::any::{TypeId, type_name};
+use std::any::type_name;
 use std::cmp::min;
 use std::ops::RangeInclusive;
 use std::process::ExitCode;
+use std::sync::OnceLock;
 use std::sync::atomic::{AtomicU64, Ordering};
-use std::sync::{OnceLock, mpsc};
 use std::{fmt, time};
 
-use indicatif::{MultiProgress, ProgressBar};
 use rand::distributions::{Distribution, Standard};
 use rayon::prelude::*;
 use time::{Duration, Instant};
 use traits::{Float, Generator, Int};
+use validate::CheckError;
 
 /// Test generators.
 mod gen {
@@ -43,7 +43,7 @@ const HUGE_TEST_CUTOFF: u64 = 5_000_000;
 /// Seed for tests that use a deterministic RNG.
 const SEED: [u8; 32] = *b"3.141592653589793238462643383279";
 
-/// Global configuration
+/// Global configuration.
 #[derive(Debug)]
 pub struct Config {
     pub timeout: Duration,
@@ -104,9 +104,9 @@ pub fn run(cfg: Config, include: &[String], exclude: &[String]) -> ExitCode {
         println!("Skipping test '{exc}'");
     }
 
-    println!("launching");
+    println!("Launching all");
     let elapsed = launch_tests(&mut tests, &cfg);
-    ui::finish(&tests, elapsed, &cfg)
+    ui::finish_all(&tests, elapsed, &cfg)
 }
 
 /// Enumerate tests to run but don't actually run them.
@@ -160,18 +160,18 @@ where
 #[derive(Debug)]
 pub struct TestInfo {
     pub name: String,
-    /// Tests are identified by the type ID of `(F, G)` (tuple of the float and generator type).
-    /// This gives an easy way to associate messages with tests.
-    id: TypeId,
     float_name: &'static str,
+    float_bits: u32,
     gen_name: &'static str,
     /// Name for display in the progress bar.
     short_name: String,
+    /// Pad the short name to a common width for progress bar use.
+    short_name_padded: String,
     total_tests: u64,
     /// Function to launch this test.
-    launch: fn(&mpsc::Sender<Msg>, &TestInfo, &Config),
+    launch: fn(&TestInfo, &Config),
     /// Progress bar to be updated.
-    pb: Option<ProgressBar>,
+    progress: Option<ui::Progress>,
     /// Once completed, this will be set.
     completed: OnceLock<Completed>,
 }
@@ -187,14 +187,18 @@ impl TestInfo {
         let f_name = type_name::<F>();
         let gen_name = G::NAME;
         let gen_short_name = G::SHORT_NAME;
+        let name = format!("{f_name} {gen_name}");
+        let short_name = format!("{f_name} {gen_short_name}");
+        let short_name_padded = format!("{short_name:18}");
 
         let info = TestInfo {
-            id: TypeId::of::<(F, G)>(),
             float_name: f_name,
+            float_bits: F::BITS,
             gen_name,
-            pb: None,
-            name: format!("{f_name} {gen_name}"),
-            short_name: format!("{f_name} {gen_short_name}"),
+            progress: None,
+            name,
+            short_name_padded,
+            short_name,
             launch: test_runner::<F, G>,
             total_tests: G::total_tests(),
             completed: OnceLock::new(),
@@ -202,106 +206,18 @@ impl TestInfo {
         v.push(info);
     }
 
-    /// Pad the short name to a common width for progress bar use.
-    fn short_name_padded(&self) -> String {
-        format!("{:18}", self.short_name)
-    }
-
-    /// Create a progress bar for this test within a multiprogress bar.
-    fn register_pb(&mut self, mp: &MultiProgress, drop_bars: &mut Vec<ProgressBar>) {
-        self.pb = Some(ui::create_pb(mp, self.total_tests, &self.short_name_padded(), drop_bars));
-    }
-
-    /// When the test is finished, update progress bar messages and finalize.
-    fn finalize_pb(&self, c: &Completed) {
-        let pb = self.pb.as_ref().unwrap();
-        ui::finalize_pb(pb, &self.short_name_padded(), c);
-    }
-
     /// True if this should be run after all others.
     fn is_huge_test(&self) -> bool {
         self.total_tests >= HUGE_TEST_CUTOFF
     }
-}
-
-/// A message sent from test runner threads to the UI/log thread.
-#[derive(Clone, Debug)]
-struct Msg {
-    id: TypeId,
-    update: Update,
-}
 
-impl Msg {
-    /// Wrap an `Update` into a message for the specified type. We use the `TypeId` of `(F, G)` to
-    /// identify which test a message in the channel came from.
-    fn new<F: Float, G: Generator<F>>(u: Update) -> Self {
-        Self { id: TypeId::of::<(F, G)>(), update: u }
-    }
-
-    /// Get the matching test from a list. Panics if not found.
-    fn find_test<'a>(&self, tests: &'a [TestInfo]) -> &'a TestInfo {
-        tests.iter().find(|t| t.id == self.id).unwrap()
-    }
-
-    /// Update UI as needed for a single message received from the test runners.
-    fn handle(self, tests: &[TestInfo], mp: &MultiProgress) {
-        let test = self.find_test(tests);
-        let pb = test.pb.as_ref().unwrap();
-
-        match self.update {
-            Update::Started => {
-                mp.println(format!("Testing '{}'", test.name)).unwrap();
-            }
-            Update::Progress { executed, failures } => {
-                pb.set_message(format! {"{failures}"});
-                pb.set_position(executed);
-            }
-            Update::Failure { fail, input, float_res } => {
-                mp.println(format!(
-                    "Failure in '{}': {fail}. parsing '{input}'. Parsed as: {float_res}",
-                    test.name
-                ))
-                .unwrap();
-            }
-            Update::Completed(c) => {
-                test.finalize_pb(&c);
-
-                let prefix = match c.result {
-                    Ok(FinishedAll) => "Completed tests for",
-                    Err(EarlyExit::Timeout) => "Timed out",
-                    Err(EarlyExit::MaxFailures) => "Max failures reached for",
-                };
-
-                mp.println(format!(
-                    "{prefix} generator '{}' in {:?}. {} tests run, {} failures",
-                    test.name, c.elapsed, c.executed, c.failures
-                ))
-                .unwrap();
-                test.completed.set(c).unwrap();
-            }
-        };
+    /// When the test is finished, update progress bar messages and finalize.
+    fn complete(&self, c: Completed) {
+        self.progress.as_ref().unwrap().complete(&c, 0);
+        self.completed.set(c).unwrap();
     }
 }
 
-/// Status sent with a message.
-#[derive(Clone, Debug)]
-enum Update {
-    /// Starting a new test runner.
-    Started,
-    /// Completed a out of b tests.
-    Progress { executed: u64, failures: u64 },
-    /// Received a failed test.
-    Failure {
-        fail: CheckFailure,
-        /// String for which parsing was attempted.
-        input: Box<str>,
-        /// The parsed & decomposed `FloatRes`, already stringified so we don't need generics here.
-        float_res: Box<str>,
-    },
-    /// Exited with an unexpected condition.
-    Completed(Completed),
-}
-
 /// Result of an input did not parsing successfully.
 #[derive(Clone, Debug)]
 enum CheckFailure {
@@ -329,6 +245,10 @@ enum CheckFailure {
         /// two representable values.
         incorrect_midpoint_rounding: bool,
     },
+    /// String did not parse successfully.
+    ParsingFailed(Box<str>),
+    /// A panic was caught.
+    Panic(Box<str>),
 }
 
 impl fmt::Display for CheckFailure {
@@ -363,6 +283,8 @@ impl fmt::Display for CheckFailure {
                 }
                 Ok(())
             }
+            CheckFailure::ParsingFailed(e) => write!(f, "parsing failed: {e}"),
+            CheckFailure::Panic(e) => write!(f, "function panicked: {e}"),
         }
     }
 }
@@ -398,55 +320,21 @@ enum EarlyExit {
 /// This launches a main thread that receives messages and handlees UI updates, and uses the
 /// rest of the thread pool to execute the tests.
 fn launch_tests(tests: &mut [TestInfo], cfg: &Config) -> Duration {
-    // Run shorter tests first
-    tests.sort_unstable_by_key(|test| test.total_tests);
+    // Run shorter tests and smaller float types first.
+    tests.sort_unstable_by_key(|test| (test.total_tests, test.float_bits));
 
     for test in tests.iter() {
         println!("Launching test '{}'", test.name);
     }
 
-    // Configure progress bars
     let mut all_progress_bars = Vec::new();
-    let mp = MultiProgress::new();
-    mp.set_move_cursor(true);
-    for test in tests.iter_mut() {
-        test.register_pb(&mp, &mut all_progress_bars);
-    }
-
-    ui::set_panic_hook(all_progress_bars);
-
-    let (tx, rx) = mpsc::channel::<Msg>();
     let start = Instant::now();
 
-    rayon::scope(|scope| {
-        // Thread that updates the UI
-        scope.spawn(|_scope| {
-            let rx = rx; // move rx
-
-            loop {
-                if tests.iter().all(|t| t.completed.get().is_some()) {
-                    break;
-                }
-
-                let msg = rx.recv().unwrap();
-                msg.handle(tests, &mp);
-            }
-
-            // All tests completed; finish things up
-            drop(mp);
-            assert_eq!(rx.try_recv().unwrap_err(), mpsc::TryRecvError::Empty);
-        });
-
-        // Don't let the thread pool be starved by huge tests. Run faster tests first in parallel,
-        // then parallelize only within the rest of the tests.
-        let (huge_tests, normal_tests): (Vec<_>, Vec<_>) =
-            tests.iter().partition(|t| t.is_huge_test());
-
-        // Run the actual tests
-        normal_tests.par_iter().for_each(|test| ((test.launch)(&tx, test, cfg)));
-
-        huge_tests.par_iter().for_each(|test| ((test.launch)(&tx, test, cfg)));
-    });
+    for test in tests.iter_mut() {
+        test.progress = Some(ui::Progress::new(test, &mut all_progress_bars));
+        ui::set_panic_hook(&all_progress_bars);
+        ((test.launch)(test, cfg));
+    }
 
     start.elapsed()
 }
@@ -454,15 +342,12 @@ fn launch_tests(tests: &mut [TestInfo], cfg: &Config) -> Duration {
 /// Test runer for a single generator.
 ///
 /// This calls the generator's iterator multiple times (in parallel) and validates each output.
-fn test_runner<F: Float, G: Generator<F>>(tx: &mpsc::Sender<Msg>, _info: &TestInfo, cfg: &Config) {
-    tx.send(Msg::new::<F, G>(Update::Started)).unwrap();
-
-    let total = G::total_tests();
+fn test_runner<F: Float, G: Generator<F>>(test: &TestInfo, cfg: &Config) {
     let gen = G::new();
     let executed = AtomicU64::new(0);
     let failures = AtomicU64::new(0);
 
-    let checks_per_update = min(total, 1000);
+    let checks_per_update = min(test.total_tests, 1000);
     let started = Instant::now();
 
     // Function to execute for a single test iteration.
@@ -474,7 +359,12 @@ fn test_runner<F: Float, G: Generator<F>>(tx: &mpsc::Sender<Msg>, _info: &TestIn
         match validate::validate::<F>(buf) {
             Ok(()) => (),
             Err(e) => {
-                tx.send(Msg::new::<F, G>(e)).unwrap();
+                let CheckError { fail, input, float_res } = e;
+                test.progress.as_ref().unwrap().println(&format!(
+                    "Failure in '{}': {fail}. parsing '{input}'. Parsed as: {float_res}",
+                    test.name
+                ));
+
                 let f = failures.fetch_add(1, Ordering::Relaxed);
                 // End early if the limit is exceeded.
                 if f >= cfg.max_failures {
@@ -486,9 +376,7 @@ fn test_runner<F: Float, G: Generator<F>>(tx: &mpsc::Sender<Msg>, _info: &TestIn
         // Send periodic updates
         if executed % checks_per_update == 0 {
             let failures = failures.load(Ordering::Relaxed);
-
-            tx.send(Msg::new::<F, G>(Update::Progress { executed, failures })).unwrap();
-
+            test.progress.as_ref().unwrap().update(executed, failures);
             if started.elapsed() > cfg.timeout {
                 return Err(EarlyExit::Timeout);
             }
@@ -499,15 +387,19 @@ fn test_runner<F: Float, G: Generator<F>>(tx: &mpsc::Sender<Msg>, _info: &TestIn
 
     // Run the test iterations in parallel. Each thread gets a string buffer to write
     // its check values to.
-    let res = gen.par_bridge().try_for_each_init(|| String::with_capacity(100), check_one);
+    let res = gen.par_bridge().try_for_each_init(String::new, check_one);
 
     let elapsed = started.elapsed();
     let executed = executed.into_inner();
     let failures = failures.into_inner();
 
     // Warn about bad estimates if relevant.
-    let warning = if executed != total && res.is_ok() {
-        let msg = format!("executed tests != estimated ({executed} != {total}) for {}", G::NAME);
+    let warning = if executed != test.total_tests && res.is_ok() {
+        let msg = format!(
+            "executed tests != estimated ({executed} != {}) for {}",
+            test.total_tests,
+            G::NAME
+        );
 
         Some(msg.into())
     } else {
@@ -515,12 +407,5 @@ fn test_runner<F: Float, G: Generator<F>>(tx: &mpsc::Sender<Msg>, _info: &TestIn
     };
 
     let result = res.map(|()| FinishedAll);
-    tx.send(Msg::new::<F, G>(Update::Completed(Completed {
-        executed,
-        failures,
-        result,
-        warning,
-        elapsed,
-    })))
-    .unwrap();
+    test.complete(Completed { executed, failures, result, warning, elapsed });
 }
diff --git a/src/etc/test-float-parse/src/traits.rs b/src/etc/test-float-parse/src/traits.rs
index f5333d63b36..57e702b7d09 100644
--- a/src/etc/test-float-parse/src/traits.rs
+++ b/src/etc/test-float-parse/src/traits.rs
@@ -147,12 +147,12 @@ pub trait Float:
 }
 
 macro_rules! impl_float {
-    ($($fty:ty, $ity:ty, $bits:literal);+) => {
+    ($($fty:ty, $ity:ty);+) => {
         $(
             impl Float for $fty {
                 type Int = $ity;
                 type SInt = <Self::Int as Int>::Signed;
-                const BITS: u32 = $bits;
+                const BITS: u32 = <$ity>::BITS;
                 const MAN_BITS: u32 = Self::MANTISSA_DIGITS - 1;
                 const MAN_MASK: Self::Int = (Self::Int::ONE << Self::MAN_BITS) - Self::Int::ONE;
                 const SIGN_MASK: Self::Int = Self::Int::ONE << (Self::BITS-1);
@@ -168,7 +168,7 @@ macro_rules! impl_float {
     }
 }
 
-impl_float!(f32, u32, 32; f64, u64, 64);
+impl_float!(f32, u32; f64, u64);
 
 /// A test generator. Should provide an iterator that produces unique patterns to parse.
 ///
@@ -177,7 +177,7 @@ impl_float!(f32, u32, 32; f64, u64, 64);
 /// allocations (which otherwise turn out to be a pretty expensive part of these tests).
 pub trait Generator<F: Float>: Iterator<Item = Self::WriteCtx> + Send + 'static {
     /// Full display and filtering name
-    const NAME: &'static str;
+    const NAME: &'static str = Self::SHORT_NAME;
 
     /// Name for display with the progress bar
     const SHORT_NAME: &'static str;
diff --git a/src/etc/test-float-parse/src/ui.rs b/src/etc/test-float-parse/src/ui.rs
index f333bd4a55d..1ee57723e6a 100644
--- a/src/etc/test-float-parse/src/ui.rs
+++ b/src/etc/test-float-parse/src/ui.rs
@@ -1,67 +1,92 @@
 //! Progress bars and such.
 
+use std::any::type_name;
+use std::fmt;
 use std::io::{self, Write};
 use std::process::ExitCode;
 use std::time::Duration;
 
-use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
+use indicatif::{ProgressBar, ProgressStyle};
 
 use crate::{Completed, Config, EarlyExit, FinishedAll, TestInfo};
 
 /// Templates for progress bars.
-const PB_TEMPLATE: &str = "[{elapsed:3} {percent:3}%] {bar:20.cyan/blue} NAME ({pos}/{len}, {msg} f, {per_sec}, eta {eta})";
-const PB_TEMPLATE_FINAL: &str =
-    "[{elapsed:3} {percent:3}%] NAME ({pos}/{len}, {msg:.COLOR}, {per_sec}, {elapsed_precise})";
-
-/// Create a new progress bar within a multiprogress bar.
-pub fn create_pb(
-    mp: &MultiProgress,
-    total_tests: u64,
-    short_name_padded: &str,
-    all_bars: &mut Vec<ProgressBar>,
-) -> ProgressBar {
-    let pb = mp.add(ProgressBar::new(total_tests));
-    let pb_style = ProgressStyle::with_template(&PB_TEMPLATE.replace("NAME", short_name_padded))
-        .unwrap()
-        .progress_chars("##-");
-
-    pb.set_style(pb_style.clone());
-    pb.set_message("0");
-    all_bars.push(pb.clone());
-    pb
+const PB_TEMPLATE: &str = "[{elapsed:3} {percent:3}%] {bar:20.cyan/blue} NAME \
+        {human_pos:>8}/{human_len:8} {msg} f {per_sec:14} eta {eta:8}";
+const PB_TEMPLATE_FINAL: &str = "[{elapsed:3} {percent:3}%] {bar:20.cyan/blue} NAME \
+        {human_pos:>8}/{human_len:8} {msg:.COLOR} {per_sec:18} {elapsed_precise}";
+
+/// Thin abstraction over our usage of a `ProgressBar`.
+#[derive(Debug)]
+pub struct Progress {
+    pb: ProgressBar,
+    make_final_style: NoDebug<Box<dyn Fn(&'static str) -> ProgressStyle + Sync>>,
 }
 
-/// Removes the status bar and replace it with a message.
-pub fn finalize_pb(pb: &ProgressBar, short_name_padded: &str, c: &Completed) {
-    let f = c.failures;
+impl Progress {
+    /// Create a new progress bar within a multiprogress bar.
+    pub fn new(test: &TestInfo, all_bars: &mut Vec<ProgressBar>) -> Self {
+        let initial_template = PB_TEMPLATE.replace("NAME", &test.short_name_padded);
+        let final_template = PB_TEMPLATE_FINAL.replace("NAME", &test.short_name_padded);
+        let initial_style =
+            ProgressStyle::with_template(&initial_template).unwrap().progress_chars("##-");
+        let make_final_style = move |color| {
+            ProgressStyle::with_template(&final_template.replace("COLOR", color))
+                .unwrap()
+                .progress_chars("##-")
+        };
 
-    // Use a tuple so we can use colors
-    let (color, msg, finish_pb): (&str, String, fn(&ProgressBar, String)) = match &c.result {
-        Ok(FinishedAll) if f > 0 => {
-            ("red", format!("{f} f (finished with errors)",), ProgressBar::finish_with_message)
-        }
-        Ok(FinishedAll) => {
-            ("green", format!("{f} f (finished successfully)",), ProgressBar::finish_with_message)
-        }
-        Err(EarlyExit::Timeout) => {
-            ("red", format!("{f} f (timed out)"), ProgressBar::abandon_with_message)
+        let pb = ProgressBar::new(test.total_tests);
+        pb.set_style(initial_style);
+        pb.set_length(test.total_tests);
+        pb.set_message("0");
+        all_bars.push(pb.clone());
+
+        Progress { pb, make_final_style: NoDebug(Box::new(make_final_style)) }
+    }
+
+    /// Completed a out of b tests.
+    pub fn update(&self, completed: u64, failures: u64) {
+        // Infrequently update the progress bar.
+        if completed % 5_000 == 0 || failures > 0 {
+            self.pb.set_position(completed);
         }
-        Err(EarlyExit::MaxFailures) => {
-            ("red", format!("{f} f (failure limit)"), ProgressBar::abandon_with_message)
+
+        if failures > 0 {
+            self.pb.set_message(format! {"{failures}"});
         }
-    };
+    }
+
+    /// Finalize the progress bar.
+    pub fn complete(&self, c: &Completed, real_total: u64) {
+        let f = c.failures;
+        let (color, msg, finish_fn): (&str, String, fn(&ProgressBar)) = match &c.result {
+            Ok(FinishedAll) if f > 0 => {
+                ("red", format!("{f} f (completed with errors)",), ProgressBar::finish)
+            }
+            Ok(FinishedAll) => {
+                ("green", format!("{f} f (completed successfully)",), ProgressBar::finish)
+            }
+            Err(EarlyExit::Timeout) => ("red", format!("{f} f (timed out)"), ProgressBar::abandon),
+            Err(EarlyExit::MaxFailures) => {
+                ("red", format!("{f} f (failure limit)"), ProgressBar::abandon)
+            }
+        };
 
-    let pb_style = ProgressStyle::with_template(
-        &PB_TEMPLATE_FINAL.replace("NAME", short_name_padded).replace("COLOR", color),
-    )
-    .unwrap();
+        self.pb.set_position(real_total);
+        self.pb.set_style(self.make_final_style.0(color));
+        self.pb.set_message(msg);
+        finish_fn(&self.pb);
+    }
 
-    pb.set_style(pb_style);
-    finish_pb(pb, msg);
+    /// Print a message to stdout above the current progress bar.
+    pub fn println(&self, msg: &str) {
+        self.pb.suspend(|| println!("{msg}"));
+    }
 }
 
 /// Print final messages after all tests are complete.
-pub fn finish(tests: &[TestInfo], total_elapsed: Duration, cfg: &Config) -> ExitCode {
+pub fn finish_all(tests: &[TestInfo], total_elapsed: Duration, cfg: &Config) -> ExitCode {
     println!("\n\nResults:");
 
     let mut failed_generators = 0;
@@ -118,8 +143,9 @@ pub fn finish(tests: &[TestInfo], total_elapsed: Duration, cfg: &Config) -> Exit
 
 /// indicatif likes to eat panic messages. This workaround isn't ideal, but it improves things.
 /// <https://github.com/console-rs/indicatif/issues/121>.
-pub fn set_panic_hook(drop_bars: Vec<ProgressBar>) {
+pub fn set_panic_hook(drop_bars: &[ProgressBar]) {
     let hook = std::panic::take_hook();
+    let drop_bars = drop_bars.to_owned();
     std::panic::set_hook(Box::new(move |info| {
         for bar in &drop_bars {
             bar.abandon();
@@ -130,3 +156,13 @@ pub fn set_panic_hook(drop_bars: Vec<ProgressBar>) {
         hook(info);
     }));
 }
+
+/// Allow non-Debug items in a `derive(Debug)` struct`.
+#[derive(Clone)]
+struct NoDebug<T>(T);
+
+impl<T> fmt::Debug for NoDebug<T> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.write_str(type_name::<Self>())
+    }
+}
diff --git a/src/etc/test-float-parse/src/validate.rs b/src/etc/test-float-parse/src/validate.rs
index 1eb3699cfb9..40dda274e3b 100644
--- a/src/etc/test-float-parse/src/validate.rs
+++ b/src/etc/test-float-parse/src/validate.rs
@@ -1,6 +1,6 @@
 //! Everything related to verifying that parsed outputs are correct.
 
-use std::any::type_name;
+use std::any::{Any, type_name};
 use std::collections::BTreeMap;
 use std::ops::RangeInclusive;
 use std::str::FromStr;
@@ -9,7 +9,7 @@ use std::sync::LazyLock;
 use num::bigint::ToBigInt;
 use num::{BigInt, BigRational, FromPrimitive, Signed, ToPrimitive};
 
-use crate::{CheckFailure, Float, Int, Update};
+use crate::{CheckFailure, Float, Int};
 
 /// Powers of two that we store for constants. Account for binary128 which has a 15-bit exponent.
 const POWERS_OF_TWO_RANGE: RangeInclusive<i32> = (-(2 << 15))..=(2 << 15);
@@ -89,10 +89,16 @@ impl Constants {
 }
 
 /// Validate that a string parses correctly
-pub fn validate<F: Float>(input: &str) -> Result<(), Update> {
-    let parsed: F = input
-        .parse()
-        .unwrap_or_else(|e| panic!("parsing failed for {}: {e}. Input: {input}", type_name::<F>()));
+pub fn validate<F: Float>(input: &str) -> Result<(), CheckError> {
+    // Catch panics in case debug assertions within `std` fail.
+    let parsed = std::panic::catch_unwind(|| {
+        input.parse::<F>().map_err(|e| CheckError {
+            fail: CheckFailure::ParsingFailed(e.to_string().into()),
+            input: input.into(),
+            float_res: "none".into(),
+        })
+    })
+    .map_err(|e| convert_panic_error(&e, input))??;
 
     // Parsed float, decoded into significand and exponent
     let decoded = decode(parsed);
@@ -104,6 +110,21 @@ pub fn validate<F: Float>(input: &str) -> Result<(), Update> {
     decoded.check(rational, input)
 }
 
+/// Turn panics into concrete error types.
+fn convert_panic_error(e: &dyn Any, input: &str) -> CheckError {
+    let msg = e
+        .downcast_ref::<String>()
+        .map(|s| s.as_str())
+        .or_else(|| e.downcast_ref::<&str>().copied())
+        .unwrap_or("(no contents)");
+
+    CheckError {
+        fail: CheckFailure::Panic(msg.into()),
+        input: input.into(),
+        float_res: "none".into(),
+    }
+}
+
 /// The result of parsing a string to a float type.
 #[derive(Clone, Copy, Debug, PartialEq)]
 pub enum FloatRes<F: Float> {
@@ -118,10 +139,19 @@ pub enum FloatRes<F: Float> {
     },
 }
 
+#[derive(Clone, Debug)]
+pub struct CheckError {
+    pub fail: CheckFailure,
+    /// String for which parsing was attempted.
+    pub input: Box<str>,
+    /// The parsed & decomposed `FloatRes`, already stringified so we don't need generics here.
+    pub float_res: Box<str>,
+}
+
 impl<F: Float> FloatRes<F> {
     /// Given a known exact rational, check that this representation is accurate within the
     /// limits of the float representation. If not, construct a failure `Update` to send.
-    fn check(self, expected: Rational, input: &str) -> Result<(), Update> {
+    fn check(self, expected: Rational, input: &str) -> Result<(), CheckError> {
         let consts = F::constants();
         // let bool_helper = |cond: bool, err| cond.then_some(()).ok_or(err);
 
@@ -173,7 +203,7 @@ impl<F: Float> FloatRes<F> {
             (Rational::Finite(r), FloatRes::Real { sig, exp }) => Self::validate_real(r, sig, exp),
         };
 
-        res.map_err(|fail| Update::Failure {
+        res.map_err(|fail| CheckError {
             fail,
             input: input.into(),
             float_res: format!("{self:?}").into(),
diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml
index 91cc4088788..909b81a723b 100644
--- a/src/librustdoc/Cargo.toml
+++ b/src/librustdoc/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "rustdoc"
 version = "0.0.0"
-edition = "2021"
+edition = "2024"
 build = "build.rs"
 
 [lib]
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index bec7fbe8f52..ab169f3c2a4 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -48,12 +48,12 @@ impl Cfg {
         exclude: &FxHashSet<Cfg>,
     ) -> Result<Option<Cfg>, InvalidCfgError> {
         match nested_cfg {
-            MetaItemInner::MetaItem(ref cfg) => Cfg::parse_without(cfg, exclude),
+            MetaItemInner::MetaItem(cfg) => Cfg::parse_without(cfg, exclude),
             MetaItemInner::Lit(MetaItemLit { kind: LitKind::Bool(b), .. }) => match *b {
                 true => Ok(Some(Cfg::True)),
                 false => Ok(Some(Cfg::False)),
             },
-            MetaItemInner::Lit(ref lit) => {
+            MetaItemInner::Lit(lit) => {
                 Err(InvalidCfgError { msg: "unexpected literal", span: lit.span })
             }
         }
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index e10a74221ae..8c6ea00d489 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -563,11 +563,13 @@ pub(crate) fn build_impl(
     // Return if the trait itself or any types of the generic parameters are doc(hidden).
     let mut stack: Vec<&Type> = vec![&for_];
 
-    if let Some(did) = trait_.as_ref().map(|t| t.def_id()) {
-        if !document_hidden && tcx.is_doc_hidden(did) {
-            return;
-        }
+    if let Some(did) = trait_.as_ref().map(|t| t.def_id())
+        && !document_hidden
+        && tcx.is_doc_hidden(did)
+    {
+        return;
     }
+
     if let Some(generics) = trait_.as_ref().and_then(|t| t.generics()) {
         stack.extend(generics);
     }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index ceffe5e5ce0..97ff4c2ef40 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -741,7 +741,7 @@ pub(crate) fn clean_generics<'tcx>(
     for p in gens.params.iter().filter(|p| !is_impl_trait(p) && !is_elided_lifetime(p)) {
         let mut p = clean_generic_param(cx, Some(gens), p);
         match &mut p.kind {
-            GenericParamDefKind::Lifetime { ref mut outlives } => {
+            GenericParamDefKind::Lifetime { outlives } => {
                 if let Some(region_pred) = region_predicates.get_mut(&Lifetime(p.name)) {
                     // We merge bounds in the `where` clause.
                     for outlive in outlives.drain(..) {
@@ -828,30 +828,26 @@ fn clean_ty_generics<'tcx>(
         .iter()
         .flat_map(|(pred, _)| {
             let mut projection = None;
-            let param_idx = (|| {
+            let param_idx = {
                 let bound_p = pred.kind();
                 match bound_p.skip_binder() {
-                    ty::ClauseKind::Trait(pred) => {
-                        if let ty::Param(param) = pred.self_ty().kind() {
-                            return Some(param.index);
-                        }
+                    ty::ClauseKind::Trait(pred) if let ty::Param(param) = pred.self_ty().kind() => {
+                        Some(param.index)
                     }
-                    ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg)) => {
-                        if let ty::Param(param) = ty.kind() {
-                            return Some(param.index);
-                        }
+                    ty::ClauseKind::TypeOutlives(ty::OutlivesPredicate(ty, _reg))
+                        if let ty::Param(param) = ty.kind() =>
+                    {
+                        Some(param.index)
                     }
-                    ty::ClauseKind::Projection(p) => {
-                        if let ty::Param(param) = p.projection_term.self_ty().kind() {
-                            projection = Some(bound_p.rebind(p));
-                            return Some(param.index);
-                        }
+                    ty::ClauseKind::Projection(p)
+                        if let ty::Param(param) = p.projection_term.self_ty().kind() =>
+                    {
+                        projection = Some(bound_p.rebind(p));
+                        Some(param.index)
                     }
-                    _ => (),
+                    _ => None,
                 }
-
-                None
-            })();
+            };
 
             if let Some(param_idx) = param_idx
                 && let Some(bounds) = impl_trait.get_mut(&param_idx)
@@ -1378,12 +1374,12 @@ pub(crate) fn clean_middle_assoc_item(assoc_item: &ty::AssocItem, cx: &mut DocCo
                     tcx.fn_sig(assoc_item.def_id).instantiate_identity().input(0).skip_binder();
                 if self_arg_ty == self_ty {
                     item.decl.inputs.values[0].type_ = SelfTy;
-                } else if let ty::Ref(_, ty, _) = *self_arg_ty.kind() {
-                    if ty == self_ty {
-                        match item.decl.inputs.values[0].type_ {
-                            BorrowedRef { ref mut type_, .. } => **type_ = SelfTy,
-                            _ => unreachable!(),
-                        }
+                } else if let ty::Ref(_, ty, _) = *self_arg_ty.kind()
+                    && ty == self_ty
+                {
+                    match item.decl.inputs.values[0].type_ {
+                        BorrowedRef { ref mut type_, .. } => **type_ = SelfTy,
+                        _ => unreachable!(),
                     }
                 }
             }
@@ -2331,25 +2327,22 @@ fn clean_middle_opaque_bounds<'tcx>(
             let bindings: ThinVec<_> = bounds
                 .iter()
                 .filter_map(|(bound, _)| {
-                    if let ty::ClauseKind::Projection(proj) = bound.kind().skip_binder() {
-                        if proj.projection_term.trait_ref(cx.tcx) == trait_ref.skip_binder() {
-                            Some(AssocItemConstraint {
-                                assoc: projection_to_path_segment(
-                                    // FIXME: This needs to be made resilient for `AliasTerm`s that
-                                    // are associated consts.
-                                    bound.kind().rebind(proj.projection_term.expect_ty(cx.tcx)),
-                                    cx,
-                                ),
-                                kind: AssocItemConstraintKind::Equality {
-                                    term: clean_middle_term(bound.kind().rebind(proj.term), cx),
-                                },
-                            })
-                        } else {
-                            None
-                        }
-                    } else {
-                        None
+                    if let ty::ClauseKind::Projection(proj) = bound.kind().skip_binder()
+                        && proj.projection_term.trait_ref(cx.tcx) == trait_ref.skip_binder()
+                    {
+                        return Some(AssocItemConstraint {
+                            assoc: projection_to_path_segment(
+                                // FIXME: This needs to be made resilient for `AliasTerm`s that
+                                // are associated consts.
+                                bound.kind().rebind(proj.projection_term.expect_ty(cx.tcx)),
+                                cx,
+                            ),
+                            kind: AssocItemConstraintKind::Equality {
+                                term: clean_middle_term(bound.kind().rebind(proj.term), cx),
+                            },
+                        });
                     }
+                    None
                 })
                 .collect();
 
@@ -2539,7 +2532,7 @@ fn clean_generic_args<'tcx>(
 ) -> GenericArgs {
     // FIXME(return_type_notation): Fix RTN parens rendering
     if let Some((inputs, output)) = generic_args.paren_sugar_inputs_output() {
-        let inputs = inputs.iter().map(|x| clean_ty(x, cx)).collect::<ThinVec<_>>().into();
+        let inputs = inputs.iter().map(|x| clean_ty(x, cx)).collect();
         let output = match output.kind {
             hir::TyKind::Tup(&[]) => None,
             _ => Some(Box::new(clean_ty(output, cx))),
@@ -2560,8 +2553,7 @@ fn clean_generic_args<'tcx>(
                 }
                 hir::GenericArg::Infer(_inf) => GenericArg::Infer,
             })
-            .collect::<ThinVec<_>>()
-            .into();
+            .collect();
         let constraints = generic_args
             .constraints
             .iter()
@@ -2688,7 +2680,7 @@ fn filter_doc_attr_ident(ident: Symbol, is_inline: bool) -> bool {
 /// Before calling this function, make sure `normal` is a `#[doc]` attribute.
 fn filter_doc_attr(args: &mut hir::AttrArgs, is_inline: bool) {
     match args {
-        hir::AttrArgs::Delimited(ref mut args) => {
+        hir::AttrArgs::Delimited(args) => {
             let tokens = filter_tokens_from_list(&args.tokens, |token| {
                 !matches!(
                     token,
@@ -2743,23 +2735,20 @@ fn add_without_unwanted_attributes<'hir>(
         }
         let mut attr = attr.clone();
         match attr {
-            hir::Attribute::Unparsed(ref mut normal) => {
-                if let [ident] = &*normal.path.segments {
-                    let ident = ident.name;
-                    if ident == sym::doc {
-                        filter_doc_attr(&mut normal.args, is_inline);
-                        attrs.push((Cow::Owned(attr), import_parent));
-                    } else if is_inline || ident != sym::cfg {
-                        // If it's not a `cfg()` attribute, we keep it.
-                        attrs.push((Cow::Owned(attr), import_parent));
-                    }
-                }
-            }
-            hir::Attribute::Parsed(..) => {
-                if is_inline {
+            hir::Attribute::Unparsed(ref mut normal) if let [ident] = &*normal.path.segments => {
+                let ident = ident.name;
+                if ident == sym::doc {
+                    filter_doc_attr(&mut normal.args, is_inline);
+                    attrs.push((Cow::Owned(attr), import_parent));
+                } else if is_inline || ident != sym::cfg {
+                    // If it's not a `cfg()` attribute, we keep it.
                     attrs.push((Cow::Owned(attr), import_parent));
                 }
             }
+            hir::Attribute::Parsed(..) if is_inline => {
+                attrs.push((Cow::Owned(attr), import_parent));
+            }
+            _ => {}
         }
     }
 }
@@ -2961,16 +2950,16 @@ fn clean_extern_crate<'tcx>(
         && !cx.is_json_output();
 
     let krate_owner_def_id = krate.owner_id.def_id;
-    if please_inline {
-        if let Some(items) = inline::try_inline(
+    if please_inline
+        && let Some(items) = inline::try_inline(
             cx,
             Res::Def(DefKind::Mod, crate_def_id),
             name,
             Some((attrs, Some(krate_owner_def_id))),
             &mut Default::default(),
-        ) {
-            return items;
-        }
+        )
+    {
+        return items;
     }
 
     vec![Item::from_def_id_and_parts(
diff --git a/src/librustdoc/clean/render_macro_matchers.rs b/src/librustdoc/clean/render_macro_matchers.rs
index 3cc5f8d615a..88db853d7c3 100644
--- a/src/librustdoc/clean/render_macro_matchers.rs
+++ b/src/librustdoc/clean/render_macro_matchers.rs
@@ -1,4 +1,4 @@
-use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw};
+use rustc_ast::token::{self, Delimiter, IdentIsRaw};
 use rustc_ast::tokenstream::{TokenStream, TokenTree};
 use rustc_ast_pretty::pprust::PrintState;
 use rustc_ast_pretty::pprust::state::State as Printer;
@@ -137,15 +137,10 @@ fn print_tts(printer: &mut Printer<'_>, tts: &TokenStream) {
                 (Dollar, token::Ident(..)) => (false, DollarIdent),
                 (DollarIdent, token::Colon) => (false, DollarIdentColon),
                 (DollarIdentColon, token::Ident(..)) => (false, Other),
-                (
-                    DollarParen,
-                    token::BinOp(BinOpToken::Plus | BinOpToken::Star) | token::Question,
-                ) => (false, Other),
+                (DollarParen, token::Plus | token::Star | token::Question) => (false, Other),
                 (DollarParen, _) => (false, DollarParenSep),
-                (DollarParenSep, token::BinOp(BinOpToken::Plus | BinOpToken::Star)) => {
-                    (false, Other)
-                }
-                (Pound, token::Not) => (false, PoundBang),
+                (DollarParenSep, token::Plus | token::Star) => (false, Other),
+                (Pound, token::Bang) => (false, PoundBang),
                 (_, token::Ident(symbol, IdentIsRaw::No))
                     if !usually_needs_space_between_keyword_and_open_delim(*symbol, tt.span) =>
                 {
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index 178b6a60b41..9e9cd528834 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -208,11 +208,11 @@ impl ExternalCrate {
                     .get_attrs(def_id, sym::doc)
                     .flat_map(|attr| attr.meta_item_list().unwrap_or_default());
                 for meta in meta_items {
-                    if meta.has_name(sym::keyword) {
-                        if let Some(v) = meta.value_str() {
-                            keyword = Some(v);
-                            break;
-                        }
+                    if meta.has_name(sym::keyword)
+                        && let Some(v) = meta.value_str()
+                    {
+                        keyword = Some(v);
+                        break;
                     }
                 }
                 return keyword.map(|p| (def_id, p));
@@ -502,7 +502,7 @@ impl Item {
         let Some(links) = cx.cache().intra_doc_links.get(&self.item_id) else { return vec![] };
         links
             .iter()
-            .filter_map(|ItemLink { link: s, link_text, page_id: id, ref fragment }| {
+            .filter_map(|ItemLink { link: s, link_text, page_id: id, fragment }| {
                 debug!(?id);
                 if let Ok((mut href, ..)) = href(*id, cx) {
                     debug!(?href);
@@ -1071,16 +1071,14 @@ pub(crate) fn extract_cfg_from_attrs<'a, I: Iterator<Item = &'a hir::Attribute>
     // treat #[target_feature(enable = "feat")] attributes as if they were
     // #[doc(cfg(target_feature = "feat"))] attributes as well
     for attr in hir_attr_lists(attrs, sym::target_feature) {
-        if attr.has_name(sym::enable) {
-            if attr.value_str().is_some() {
-                // Clone `enable = "feat"`, change to `target_feature = "feat"`.
-                // Unwrap is safe because `value_str` succeeded above.
-                let mut meta = attr.meta_item().unwrap().clone();
-                meta.path = ast::Path::from_ident(Ident::with_dummy_span(sym::target_feature));
-
-                if let Ok(feat_cfg) = Cfg::parse(&ast::MetaItemInner::MetaItem(meta)) {
-                    cfg &= feat_cfg;
-                }
+        if attr.has_name(sym::enable) && attr.value_str().is_some() {
+            // Clone `enable = "feat"`, change to `target_feature = "feat"`.
+            // Unwrap is safe because `value_str` succeeded above.
+            let mut meta = attr.meta_item().unwrap().clone();
+            meta.path = ast::Path::from_ident(Ident::with_dummy_span(sym::target_feature));
+
+            if let Ok(feat_cfg) = Cfg::parse(&ast::MetaItemInner::MetaItem(meta)) {
+                cfg &= feat_cfg;
             }
         }
     }
@@ -1150,7 +1148,7 @@ pub(crate) struct Attributes {
 }
 
 impl Attributes {
-    pub(crate) fn lists(&self, name: Symbol) -> impl Iterator<Item = ast::MetaItemInner> + '_ {
+    pub(crate) fn lists(&self, name: Symbol) -> impl Iterator<Item = ast::MetaItemInner> {
         hir_attr_lists(&self.other_attrs[..], name)
     }
 
@@ -1160,10 +1158,10 @@ impl Attributes {
                 continue;
             }
 
-            if let Some(items) = attr.meta_item_list() {
-                if items.iter().filter_map(|i| i.meta_item()).any(|it| it.has_name(flag)) {
-                    return true;
-                }
+            if let Some(items) = attr.meta_item_list()
+                && items.iter().filter_map(|i| i.meta_item()).any(|it| it.has_name(flag))
+            {
+                return true;
             }
         }
 
@@ -1864,7 +1862,7 @@ impl PrimitiveType {
             .copied()
     }
 
-    pub(crate) fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> + '_ {
+    pub(crate) fn all_impls(tcx: TyCtxt<'_>) -> impl Iterator<Item = DefId> {
         Self::simplified_types()
             .values()
             .flatten()
@@ -2259,7 +2257,7 @@ impl GenericArgs {
             GenericArgs::Parenthesized { inputs, output } => inputs.is_empty() && output.is_none(),
         }
     }
-    pub(crate) fn constraints<'a>(&'a self) -> Box<dyn Iterator<Item = AssocItemConstraint> + 'a> {
+    pub(crate) fn constraints(&self) -> Box<dyn Iterator<Item = AssocItemConstraint> + '_> {
         match self {
             GenericArgs::AngleBracketed { constraints, .. } => {
                 Box::new(constraints.iter().cloned())
@@ -2419,7 +2417,7 @@ impl ConstantKind {
             ConstantKind::Local { body, .. } | ConstantKind::Anonymous { body } => {
                 rendered_const(tcx, tcx.hir_body(body), tcx.hir_body_owner_def_id(body))
             }
-            ConstantKind::Infer { .. } => "_".to_string(),
+            ConstantKind::Infer => "_".to_string(),
         }
     }
 
diff --git a/src/librustdoc/clean/utils.rs b/src/librustdoc/clean/utils.rs
index 34656b26ce2..f81db58950c 100644
--- a/src/librustdoc/clean/utils.rs
+++ b/src/librustdoc/clean/utils.rs
@@ -60,7 +60,7 @@ pub(crate) fn krate(cx: &mut DocContext<'_>) -> Crate {
     let primitives = local_crate.primitives(cx.tcx);
     let keywords = local_crate.keywords(cx.tcx);
     {
-        let ItemKind::ModuleItem(ref mut m) = &mut module.inner.kind else { unreachable!() };
+        let ItemKind::ModuleItem(m) = &mut module.inner.kind else { unreachable!() };
         m.items.extend(primitives.iter().map(|&(def_id, prim)| {
             Item::from_def_id_and_parts(
                 def_id,
@@ -223,7 +223,7 @@ fn clean_middle_generic_args_with_constraints<'tcx>(
 
     let args = clean_middle_generic_args(cx, args.map_bound(|args| &args[..]), has_self, did);
 
-    GenericArgs::AngleBracketed { args: args.into(), constraints }
+    GenericArgs::AngleBracketed { args, constraints }
 }
 
 pub(super) fn clean_middle_path<'tcx>(
@@ -302,7 +302,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
     use rustc_hir::*;
     debug!("trying to get a name from pattern: {p:?}");
 
-    Symbol::intern(&match p.kind {
+    Symbol::intern(&match &p.kind {
         // FIXME(never_patterns): does this make sense?
         PatKind::Wild
         | PatKind::Err(_)
@@ -313,8 +313,9 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
         }
         PatKind::Binding(_, _, ident, _) => return ident.name,
         PatKind::Box(p) | PatKind::Ref(p, _) | PatKind::Guard(p, _) => return name_from_pat(p),
-        PatKind::TupleStruct(ref p, ..)
-        | PatKind::Expr(PatExpr { kind: PatExprKind::Path(ref p), .. }) => qpath_to_string(p),
+        PatKind::TupleStruct(p, ..) | PatKind::Expr(PatExpr { kind: PatExprKind::Path(p), .. }) => {
+            qpath_to_string(p)
+        }
         PatKind::Or(pats) => {
             fmt::from_fn(|f| pats.iter().map(|p| name_from_pat(p)).joined(" | ", f)).to_string()
         }
@@ -329,7 +330,7 @@ pub(crate) fn name_from_pat(p: &hir::Pat<'_>) -> Symbol {
             return Symbol::intern("()");
         }
         PatKind::Slice(begin, mid, end) => {
-            fn print_pat<'a>(pat: &'a Pat<'a>, wild: bool) -> impl Display + 'a {
+            fn print_pat(pat: &Pat<'_>, wild: bool) -> impl Display {
                 fmt::from_fn(move |f| {
                     if wild {
                         f.write_str("..")?;
@@ -393,7 +394,7 @@ pub(crate) fn print_evaluated_const(
 fn format_integer_with_underscore_sep(num: &str) -> String {
     let num_chars: Vec<_> = num.chars().collect();
     let mut num_start_index = if num_chars.first() == Some(&'-') { 1 } else { 0 };
-    let chunk_size = match num[num_start_index..].as_bytes() {
+    let chunk_size = match &num.as_bytes()[num_start_index..] {
         [b'0', b'b' | b'x', ..] => {
             num_start_index += 2;
             4
@@ -493,7 +494,7 @@ pub(crate) fn resolve_type(cx: &mut DocContext<'_>, path: Path) -> Type {
 pub(crate) fn synthesize_auto_trait_and_blanket_impls(
     cx: &mut DocContext<'_>,
     item_def_id: DefId,
-) -> impl Iterator<Item = Item> {
+) -> impl Iterator<Item = Item> + use<> {
     let auto_impls = cx
         .sess()
         .prof
@@ -523,7 +524,7 @@ pub(crate) fn register_res(cx: &mut DocContext<'_>, res: Res) -> DefId {
             | AssocConst
             | Variant
             | Fn
-            | TyAlias { .. }
+            | TyAlias
             | Enum
             | Trait
             | Struct
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index fd4d9845c89..9cf471733f9 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -315,23 +315,30 @@ pub(crate) enum ModuleSorting {
     Alphabetical,
 }
 
-#[derive(Copy, Clone, Debug, PartialEq, Eq)]
+#[derive(Clone, Debug, PartialEq, Eq)]
 pub(crate) enum EmitType {
     Unversioned,
     Toolchain,
     InvocationSpecific,
+    DepInfo(Option<PathBuf>),
 }
 
 impl FromStr for EmitType {
     type Err = ();
 
     fn from_str(s: &str) -> Result<Self, Self::Err> {
-        use EmitType::*;
         match s {
-            "unversioned-shared-resources" => Ok(Unversioned),
-            "toolchain-shared-resources" => Ok(Toolchain),
-            "invocation-specific" => Ok(InvocationSpecific),
-            _ => Err(()),
+            "unversioned-shared-resources" => Ok(Self::Unversioned),
+            "toolchain-shared-resources" => Ok(Self::Toolchain),
+            "invocation-specific" => Ok(Self::InvocationSpecific),
+            "dep-info" => Ok(Self::DepInfo(None)),
+            option => {
+                if let Some(file) = option.strip_prefix("dep-info=") {
+                    Ok(Self::DepInfo(Some(Path::new(file).into())))
+                } else {
+                    Err(())
+                }
+            }
         }
     }
 }
@@ -340,6 +347,15 @@ impl RenderOptions {
     pub(crate) fn should_emit_crate(&self) -> bool {
         self.emit.is_empty() || self.emit.contains(&EmitType::InvocationSpecific)
     }
+
+    pub(crate) fn dep_info(&self) -> Option<Option<&Path>> {
+        for emit in &self.emit {
+            if let EmitType::DepInfo(file) = emit {
+                return Some(file.as_deref());
+            }
+        }
+        None
+    }
 }
 
 /// Create the input (string or file path)
@@ -629,10 +645,10 @@ impl Options {
 
         let extension_css = matches.opt_str("e").map(|s| PathBuf::from(&s));
 
-        if let Some(ref p) = extension_css {
-            if !p.is_file() {
-                dcx.fatal("option --extend-css argument must be a file");
-            }
+        if let Some(ref p) = extension_css
+            && !p.is_file()
+        {
+            dcx.fatal("option --extend-css argument must be a file");
         }
 
         let mut themes = Vec::new();
@@ -704,10 +720,10 @@ impl Options {
         }
 
         let index_page = matches.opt_str("index-page").map(|s| PathBuf::from(&s));
-        if let Some(ref index_page) = index_page {
-            if !index_page.is_file() {
-                dcx.fatal("option `--index-page` argument must be a file");
-            }
+        if let Some(ref index_page) = index_page
+            && !index_page.is_file()
+        {
+            dcx.fatal("option `--index-page` argument must be a file");
         }
 
         let target = parse_target_triple(early_dcx, matches);
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 7221e2ce6b1..f95ae380fa8 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -15,11 +15,12 @@ use rustc_hir::def::Res;
 use rustc_hir::def_id::{DefId, DefIdMap, DefIdSet, LocalDefId};
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{HirId, Path};
-use rustc_interface::interface;
 use rustc_lint::{MissingDoc, late_lint_mod};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
-use rustc_session::config::{self, CrateType, ErrorOutputType, Input, ResolveDocLinks};
+use rustc_session::config::{
+    self, CrateType, ErrorOutputType, Input, OutFileName, OutputType, OutputTypes, ResolveDocLinks,
+};
 pub(crate) use rustc_session::config::{Options, UnstableOptions};
 use rustc_session::{Session, lint};
 use rustc_span::source_map;
@@ -219,7 +220,7 @@ pub(crate) fn create_config(
         remap_path_prefix,
         ..
     }: RustdocOptions,
-    RenderOptions { document_private, .. }: &RenderOptions,
+    render_options: &RenderOptions,
 ) -> rustc_interface::Config {
     // Add the doc cfg into the doc build.
     cfgs.push("doc".to_string());
@@ -245,8 +246,11 @@ pub(crate) fn create_config(
 
     let crate_types =
         if proc_macro_crate { vec![CrateType::ProcMacro] } else { vec![CrateType::Rlib] };
-    let resolve_doc_links =
-        if *document_private { ResolveDocLinks::All } else { ResolveDocLinks::Exported };
+    let resolve_doc_links = if render_options.document_private {
+        ResolveDocLinks::All
+    } else {
+        ResolveDocLinks::Exported
+    };
     let test = scrape_examples_options.map(|opts| opts.scrape_tests).unwrap_or(false);
     // plays with error output here!
     let sessopts = config::Options {
@@ -269,10 +273,18 @@ pub(crate) fn create_config(
         crate_name,
         test,
         remap_path_prefix,
+        output_types: if let Some(file) = render_options.dep_info() {
+            OutputTypes::new(&[(
+                OutputType::DepInfo,
+                file.map(|f| OutFileName::Real(f.to_path_buf())),
+            )])
+        } else {
+            OutputTypes::new(&[])
+        },
         ..Options::default()
     };
 
-    interface::Config {
+    rustc_interface::Config {
         opts: sessopts,
         crate_cfg: cfgs,
         crate_check_cfg: check_cfgs,
diff --git a/src/librustdoc/display.rs b/src/librustdoc/display.rs
index ee8dde013ee..aa0fad26520 100644
--- a/src/librustdoc/display.rs
+++ b/src/librustdoc/display.rs
@@ -22,7 +22,7 @@ where
         let mut iter = self.into_iter();
         let Some(first) = iter.next() else { return Ok(()) };
         first.fmt(f)?;
-        while let Some(item) = iter.next() {
+        for item in iter {
             f.write_str(sep)?;
             item.fmt(f)?;
         }
diff --git a/src/librustdoc/doctest/extracted.rs b/src/librustdoc/doctest/extracted.rs
index 03c8814a4c9..ce362eabfc4 100644
--- a/src/librustdoc/doctest/extracted.rs
+++ b/src/librustdoc/doctest/extracted.rs
@@ -33,7 +33,7 @@ impl ExtractedDocTests {
         opts: &super::GlobalTestOptions,
         options: &RustdocOptions,
     ) {
-        let edition = scraped_test.edition(&options);
+        let edition = scraped_test.edition(options);
 
         let ScrapedDocTest { filename, line, langstr, text, name } = scraped_test;
 
@@ -48,7 +48,7 @@ impl ExtractedDocTests {
         let (full_test_code, size) = doctest.generate_unique_doctest(
             &text,
             langstr.test_harness,
-            &opts,
+            opts,
             Some(&opts.crate_name),
         );
         self.doctests.push(ExtractedDocTest {
diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs
index 3ac7abd0aa5..907e2a3eb2f 100644
--- a/src/librustdoc/doctest/rust.rs
+++ b/src/librustdoc/doctest/rust.rs
@@ -98,10 +98,9 @@ impl HirCollector<'_> {
         let ast_attrs = self.tcx.hir().attrs(self.tcx.local_def_id_to_hir_id(def_id));
         if let Some(ref cfg) =
             extract_cfg_from_attrs(ast_attrs.iter(), self.tcx, &FxHashSet::default())
+            && !cfg.matches(&self.tcx.sess.psess, Some(self.tcx.features()))
         {
-            if !cfg.matches(&self.tcx.sess.psess, Some(self.tcx.features())) {
-                return;
-            }
+            return;
         }
 
         let has_name = !name.is_empty();
diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 4760e579199..2648641e53e 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -419,7 +419,9 @@ impl DocFolder for CacheBuilder<'_, '_> {
                 }
             }
 
-            if let Some(generics) = i.trait_.as_ref().and_then(|t| t.generics()) {
+            if let Some(trait_) = &i.trait_
+                && let Some(generics) = trait_.generics()
+            {
                 for bound in generics {
                     dids.extend(bound.def_id(self.cache));
                 }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 522ef1af376..8b8439a2535 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -15,7 +15,6 @@ use std::iter::{self, once};
 use itertools::Either;
 use rustc_abi::ExternAbi;
 use rustc_attr_parsing::{ConstStability, StabilityLevel, StableSince};
-use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
@@ -41,10 +40,10 @@ pub(crate) fn write_str(s: &mut String, f: fmt::Arguments<'_>) {
     s.write_fmt(f).unwrap();
 }
 
-pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>(
-    bounds: &'a [clean::GenericBound],
-    cx: &'a Context<'tcx>,
-) -> impl Display + 'a + Captures<'tcx> {
+pub(crate) fn print_generic_bounds(
+    bounds: &[clean::GenericBound],
+    cx: &Context<'_>,
+) -> impl Display {
     fmt::from_fn(move |f| {
         let mut bounds_dup = FxHashSet::default();
 
@@ -57,10 +56,7 @@ pub(crate) fn print_generic_bounds<'a, 'tcx: 'a>(
 }
 
 impl clean::GenericParamDef {
-    pub(crate) fn print<'a, 'tcx: 'a>(
-        &'a self,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'a + Captures<'tcx> {
+    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| match &self.kind {
             clean::GenericParamDefKind::Lifetime { outlives } => {
                 write!(f, "{}", self.name)?;
@@ -80,7 +76,7 @@ impl clean::GenericParamDef {
                     print_generic_bounds(bounds, cx).fmt(f)?;
                 }
 
-                if let Some(ref ty) = default {
+                if let Some(ty) = default {
                     f.write_str(" = ")?;
                     ty.print(cx).fmt(f)?;
                 }
@@ -107,10 +103,7 @@ impl clean::GenericParamDef {
 }
 
 impl clean::Generics {
-    pub(crate) fn print<'a, 'tcx: 'a>(
-        &'a self,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'a + Captures<'tcx> {
+    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| {
             let mut real_params = self.params.iter().filter(|p| !p.is_synthetic_param()).peekable();
             if real_params.peek().is_none() {
@@ -134,10 +127,7 @@ pub(crate) enum Ending {
     NoNewline,
 }
 
-fn print_where_predicate<'a, 'tcx: 'a>(
-    predicate: &'a clean::WherePredicate,
-    cx: &'a Context<'tcx>,
-) -> impl Display + 'a + Captures<'tcx> {
+fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) -> impl Display {
     fmt::from_fn(move |f| {
         match predicate {
             clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => {
@@ -173,12 +163,12 @@ fn print_where_predicate<'a, 'tcx: 'a>(
 /// * The Generics from which to emit a where-clause.
 /// * The number of spaces to indent each line with.
 /// * Whether the where-clause needs to add a comma and newline after the last bound.
-pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
-    gens: &'a clean::Generics,
-    cx: &'a Context<'tcx>,
+pub(crate) fn print_where_clause(
+    gens: &clean::Generics,
+    cx: &Context<'_>,
     indent: usize,
     ending: Ending,
-) -> Option<impl Display + 'a + Captures<'tcx>> {
+) -> Option<impl Display> {
     if gens.where_predicates.is_empty() {
         return None;
     }
@@ -250,13 +240,13 @@ pub(crate) fn print_where_clause<'a, 'tcx: 'a>(
 }
 
 impl clean::Lifetime {
-    pub(crate) fn print(&self) -> impl Display + '_ {
+    pub(crate) fn print(&self) -> impl Display {
         self.0.as_str()
     }
 }
 
 impl clean::ConstantKind {
-    pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display + '_ {
+    pub(crate) fn print(&self, tcx: TyCtxt<'_>) -> impl Display {
         let expr = self.expr(tcx);
         fmt::from_fn(move |f| {
             if f.alternate() { f.write_str(&expr) } else { write!(f, "{}", Escape(&expr)) }
@@ -265,7 +255,7 @@ impl clean::ConstantKind {
 }
 
 impl clean::PolyTrait {
-    fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> {
+    fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| {
             print_higher_ranked_params_with_space(&self.generic_params, cx, "for").fmt(f)?;
             self.trait_.print(cx).fmt(f)
@@ -274,10 +264,7 @@ impl clean::PolyTrait {
 }
 
 impl clean::GenericBound {
-    pub(crate) fn print<'a, 'tcx: 'a>(
-        &'a self,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'a + Captures<'tcx> {
+    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| match self {
             clean::GenericBound::Outlives(lt) => write!(f, "{}", lt.print()),
             clean::GenericBound::TraitBound(ty, modifiers) => {
@@ -304,7 +291,7 @@ impl clean::GenericBound {
 }
 
 impl clean::GenericArgs {
-    fn print<'a, 'tcx: 'a>(&'a self, cx: &'a Context<'tcx>) -> impl Display + 'a + Captures<'tcx> {
+    fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| {
             match self {
                 clean::GenericArgs::AngleBracketed { args, constraints } => {
@@ -636,10 +623,9 @@ pub(crate) fn href_relative_parts<'fqp>(
         // e.g. linking to std::iter from std::vec (`dissimilar_part_count` will be 1)
         if f != r {
             let dissimilar_part_count = relative_to_fqp.len() - i;
-            let fqp_module = &fqp[i..fqp.len()];
+            let fqp_module = &fqp[i..];
             return Box::new(
-                iter::repeat(sym::dotdot)
-                    .take(dissimilar_part_count)
+                iter::repeat_n(sym::dotdot, dissimilar_part_count)
                     .chain(fqp_module.iter().copied()),
             );
         }
@@ -652,7 +638,7 @@ pub(crate) fn href_relative_parts<'fqp>(
         Ordering::Greater => {
             // e.g. linking to std::sync from std::sync::atomic
             let dissimilar_part_count = relative_to_fqp.len() - fqp.len();
-            Box::new(iter::repeat(sym::dotdot).take(dissimilar_part_count))
+            Box::new(iter::repeat_n(sym::dotdot, dissimilar_part_count))
         }
         Ordering::Equal => {
             // linking to the same module
@@ -783,10 +769,9 @@ fn primitive_link_fragment(
                     ExternalLocation::Local => {
                         let cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx());
                         Some(if cx.current.first() == Some(&cname_sym) {
-                            iter::repeat(sym::dotdot).take(cx.current.len() - 1).collect()
+                            iter::repeat_n(sym::dotdot, cx.current.len() - 1).collect()
                         } else {
-                            iter::repeat(sym::dotdot)
-                                .take(cx.current.len())
+                            iter::repeat_n(sym::dotdot, cx.current.len())
                                 .chain(iter::once(cname_sym))
                                 .collect()
                         })
@@ -809,11 +794,11 @@ fn primitive_link_fragment(
     Ok(())
 }
 
-fn tybounds<'a, 'tcx: 'a>(
-    bounds: &'a [clean::PolyTrait],
-    lt: &'a Option<clean::Lifetime>,
-    cx: &'a Context<'tcx>,
-) -> impl Display + 'a + Captures<'tcx> {
+fn tybounds(
+    bounds: &[clean::PolyTrait],
+    lt: &Option<clean::Lifetime>,
+    cx: &Context<'_>,
+) -> impl Display {
     fmt::from_fn(move |f| {
         bounds.iter().map(|bound| bound.print(cx)).joined(" + ", f)?;
         if let Some(lt) = lt {
@@ -825,11 +810,11 @@ fn tybounds<'a, 'tcx: 'a>(
     })
 }
 
-fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>(
-    params: &'a [clean::GenericParamDef],
-    cx: &'a Context<'tcx>,
+fn print_higher_ranked_params_with_space(
+    params: &[clean::GenericParamDef],
+    cx: &Context<'_>,
     keyword: &'static str,
-) -> impl Display + 'a + Captures<'tcx> {
+) -> impl Display {
     fmt::from_fn(move |f| {
         if !params.is_empty() {
             f.write_str(keyword)?;
@@ -841,11 +826,7 @@ fn print_higher_ranked_params_with_space<'a, 'tcx: 'a>(
     })
 }
 
-pub(crate) fn anchor<'a: 'cx, 'cx>(
-    did: DefId,
-    text: Symbol,
-    cx: &'cx Context<'a>,
-) -> impl Display + Captures<'a> + 'cx {
+pub(crate) fn anchor(did: DefId, text: Symbol, cx: &Context<'_>) -> impl Display {
     fmt::from_fn(move |f| {
         let parts = href(did, cx);
         if let Ok((url, short_ty, fqp)) = parts {
@@ -1121,29 +1102,19 @@ fn fmt_type(
 }
 
 impl clean::Type {
-    pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>(
-        &'a self,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'b + Captures<'tcx> {
+    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| fmt_type(self, f, false, cx))
     }
 }
 
 impl clean::Path {
-    pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>(
-        &'a self,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'b + Captures<'tcx> {
+    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| resolved_path(f, self.def_id(), self, false, false, cx))
     }
 }
 
 impl clean::Impl {
-    pub(crate) fn print<'a, 'tcx: 'a>(
-        &'a self,
-        use_absolute: bool,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'a + Captures<'tcx> {
+    pub(crate) fn print(&self, use_absolute: bool, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| {
             f.write_str("impl")?;
             self.generics.print(cx).fmt(f)?;
@@ -1182,12 +1153,12 @@ impl clean::Impl {
             print_where_clause(&self.generics, cx, 0, Ending::Newline).maybe_display().fmt(f)
         })
     }
-    fn print_type<'a, 'tcx: 'a>(
+    fn print_type(
         &self,
         type_: &clean::Type,
         f: &mut fmt::Formatter<'_>,
         use_absolute: bool,
-        cx: &'a Context<'tcx>,
+        cx: &Context<'_>,
     ) -> Result<(), fmt::Error> {
         if let clean::Type::Tuple(types) = type_
             && let [clean::Type::Generic(name)] = &types[..]
@@ -1258,10 +1229,7 @@ impl clean::Impl {
 }
 
 impl clean::Arguments {
-    pub(crate) fn print<'a, 'tcx: 'a>(
-        &'a self,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'a + Captures<'tcx> {
+    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| {
             self.values
                 .iter()
@@ -1301,10 +1269,7 @@ impl Display for Indent {
 }
 
 impl clean::FnDecl {
-    pub(crate) fn print<'b, 'a: 'b, 'tcx: 'a>(
-        &'a self,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'b + Captures<'tcx> {
+    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| {
             let ellipsis = if self.c_variadic { ", ..." } else { "" };
             if f.alternate() {
@@ -1333,12 +1298,12 @@ impl clean::FnDecl {
     ///   are preserved.
     /// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is
     ///   necessary.
-    pub(crate) fn full_print<'a, 'tcx: 'a>(
-        &'a self,
+    pub(crate) fn full_print(
+        &self,
         header_len: usize,
         indent: usize,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'a + Captures<'tcx> {
+        cx: &Context<'_>,
+    ) -> impl Display {
         fmt::from_fn(move |f| {
             // First, generate the text form of the declaration, with no line wrapping, and count the bytes.
             let mut counter = WriteCounter(0);
@@ -1420,10 +1385,7 @@ impl clean::FnDecl {
         self.print_output(cx).fmt(f)
     }
 
-    fn print_output<'a, 'tcx: 'a>(
-        &'a self,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'a + Captures<'tcx> {
+    fn print_output(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| match &self.output {
             clean::Tuple(tys) if tys.is_empty() => Ok(()),
             ty if f.alternate() => {
@@ -1434,10 +1396,7 @@ impl clean::FnDecl {
     }
 }
 
-pub(crate) fn visibility_print_with_space<'a, 'tcx: 'a>(
-    item: &clean::Item,
-    cx: &'a Context<'tcx>,
-) -> impl Display + 'a + Captures<'tcx> {
+pub(crate) fn visibility_print_with_space(item: &clean::Item, cx: &Context<'_>) -> impl Display {
     use std::fmt::Write as _;
     let vis: Cow<'static, str> = match item.visibility(cx.tcx()) {
         None => "".into(),
@@ -1546,10 +1505,7 @@ pub(crate) fn print_constness_with_space(
 }
 
 impl clean::Import {
-    pub(crate) fn print<'a, 'tcx: 'a>(
-        &'a self,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'a + Captures<'tcx> {
+    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| match self.kind {
             clean::ImportKind::Simple(name) => {
                 if name == self.source.path.last() {
@@ -1570,10 +1526,7 @@ impl clean::Import {
 }
 
 impl clean::ImportSource {
-    pub(crate) fn print<'a, 'tcx: 'a>(
-        &'a self,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'a + Captures<'tcx> {
+    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| match self.did {
             Some(did) => resolved_path(f, did, &self.path, true, false, cx),
             _ => {
@@ -1593,10 +1546,7 @@ impl clean::ImportSource {
 }
 
 impl clean::AssocItemConstraint {
-    pub(crate) fn print<'a, 'tcx: 'a>(
-        &'a self,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'a + Captures<'tcx> {
+    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| {
             f.write_str(self.assoc.name.as_str())?;
             self.assoc.args.print(cx).fmt(f)?;
@@ -1627,15 +1577,12 @@ pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display {
     })
 }
 
-pub(crate) fn print_default_space<'a>(v: bool) -> &'a str {
+pub(crate) fn print_default_space(v: bool) -> &'static str {
     if v { "default " } else { "" }
 }
 
 impl clean::GenericArg {
-    pub(crate) fn print<'a, 'tcx: 'a>(
-        &'a self,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'a + Captures<'tcx> {
+    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| match self {
             clean::GenericArg::Lifetime(lt) => lt.print().fmt(f),
             clean::GenericArg::Type(ty) => ty.print(cx).fmt(f),
@@ -1646,10 +1593,7 @@ impl clean::GenericArg {
 }
 
 impl clean::Term {
-    pub(crate) fn print<'a, 'tcx: 'a>(
-        &'a self,
-        cx: &'a Context<'tcx>,
-    ) -> impl Display + 'a + Captures<'tcx> {
+    pub(crate) fn print(&self, cx: &Context<'_>) -> impl Display {
         fmt::from_fn(move |f| match self {
             clean::Term::Type(ty) => ty.print(cx).fmt(f),
             clean::Term::Constant(ct) => ct.print(cx.tcx()).fmt(f),
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index ed4b97d3625..c943d3ad4d0 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -100,7 +100,7 @@ fn write_header(
     }
 
     if let Some(extra) = extra_content {
-        out.push_str(&extra);
+        out.push_str(extra);
     }
     if class.is_empty() {
         write_str(
@@ -131,7 +131,7 @@ fn write_header(
 /// * If the other `Class` is unclassified and only contains white characters (backline,
 ///   whitespace, etc), it can be merged.
 /// * `Class::Ident` is considered the same as unclassified (because it doesn't have an associated
-///    CSS class).
+///   CSS class).
 fn can_merge(class1: Option<Class>, class2: Option<Class>, text: &str) -> bool {
     match (class1, class2) {
         (Some(c1), Some(c2)) => c1.is_equal_to(c2),
@@ -233,7 +233,7 @@ impl<F: Write> TokenHandler<'_, '_, F> {
 
     #[inline]
     fn write_line_number(&mut self, line: u32, extra: &'static str) {
-        (self.write_line_number)(&mut self.out, line, extra);
+        (self.write_line_number)(self.out, line, extra);
     }
 }
 
@@ -610,7 +610,7 @@ impl Decorations {
         let (mut starts, mut ends): (Vec<_>, Vec<_>) = info
             .0
             .iter()
-            .flat_map(|(&kind, ranges)| ranges.into_iter().map(move |&(lo, hi)| ((lo, kind), hi)))
+            .flat_map(|(&kind, ranges)| ranges.iter().map(move |&(lo, hi)| ((lo, kind), hi)))
             .unzip();
 
         // Sort the sequences in document order.
@@ -1102,53 +1102,52 @@ fn string_without_closing_tag<T: Display>(
         });
     }
 
-    if let Some(href_context) = href_context {
-        if let Some(href) =
-            href_context.context.shared.span_correspondence_map.get(&def_span).and_then(|href| {
-                let context = href_context.context;
-                // FIXME: later on, it'd be nice to provide two links (if possible) for all items:
-                // one to the documentation page and one to the source definition.
-                // FIXME: currently, external items only generate a link to their documentation,
-                // a link to their definition can be generated using this:
-                // https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338
-                match href {
-                    LinkFromSrc::Local(span) => {
-                        context.href_from_span_relative(*span, &href_context.current_href)
-                    }
-                    LinkFromSrc::External(def_id) => {
-                        format::href_with_root_path(*def_id, context, Some(href_context.root_path))
-                            .ok()
-                            .map(|(url, _, _)| url)
-                    }
-                    LinkFromSrc::Primitive(prim) => format::href_with_root_path(
-                        PrimitiveType::primitive_locations(context.tcx())[prim],
-                        context,
-                        Some(href_context.root_path),
-                    )
-                    .ok()
-                    .map(|(url, _, _)| url),
-                    LinkFromSrc::Doc(def_id) => {
-                        format::href_with_root_path(*def_id, context, Some(href_context.root_path))
-                            .ok()
-                            .map(|(doc_link, _, _)| doc_link)
-                    }
+    if let Some(href_context) = href_context
+        && let Some(href) = href_context.context.shared.span_correspondence_map.get(&def_span)
+        && let Some(href) = {
+            let context = href_context.context;
+            // FIXME: later on, it'd be nice to provide two links (if possible) for all items:
+            // one to the documentation page and one to the source definition.
+            // FIXME: currently, external items only generate a link to their documentation,
+            // a link to their definition can be generated using this:
+            // https://github.com/rust-lang/rust/blob/60f1a2fc4b535ead9c85ce085fdce49b1b097531/src/librustdoc/html/render/context.rs#L315-L338
+            match href {
+                LinkFromSrc::Local(span) => {
+                    context.href_from_span_relative(*span, &href_context.current_href)
                 }
-            })
-        {
-            if !open_tag {
-                // We're already inside an element which has the same klass, no need to give it
-                // again.
+                LinkFromSrc::External(def_id) => {
+                    format::href_with_root_path(*def_id, context, Some(href_context.root_path))
+                        .ok()
+                        .map(|(url, _, _)| url)
+                }
+                LinkFromSrc::Primitive(prim) => format::href_with_root_path(
+                    PrimitiveType::primitive_locations(context.tcx())[prim],
+                    context,
+                    Some(href_context.root_path),
+                )
+                .ok()
+                .map(|(url, _, _)| url),
+                LinkFromSrc::Doc(def_id) => {
+                    format::href_with_root_path(*def_id, context, Some(href_context.root_path))
+                        .ok()
+                        .map(|(doc_link, _, _)| doc_link)
+                }
+            }
+        }
+    {
+        if !open_tag {
+            // We're already inside an element which has the same klass, no need to give it
+            // again.
+            write!(out, "<a href=\"{href}\">{text_s}").unwrap();
+        } else {
+            let klass_s = klass.as_html();
+            if klass_s.is_empty() {
                 write!(out, "<a href=\"{href}\">{text_s}").unwrap();
             } else {
-                let klass_s = klass.as_html();
-                if klass_s.is_empty() {
-                    write!(out, "<a href=\"{href}\">{text_s}").unwrap();
-                } else {
-                    write!(out, "<a class=\"{klass_s}\" href=\"{href}\">{text_s}").unwrap();
-                }
+                write!(out, "<a class=\"{klass_s}\" href=\"{href}\">{text_s}").unwrap();
             }
-            return Some("</a>");
         }
+        return Some("</a>");
     }
     if !open_tag {
         write!(out, "{}", text_s).unwrap();
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index d9e49577d39..079651e8603 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -1308,18 +1308,17 @@ impl LangString {
                         seen_other_tags = true;
                         data.unknown.push(x.to_owned());
                     }
-                    LangStringToken::KeyValueAttribute(key, value) => {
-                        if key == "class" {
-                            data.added_classes.push(value.to_owned());
-                        } else if let Some(extra) = extra {
-                            extra.error_invalid_codeblock_attr(format!(
-                                "unsupported attribute `{key}`"
-                            ));
-                        }
+                    LangStringToken::KeyValueAttribute("class", value) => {
+                        data.added_classes.push(value.to_owned());
+                    }
+                    LangStringToken::KeyValueAttribute(key, ..) if let Some(extra) = extra => {
+                        extra
+                            .error_invalid_codeblock_attr(format!("unsupported attribute `{key}`"));
                     }
                     LangStringToken::ClassAttribute(class) => {
                         data.added_classes.push(class.to_owned());
                     }
+                    _ => {}
                 }
             }
         };
@@ -1792,7 +1791,7 @@ pub(crate) fn markdown_links<'md, R>(
                     }
                 }
             } else if !c.is_ascii_whitespace() {
-                while let Some((j, c)) = iter.next() {
+                for (j, c) in iter.by_ref() {
                     if c.is_ascii_whitespace() {
                         return MarkdownLinkRange::Destination(i + span.start..j + span.start);
                     }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index bd4af359404..b2ad2fa773a 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -47,7 +47,6 @@ use rinja::Template;
 use rustc_attr_parsing::{
     ConstStability, DeprecatedSince, Deprecation, RustcVersion, StabilityLevel, StableSince,
 };
-use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_hir::Mutability;
 use rustc_hir::def_id::{DefId, DefIdSet};
@@ -82,7 +81,7 @@ use crate::html::{highlight, sources};
 use crate::scrape_examples::{CallData, CallLocation};
 use crate::{DOC_RUST_LANG_ORG_VERSION, try_none};
 
-pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display + '_ {
+pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display {
     fmt::from_fn(move |f| {
         if !v.ends_with('/') && !v.is_empty() { write!(f, "{v}/") } else { f.write_str(v) }
     })
@@ -310,7 +309,7 @@ impl ItemEntry {
 }
 
 impl ItemEntry {
-    pub(crate) fn print(&self) -> impl fmt::Display + '_ {
+    pub(crate) fn print(&self) -> impl fmt::Display {
         fmt::from_fn(move |f| write!(f, "<a href=\"{}\">{}</a>", self.url, Escape(&self.name)))
     }
 }
@@ -505,12 +504,12 @@ fn scrape_examples_help(shared: &SharedContext<'_>) -> String {
     )
 }
 
-fn document<'a, 'cx: 'a>(
-    cx: &'a Context<'cx>,
-    item: &'a clean::Item,
-    parent: Option<&'a clean::Item>,
+fn document(
+    cx: &Context<'_>,
+    item: &clean::Item,
+    parent: Option<&clean::Item>,
     heading_offset: HeadingOffset,
-) -> impl fmt::Display + 'a + Captures<'cx> {
+) -> impl fmt::Display {
     if let Some(ref name) = item.name {
         info!("Documenting {name}");
     }
@@ -526,12 +525,12 @@ fn document<'a, 'cx: 'a>(
 }
 
 /// Render md_text as markdown.
-fn render_markdown<'a, 'cx: 'a>(
-    cx: &'a Context<'cx>,
-    md_text: &'a str,
+fn render_markdown(
+    cx: &Context<'_>,
+    md_text: &str,
     links: Vec<RenderedLink>,
     heading_offset: HeadingOffset,
-) -> impl fmt::Display + 'a + Captures<'cx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |f| {
         write!(
             f,
@@ -552,13 +551,13 @@ fn render_markdown<'a, 'cx: 'a>(
 
 /// Writes a documentation block containing only the first paragraph of the documentation. If the
 /// docs are longer, a "Read more" link is appended to the end.
-fn document_short<'a, 'cx: 'a>(
-    item: &'a clean::Item,
-    cx: &'a Context<'cx>,
-    link: AssocItemLink<'a>,
-    parent: &'a clean::Item,
+fn document_short(
+    item: &clean::Item,
+    cx: &Context<'_>,
+    link: AssocItemLink<'_>,
+    parent: &clean::Item,
     show_def_docs: bool,
-) -> impl fmt::Display + 'a + Captures<'cx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |f| {
         document_item_info(cx, item, Some(parent)).render_into(f).unwrap();
         if !show_def_docs {
@@ -595,28 +594,28 @@ fn document_short<'a, 'cx: 'a>(
     })
 }
 
-fn document_full_collapsible<'a, 'cx: 'a>(
-    item: &'a clean::Item,
-    cx: &'a Context<'cx>,
+fn document_full_collapsible(
+    item: &clean::Item,
+    cx: &Context<'_>,
     heading_offset: HeadingOffset,
-) -> impl fmt::Display + 'a + Captures<'cx> {
+) -> impl fmt::Display {
     document_full_inner(item, cx, true, heading_offset)
 }
 
-fn document_full<'a, 'cx: 'a>(
-    item: &'a clean::Item,
-    cx: &'a Context<'cx>,
+fn document_full(
+    item: &clean::Item,
+    cx: &Context<'_>,
     heading_offset: HeadingOffset,
-) -> impl fmt::Display + 'a + Captures<'cx> {
+) -> impl fmt::Display {
     document_full_inner(item, cx, false, heading_offset)
 }
 
-fn document_full_inner<'a, 'cx: 'a>(
-    item: &'a clean::Item,
-    cx: &'a Context<'cx>,
+fn document_full_inner(
+    item: &clean::Item,
+    cx: &Context<'_>,
     is_collapsible: bool,
     heading_offset: HeadingOffset,
-) -> impl fmt::Display + 'a + Captures<'cx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |f| {
         if let Some(s) = item.opt_doc_value() {
             debug!("Doc block: =====\n{s}\n=====");
@@ -797,11 +796,11 @@ pub(crate) fn render_impls(
 }
 
 /// Build a (possibly empty) `href` attribute (a key-value pair) for the given associated item.
-fn assoc_href_attr<'a, 'tcx>(
+fn assoc_href_attr(
     it: &clean::Item,
-    link: AssocItemLink<'a>,
-    cx: &Context<'tcx>,
-) -> Option<impl fmt::Display + 'a + Captures<'tcx>> {
+    link: AssocItemLink<'_>,
+    cx: &Context<'_>,
+) -> Option<impl fmt::Display> {
     let name = it.name.unwrap();
     let item_type = it.type_();
 
@@ -812,7 +811,7 @@ fn assoc_href_attr<'a, 'tcx>(
     }
 
     let href = match link {
-        AssocItemLink::Anchor(Some(ref id)) => Href::AnchorId(id),
+        AssocItemLink::Anchor(Some(id)) => Href::AnchorId(id),
         AssocItemLink::Anchor(None) => Href::Anchor(item_type),
         AssocItemLink::GotoSource(did, provided_methods) => {
             // We're creating a link from the implementation of an associated item to its
@@ -877,15 +876,15 @@ enum AssocConstValue<'a> {
     None,
 }
 
-fn assoc_const<'a, 'tcx>(
-    it: &'a clean::Item,
-    generics: &'a clean::Generics,
-    ty: &'a clean::Type,
-    value: AssocConstValue<'a>,
-    link: AssocItemLink<'a>,
+fn assoc_const(
+    it: &clean::Item,
+    generics: &clean::Generics,
+    ty: &clean::Type,
+    value: AssocConstValue<'_>,
+    link: AssocItemLink<'_>,
     indent: usize,
-    cx: &'a Context<'tcx>,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+    cx: &Context<'_>,
+) -> impl fmt::Display {
     let tcx = cx.tcx();
     fmt::from_fn(move |w| {
         write!(
@@ -917,15 +916,15 @@ fn assoc_const<'a, 'tcx>(
     })
 }
 
-fn assoc_type<'a, 'tcx>(
-    it: &'a clean::Item,
-    generics: &'a clean::Generics,
-    bounds: &'a [clean::GenericBound],
-    default: Option<&'a clean::Type>,
-    link: AssocItemLink<'a>,
+fn assoc_type(
+    it: &clean::Item,
+    generics: &clean::Generics,
+    bounds: &[clean::GenericBound],
+    default: Option<&clean::Type>,
+    link: AssocItemLink<'_>,
     indent: usize,
-    cx: &'a Context<'tcx>,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+    cx: &Context<'_>,
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         write!(
             w,
@@ -947,15 +946,15 @@ fn assoc_type<'a, 'tcx>(
     })
 }
 
-fn assoc_method<'a, 'tcx>(
-    meth: &'a clean::Item,
-    g: &'a clean::Generics,
-    d: &'a clean::FnDecl,
-    link: AssocItemLink<'a>,
+fn assoc_method(
+    meth: &clean::Item,
+    g: &clean::Generics,
+    d: &clean::FnDecl,
+    link: AssocItemLink<'_>,
     parent: ItemType,
-    cx: &'a Context<'tcx>,
+    cx: &Context<'_>,
     render_mode: RenderMode,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     let tcx = cx.tcx();
     let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item");
     let name = meth.name.as_ref().unwrap();
@@ -1031,7 +1030,7 @@ fn render_stability_since_raw_with_extra(
     stable_version: Option<StableSince>,
     const_stability: Option<ConstStability>,
     extra_class: &str,
-) -> Option<impl fmt::Display + '_> {
+) -> Option<impl fmt::Display> {
     let mut title = String::new();
     let mut stability = String::new();
 
@@ -1102,13 +1101,13 @@ fn render_stability_since_raw(
     render_stability_since_raw_with_extra(ver, const_stability, "")
 }
 
-fn render_assoc_item<'a, 'tcx>(
-    item: &'a clean::Item,
-    link: AssocItemLink<'a>,
+fn render_assoc_item(
+    item: &clean::Item,
+    link: AssocItemLink<'_>,
     parent: ItemType,
-    cx: &'a Context<'tcx>,
+    cx: &Context<'_>,
     render_mode: RenderMode,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |f| match &item.kind {
         clean::StrippedItem(..) => Ok(()),
         clean::RequiredMethodItem(m) | clean::MethodItem(m, _) => {
@@ -1144,7 +1143,7 @@ fn render_assoc_item<'a, 'tcx>(
             cx,
         )
         .fmt(f),
-        clean::RequiredAssocTypeItem(ref generics, ref bounds) => assoc_type(
+        clean::RequiredAssocTypeItem(generics, bounds) => assoc_type(
             item,
             generics,
             bounds,
@@ -1154,7 +1153,7 @@ fn render_assoc_item<'a, 'tcx>(
             cx,
         )
         .fmt(f),
-        clean::AssocTypeItem(ref ty, ref bounds) => assoc_type(
+        clean::AssocTypeItem(ty, bounds) => assoc_type(
             item,
             &ty.generics,
             bounds,
@@ -1170,11 +1169,7 @@ fn render_assoc_item<'a, 'tcx>(
 
 // When an attribute is rendered inside a `<pre>` tag, it is formatted using
 // a whitespace prefix and newline.
-fn render_attributes_in_pre<'a, 'tcx: 'a>(
-    it: &'a clean::Item,
-    prefix: &'a str,
-    cx: &'a Context<'tcx>,
-) -> impl fmt::Display + Captures<'a> + Captures<'tcx> {
+fn render_attributes_in_pre(it: &clean::Item, prefix: &str, cx: &Context<'_>) -> impl fmt::Display {
     fmt::from_fn(move |f| {
         for a in it.attributes(cx.tcx(), cx.cache(), false) {
             writeln!(f, "{prefix}{a}")?;
@@ -1206,12 +1201,12 @@ impl<'a> AssocItemLink<'a> {
     }
 }
 
-pub fn write_section_heading<'a>(
-    title: &'a str,
-    id: &'a str,
-    extra_class: Option<&'a str>,
-    extra: impl fmt::Display + 'a,
-) -> impl fmt::Display + 'a {
+pub fn write_section_heading(
+    title: &str,
+    id: &str,
+    extra_class: Option<&str>,
+    extra: impl fmt::Display,
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         let (extra_class, whitespace) = match extra_class {
             Some(extra) => (extra, " "),
@@ -1227,7 +1222,7 @@ pub fn write_section_heading<'a>(
     })
 }
 
-fn write_impl_section_heading<'a>(title: &'a str, id: &'a str) -> impl fmt::Display + 'a {
+fn write_impl_section_heading(title: &str, id: &str) -> impl fmt::Display {
     write_section_heading(title, id, None, "")
 }
 
@@ -1276,12 +1271,12 @@ pub(crate) fn render_all_impls(
     }
 }
 
-fn render_assoc_items<'a, 'cx: 'a>(
-    cx: &'a Context<'cx>,
-    containing_item: &'a clean::Item,
+fn render_assoc_items(
+    cx: &Context<'_>,
+    containing_item: &clean::Item,
     it: DefId,
-    what: AssocItemRender<'a>,
-) -> impl fmt::Display + 'a + Captures<'cx> {
+    what: AssocItemRender<'_>,
+) -> impl fmt::Display {
     fmt::from_fn(move |f| {
         let mut derefs = DefIdSet::default();
         derefs.insert(it);
@@ -1466,10 +1461,10 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
     }
 }
 
-pub(crate) fn notable_traits_button<'a, 'tcx>(
-    ty: &'a clean::Type,
-    cx: &'a Context<'tcx>,
-) -> Option<impl fmt::Display + 'a + Captures<'tcx>> {
+pub(crate) fn notable_traits_button(
+    ty: &clean::Type,
+    cx: &Context<'_>,
+) -> Option<impl fmt::Display> {
     let mut has_notable_trait = false;
 
     if ty.is_unit() {
@@ -1623,16 +1618,16 @@ struct ImplRenderingParameters {
     toggle_open_by_default: bool,
 }
 
-fn render_impl<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    i: &'a Impl,
-    parent: &'a clean::Item,
-    link: AssocItemLink<'a>,
+fn render_impl(
+    cx: &Context<'_>,
+    i: &Impl,
+    parent: &clean::Item,
+    link: AssocItemLink<'_>,
     render_mode: RenderMode,
     use_absolute: Option<bool>,
-    aliases: &'a [String],
+    aliases: &[String],
     rendering_params: ImplRenderingParameters,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         let cache = &cx.shared.cache;
         let traits = &cache.traits;
@@ -1780,7 +1775,7 @@ fn render_impl<'a, 'tcx>(
                         );
                     }
                 }
-                clean::RequiredAssocConstItem(ref generics, ref ty) => {
+                clean::RequiredAssocConstItem(generics, ty) => {
                     let source_id = format!("{item_type}.{name}");
                     let id = cx.derive_id(&source_id);
                     write_str(
@@ -1847,7 +1842,7 @@ fn render_impl<'a, 'tcx>(
                         ),
                     );
                 }
-                clean::RequiredAssocTypeItem(ref generics, ref bounds) => {
+                clean::RequiredAssocTypeItem(generics, bounds) => {
                     let source_id = format!("{item_type}.{name}");
                     let id = cx.derive_id(&source_id);
                     write_str(
@@ -2135,11 +2130,11 @@ fn render_impl<'a, 'tcx>(
 
 // Render the items that appear on the right side of methods, impls, and
 // associated types. For example "1.0.0 (const: 1.39.0) · source".
-fn render_rightside<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    item: &'a clean::Item,
+fn render_rightside(
+    cx: &Context<'_>,
+    item: &clean::Item,
     render_mode: RenderMode,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     let tcx = cx.tcx();
 
     fmt::from_fn(move |w| {
@@ -2174,17 +2169,17 @@ fn render_rightside<'a, 'tcx>(
     })
 }
 
-pub(crate) fn render_impl_summary<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    i: &'a Impl,
-    parent: &'a clean::Item,
+pub(crate) fn render_impl_summary(
+    cx: &Context<'_>,
+    i: &Impl,
+    parent: &clean::Item,
     show_def_docs: bool,
     use_absolute: Option<bool>,
     // This argument is used to reference same type with different paths to avoid duplication
     // in documentation pages for trait with automatic implementations like "Send" and "Sync".
-    aliases: &'a [String],
-    doc: Option<&'a str>,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+    aliases: &[String],
+    doc: Option<&str>,
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         let inner_impl = i.inner_impl();
         let id = cx.derive_id(get_id_for_impl(cx.tcx(), i.impl_item.item_id));
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index b647b2aad75..3c5c2ce1976 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -1,10 +1,9 @@
 use std::cmp::Ordering;
-use std::fmt;
-use std::fmt::{Display, Write as _};
+use std::fmt::{self, Display, Write as _};
+use std::iter;
 
 use rinja::Template;
 use rustc_abi::VariantIdx;
-use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
 use rustc_hir as hir;
 use rustc_hir::def::CtorKind;
@@ -92,44 +91,32 @@ macro_rules! item_template {
 macro_rules! item_template_methods {
     () => {};
     (document $($rest:tt)*) => {
-        fn document<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
-            fmt::from_fn(move |f| {
-                let (item, cx) = self.item_and_cx();
-                let v = document(cx, item, None, HeadingOffset::H2);
-                write!(f, "{v}")
-            })
+        fn document(&self) -> impl fmt::Display {
+            let (item, cx) = self.item_and_cx();
+            document(cx, item, None, HeadingOffset::H2)
         }
         item_template_methods!($($rest)*);
     };
     (document_type_layout $($rest:tt)*) => {
-        fn document_type_layout<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
-            fmt::from_fn(move |f| {
-                let (item, cx) = self.item_and_cx();
-                let def_id = item.item_id.expect_def_id();
-                let v = document_type_layout(cx, def_id);
-                write!(f, "{v}")
-            })
+        fn document_type_layout(&self) -> impl fmt::Display {
+            let (item, cx) = self.item_and_cx();
+            let def_id = item.item_id.expect_def_id();
+            document_type_layout(cx, def_id)
         }
         item_template_methods!($($rest)*);
     };
     (render_attributes_in_pre $($rest:tt)*) => {
-        fn render_attributes_in_pre<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
-            fmt::from_fn(move |f| {
-                let (item, cx) = self.item_and_cx();
-                let v = render_attributes_in_pre(item, "", cx);
-                write!(f, "{v}")
-            })
+        fn render_attributes_in_pre(&self) -> impl fmt::Display {
+            let (item, cx) = self.item_and_cx();
+            render_attributes_in_pre(item, "", cx)
         }
         item_template_methods!($($rest)*);
     };
     (render_assoc_items $($rest:tt)*) => {
-        fn render_assoc_items<'b>(&'b self) -> impl fmt::Display + Captures<'a> + 'b + Captures<'cx> {
-            fmt::from_fn(move |f| {
-                let (item, cx) = self.item_and_cx();
-                let def_id = item.item_id.expect_def_id();
-                let v = render_assoc_items(cx, item, def_id, AssocItemRender::All);
-                write!(f, "{v}")
-            })
+        fn render_assoc_items(&self) -> impl fmt::Display {
+            let (item, cx) = self.item_and_cx();
+            let def_id = item.item_id.expect_def_id();
+            render_assoc_items(cx, item, def_id, AssocItemRender::All)
         }
         item_template_methods!($($rest)*);
     };
@@ -162,10 +149,7 @@ struct ItemVars<'a> {
     src_href: Option<&'a str>,
 }
 
-pub(super) fn print_item<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    item: &'a clean::Item,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item) -> impl fmt::Display {
     debug_assert!(!item.is_stripped());
 
     fmt::from_fn(|buf| {
@@ -241,30 +225,30 @@ pub(super) fn print_item<'a, 'tcx>(
         item_vars.render_into(buf).unwrap();
 
         match &item.kind {
-            clean::ModuleItem(ref m) => {
+            clean::ModuleItem(m) => {
                 write!(buf, "{}", item_module(cx, item, &m.items))
             }
-            clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f, _) => {
+            clean::FunctionItem(f) | clean::ForeignFunctionItem(f, _) => {
                 write!(buf, "{}", item_function(cx, item, f))
             }
-            clean::TraitItem(ref t) => write!(buf, "{}", item_trait(cx, item, t)),
-            clean::StructItem(ref s) => {
+            clean::TraitItem(t) => write!(buf, "{}", item_trait(cx, item, t)),
+            clean::StructItem(s) => {
                 write!(buf, "{}", item_struct(cx, item, s))
             }
-            clean::UnionItem(ref s) => write!(buf, "{}", item_union(cx, item, s)),
-            clean::EnumItem(ref e) => write!(buf, "{}", item_enum(cx, item, e)),
-            clean::TypeAliasItem(ref t) => {
+            clean::UnionItem(s) => write!(buf, "{}", item_union(cx, item, s)),
+            clean::EnumItem(e) => write!(buf, "{}", item_enum(cx, item, e)),
+            clean::TypeAliasItem(t) => {
                 write!(buf, "{}", item_type_alias(cx, item, t))
             }
-            clean::MacroItem(ref m) => write!(buf, "{}", item_macro(cx, item, m)),
-            clean::ProcMacroItem(ref m) => {
+            clean::MacroItem(m) => write!(buf, "{}", item_macro(cx, item, m)),
+            clean::ProcMacroItem(m) => {
                 write!(buf, "{}", item_proc_macro(cx, item, m))
             }
             clean::PrimitiveItem(_) => write!(buf, "{}", item_primitive(cx, item)),
-            clean::StaticItem(ref i) => {
+            clean::StaticItem(i) => {
                 write!(buf, "{}", item_static(cx, item, i, None))
             }
-            clean::ForeignStaticItem(ref i, safety) => {
+            clean::ForeignStaticItem(i, safety) => {
                 write!(buf, "{}", item_static(cx, item, i, Some(*safety)))
             }
             clean::ConstantItem(ci) => {
@@ -274,7 +258,7 @@ pub(super) fn print_item<'a, 'tcx>(
                 write!(buf, "{}", item_foreign_type(cx, item))
             }
             clean::KeywordItem => write!(buf, "{}", item_keyword(cx, item)),
-            clean::TraitAliasItem(ref ta) => {
+            clean::TraitAliasItem(ta) => {
                 write!(buf, "{}", item_trait_alias(cx, item, ta))
             }
             _ => {
@@ -321,11 +305,7 @@ trait ItemTemplate<'a, 'cx: 'a>: rinja::Template + Display {
     fn item_and_cx(&self) -> (&'a clean::Item, &'a Context<'cx>);
 }
 
-fn item_module<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    item: &'a clean::Item,
-    items: &'a [clean::Item],
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_module(cx: &Context<'_>, item: &clean::Item, items: &[clean::Item]) -> impl fmt::Display {
     fmt::from_fn(|w| {
         write!(w, "{}", document(cx, item, None, HeadingOffset::H2))?;
 
@@ -541,14 +521,14 @@ fn item_module<'a, 'tcx>(
 
 /// Render the stability, deprecation and portability tags that are displayed in the item's summary
 /// at the module level.
-fn extra_info_tags<'a, 'tcx: 'a>(
-    tcx: TyCtxt<'tcx>,
-    item: &'a clean::Item,
-    parent: &'a clean::Item,
+fn extra_info_tags(
+    tcx: TyCtxt<'_>,
+    item: &clean::Item,
+    parent: &clean::Item,
     import_def_id: Option<DefId>,
-) -> impl Display + 'a + Captures<'tcx> {
+) -> impl Display {
     fmt::from_fn(move |f| {
-        fn tag_html<'a>(class: &'a str, title: &'a str, contents: &'a str) -> impl Display + 'a {
+        fn tag_html(class: &str, title: &str, contents: &str) -> impl Display {
             fmt::from_fn(move |f| {
                 write!(
                     f,
@@ -597,11 +577,7 @@ fn extra_info_tags<'a, 'tcx: 'a>(
     })
 }
 
-fn item_function<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    f: &'a clean::Function,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_function(cx: &Context<'_>, it: &clean::Item, f: &clean::Function) -> impl fmt::Display {
     fmt::from_fn(|w| {
         let tcx = cx.tcx();
         let header = it.fn_header(tcx).expect("printing a function which isn't a function");
@@ -657,11 +633,7 @@ fn item_function<'a, 'tcx>(
     })
 }
 
-fn item_trait<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    t: &'a clean::Trait,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_trait(cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) -> impl fmt::Display {
     fmt::from_fn(|w| {
         let tcx = cx.tcx();
         let bounds = bounds(&t.bounds, false, cx);
@@ -831,11 +803,7 @@ fn item_trait<'a, 'tcx>(
         // Trait documentation
         write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?;
 
-        fn trait_item<'a, 'tcx>(
-            cx: &'a Context<'tcx>,
-            m: &'a clean::Item,
-            t: &'a clean::Item,
-        ) -> impl fmt::Display + 'a + Captures<'tcx> {
+        fn trait_item(cx: &Context<'_>, m: &clean::Item, t: &clean::Item) -> impl fmt::Display {
             fmt::from_fn(|w| {
                 let name = m.name.unwrap();
                 info!("Documenting {name} on {ty_name:?}", ty_name = t.name);
@@ -1021,7 +989,7 @@ fn item_trait<'a, 'tcx>(
                     extern_crates.insert(did.krate);
                 }
                 match implementor.inner_impl().for_.without_borrowed_ref() {
-                    clean::Type::Path { ref path } if !path.is_assoc_ty() => {
+                    clean::Type::Path { path } if !path.is_assoc_ty() => {
                         let did = path.def_id();
                         let &mut (prev_did, ref mut has_duplicates) =
                             implementor_dups.entry(path.last()).or_insert((did, false));
@@ -1224,10 +1192,8 @@ fn item_trait<'a, 'tcx>(
         // to already be in the HTML, and will be ignored.
         //
         // [JSONP]: https://en.wikipedia.org/wiki/JSONP
-        let mut js_src_path: UrlPartsBuilder = std::iter::repeat("..")
-            .take(cx.current.len())
-            .chain(std::iter::once("trait.impl"))
-            .collect();
+        let mut js_src_path: UrlPartsBuilder =
+            iter::repeat_n("..", cx.current.len()).chain(iter::once("trait.impl")).collect();
         if let Some(did) = it.item_id.as_def_id()
             && let get_extern = { || cx.shared.cache.external_paths.get(&did).map(|s| &s.0) }
             && let Some(fqp) = cx.shared.cache.exact_paths.get(&did).or_else(get_extern)
@@ -1254,11 +1220,11 @@ fn item_trait<'a, 'tcx>(
     })
 }
 
-fn item_trait_alias<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    t: &'a clean::TraitAlias,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_trait_alias(
+    cx: &Context<'_>,
+    it: &clean::Item,
+    t: &clean::TraitAlias,
+) -> impl fmt::Display {
     fmt::from_fn(|w| {
         wrap_item(w, |w| {
             write!(
@@ -1285,11 +1251,7 @@ fn item_trait_alias<'a, 'tcx>(
     })
 }
 
-fn item_type_alias<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    t: &'a clean::TypeAlias,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_type_alias(cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) -> impl fmt::Display {
     fmt::from_fn(|w| {
         wrap_item(w, |w| {
             write!(
@@ -1482,10 +1444,8 @@ fn item_type_alias<'a, 'tcx>(
             && let get_local = { || cache.paths.get(&self_did).map(|(p, _)| p) }
             && let Some(self_fqp) = cache.exact_paths.get(&self_did).or_else(get_local)
         {
-            let mut js_src_path: UrlPartsBuilder = std::iter::repeat("..")
-                .take(cx.current.len())
-                .chain(std::iter::once("type.impl"))
-                .collect();
+            let mut js_src_path: UrlPartsBuilder =
+                iter::repeat_n("..", cx.current.len()).chain(iter::once("type.impl")).collect();
             js_src_path.extend(target_fqp[..target_fqp.len() - 1].iter().copied());
             js_src_path.push_fmt(format_args!("{target_type}.{}.js", target_fqp.last().unwrap()));
             let self_path = fmt::from_fn(|f| self_fqp.iter().joined("::", f));
@@ -1499,11 +1459,7 @@ fn item_type_alias<'a, 'tcx>(
     })
 }
 
-fn item_union<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    s: &'a clean::Union,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_union(cx: &Context<'_>, it: &clean::Item, s: &clean::Union) -> impl fmt::Display {
     item_template!(
         #[template(path = "item_union.html")]
         struct ItemUnion<'a, 'cx> {
@@ -1515,40 +1471,25 @@ fn item_union<'a, 'tcx>(
     );
 
     impl<'a, 'cx: 'a> ItemUnion<'a, 'cx> {
-        fn render_union<'b>(&'b self) -> impl Display + Captures<'a> + 'b + Captures<'cx> {
-            fmt::from_fn(move |f| {
-                let v = render_union(self.it, Some(&self.s.generics), &self.s.fields, self.cx);
-                write!(f, "{v}")
-            })
+        fn render_union(&self) -> impl Display {
+            render_union(self.it, Some(&self.s.generics), &self.s.fields, self.cx)
         }
 
-        fn document_field<'b>(
-            &'b self,
-            field: &'a clean::Item,
-        ) -> impl Display + Captures<'a> + 'b + Captures<'cx> {
-            fmt::from_fn(move |f| {
-                let v = document(self.cx, field, Some(self.it), HeadingOffset::H3);
-                write!(f, "{v}")
-            })
+        fn document_field(&self, field: &'a clean::Item) -> impl Display {
+            document(self.cx, field, Some(self.it), HeadingOffset::H3)
         }
 
         fn stability_field(&self, field: &clean::Item) -> Option<String> {
             field.stability_class(self.cx.tcx())
         }
 
-        fn print_ty<'b>(
-            &'b self,
-            ty: &'a clean::Type,
-        ) -> impl Display + Captures<'a> + 'b + Captures<'cx> {
-            fmt::from_fn(move |f| {
-                let v = ty.print(self.cx);
-                write!(f, "{v}")
-            })
+        fn print_ty(&self, ty: &'a clean::Type) -> impl Display {
+            ty.print(self.cx)
         }
 
         fn fields_iter(
             &self,
-        ) -> std::iter::Peekable<impl Iterator<Item = (&'a clean::Item, &'a clean::Type)>> {
+        ) -> iter::Peekable<impl Iterator<Item = (&'a clean::Item, &'a clean::Type)>> {
             self.s
                 .fields
                 .iter()
@@ -1566,10 +1507,7 @@ fn item_union<'a, 'tcx>(
     })
 }
 
-fn print_tuple_struct_fields<'a, 'cx: 'a>(
-    cx: &'a Context<'cx>,
-    s: &'a [clean::Item],
-) -> impl Display + 'a + Captures<'cx> {
+fn print_tuple_struct_fields(cx: &Context<'_>, s: &[clean::Item]) -> impl Display {
     fmt::from_fn(|f| {
         if !s.is_empty()
             && s.iter().all(|field| {
@@ -1591,11 +1529,7 @@ fn print_tuple_struct_fields<'a, 'cx: 'a>(
     })
 }
 
-fn item_enum<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    e: &'a clean::Enum,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_enum(cx: &Context<'_>, it: &clean::Item, e: &clean::Enum) -> impl fmt::Display {
     fmt::from_fn(|w| {
         let count_variants = e.variants().count();
         wrap_item(w, |w| {
@@ -1658,14 +1592,14 @@ fn should_show_enum_discriminant(
     repr.c() || repr.int.is_some()
 }
 
-fn display_c_like_variant<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    item: &'a clean::Item,
-    variant: &'a clean::Variant,
+fn display_c_like_variant(
+    cx: &Context<'_>,
+    item: &clean::Item,
+    variant: &clean::Variant,
     index: VariantIdx,
     should_show_enum_discriminant: bool,
     enum_def_id: DefId,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         let name = item.name.unwrap();
         if let Some(ref value) = variant.discriminant {
@@ -1685,15 +1619,15 @@ fn display_c_like_variant<'a, 'tcx>(
     })
 }
 
-fn render_enum_fields<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    g: Option<&'a clean::Generics>,
-    variants: &'a IndexVec<VariantIdx, clean::Item>,
+fn render_enum_fields(
+    cx: &Context<'_>,
+    g: Option<&clean::Generics>,
+    variants: &IndexVec<VariantIdx, clean::Item>,
     count_variants: usize,
     has_stripped_entries: bool,
     is_non_exhaustive: bool,
     enum_def_id: DefId,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         let should_show_enum_discriminant =
             should_show_enum_discriminant(cx, enum_def_id, variants);
@@ -1764,12 +1698,12 @@ fn render_enum_fields<'a, 'tcx>(
     })
 }
 
-fn item_variants<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    variants: &'a IndexVec<VariantIdx, clean::Item>,
+fn item_variants(
+    cx: &Context<'_>,
+    it: &clean::Item,
+    variants: &IndexVec<VariantIdx, clean::Item>,
     enum_def_id: DefId,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         let tcx = cx.tcx();
         write!(
@@ -1895,11 +1829,7 @@ fn item_variants<'a, 'tcx>(
     })
 }
 
-fn item_macro<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    t: &'a clean::Macro,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_macro(cx: &Context<'_>, it: &clean::Item, t: &clean::Macro) -> impl fmt::Display {
     fmt::from_fn(|w| {
         wrap_item(w, |w| {
             // FIXME: Also print `#[doc(hidden)]` for `macro_rules!` if it `is_doc_hidden`.
@@ -1912,11 +1842,7 @@ fn item_macro<'a, 'tcx>(
     })
 }
 
-fn item_proc_macro<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    m: &'a clean::ProcMacro,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_proc_macro(cx: &Context<'_>, it: &clean::Item, m: &clean::ProcMacro) -> impl fmt::Display {
     fmt::from_fn(|w| {
         wrap_item(w, |w| {
             let name = it.name.expect("proc-macros always have names");
@@ -1947,10 +1873,7 @@ fn item_proc_macro<'a, 'tcx>(
     })
 }
 
-fn item_primitive<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_primitive(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
     fmt::from_fn(|w| {
         let def_id = it.item_id.expect_def_id();
         write!(w, "{}", document(cx, it, None, HeadingOffset::H2))?;
@@ -1968,13 +1891,13 @@ fn item_primitive<'a, 'tcx>(
     })
 }
 
-fn item_constant<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    generics: &'a clean::Generics,
-    ty: &'a clean::Type,
-    c: &'a clean::ConstantKind,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_constant(
+    cx: &Context<'_>,
+    it: &clean::Item,
+    generics: &clean::Generics,
+    ty: &clean::Type,
+    c: &clean::ConstantKind,
+) -> impl fmt::Display {
     fmt::from_fn(|w| {
         wrap_item(w, |w| {
             let tcx = cx.tcx();
@@ -2028,11 +1951,7 @@ fn item_constant<'a, 'tcx>(
     })
 }
 
-fn item_struct<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    s: &'a clean::Struct,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_struct(cx: &Context<'_>, it: &clean::Item, s: &clean::Struct) -> impl fmt::Display {
     fmt::from_fn(|w| {
         wrap_item(w, |w| {
             render_attributes_in_code(w, it, cx);
@@ -2056,12 +1975,12 @@ fn item_struct<'a, 'tcx>(
     })
 }
 
-fn item_fields<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    fields: &'a [clean::Item],
+fn item_fields(
+    cx: &Context<'_>,
+    it: &clean::Item,
+    fields: &[clean::Item],
     ctor_kind: Option<CtorKind>,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         let mut fields = fields
             .iter()
@@ -2111,12 +2030,12 @@ fn item_fields<'a, 'tcx>(
     })
 }
 
-fn item_static<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-    s: &'a clean::Static,
+fn item_static(
+    cx: &Context<'_>,
+    it: &clean::Item,
+    s: &clean::Static,
     safety: Option<hir::Safety>,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         wrap_item(w, |w| {
             render_attributes_in_code(w, it, cx);
@@ -2135,10 +2054,7 @@ fn item_static<'a, 'tcx>(
     })
 }
 
-fn item_foreign_type<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_foreign_type(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
     fmt::from_fn(|w| {
         wrap_item(w, |w| {
             w.write_str("extern {\n")?;
@@ -2155,10 +2071,7 @@ fn item_foreign_type<'a, 'tcx>(
     })
 }
 
-fn item_keyword<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    it: &'a clean::Item,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn item_keyword(cx: &Context<'_>, it: &clean::Item) -> impl fmt::Display {
     document(cx, it, None, HeadingOffset::H2)
 }
 
@@ -2268,18 +2181,14 @@ pub(super) fn full_path(cx: &Context<'_>, item: &clean::Item) -> String {
     s
 }
 
-pub(super) fn item_path(ty: ItemType, name: &str) -> impl Display + '_ {
+pub(super) fn item_path(ty: ItemType, name: &str) -> impl Display {
     fmt::from_fn(move |f| match ty {
         ItemType::Module => write!(f, "{}index.html", ensure_trailing_slash(name)),
         _ => write!(f, "{ty}.{name}.html"),
     })
 }
 
-fn bounds<'a, 'tcx>(
-    bounds: &'a [clean::GenericBound],
-    trait_alias: bool,
-    cx: &'a Context<'tcx>,
-) -> impl Display + 'a + Captures<'tcx> {
+fn bounds(bounds: &[clean::GenericBound], trait_alias: bool, cx: &Context<'_>) -> impl Display {
     (!bounds.is_empty())
         .then_some(fmt::from_fn(move |f| {
             let has_lots_of_bounds = bounds.len() > 2;
@@ -2329,13 +2238,13 @@ impl Ord for ImplString {
     }
 }
 
-fn render_implementor<'a, 'tcx>(
-    cx: &'a Context<'tcx>,
-    implementor: &'a Impl,
-    trait_: &'a clean::Item,
-    implementor_dups: &'a FxHashMap<Symbol, (DefId, bool)>,
-    aliases: &'a [String],
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+fn render_implementor(
+    cx: &Context<'_>,
+    implementor: &Impl,
+    trait_: &clean::Item,
+    implementor_dups: &FxHashMap<Symbol, (DefId, bool)>,
+    aliases: &[String],
+) -> impl fmt::Display {
     // If there's already another implementor that has the same abridged name, use the
     // full path, for example in `std::iter::ExactSizeIterator`
     let use_absolute = match implementor.inner_impl().for_ {
@@ -2364,12 +2273,12 @@ fn render_implementor<'a, 'tcx>(
     )
 }
 
-fn render_union<'a, 'cx: 'a>(
-    it: &'a clean::Item,
-    g: Option<&'a clean::Generics>,
-    fields: &'a [clean::Item],
-    cx: &'a Context<'cx>,
-) -> impl Display + 'a + Captures<'cx> {
+fn render_union(
+    it: &clean::Item,
+    g: Option<&clean::Generics>,
+    fields: &[clean::Item],
+    cx: &Context<'_>,
+) -> impl Display {
     fmt::from_fn(move |mut f| {
         write!(f, "{}union {}", visibility_print_with_space(it, cx), it.name.unwrap(),)?;
 
@@ -2421,15 +2330,15 @@ fn render_union<'a, 'cx: 'a>(
     })
 }
 
-fn render_struct<'a, 'tcx>(
-    it: &'a clean::Item,
-    g: Option<&'a clean::Generics>,
+fn render_struct(
+    it: &clean::Item,
+    g: Option<&clean::Generics>,
     ty: Option<CtorKind>,
-    fields: &'a [clean::Item],
-    tab: &'a str,
+    fields: &[clean::Item],
+    tab: &str,
     structhead: bool,
-    cx: &'a Context<'tcx>,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+    cx: &Context<'_>,
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         write!(
             w,
@@ -2457,15 +2366,15 @@ fn render_struct<'a, 'tcx>(
     })
 }
 
-fn render_struct_fields<'a, 'tcx>(
-    g: Option<&'a clean::Generics>,
+fn render_struct_fields(
+    g: Option<&clean::Generics>,
     ty: Option<CtorKind>,
-    fields: &'a [clean::Item],
-    tab: &'a str,
+    fields: &[clean::Item],
+    tab: &str,
     structhead: bool,
     has_stripped_entries: bool,
-    cx: &'a Context<'tcx>,
-) -> impl fmt::Display + 'a + Captures<'tcx> {
+    cx: &Context<'_>,
+) -> impl fmt::Display {
     fmt::from_fn(move |w| {
         match ty {
             None => {
@@ -2581,7 +2490,7 @@ fn document_non_exhaustive_header(item: &clean::Item) -> &str {
     if item.is_non_exhaustive() { " (Non-exhaustive)" } else { "" }
 }
 
-fn document_non_exhaustive(item: &clean::Item) -> impl Display + '_ {
+fn document_non_exhaustive(item: &clean::Item) -> impl Display {
     fmt::from_fn(|f| {
         if item.is_non_exhaustive() {
             write!(
diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs
index 95f617c9839..b39701fae1d 100644
--- a/src/librustdoc/html/render/search_index.rs
+++ b/src/librustdoc/html/render/search_index.rs
@@ -842,10 +842,7 @@ pub(crate) fn get_function_type_for_search(
         }
         clean::ConstantItem(ref c) => make_nullary_fn(&c.type_),
         clean::StaticItem(ref s) => make_nullary_fn(&s.type_),
-        clean::StructFieldItem(ref t) => {
-            let Some(parent) = parent else {
-                return None;
-            };
+        clean::StructFieldItem(ref t) if let Some(parent) = parent => {
             let mut rgen: FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)> =
                 Default::default();
             let output = get_index_type(t, vec![], &mut rgen);
diff --git a/src/librustdoc/html/render/search_index/encode.rs b/src/librustdoc/html/render/search_index/encode.rs
index 8816ea65059..de2f54558ff 100644
--- a/src/librustdoc/html/render/search_index/encode.rs
+++ b/src/librustdoc/html/render/search_index/encode.rs
@@ -182,9 +182,9 @@ pub(crate) fn write_bitmap_to_bytes(
             out.write_all(&[b])?;
         }
         if size < NO_OFFSET_THRESHOLD {
-            4 + 4 * size + ((size + 7) / 8)
+            4 + 4 * size + size.div_ceil(8)
         } else {
-            4 + 8 * size + ((size + 7) / 8)
+            4 + 8 * size + size.div_ceil(8)
         }
     } else {
         out.write_all(&u32::to_le_bytes(SERIAL_COOKIE_NO_RUNCONTAINER))?;
diff --git a/src/librustdoc/html/render/sidebar.rs b/src/librustdoc/html/render/sidebar.rs
index 64dbaf9083e..3130815af0b 100644
--- a/src/librustdoc/html/render/sidebar.rs
+++ b/src/librustdoc/html/render/sidebar.rs
@@ -79,7 +79,7 @@ impl<'a> LinkBlock<'a> {
 }
 
 /// A link to an item. Content should not be escaped.
-#[derive(Ord, PartialEq, Eq, Hash, Clone)]
+#[derive(PartialEq, Eq, Hash, Clone)]
 pub(crate) struct Link<'a> {
     /// The content for the anchor tag and title attr
     name: Cow<'a, str>,
@@ -91,13 +91,13 @@ pub(crate) struct Link<'a> {
     children: Vec<Link<'a>>,
 }
 
-impl PartialOrd for Link<'_> {
-    fn partial_cmp(&self, other: &Link<'_>) -> Option<Ordering> {
+impl Ord for Link<'_> {
+    fn cmp(&self, other: &Self) -> Ordering {
         match compare_names(&self.name, &other.name) {
-            Ordering::Equal => (),
-            result => return Some(result),
+            Ordering::Equal => {}
+            result => return result,
         }
-        (&self.name_html, &self.href, &self.children).partial_cmp(&(
+        (&self.name_html, &self.href, &self.children).cmp(&(
             &other.name_html,
             &other.href,
             &other.children,
@@ -105,6 +105,12 @@ impl PartialOrd for Link<'_> {
     }
 }
 
+impl PartialOrd for Link<'_> {
+    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+        Some(self.cmp(other))
+    }
+}
+
 impl<'a> Link<'a> {
     pub fn new(href: impl Into<Cow<'a, str>>, name: impl Into<Cow<'a, str>>) -> Self {
         Self { href: href.into(), name: name.into(), children: vec![], name_html: None }
diff --git a/src/librustdoc/html/render/span_map.rs b/src/librustdoc/html/render/span_map.rs
index ce9c42c01cc..82385c1c4db 100644
--- a/src/librustdoc/html/render/span_map.rs
+++ b/src/librustdoc/html/render/span_map.rs
@@ -95,10 +95,8 @@ impl SpanMapVisitor<'_> {
                     .unwrap_or(path.span);
                 self.matches.insert(span, link);
             }
-            Res::Local(_) => {
-                if let Some(span) = self.tcx.hir().res_span(path.res) {
-                    self.matches.insert(path.span, LinkFromSrc::Local(clean::Span::new(span)));
-                }
+            Res::Local(_) if let Some(span) = self.tcx.hir().res_span(path.res) => {
+                self.matches.insert(path.span, LinkFromSrc::Local(clean::Span::new(span)));
             }
             Res::PrimTy(p) => {
                 // FIXME: Doesn't handle "path-like" primitives like arrays or tuples.
@@ -111,15 +109,15 @@ impl SpanMapVisitor<'_> {
 
     /// Used to generate links on items' definition to go to their documentation page.
     pub(crate) fn extract_info_from_hir_id(&mut self, hir_id: HirId) {
-        if let Node::Item(item) = self.tcx.hir_node(hir_id) {
-            if let Some(span) = self.tcx.def_ident_span(item.owner_id) {
-                let cspan = clean::Span::new(span);
-                // If the span isn't from the current crate, we ignore it.
-                if cspan.inner().is_dummy() || cspan.cnum(self.tcx.sess) != LOCAL_CRATE {
-                    return;
-                }
-                self.matches.insert(span, LinkFromSrc::Doc(item.owner_id.to_def_id()));
+        if let Node::Item(item) = self.tcx.hir_node(hir_id)
+            && let Some(span) = self.tcx.def_ident_span(item.owner_id)
+        {
+            let cspan = clean::Span::new(span);
+            // If the span isn't from the current crate, we ignore it.
+            if cspan.inner().is_dummy() || cspan.cnum(self.tcx.sess) != LOCAL_CRATE {
+                return;
             }
+            self.matches.insert(span, LinkFromSrc::Doc(item.owner_id.to_def_id()));
         }
     }
 
diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs
index 0f01db5f6bc..a1ee5c8c548 100644
--- a/src/librustdoc/html/render/type_layout.rs
+++ b/src/librustdoc/html/render/type_layout.rs
@@ -2,7 +2,6 @@ use std::fmt;
 
 use rinja::Template;
 use rustc_abi::{Primitive, TagEncoding, Variants};
-use rustc_data_structures::captures::Captures;
 use rustc_hir::def_id::DefId;
 use rustc_middle::span_bug;
 use rustc_middle::ty::layout::LayoutError;
@@ -26,10 +25,7 @@ struct TypeLayoutSize {
     size: u64,
 }
 
-pub(crate) fn document_type_layout<'a, 'cx: 'a>(
-    cx: &'a Context<'cx>,
-    ty_def_id: DefId,
-) -> impl fmt::Display + 'a + Captures<'cx> {
+pub(crate) fn document_type_layout(cx: &Context<'_>, ty_def_id: DefId) -> impl fmt::Display {
     fmt::from_fn(move |f| {
         if !cx.shared.show_type_layout {
             return Ok(());
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index 0185d0c3bb5..b2bbf4614bf 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -153,7 +153,7 @@ fn write_rendered_cross_crate_info(
     include_sources: bool,
 ) -> Result<(), Error> {
     let m = &opt.should_merge;
-    if opt.emit.is_empty() || opt.emit.contains(&EmitType::InvocationSpecific) {
+    if opt.should_emit_crate() {
         if include_sources {
             write_rendered_cci::<SourcesPart, _>(SourcesPart::blank, dst, crates, m)?;
         }
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index 78c86a27632..cbbd4b01d83 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -333,7 +333,7 @@ pub(crate) fn print_src(
     source_context: &SourceContext<'_>,
 ) {
     let mut lines = s.lines().count();
-    let line_info = if let SourceContext::Embedded(ref info) = source_context {
+    let line_info = if let SourceContext::Embedded(info) = source_context {
         highlight::LineInfo::new_scraped(lines as u32, info.offset as u32)
     } else {
         highlight::LineInfo::new(lines as u32)
diff --git a/src/librustdoc/html/static/js/rustdoc.d.ts b/src/librustdoc/html/static/js/rustdoc.d.ts
index acea7828e86..1554c045a32 100644
--- a/src/librustdoc/html/static/js/rustdoc.d.ts
+++ b/src/librustdoc/html/static/js/rustdoc.d.ts
@@ -123,7 +123,7 @@ declare namespace rustdoc {
      * Same as QueryElement, but bindings and typeFilter support strings
      */
     interface ParserQueryElement {
-        name: string,
+        name: string|null,
         id: number|null,
         fullPath: Array<string>,
         pathWithoutLast: Array<string>,
@@ -131,11 +131,17 @@ declare namespace rustdoc {
         normalizedPathLast: string,
         generics: Array<ParserQueryElement>,
         bindings: Map<string, Array<ParserQueryElement>>,
-        bindingName: {name: string, generics: ParserQueryElement[]}|null,
-        typeFilter: string|null,
+        bindingName: {name: string|null, generics: ParserQueryElement[]}|null,
+        typeFilter: number|string|null,
     }
 
     /**
+     * Same as ParserQueryElement, but all fields are optional.
+     */
+    type ParserQueryElementFields = {
+        [K in keyof ParserQueryElement]?: ParserQueryElement[T]
+    }
+    /**
      * Intermediate parser state. Discarded when parsing is done.
      */
     interface ParserState {
@@ -176,10 +182,11 @@ declare namespace rustdoc {
         name: string,
         normalizedName: string,
         word: string,
+        paramNames: string[],
         parent: ({ty: number, name: string, path: string, exactPath: string}|null|undefined),
         path: string,
         ty: number,
-        type?: FunctionSearchType
+        type: FunctionSearchType | null,
     }
 
     /**
@@ -390,7 +397,7 @@ declare namespace rustdoc {
      */
     type RawSearchIndexCrate = {
     doc: string,
-    a: Object,
+    a: { [key: string]: number[] },
     n: Array<string>,
     t: string,
     D: string,
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js
index ccbd6811b07..c275127997a 100644
--- a/src/librustdoc/html/static/js/search.js
+++ b/src/librustdoc/html/static/js/search.js
@@ -638,7 +638,6 @@ function getNextElem(query, parserState, elems, isInGenerics) {
                 getFilteredNextElem(query, parserState, generics, isInGenerics);
                 generics[generics.length - 1].bindingName = makePrimitiveElement("output");
             } else {
-                // @ts-expect-error
                 generics.push(makePrimitiveElement(null, {
                     bindingName: makePrimitiveElement("output"),
                     typeFilter: null,
@@ -791,7 +790,7 @@ function createQueryElement(query, parserState, name, generics, isInGenerics) {
         generics: generics.filter(gen => {
             // Syntactically, bindings are parsed as generics,
             // but the query engine treats them differently.
-            if (gen.bindingName !== null) {
+            if (gen.bindingName !== null && gen.bindingName.name !== null) {
                 if (gen.name !== null) {
                     gen.bindingName.generics.unshift(gen);
                 }
@@ -811,8 +810,8 @@ function createQueryElement(query, parserState, name, generics, isInGenerics) {
 
 /**
  *
- * @param {string} name
- * @param {Object=} extra
+ * @param {string|null} name
+ * @param {rustdoc.ParserQueryElementFields=} extra
  * @returns {rustdoc.ParserQueryElement}
  */
 function makePrimitiveElement(name, extra) {
@@ -1478,73 +1477,61 @@ class DocSearch {
          * Special type name IDs for searching by array.
          * @type {number}
          */
-        // @ts-expect-error
         this.typeNameIdOfArray = this.buildTypeMapIndex("array");
         /**
          * Special type name IDs for searching by slice.
          * @type {number}
          */
-        // @ts-expect-error
         this.typeNameIdOfSlice = this.buildTypeMapIndex("slice");
         /**
          * Special type name IDs for searching by both array and slice (`[]` syntax).
          * @type {number}
          */
-        // @ts-expect-error
         this.typeNameIdOfArrayOrSlice = this.buildTypeMapIndex("[]");
         /**
          * Special type name IDs for searching by tuple.
          * @type {number}
          */
-        // @ts-expect-error
         this.typeNameIdOfTuple = this.buildTypeMapIndex("tuple");
         /**
          * Special type name IDs for searching by unit.
          * @type {number}
          */
-        // @ts-expect-error
         this.typeNameIdOfUnit = this.buildTypeMapIndex("unit");
         /**
          * Special type name IDs for searching by both tuple and unit (`()` syntax).
          * @type {number}
          */
-        // @ts-expect-error
         this.typeNameIdOfTupleOrUnit = this.buildTypeMapIndex("()");
         /**
          * Special type name IDs for searching `fn`.
          * @type {number}
          */
-        // @ts-expect-error
         this.typeNameIdOfFn = this.buildTypeMapIndex("fn");
         /**
          * Special type name IDs for searching `fnmut`.
          * @type {number}
          */
-        // @ts-expect-error
         this.typeNameIdOfFnMut = this.buildTypeMapIndex("fnmut");
         /**
          * Special type name IDs for searching `fnonce`.
          * @type {number}
          */
-        // @ts-expect-error
         this.typeNameIdOfFnOnce = this.buildTypeMapIndex("fnonce");
         /**
          * Special type name IDs for searching higher order functions (`->` syntax).
          * @type {number}
          */
-        // @ts-expect-error
         this.typeNameIdOfHof = this.buildTypeMapIndex("->");
         /**
          * Special type name IDs the output assoc type.
          * @type {number}
          */
-        // @ts-expect-error
         this.typeNameIdOfOutput = this.buildTypeMapIndex("output", true);
         /**
          * Special type name IDs for searching by reference.
          * @type {number}
          */
-        // @ts-expect-error
         this.typeNameIdOfReference = this.buildTypeMapIndex("reference");
 
         /**
@@ -1586,7 +1573,6 @@ class DocSearch {
         /**
          *  @type {Array<rustdoc.Row>}
          */
-        // @ts-expect-error
         this.searchIndex = this.buildIndex(rawSearchIndex);
     }
 
@@ -1598,10 +1584,16 @@ class DocSearch {
      * done more quickly. Two types with the same name but different item kinds
      * get the same ID.
      *
-     * @param {string} name
+     * @template T extends string
+     * @overload
+     * @param {T} name
      * @param {boolean=} isAssocType - True if this is an assoc type
+     * @returns {T extends "" ? null : number}
+     *
+     * @param {string} name
+     * @param {boolean=} isAssocType
+     * @returns {number | null}
      *
-     * @returns {number?}
      */
     buildTypeMapIndex(name, isAssocType) {
         if (name === "" || name === null) {
@@ -1909,6 +1901,7 @@ class DocSearch {
      * Convert raw search index into in-memory search index.
      *
      * @param {Map<string, rustdoc.RawSearchIndexCrate>} rawSearchIndex
+     * @returns {rustdoc.Row[]}
      */
     buildIndex(rawSearchIndex) {
         /**
@@ -2008,6 +2001,7 @@ class DocSearch {
             return cb;
         };
 
+        /** @type {rustdoc.Row[]} */
         const searchIndex = [];
         let currentIndex = 0;
         let id = 0;
@@ -2108,8 +2102,6 @@ class DocSearch {
             // an array of [(Number) item type,
             //              (String) name]
             const rawPaths = crateCorpus.p;
-            // an array of [(String) alias name
-            //             [Number] index to items]
             const aliases = crateCorpus.a;
             // an array of [(Number) item index,
             //              (String) comma-separated list of function generic param names]
@@ -2232,6 +2224,7 @@ class DocSearch {
                 // object defined above.
                 const itemParentIdx = itemParentIdxDecoder.next();
                 normalizedName = word.indexOf("_") === -1 ? word : word.replace(/_/g, "");
+                /** @type {rustdoc.Row} */
                 const row = {
                     crate,
                     ty: itemTypes.charCodeAt(i) - 65, // 65 = "A"
@@ -2274,16 +2267,14 @@ class DocSearch {
                         continue;
                     }
 
-                    // @ts-expect-error
+                    /** @type{number[]} */
                     let currentNameAliases;
                     if (currentCrateAliases.has(alias_name)) {
                         currentNameAliases = currentCrateAliases.get(alias_name);
                     } else {
                         currentNameAliases = [];
-                        // @ts-expect-error
                         currentCrateAliases.set(alias_name, currentNameAliases);
                     }
-                    // @ts-expect-error
                     for (const local_alias of aliases[alias_name]) {
                         currentNameAliases.push(local_alias + currentIndex);
                     }
@@ -2326,15 +2317,13 @@ class DocSearch {
          * @param {rustdoc.ParserQueryElement} elem
          */
         function convertTypeFilterOnElem(elem) {
-            if (elem.typeFilter !== null) {
+            if (typeof elem.typeFilter === "string") {
                 let typeFilter = elem.typeFilter;
                 if (typeFilter === "const") {
                     typeFilter = "constant";
                 }
-                // @ts-expect-error
                 elem.typeFilter = itemTypeFromName(typeFilter);
             } else {
-                // @ts-expect-error
                 elem.typeFilter = NO_TYPE_FILTER;
             }
             for (const elem2 of elem.generics) {
@@ -2407,9 +2396,9 @@ class DocSearch {
                     continue;
                 }
                 if (!foundStopChar) {
-                    let extra = "";
+                    /** @type String[] */
+                    let extra = [];
                     if (isLastElemGeneric(query.elems, parserState)) {
-                        // @ts-expect-error
                         extra = [" after ", ">"];
                     } else if (prevIs(parserState, "\"")) {
                         throw ["Cannot have more than one element if you use quotes"];
@@ -2547,7 +2536,7 @@ class DocSearch {
          * See `buildTypeMapIndex` for more information.
          *
          * @param {rustdoc.QueryElement} elem
-         * @param {boolean} isAssocType
+         * @param {boolean=} isAssocType
          */
         const convertNameToId = (elem, isAssocType) => {
             const loweredName = elem.pathLast.toLowerCase();
@@ -2627,7 +2616,6 @@ class DocSearch {
                 ];
             }
             for (const elem2 of elem.generics) {
-                // @ts-expect-error
                 convertNameToId(elem2);
             }
             elem.bindings = new Map(Array.from(elem.bindings.entries())
@@ -2750,7 +2738,11 @@ class DocSearch {
             return [displayPath, href, `${exactPath}::${name}`];
         };
 
-        // @ts-expect-error
+        /**
+         *
+         * @param {string} path
+         * @returns {string}
+         */
         function pathSplitter(path) {
             const tmp = "<span>" + path.replace(/::/g, "::</span><span>");
             if (tmp.endsWith("<span>")) {
@@ -2763,9 +2755,9 @@ class DocSearch {
          * Add extra data to result objects, and filter items that have been
          * marked for removal.
          *
-         * @param {[rustdoc.ResultObject]} results
+         * @param {rustdoc.ResultObject[]} results
          * @param {"sig"|"elems"|"returned"|null} typeInfo
-         * @returns {[rustdoc.ResultObject]}
+         * @returns {rustdoc.ResultObject[]}
          */
         const transformResults = (results, typeInfo) => {
             const duplicates = new Set();
@@ -2840,7 +2832,7 @@ class DocSearch {
             }
             let fnInputs = null;
             let fnOutput = null;
-            // @ts-expect-error
+            /** @type {Map<number, number> | null} */
             let mgens = null;
             if (typeInfo !== "elems" && typeInfo !== "returned") {
                 fnInputs = unifyFunctionTypes(
@@ -3053,7 +3045,6 @@ class DocSearch {
                             writeFn(nested, result);
                         }
                         return;
-                    // @ts-expect-error
                     } else if (mgens) {
                         for (const [queryId, fnId] of mgens) {
                             if (fnId === fnType.id) {
@@ -3069,7 +3060,7 @@ class DocSearch {
                         name: fnParamNames[-1 - fnType.id],
                         highlighted: !!fnType.highlighted,
                     }, result);
-                    // @ts-expect-error
+                    /** @type{string[]} */
                     const where = [];
                     onEachBtwn(
                         fnType.generics,
@@ -3079,7 +3070,6 @@ class DocSearch {
                         () => pushText({ name: " + ", highlighted: false }, where),
                     );
                     if (where.length > 0) {
-                        // @ts-expect-error
                         whereClause.set(fnParamNames[-1 - fnType.id], where);
                     }
                 } else {
@@ -3181,7 +3171,7 @@ class DocSearch {
          * @param {rustdoc.Results} results
          * @param {"sig"|"elems"|"returned"|null} typeInfo
          * @param {string} preferredCrate
-         * @returns {Promise<[rustdoc.ResultObject]>}
+         * @returns {Promise<rustdoc.ResultObject[]>}
          */
         const sortResults = async(results, typeInfo, preferredCrate) => {
             const userQuery = parsedQuery.userQuery;
@@ -3337,7 +3327,6 @@ class DocSearch {
                 return 0;
             });
 
-            // @ts-expect-error
             return transformResults(result_list, typeInfo);
         };
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 1f2f8f7d33a..4fe5e13c3af 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -147,7 +147,7 @@ pub fn main() {
 
         #[cfg(target_os = "macos")]
         {
-            extern "C" {
+            unsafe extern "C" {
                 fn _rjem_je_zone_register();
             }
 
@@ -561,7 +561,7 @@ fn opts() -> Vec<RustcOptGroup> {
             "",
             "emit",
             "Comma separated list of types of output for rustdoc to emit",
-            "[unversioned-shared-resources,toolchain-shared-resources,invocation-specific]",
+            "[unversioned-shared-resources,toolchain-shared-resources,invocation-specific,dep-info]",
         ),
         opt(Unstable, FlagMulti, "", "no-run", "Compile doctests without running them", ""),
         opt(
@@ -890,7 +890,13 @@ fn main_args(early_dcx: &mut EarlyDiagCtxt, at_args: &[String]) {
                 // if we ran coverage, bail early, we don't need to also generate docs at this point
                 // (also we didn't load in any of the useful passes)
                 return;
-            } else if run_check {
+            }
+
+            if render_opts.dep_info().is_some() {
+                rustc_interface::passes::write_dep_info(tcx);
+            }
+
+            if run_check {
                 // Since we're in "check" mode, no need to generate anything beyond this point.
                 return;
             }
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 97e6d314642..fdbb792d25d 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -58,7 +58,7 @@ fn filter_assoc_items_by_name_and_namespace(
     assoc_items_of: DefId,
     ident: Ident,
     ns: Namespace,
-) -> impl Iterator<Item = &ty::AssocItem> + '_ {
+) -> impl Iterator<Item = &ty::AssocItem> {
     tcx.associated_items(assoc_items_of).filter_by_name_unhygienic(ident.name).filter(move |item| {
         item.kind.namespace() == ns && tcx.hygienic_eq(ident, item.ident(tcx), assoc_items_of)
     })
@@ -1334,14 +1334,12 @@ impl LinkCollector<'_, '_> {
             }
 
         // item can be non-local e.g. when using `#[rustc_doc_primitive = "pointer"]`
-        if let Some((src_id, dst_id)) = id.as_local().and_then(|dst_id| {
-            diag_info.item.item_id.expect_def_id().as_local().map(|src_id| (src_id, dst_id))
-        }) {
-            if self.cx.tcx.effective_visibilities(()).is_exported(src_id)
-                && !self.cx.tcx.effective_visibilities(()).is_exported(dst_id)
-            {
-                privacy_error(self.cx, diag_info, path_str);
-            }
+        if let Some(dst_id) = id.as_local()
+            && let Some(src_id) = diag_info.item.item_id.expect_def_id().as_local()
+            && self.cx.tcx.effective_visibilities(()).is_exported(src_id)
+            && !self.cx.tcx.effective_visibilities(()).is_exported(dst_id)
+        {
+            privacy_error(self.cx, diag_info, path_str);
         }
 
         Some(())
@@ -1405,10 +1403,10 @@ impl LinkCollector<'_, '_> {
         // which we want in some cases but not in others.
         cache_errors: bool,
     ) -> Option<Vec<(Res, Option<UrlFragment>)>> {
-        if let Some(res) = self.visited_links.get(&key) {
-            if res.is_some() || cache_errors {
-                return res.clone().map(|r| vec![r]);
-            }
+        if let Some(res) = self.visited_links.get(&key)
+            && (res.is_some() || cache_errors)
+        {
+            return res.clone().map(|r| vec![r]);
         }
 
         let mut candidates = self.resolve_with_disambiguator(&key, diag.clone());
@@ -1432,10 +1430,10 @@ impl LinkCollector<'_, '_> {
         // and after removing duplicated kinds, only one remains, the `ambiguity_error` function
         // won't emit an error. So at this point, we can just take the first candidate as it was
         // the first retrieved and use it to generate the link.
-        if let [candidate, _candidate2, ..] = *candidates {
-            if !ambiguity_error(self.cx, &diag, &key.path_str, &candidates, false) {
-                candidates = vec![candidate];
-            }
+        if let [candidate, _candidate2, ..] = *candidates
+            && !ambiguity_error(self.cx, &diag, &key.path_str, &candidates, false)
+        {
+            candidates = vec![candidate];
         }
 
         let mut out = Vec::with_capacity(candidates.len());
@@ -1480,17 +1478,16 @@ impl LinkCollector<'_, '_> {
                         // See https://github.com/rust-lang/rust/pull/76955#discussion_r493953382 for a good approach.
                         let mut err = ResolutionFailure::NotResolved(err);
                         for other_ns in [TypeNS, ValueNS, MacroNS] {
-                            if other_ns != expected_ns {
-                                if let Ok(&[res, ..]) = self
+                            if other_ns != expected_ns
+                                && let Ok(&[res, ..]) = self
                                     .resolve(path_str, other_ns, None, item_id, module_id)
                                     .as_deref()
-                                {
-                                    err = ResolutionFailure::WrongNamespace {
-                                        res: full_res(self.cx.tcx, res),
-                                        expected_ns,
-                                    };
-                                    break;
-                                }
+                            {
+                                err = ResolutionFailure::WrongNamespace {
+                                    res: full_res(self.cx.tcx, res),
+                                    expected_ns,
+                                };
+                                break;
                             }
                         }
                         resolution_failure(self, diag, path_str, disambiguator, smallvec![err]);
@@ -1674,11 +1671,11 @@ impl Disambiguator {
             Ok(Some((d, &rest[1..], &rest[1..])))
         } else {
             for (suffix, kind) in suffixes {
-                if let Some(path_str) = link.strip_suffix(suffix) {
-                    // Avoid turning `!` or `()` into an empty string
-                    if !path_str.is_empty() {
-                        return Ok(Some((Kind(kind), path_str, link)));
-                    }
+                // Avoid turning `!` or `()` into an empty string
+                if let Some(path_str) = link.strip_suffix(suffix)
+                    && !path_str.is_empty()
+                {
+                    return Ok(Some((Kind(kind), path_str, link)));
                 }
             }
             Ok(None)
@@ -2060,7 +2057,7 @@ fn resolution_failure(
                                 return;
                             }
                             Trait
-                            | TyAlias { .. }
+                            | TyAlias
                             | ForeignTy
                             | OpaqueTy
                             | TraitAlias
diff --git a/src/librustdoc/passes/collect_trait_impls.rs b/src/librustdoc/passes/collect_trait_impls.rs
index 87f85c57315..f4e4cd924f7 100644
--- a/src/librustdoc/passes/collect_trait_impls.rs
+++ b/src/librustdoc/passes/collect_trait_impls.rs
@@ -177,23 +177,22 @@ pub(crate) fn collect_trait_impls(mut krate: Crate, cx: &mut DocContext<'_>) ->
             } else if let Some(did) = target.def_id(&cx.cache) {
                 cleaner.items.insert(did.into());
             }
-            if let Some(for_did) = for_.def_id(&cx.cache) {
-                if type_did_to_deref_target.insert(for_did, target).is_none() {
-                    // Since only the `DefId` portion of the `Type` instances is known to be same for both the
-                    // `Deref` target type and the impl for type positions, this map of types is keyed by
-                    // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly.
-                    if cleaner.keep_impl_with_def_id(for_did.into()) {
-                        let mut targets = DefIdSet::default();
-                        targets.insert(for_did);
-                        add_deref_target(
-                            cx,
-                            &type_did_to_deref_target,
-                            &mut cleaner,
-                            &mut targets,
-                            for_did,
-                        );
-                    }
-                }
+            if let Some(for_did) = for_.def_id(&cx.cache)
+                && type_did_to_deref_target.insert(for_did, target).is_none()
+                // Since only the `DefId` portion of the `Type` instances is known to be same for both the
+                // `Deref` target type and the impl for type positions, this map of types is keyed by
+                // `DefId` and for convenience uses a special cleaner that accepts `DefId`s directly.
+                && cleaner.keep_impl_with_def_id(for_did.into())
+            {
+                let mut targets = DefIdSet::default();
+                targets.insert(for_did);
+                add_deref_target(
+                    cx,
+                    &type_did_to_deref_target,
+                    &mut cleaner,
+                    &mut targets,
+                    for_did,
+                );
             }
         }
     }
diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs
index 3fb154dc515..b9739726c95 100644
--- a/src/librustdoc/passes/lint/html_tags.rs
+++ b/src/librustdoc/passes/lint/html_tags.rs
@@ -28,9 +28,9 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &
             // We don't try to detect stuff `<like, this>` because that's not valid HTML,
             // and we don't try to detect stuff `<like this>` because that's not valid Rust.
             let mut generics_end = range.end;
-            if let Some(Some(mut generics_start)) = (is_open_tag
-                && dox[..generics_end].ends_with('>'))
-            .then(|| extract_path_backwards(dox, range.start))
+            if is_open_tag
+                && dox[..generics_end].ends_with('>')
+                && let Some(mut generics_start) = extract_path_backwards(dox, range.start)
             {
                 while generics_start != 0
                     && generics_end < dox.len()
diff --git a/src/librustdoc/passes/lint/unportable_markdown.rs b/src/librustdoc/passes/lint/unportable_markdown.rs
index a3c3134f4c2..95646413a2d 100644
--- a/src/librustdoc/passes/lint/unportable_markdown.rs
+++ b/src/librustdoc/passes/lint/unportable_markdown.rs
@@ -73,15 +73,15 @@ pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &
         }
         let parser_old = cmarko::Parser::new_ext(dox, main_body_opts_old()).into_offset_iter();
         for (event, span) in parser_old {
-            if let cmarko::Event::Start(cmarko::Tag::BlockQuote) = event {
-                if !dox[span.clone()].starts_with("> ") {
-                    spaceless_block_quotes.remove(&span.start);
-                }
+            if let cmarko::Event::Start(cmarko::Tag::BlockQuote) = event
+                && !dox[span.clone()].starts_with("> ")
+            {
+                spaceless_block_quotes.remove(&span.start);
             }
-            if let cmarko::Event::FootnoteReference(_) = event {
-                if !found_footnote_references.contains(&(span.start + 1)) {
-                    missing_footnote_references.insert(span.start + 1, span);
-                }
+            if let cmarko::Event::FootnoteReference(_) = event
+                && !found_footnote_references.contains(&(span.start + 1))
+            {
+                missing_footnote_references.insert(span.start + 1, span);
             }
         }
     }
diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs
index 8cf39afd55c..fdab2b08779 100644
--- a/src/librustdoc/passes/propagate_stability.rs
+++ b/src/librustdoc/passes/propagate_stability.rs
@@ -39,15 +39,15 @@ impl DocFolder for StabilityPropagator<'_, '_> {
                 let item_stability = self.cx.tcx.lookup_stability(def_id);
                 let inline_stability =
                     item.inline_stmt_id.and_then(|did| self.cx.tcx.lookup_stability(did));
-                let is_glob_export = item.inline_stmt_id.and_then(|id| {
+                let is_glob_export = item.inline_stmt_id.map(|id| {
                     let hir_id = self.cx.tcx.local_def_id_to_hir_id(id);
-                    Some(matches!(
+                    matches!(
                         self.cx.tcx.hir_node(hir_id),
                         rustc_hir::Node::Item(rustc_hir::Item {
                             kind: rustc_hir::ItemKind::Use(_, rustc_hir::UseKind::Glob),
                             ..
                         })
-                    ))
+                    )
                 });
                 let own_stability = if let Some(item_stab) = item_stability
                     && let StabilityLevel::Stable { since: _, allowed_through_unstable_modules } =
diff --git a/src/librustdoc/passes/strip_hidden.rs b/src/librustdoc/passes/strip_hidden.rs
index a71bb62e56c..bcdca862862 100644
--- a/src/librustdoc/passes/strip_hidden.rs
+++ b/src/librustdoc/passes/strip_hidden.rs
@@ -7,9 +7,8 @@ use rustc_middle::ty::TyCtxt;
 use rustc_span::symbol::sym;
 use tracing::debug;
 
-use crate::clean;
 use crate::clean::utils::inherits_doc_hidden;
-use crate::clean::{Item, ItemIdSet};
+use crate::clean::{self, Item, ItemIdSet, reexport_chain};
 use crate::core::DocContext;
 use crate::fold::{DocFolder, strip_item};
 use crate::passes::{ImplStripper, Pass};
@@ -89,6 +88,25 @@ impl Stripper<'_, '_> {
 impl DocFolder for Stripper<'_, '_> {
     fn fold_item(&mut self, i: Item) -> Option<Item> {
         let has_doc_hidden = i.is_doc_hidden();
+
+        if let clean::ImportItem(clean::Import { source, .. }) = &i.kind
+            && let Some(source_did) = source.did
+            && let Some(import_def_id) = i.def_id().and_then(|def_id| def_id.as_local())
+        {
+            let reexports = reexport_chain(self.tcx, import_def_id, source_did);
+
+            // Check if any reexport in the chain has a hidden source
+            let has_hidden_source = reexports
+                .iter()
+                .filter_map(|reexport| reexport.id())
+                .any(|reexport_did| self.tcx.is_doc_hidden(reexport_did))
+                || self.tcx.is_doc_hidden(source_did);
+
+            if has_hidden_source {
+                return None;
+            }
+        }
+
         let is_impl_or_exported_macro = match i.kind {
             clean::ImplItem(..) => true,
             // If the macro has the `#[macro_export]` attribute, it means it's accessible at the
diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs
index 3e66ed9f56d..369fc52860e 100644
--- a/src/librustdoc/visit_lib.rs
+++ b/src/librustdoc/visit_lib.rs
@@ -57,10 +57,10 @@ impl LibEmbargoVisitor<'_, '_> {
         }
 
         for item in self.tcx.module_children(def_id).iter() {
-            if let Some(def_id) = item.res.opt_def_id() {
-                if item.vis.is_public() {
-                    self.visit_item(def_id);
-                }
+            if let Some(def_id) = item.res.opt_def_id()
+                && item.vis.is_public()
+            {
+                self.visit_item(def_id);
             }
         }
     }
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
index ab5f97199ce..4f024ecaf29 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils/mod.rs
@@ -682,19 +682,20 @@ pub fn eq_generics(l: &Generics, r: &Generics) -> bool {
 
 pub fn eq_where_predicate(l: &WherePredicate, r: &WherePredicate) -> bool {
     use WherePredicateKind::*;
-    match (&l.kind, &r.kind) {
-        (BoundPredicate(l), BoundPredicate(r)) => {
-            over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
-                eq_generic_param(l, r)
-            }) && eq_ty(&l.bounded_ty, &r.bounded_ty)
-                && over(&l.bounds, &r.bounds, eq_generic_bound)
-        },
-        (RegionPredicate(l), RegionPredicate(r)) => {
-            eq_id(l.lifetime.ident, r.lifetime.ident) && over(&l.bounds, &r.bounds, eq_generic_bound)
-        },
-        (EqPredicate(l), EqPredicate(r)) => eq_ty(&l.lhs_ty, &r.lhs_ty) && eq_ty(&l.rhs_ty, &r.rhs_ty),
-        _ => false,
-    }
+    over(&l.attrs, &r.attrs, eq_attr) 
+        && match (&l.kind, &r.kind) {
+            (BoundPredicate(l), BoundPredicate(r)) => {
+                over(&l.bound_generic_params, &r.bound_generic_params, |l, r| {
+                    eq_generic_param(l, r)
+                }) && eq_ty(&l.bounded_ty, &r.bounded_ty)
+                    && over(&l.bounds, &r.bounds, eq_generic_bound)
+            },
+            (RegionPredicate(l), RegionPredicate(r)) => {
+                eq_id(l.lifetime.ident, r.lifetime.ident) && over(&l.bounds, &r.bounds, eq_generic_bound)
+            },
+            (EqPredicate(l), EqPredicate(r)) => eq_ty(&l.lhs_ty, &r.lhs_ty) && eq_ty(&l.rhs_ty, &r.rhs_ty),
+            _ => false,
+        }
 }
 
 pub fn eq_use_tree(l: &UseTree, r: &UseTree) -> bool {
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 4bd86a25335..c47c08285c2 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -1108,14 +1108,9 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
     pub fn hash_ty_pat(&mut self, pat: &TyPat<'_>) {
         std::mem::discriminant(&pat.kind).hash(&mut self.s);
         match pat.kind {
-            TyPatKind::Range(s, e, i) => {
-                if let Some(s) = s {
-                    self.hash_const_arg(s);
-                }
-                if let Some(e) = e {
-                    self.hash_const_arg(e);
-                }
-                std::mem::discriminant(&i).hash(&mut self.s);
+            TyPatKind::Range(s, e) => {
+                self.hash_const_arg(s);
+                self.hash_const_arg(e);
             },
             TyPatKind::Err(_) => {},
         }
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index 3ce2cdfebe9..1a457bc7f21 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -1,6 +1,6 @@
 #![allow(clippy::similar_names)] // `expr` and `expn`
 
-use std::sync::Arc;
+use std::sync::{Arc, OnceLock};
 
 use crate::get_unique_attr;
 use crate::visitors::{Descend, for_each_expr_without_closures};
@@ -8,7 +8,6 @@ use crate::visitors::{Descend, for_each_expr_without_closures};
 use arrayvec::ArrayVec;
 use rustc_ast::{FormatArgs, FormatArgument, FormatPlaceholder};
 use rustc_data_structures::fx::FxHashMap;
-use rustc_data_structures::sync::OnceLock;
 use rustc_hir::{self as hir, Expr, ExprKind, HirId, Node, QPath};
 use rustc_lint::{LateContext, LintContext};
 use rustc_span::def_id::DefId;
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index b302c6a49f5..978836cb663 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -190,6 +190,9 @@ pub struct Config {
     /// The cargo executable.
     pub cargo_path: Option<PathBuf>,
 
+    /// Rustc executable used to compile run-make recipes.
+    pub stage0_rustc_path: Option<PathBuf>,
+
     /// The rustdoc executable.
     pub rustdoc_path: Option<PathBuf>,
 
diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs
index 8c909bcb195..b2ad5a3b3d0 100644
--- a/src/tools/compiletest/src/directive-list.rs
+++ b/src/tools/compiletest/src/directive-list.rs
@@ -52,6 +52,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "ignore-coverage-run",
     "ignore-cross-compile",
     "ignore-eabi",
+    "ignore-elf",
     "ignore-emscripten",
     "ignore-endian-big",
     "ignore-enzyme",
@@ -182,6 +183,7 @@ const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     "only-bpf",
     "only-cdb",
     "only-dist",
+    "only-elf",
     "only-emscripten",
     "only-gnu",
     "only-i686-pc-windows-gnu",
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 53ee901b8bc..7675e13990d 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -709,11 +709,11 @@ impl TestProps {
 /// returns a struct containing various parts of the directive.
 fn line_directive<'line>(
     line_number: usize,
-    comment: &str,
     original_line: &'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 after_comment =
+        original_line.trim_start().strip_prefix(COMPILETEST_DIRECTIVE_PREFIX)?.trim_start();
 
     let revision;
     let raw_directive;
@@ -722,7 +722,7 @@ fn line_directive<'line>(
         // A comment like `//@[foo]` only applies to revision `foo`.
         let Some((line_revision, after_close_bracket)) = after_open_bracket.split_once(']') else {
             panic!(
-                "malformed condition directive: expected `{comment}[foo]`, found `{original_line}`"
+                "malformed condition directive: expected `{COMPILETEST_DIRECTIVE_PREFIX}[foo]`, found `{original_line}`"
             )
         };
 
@@ -836,6 +836,8 @@ pub(crate) fn check_directive<'a>(
     CheckDirectiveResult { is_known_directive: is_known(&directive_name), trailing_directive }
 }
 
+const COMPILETEST_DIRECTIVE_PREFIX: &str = "//@";
+
 fn iter_header(
     mode: Mode,
     _suite: &str,
@@ -849,8 +851,7 @@ fn iter_header(
     }
 
     // Coverage tests in coverage-run mode always have these extra directives, without needing to
-    // specify them manually in every test file. (Some of the comments below have been copied over
-    // from the old `tests/run-make/coverage-reports/Makefile`, which no longer exists.)
+    // specify them manually in every test file.
     //
     // FIXME(jieyouxu): I feel like there's a better way to do this, leaving for later.
     if mode == Mode::CoverageRun {
@@ -867,9 +868,6 @@ fn iter_header(
         }
     }
 
-    // NOTE(jieyouxu): once we get rid of `Makefile`s we can unconditionally check for `//@`.
-    let comment = if testfile.extension().is_some_and(|e| e == "rs") { "//@" } else { "#" };
-
     let mut rdr = BufReader::with_capacity(1024, rdr);
     let mut ln = String::new();
     let mut line_number = 0;
@@ -882,7 +880,7 @@ fn iter_header(
         }
         let ln = ln.trim();
 
-        let Some(directive_line) = line_directive(line_number, comment, ln) else {
+        let Some(directive_line) = line_directive(line_number, ln) else {
             continue;
         };
 
diff --git a/src/tools/compiletest/src/header/cfg.rs b/src/tools/compiletest/src/header/cfg.rs
index 72a3b9d85c8..c369fff97f4 100644
--- a/src/tools/compiletest/src/header/cfg.rs
+++ b/src/tools/compiletest/src/header/cfg.rs
@@ -167,6 +167,16 @@ fn parse_cfg_name_directive<'a>(
     }
 
     condition! {
+        name: "elf",
+        condition: !config.target.contains("windows")
+            && !config.target.contains("wasm")
+            && !config.target.contains("apple")
+            && !config.target.contains("aix")
+            && !config.target.contains("uefi"),
+        message: "when the target binary format is ELF"
+    }
+
+    condition! {
         name: "enzyme",
         condition: config.has_enzyme,
         message: "when rustc is built with LLVM Enzyme"
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index d7079fdeee6..007318be7cc 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -239,11 +239,6 @@ fn check_ignore(config: &Config, contents: &str) -> bool {
     d.ignore
 }
 
-fn parse_makefile(config: &Config, contents: &str) -> EarlyProps {
-    let bytes = contents.as_bytes();
-    EarlyProps::from_reader(config, Path::new("Makefile"), bytes)
-}
-
 #[test]
 fn should_fail() {
     let config: Config = cfg().build();
@@ -261,10 +256,6 @@ fn revisions() {
     let config: Config = cfg().build();
 
     assert_eq!(parse_rs(&config, "//@ revisions: a b c").revisions, vec!["a", "b", "c"],);
-    assert_eq!(
-        parse_makefile(&config, "# revisions: hello there").revisions,
-        vec!["hello", "there"],
-    );
 }
 
 #[test]
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index 9dff7047bc4..dd611b19a8d 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -21,7 +21,7 @@ pub mod util;
 
 use core::panic;
 use std::collections::HashSet;
-use std::ffi::{OsStr, OsString};
+use std::ffi::OsString;
 use std::io::{self, ErrorKind};
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
@@ -54,6 +54,12 @@ pub fn parse_config(args: Vec<String>) -> Config {
         .reqopt("", "run-lib-path", "path to target shared libraries", "PATH")
         .reqopt("", "rustc-path", "path to rustc to use for compiling", "PATH")
         .optopt("", "cargo-path", "path to cargo to use for compiling", "PATH")
+        .optopt(
+            "",
+            "stage0-rustc-path",
+            "path to rustc to use for compiling run-make recipes",
+            "PATH",
+        )
         .optopt("", "rustdoc-path", "path to rustdoc to use for compiling", "PATH")
         .optopt("", "coverage-dump-path", "path to coverage-dump to use in tests", "PATH")
         .reqopt("", "python", "path to python to use for doc tests", "PATH")
@@ -268,12 +274,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
                 let path = Path::new(f);
                 let mut iter = path.iter().skip(1);
 
-                // We skip the test folder and check if the user passed `rmake.rs` or `Makefile`.
-                if iter
-                    .next()
-                    .is_some_and(|s| s == OsStr::new("rmake.rs") || s == OsStr::new("Makefile"))
-                    && iter.next().is_none()
-                {
+                // We skip the test folder and check if the user passed `rmake.rs`.
+                if iter.next().is_some_and(|s| s == "rmake.rs") && iter.next().is_none() {
                     path.parent().unwrap().to_str().unwrap().to_string()
                 } else {
                     f.to_string()
@@ -320,6 +322,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         run_lib_path: make_absolute(opt_path(matches, "run-lib-path")),
         rustc_path: opt_path(matches, "rustc-path"),
         cargo_path: matches.opt_str("cargo-path").map(PathBuf::from),
+        stage0_rustc_path: matches.opt_str("stage0-rustc-path").map(PathBuf::from),
         rustdoc_path: matches.opt_str("rustdoc-path").map(PathBuf::from),
         coverage_dump_path: matches.opt_str("coverage-dump-path").map(PathBuf::from),
         python: matches.opt_str("python").unwrap(),
@@ -776,16 +779,9 @@ fn collect_tests_from_dir(
         return Ok(());
     }
 
-    // For run-make tests, a "test file" is actually a directory that contains
-    // an `rmake.rs` or `Makefile`"
+    // For run-make tests, a "test file" is actually a directory that contains an `rmake.rs`.
     if cx.config.mode == Mode::RunMake {
-        if dir.join("Makefile").exists() && dir.join("rmake.rs").exists() {
-            return Err(io::Error::other(
-                "run-make tests cannot have both `Makefile` and `rmake.rs`",
-            ));
-        }
-
-        if dir.join("Makefile").exists() || dir.join("rmake.rs").exists() {
+        if dir.join("rmake.rs").exists() {
             let paths = TestPaths {
                 file: dir.to_path_buf(),
                 relative_dir: relative_dir_path.parent().unwrap().to_path_buf(),
@@ -854,24 +850,14 @@ pub fn is_test(file_name: &OsString) -> bool {
     !invalid_prefixes.iter().any(|p| file_name.starts_with(p))
 }
 
-/// For a single test file, creates one or more test structures (one per revision)
-/// that can be handed over to libtest to run, possibly in parallel.
+/// For a single test file, creates one or more test structures (one per revision) that can be
+/// handed over to libtest to run, possibly in parallel.
 fn make_test(cx: &TestCollectorCx, collector: &mut TestCollector, testpaths: &TestPaths) {
-    // For run-make tests, each "test file" is actually a _directory_ containing
-    // an `rmake.rs` or `Makefile`. But for the purposes of directive parsing,
-    // we want to look at that recipe file, not the directory itself.
+    // For run-make tests, each "test file" is actually a _directory_ containing an `rmake.rs`. But
+    // for the purposes of directive parsing, we want to look at that recipe file, not the directory
+    // itself.
     let test_path = if cx.config.mode == Mode::RunMake {
-        if testpaths.file.join("rmake.rs").exists() && testpaths.file.join("Makefile").exists() {
-            panic!("run-make tests cannot have both `rmake.rs` and `Makefile`");
-        }
-
-        if testpaths.file.join("rmake.rs").exists() {
-            // Parse directives in rmake.rs.
-            testpaths.file.join("rmake.rs")
-        } else {
-            // Parse directives in the Makefile.
-            testpaths.file.join("Makefile")
-        }
+        testpaths.file.join("rmake.rs")
     } else {
         PathBuf::from(&testpaths.file)
     };
diff --git a/src/tools/compiletest/src/raise_fd_limit.rs b/src/tools/compiletest/src/raise_fd_limit.rs
index 4445ecb7ce8..7b12ba946b9 100644
--- a/src/tools/compiletest/src/raise_fd_limit.rs
+++ b/src/tools/compiletest/src/raise_fd_limit.rs
@@ -7,7 +7,6 @@
 #[cfg(target_vendor = "apple")]
 #[allow(non_camel_case_types)]
 pub unsafe fn raise_fd_limit() {
-    use std::mem::size_of_val;
     use std::ptr::null_mut;
     use std::{cmp, io};
 
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index f36d43b211f..6e250ca12c9 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2412,8 +2412,9 @@ impl<'test> TestCx<'test> {
         let rust_src_dir = rust_src_dir.read_link().unwrap_or(rust_src_dir.to_path_buf());
         normalize_path(&rust_src_dir.join("library"), "$SRC_DIR_REAL");
 
-        // eg. /home/user/rust/build/x86_64-unknown-linux-gnu/test/ui
-        normalize_path(&self.config.build_test_suite_root, "$TEST_BUILD_DIR");
+        // eg.
+        // /home/user/rust/build/x86_64-unknown-linux-gnu/test/ui/<test_dir>/$name.$revision.$mode/
+        normalize_path(&self.output_base_dir(), "$TEST_BUILD_DIR");
         // eg. /home/user/rust/build
         normalize_path(&self.config.build_root, "$BUILD_DIR");
 
@@ -2434,6 +2435,18 @@ impl<'test> TestCx<'test> {
             .into_owned();
 
         normalized = Self::normalize_platform_differences(&normalized);
+
+        // Normalize long type name hash.
+        normalized =
+            static_regex!(r"\$TEST_BUILD_DIR/(?P<filename>[^\.]+).long-type-(?P<hash>\d+).txt")
+                .replace_all(&normalized, |caps: &Captures<'_>| {
+                    format!(
+                        "$TEST_BUILD_DIR/{filename}.long-type-$LONG_TYPE_HASH.txt",
+                        filename = &caps["filename"]
+                    )
+                })
+                .into_owned();
+
         normalized = normalized.replace("\t", "\\t"); // makes tabs visible
 
         // Remove test annotations like `//~ ERROR text` from the output,
diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs
index 9bb3993223e..8900752bd4b 100644
--- a/src/tools/compiletest/src/runtest/run_make.rs
+++ b/src/tools/compiletest/src/runtest/run_make.rs
@@ -9,171 +9,10 @@ use crate::util::{copy_dir_all, dylib_env_var};
 
 impl TestCx<'_> {
     pub(super) fn run_rmake_test(&self) {
-        let test_dir = &self.testpaths.file;
-        if test_dir.join("rmake.rs").exists() {
-            self.run_rmake_v2_test();
-        } else if test_dir.join("Makefile").exists() {
-            self.run_rmake_legacy_test();
-        } else {
-            self.fatal("failed to find either `rmake.rs` or `Makefile`")
-        }
-    }
-
-    fn run_rmake_legacy_test(&self) {
-        let cwd = env::current_dir().unwrap();
-
-        // FIXME(Zalathar): This should probably be `output_base_dir` to avoid
-        // an unnecessary extra subdirectory, but since legacy Makefile tests
-        // are hopefully going away, it seems safer to leave this perilous code
-        // as-is until it can all be deleted.
-        let tmpdir = cwd.join(self.output_base_name());
-        ignore_not_found(|| recursive_remove(&tmpdir)).unwrap();
-
-        fs::create_dir_all(&tmpdir).unwrap();
-
-        let host = &self.config.host;
-        let make = if host.contains("dragonfly")
-            || host.contains("freebsd")
-            || host.contains("netbsd")
-            || host.contains("openbsd")
-            || host.contains("aix")
-        {
-            "gmake"
-        } else {
-            "make"
-        };
-
-        let mut cmd = Command::new(make);
-        cmd.current_dir(&self.testpaths.file)
-            .stdout(Stdio::piped())
-            .stderr(Stdio::piped())
-            .env("TARGET", &self.config.target)
-            .env("PYTHON", &self.config.python)
-            .env("S", &self.config.src_root)
-            .env("RUST_BUILD_STAGE", &self.config.stage_id)
-            .env("RUSTC", cwd.join(&self.config.rustc_path))
-            .env("TMPDIR", &tmpdir)
-            .env("LD_LIB_PATH_ENVVAR", dylib_env_var())
-            .env("HOST_RPATH_DIR", cwd.join(&self.config.compile_lib_path))
-            .env("TARGET_RPATH_DIR", cwd.join(&self.config.run_lib_path))
-            .env("LLVM_COMPONENTS", &self.config.llvm_components)
-            // We for sure don't want these tests to run in parallel, so make
-            // sure they don't have access to these vars if we run via `make`
-            // at the top level
-            .env_remove("MAKEFLAGS")
-            .env_remove("MFLAGS")
-            .env_remove("CARGO_MAKEFLAGS");
-
-        if let Some(ref cargo) = self.config.cargo_path {
-            cmd.env("CARGO", cwd.join(cargo));
-        }
-
-        if let Some(ref rustdoc) = self.config.rustdoc_path {
-            cmd.env("RUSTDOC", cwd.join(rustdoc));
-        }
-
-        if let Some(ref node) = self.config.nodejs {
-            cmd.env("NODE", node);
-        }
-
-        if let Some(ref linker) = self.config.target_linker {
-            cmd.env("RUSTC_LINKER", linker);
-        }
-
-        if let Some(ref clang) = self.config.run_clang_based_tests_with {
-            cmd.env("CLANG", clang);
-        }
-
-        if let Some(ref filecheck) = self.config.llvm_filecheck {
-            cmd.env("LLVM_FILECHECK", filecheck);
-        }
-
-        if let Some(ref llvm_bin_dir) = self.config.llvm_bin_dir {
-            cmd.env("LLVM_BIN_DIR", llvm_bin_dir);
-        }
-
-        if let Some(ref remote_test_client) = self.config.remote_test_client {
-            cmd.env("REMOTE_TEST_CLIENT", remote_test_client);
-        }
-
-        // We don't want RUSTFLAGS set from the outside to interfere with
-        // compiler flags set in the test cases:
-        cmd.env_remove("RUSTFLAGS");
-
-        // Use dynamic musl for tests because static doesn't allow creating dylibs
-        if self.config.host.contains("musl") {
-            cmd.env("RUSTFLAGS", "-Ctarget-feature=-crt-static").env("IS_MUSL_HOST", "1");
-        }
-
-        if self.config.bless {
-            cmd.env("RUSTC_BLESS_TEST", "--bless");
-            // Assume this option is active if the environment variable is "defined", with _any_ value.
-            // As an example, a `Makefile` can use this option by:
-            //
-            //   ifdef RUSTC_BLESS_TEST
-            //       cp "$(TMPDIR)"/actual_something.ext expected_something.ext
-            //   else
-            //       $(DIFF) expected_something.ext "$(TMPDIR)"/actual_something.ext
-            //   endif
-        }
-
-        if self.config.target.contains("msvc") && !self.config.cc.is_empty() {
-            // We need to pass a path to `lib.exe`, so assume that `cc` is `cl.exe`
-            // and that `lib.exe` lives next to it.
-            let lib = Path::new(&self.config.cc).parent().unwrap().join("lib.exe");
-
-            // MSYS doesn't like passing flags of the form `/foo` as it thinks it's
-            // a path and instead passes `C:\msys64\foo`, so convert all
-            // `/`-arguments to MSVC here to `-` arguments.
-            let cflags = self
-                .config
-                .cflags
-                .split(' ')
-                .map(|s| s.replace("/", "-"))
-                .collect::<Vec<_>>()
-                .join(" ");
-            let cxxflags = self
-                .config
-                .cxxflags
-                .split(' ')
-                .map(|s| s.replace("/", "-"))
-                .collect::<Vec<_>>()
-                .join(" ");
-
-            cmd.env("IS_MSVC", "1")
-                .env("IS_WINDOWS", "1")
-                .env("MSVC_LIB", format!("'{}' -nologo", lib.display()))
-                .env("MSVC_LIB_PATH", format!("{}", lib.display()))
-                .env("CC", format!("'{}' {}", self.config.cc, cflags))
-                .env("CXX", format!("'{}' {}", &self.config.cxx, cxxflags));
-        } else {
-            cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags))
-                .env("CXX", format!("{} {}", self.config.cxx, self.config.cxxflags))
-                .env("AR", &self.config.ar);
-
-            if self.config.target.contains("windows") {
-                cmd.env("IS_WINDOWS", "1");
-            }
-        }
-
-        let (output, truncated) =
-            self.read2_abbreviated(cmd.spawn().expect("failed to spawn `make`"));
-        if !output.status.success() {
-            let res = ProcRes {
-                status: output.status,
-                stdout: String::from_utf8_lossy(&output.stdout).into_owned(),
-                stderr: String::from_utf8_lossy(&output.stderr).into_owned(),
-                truncated,
-                cmdline: format!("{:?}", cmd),
-            };
-            self.fatal_proc_rec("make failed", &res);
-        }
-    }
-
-    fn run_rmake_v2_test(&self) {
         // For `run-make` V2, we need to perform 2 steps to build and run a `run-make` V2 recipe
         // (`rmake.rs`) to run the actual tests. The support library is already built as a tool rust
-        // library and is available under `build/$TARGET/stageN-tools-bin/librun_make_support.rlib`.
+        // library and is available under
+        // `build/$HOST/stage0-bootstrap-tools/$TARGET/release/librun_make_support.rlib`.
         //
         // 1. We need to build the recipe `rmake.rs` as a binary and link in the `run_make_support`
         //    library.
@@ -191,8 +30,6 @@ impl TestCx<'_> {
         // recipes to `remove_dir_all($TMPDIR)` without running into issues related trying to remove
         // a currently running executable because the recipe executable is not under the
         // `rmake_out/` directory.
-        //
-        // This setup intentionally diverges from legacy Makefile run-make tests.
         let base_dir = self.output_base_dir();
         ignore_not_found(|| recursive_remove(&base_dir)).unwrap();
 
@@ -224,25 +61,21 @@ impl TestCx<'_> {
         //
         // ```
         // build/<target_triple>/
-        // ├── stageN-tools-bin/
-        // │   └── librun_make_support.rlib       // <- support rlib itself
-        // ├── stageN-tools/
-        // │   ├── release/deps/                  // <- deps of deps
-        // │   └── <host_triple>/release/deps/    // <- deps
+        // ├── stage0-bootstrap-tools/
+        // │   ├── <host_triple>/release/librun_make_support.rlib   // <- support rlib itself
+        // │   ├── <host_triple>/release/deps/                      // <- deps
+        // │   └── release/deps/                                    // <- deps of deps
         // ```
         //
         // FIXME(jieyouxu): there almost certainly is a better way to do this (specifically how the
-        // support lib and its deps are organized, can't we copy them to the tools-bin dir as
-        // well?), but this seems to work for now.
+        // support lib and its deps are organized), but this seems to work for now.
 
-        let stage_number = self.config.stage;
+        let tools_bin = host_build_root.join("stage0-bootstrap-tools");
+        let support_host_path = tools_bin.join(&self.config.host).join("release");
+        let support_lib_path = support_host_path.join("librun_make_support.rlib");
 
-        let stage_tools_bin = host_build_root.join(format!("stage{stage_number}-tools-bin"));
-        let support_lib_path = stage_tools_bin.join("librun_make_support.rlib");
-
-        let stage_tools = host_build_root.join(format!("stage{stage_number}-tools"));
-        let support_lib_deps = stage_tools.join(&self.config.host).join("release").join("deps");
-        let support_lib_deps_deps = stage_tools.join("release").join("deps");
+        let support_lib_deps = support_host_path.join("deps");
+        let support_lib_deps_deps = tools_bin.join("release").join("deps");
 
         // To compile the recipe with rustc, we need to provide suitable dynamic library search
         // paths to rustc. This includes both:
@@ -253,12 +86,6 @@ impl TestCx<'_> {
         let base_dylib_search_paths =
             Vec::from_iter(env::split_paths(&env::var(dylib_env_var()).unwrap()));
 
-        let host_dylib_search_paths = {
-            let mut paths = vec![self.config.compile_lib_path.clone()];
-            paths.extend(base_dylib_search_paths.iter().cloned());
-            paths
-        };
-
         // Calculate the paths of the recipe binary. As previously discussed, this is placed at
         // `<base_dir>/<bin_name>` with `bin_name` being `rmake` or `rmake.exe` depending on
         // platform.
@@ -268,7 +95,15 @@ impl TestCx<'_> {
             p
         };
 
-        let mut rustc = Command::new(&self.config.rustc_path);
+        // run-make-support and run-make tests are compiled using the stage0 compiler
+        // If the stage is 0, then the compiler that we test (either bootstrap or an explicitly
+        // set compiler) is the one that actually compiled run-make-support.
+        let stage0_rustc = self
+            .config
+            .stage0_rustc_path
+            .as_ref()
+            .expect("stage0 rustc is required to run run-make tests");
+        let mut rustc = Command::new(&stage0_rustc);
         rustc
             .arg("-o")
             .arg(&recipe_bin)
@@ -282,35 +117,12 @@ impl TestCx<'_> {
             .arg(format!("run_make_support={}", &support_lib_path.to_string_lossy()))
             .arg("--edition=2021")
             .arg(&self.testpaths.file.join("rmake.rs"))
-            .arg("-Cprefer-dynamic")
-            // Provide necessary library search paths for rustc.
-            .env(dylib_env_var(), &env::join_paths(host_dylib_search_paths).unwrap());
+            .arg("-Cprefer-dynamic");
 
         // In test code we want to be very pedantic about values being silently discarded that are
         // annotated with `#[must_use]`.
         rustc.arg("-Dunused_must_use");
 
-        // > `cg_clif` uses `COMPILETEST_FORCE_STAGE0=1 ./x.py test --stage 0` for running the rustc
-        // > test suite. With the introduction of rmake.rs this broke. `librun_make_support.rlib` is
-        // > compiled using the bootstrap rustc wrapper which sets `--sysroot
-        // > build/aarch64-unknown-linux-gnu/stage0-sysroot`, but then compiletest will compile
-        // > `rmake.rs` using the sysroot of the bootstrap compiler causing it to not find the
-        // > `libstd.rlib` against which `librun_make_support.rlib` is compiled.
-        //
-        // The gist here is that we have to pass the proper stage0 sysroot if we want
-        //
-        // ```
-        // $ COMPILETEST_FORCE_STAGE0=1 ./x test run-make --stage 0
-        // ```
-        //
-        // to work correctly.
-        //
-        // See <https://github.com/rust-lang/rust/pull/122248> for more background.
-        let stage0_sysroot = host_build_root.join("stage0-sysroot");
-        if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() {
-            rustc.arg("--sysroot").arg(&stage0_sysroot);
-        }
-
         // Now run rustc to build the recipe.
         let res = self.run_command_to_procres(&mut rustc);
         if !res.status.success() {
@@ -320,35 +132,24 @@ impl TestCx<'_> {
         // To actually run the recipe, we have to provide the recipe with a bunch of information
         // provided through env vars.
 
-        // Compute stage-specific standard library paths.
-        let stage_std_path = host_build_root.join(format!("stage{stage_number}")).join("lib");
-
         // Compute dynamic library search paths for recipes.
+        // These dylib directories are needed to **execute the recipe**.
         let recipe_dylib_search_paths = {
             let mut paths = base_dylib_search_paths.clone();
-
-            // For stage 0, we need to explicitly include the stage0-sysroot libstd dylib.
-            // See <https://github.com/rust-lang/rust/issues/135373>.
-            if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() {
-                paths.push(
-                    stage0_sysroot.join("lib").join("rustlib").join(&self.config.host).join("lib"),
-                );
-            }
-
-            paths.push(support_lib_path.parent().unwrap().to_path_buf());
-            paths.push(stage_std_path.join("rustlib").join(&self.config.host).join("lib"));
-            paths
-        };
-
-        // Compute runtime library search paths for recipes. This is target-specific.
-        let target_runtime_dylib_search_paths = {
-            let mut paths = vec![rmake_out_dir.clone()];
-            paths.extend(base_dylib_search_paths.iter().cloned());
+            paths.push(
+                stage0_rustc
+                    .parent()
+                    .unwrap()
+                    .parent()
+                    .unwrap()
+                    .join("lib")
+                    .join("rustlib")
+                    .join(&self.config.host)
+                    .join("lib"),
+            );
             paths
         };
 
-        // FIXME(jieyouxu): please rename `TARGET_RPATH_ENV`, `HOST_RPATH_DIR` and
-        // `TARGET_RPATH_DIR`, it is **extremely** confusing!
         let mut cmd = Command::new(&recipe_bin);
         cmd.current_dir(&rmake_out_dir)
             .stdout(Stdio::piped())
@@ -357,9 +158,14 @@ impl TestCx<'_> {
             // example, this could be `LD_LIBRARY_PATH` on some linux distros but `PATH` on Windows.
             .env("LD_LIB_PATH_ENVVAR", dylib_env_var())
             // Provide the dylib search paths.
+            // This is required to run the **recipe** itself.
             .env(dylib_env_var(), &env::join_paths(recipe_dylib_search_paths).unwrap())
-            // Provide runtime dylib search paths.
-            .env("TARGET_RPATH_ENV", &env::join_paths(target_runtime_dylib_search_paths).unwrap())
+            // Provide the directory to libraries that are needed to run the *compiler* invoked
+            // by the recipe.
+            .env("HOST_RUSTC_DYLIB_PATH", &self.config.compile_lib_path)
+            // Provide the directory to libraries that might be needed to run binaries created
+            // by a compiler invoked by the recipe.
+            .env("TARGET_EXE_DYLIB_PATH", &self.config.run_lib_path)
             // Provide the target.
             .env("TARGET", &self.config.target)
             // Some tests unfortunately still need Python, so provide path to a Python interpreter.
@@ -370,13 +176,6 @@ impl TestCx<'_> {
             .env("BUILD_ROOT", &host_build_root)
             // Provide path to stage-corresponding rustc.
             .env("RUSTC", &self.config.rustc_path)
-            // Provide the directory to libraries that are needed to run the *compiler*. This is not
-            // to be confused with `TARGET_RPATH_ENV` or `TARGET_RPATH_DIR`. This is needed if the
-            // recipe wants to invoke rustc.
-            .env("HOST_RPATH_DIR", &self.config.compile_lib_path)
-            // Provide the directory to libraries that might be needed to run compiled binaries
-            // (further compiled by the recipe!).
-            .env("TARGET_RPATH_DIR", &self.config.run_lib_path)
             // Provide which LLVM components are available (e.g. which LLVM components are provided
             // through a specific CI runner).
             .env("LLVM_COMPONENTS", &self.config.llvm_components);
diff --git a/src/tools/jsondocck/src/main.rs b/src/tools/jsondocck/src/main.rs
index 7bfa7e3355d..54249fbd9ae 100644
--- a/src/tools/jsondocck/src/main.rs
+++ b/src/tools/jsondocck/src/main.rs
@@ -1,6 +1,6 @@
 use std::borrow::Cow;
 use std::process::ExitCode;
-use std::sync::OnceLock;
+use std::sync::LazyLock;
 use std::{env, fs};
 
 use regex::{Regex, RegexBuilder};
@@ -151,8 +151,7 @@ impl CommandKind {
     }
 }
 
-static LINE_PATTERN: OnceLock<Regex> = OnceLock::new();
-fn line_pattern() -> Regex {
+static LINE_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
     RegexBuilder::new(
         r#"
         //@\s+
@@ -165,7 +164,19 @@ fn line_pattern() -> Regex {
     .unicode(true)
     .build()
     .unwrap()
-}
+});
+
+static DEPRECATED_LINE_PATTERN: LazyLock<Regex> = LazyLock::new(|| {
+    RegexBuilder::new(
+        r#"
+        //\s+@
+    "#,
+    )
+    .ignore_whitespace(true)
+    .unicode(true)
+    .build()
+    .unwrap()
+});
 
 fn print_err(msg: &str, lineno: usize) {
     eprintln!("Invalid command: {} on line {}", msg, lineno)
@@ -184,21 +195,23 @@ fn get_commands(template: &str) -> Result<Vec<Command>, ()> {
     for (lineno, line) in file.split('\n').enumerate() {
         let lineno = lineno + 1;
 
-        let cap = match LINE_PATTERN.get_or_init(line_pattern).captures(line) {
-            Some(c) => c,
-            None => continue,
+        if DEPRECATED_LINE_PATTERN.is_match(line) {
+            print_err("Deprecated command syntax, replace `// @` with `//@ `", lineno);
+            errors = true;
+            continue;
+        }
+
+        let Some(cap) = LINE_PATTERN.captures(line) else {
+            continue;
         };
 
-        let negated = cap.name("negated").unwrap().as_str() == "!";
+        let negated = &cap["negated"] == "!";
 
         let args_str = &cap["args"];
-        let args = match shlex::split(args_str) {
-            Some(args) => args,
-            None => {
-                print_err(&format!("Invalid arguments to shlex::split: `{args_str}`",), lineno);
-                errors = true;
-                continue;
-            }
+        let Some(args) = shlex::split(args_str) else {
+            print_err(&format!("Invalid arguments to shlex::split: `{args_str}`",), lineno);
+            errors = true;
+            continue;
         };
 
         if let Some((kind, path)) = CommandKind::parse(&cap["cmd"], negated, &args) {
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index a4f2a117b18..ff3a25e94bd 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -285,9 +285,19 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
 pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
-    fn expose_ptr(&self, alloc_id: AllocId, tag: BorTag) -> InterpResult<'tcx> {
+    fn expose_provenance(&self, provenance: Provenance) -> InterpResult<'tcx> {
         let this = self.eval_context_ref();
         let mut global_state = this.machine.alloc_addresses.borrow_mut();
+
+        let (alloc_id, tag) = match provenance {
+            Provenance::Concrete { alloc_id, tag } => (alloc_id, tag),
+            Provenance::Wildcard => {
+                // No need to do anything for wildcard pointers as
+                // their provenances have already been previously exposed.
+                return interp_ok(());
+            }
+        };
+
         // In strict mode, we don't need this, so we can save some cycles by not tracking it.
         if global_state.provenance_mode == ProvenanceMode::Strict {
             return interp_ok(());
@@ -422,6 +432,19 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let rel_offset = this.truncate_to_target_usize(addr.bytes().wrapping_sub(base_addr));
         Some((alloc_id, Size::from_bytes(rel_offset)))
     }
+
+    /// Prepare all exposed memory for a native call.
+    /// This overapproximates the modifications which external code might make to memory:
+    /// We set all reachable allocations as initialized, mark all reachable provenances as exposed
+    /// and overwrite them with `Provenance::WILDCARD`.
+    fn prepare_exposed_for_native_call(&mut self) -> InterpResult<'tcx> {
+        let this = self.eval_context_mut();
+        // We need to make a deep copy of this list, but it's fine; it also serves as scratch space
+        // for the search within `prepare_for_native_call`.
+        let exposed: Vec<AllocId> =
+            this.machine.alloc_addresses.get_mut().exposed.iter().copied().collect();
+        this.prepare_for_native_call(exposed)
+    }
 }
 
 impl<'tcx> MiriMachine<'tcx> {
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 4ece8f7895d..dbb092f6728 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -1291,18 +1291,12 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
     /// Called on `ptr as usize` casts.
     /// (Actually computing the resulting `usize` doesn't need machine help,
     /// that's just `Scalar::try_to_int`.)
+    #[inline(always)]
     fn expose_provenance(
         ecx: &InterpCx<'tcx, Self>,
         provenance: Self::Provenance,
     ) -> InterpResult<'tcx> {
-        match provenance {
-            Provenance::Concrete { alloc_id, tag } => ecx.expose_ptr(alloc_id, tag),
-            Provenance::Wildcard => {
-                // No need to do anything for wildcard pointers as
-                // their provenances have already been previously exposed.
-                interp_ok(())
-            }
-        }
+        ecx.expose_provenance(provenance)
     }
 
     /// Convert a pointer with provenance into an allocation-offset pair and extra provenance info.
diff --git a/src/tools/miri/src/shims/native_lib.rs b/src/tools/miri/src/shims/native_lib.rs
index 8c9e1860f31..c6fcb0355eb 100644
--- a/src/tools/miri/src/shims/native_lib.rs
+++ b/src/tools/miri/src/shims/native_lib.rs
@@ -160,16 +160,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             let imm = this.read_immediate(arg)?;
             libffi_args.push(imm_to_carg(&imm, this)?);
-            // If we are passing a pointer, prepare the memory it points to.
+            // If we are passing a pointer, expose its provenance. Below, all exposed memory
+            // (previously exposed and new exposed) will then be properly prepared.
             if matches!(arg.layout.ty.kind(), ty::RawPtr(..)) {
                 let ptr = imm.to_scalar().to_pointer(this)?;
                 let Some(prov) = ptr.provenance else {
-                    // Pointer without provenance may not access any memory.
-                    continue;
-                };
-                // We use `get_alloc_id` for its best-effort behaviour with Wildcard provenance.
-                let Some(alloc_id) = prov.get_alloc_id() else {
-                    // Wildcard pointer, whatever it points to must be already exposed.
+                    // Pointer without provenance may not access any memory anyway, skip.
                     continue;
                 };
                 // The first time this happens, print a warning.
@@ -178,12 +174,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     this.emit_diagnostic(NonHaltingDiagnostic::NativeCallSharedMem);
                 }
 
-                this.prepare_for_native_call(alloc_id, prov)?;
+                this.expose_provenance(prov)?;
             }
         }
 
-        // FIXME: In the future, we should also call `prepare_for_native_call` on all previously
-        // exposed allocations, since C may access any of them.
+        // Prepare all exposed memory.
+        this.prepare_exposed_for_native_call()?;
 
         // Convert them to `libffi::high::Arg` type.
         let libffi_args = libffi_args
diff --git a/src/tools/miri/tests/native-lib/pass/ptr_write_access.rs b/src/tools/miri/tests/native-lib/pass/ptr_write_access.rs
index a92e63a4da6..bd4e0b23601 100644
--- a/src/tools/miri/tests/native-lib/pass/ptr_write_access.rs
+++ b/src/tools/miri/tests/native-lib/pass/ptr_write_access.rs
@@ -6,7 +6,7 @@
 #![feature(box_as_ptr)]
 
 use std::mem::MaybeUninit;
-use std::ptr::null;
+use std::ptr;
 
 fn main() {
     test_increment_int();
@@ -20,6 +20,8 @@ fn main() {
     test_pass_dangling();
     test_swap_ptr_triple_dangling();
     test_return_ptr();
+    test_pass_ptr_as_int();
+    test_pass_ptr_via_previously_shared_mem();
 }
 
 /// Test function that modifies an int.
@@ -112,7 +114,7 @@ fn test_swap_ptr() {
     }
 
     let x = 61;
-    let (mut ptr0, mut ptr1) = (&raw const x, null());
+    let (mut ptr0, mut ptr1) = (&raw const x, ptr::null());
 
     unsafe { swap_ptr(&mut ptr0, &mut ptr1) };
     assert_eq!(unsafe { *ptr1 }, x);
@@ -131,7 +133,7 @@ fn test_swap_ptr_tuple() {
     }
 
     let x = 71;
-    let mut tuple = Tuple { ptr0: &raw const x, ptr1: null() };
+    let mut tuple = Tuple { ptr0: &raw const x, ptr1: ptr::null() };
 
     unsafe { swap_ptr_tuple(&mut tuple) }
     assert_eq!(unsafe { *tuple.ptr1 }, x);
@@ -148,7 +150,7 @@ fn test_overwrite_dangling() {
     drop(b);
 
     unsafe { overwrite_ptr(&mut ptr) };
-    assert_eq!(ptr, null());
+    assert_eq!(ptr, ptr::null());
 }
 
 /// Test function that passes a dangling pointer.
@@ -200,3 +202,33 @@ fn test_return_ptr() {
     let ptr = unsafe { return_ptr(ptr) };
     assert_eq!(unsafe { *ptr }, x);
 }
+
+/// Test casting a pointer to an integer and passing that to C.
+fn test_pass_ptr_as_int() {
+    extern "C" {
+        fn pass_ptr_as_int(ptr: usize, set_to_val: i32);
+    }
+
+    let mut m: MaybeUninit<i32> = MaybeUninit::uninit();
+    unsafe { pass_ptr_as_int(m.as_mut_ptr() as usize, 42) };
+    assert_eq!(unsafe { m.assume_init() }, 42);
+}
+
+fn test_pass_ptr_via_previously_shared_mem() {
+    extern "C" {
+        fn set_shared_mem(ptr: *mut *mut i32);
+        fn init_ptr_stored_in_shared_mem(val: i32);
+    }
+
+    let mut m: *mut i32 = ptr::null_mut();
+    let ptr_to_m = &raw mut m;
+    unsafe { set_shared_mem(&raw mut m) };
+
+    let mut m2: MaybeUninit<i32> = MaybeUninit::uninit();
+    // Store a pointer to m2 somewhere that C code can access it.
+    unsafe { ptr_to_m.write(m2.as_mut_ptr()) };
+    // Have C code write there.
+    unsafe { init_ptr_stored_in_shared_mem(42) };
+    // Ensure this memory is now considered initialized.
+    assert_eq!(unsafe { m2.assume_init() }, 42);
+}
diff --git a/src/tools/miri/tests/native-lib/ptr_read_access.c b/src/tools/miri/tests/native-lib/ptr_read_access.c
index 3b427d6033e..b89126d3d7c 100644
--- a/src/tools/miri/tests/native-lib/ptr_read_access.c
+++ b/src/tools/miri/tests/native-lib/ptr_read_access.c
@@ -1,33 +1,34 @@
 #include <stdio.h>
+#include <stdint.h>
 
 // See comments in build_native_lib()
 #define EXPORT __attribute__((visibility("default")))
 
 /* Test: test_access_pointer */
 
-EXPORT void print_pointer(const int *ptr) {
+EXPORT void print_pointer(const int32_t *ptr) {
   printf("printing pointer dereference from C: %d\n", *ptr);
 }
 
 /* Test: test_access_simple */
 
 typedef struct Simple {
-  int field;
+  int32_t field;
 } Simple;
 
-EXPORT int access_simple(const Simple *s_ptr) {
+EXPORT int32_t access_simple(const Simple *s_ptr) {
   return s_ptr->field;
 }
 
 /* Test: test_access_nested */
 
 typedef struct Nested {
-  int value;
+  int32_t value;
   struct Nested *next;
 } Nested;
 
 // Returns the innermost/last value of a Nested pointer chain.
-EXPORT int access_nested(const Nested *n_ptr) {
+EXPORT int32_t access_nested(const Nested *n_ptr) {
   // Edge case: `n_ptr == NULL` (i.e. first Nested is None).
   if (!n_ptr) { return 0; }
 
@@ -41,10 +42,10 @@ EXPORT int access_nested(const Nested *n_ptr) {
 /* Test: test_access_static */
 
 typedef struct Static {
-    int value;
+    int32_t value;
     struct Static *recurse;
 } Static;
 
-EXPORT int access_static(const Static *s_ptr) {
+EXPORT int32_t access_static(const Static *s_ptr) {
   return s_ptr->recurse->recurse->value;
 }
diff --git a/src/tools/miri/tests/native-lib/ptr_write_access.c b/src/tools/miri/tests/native-lib/ptr_write_access.c
index b54c5d86b21..fd8b005499c 100644
--- a/src/tools/miri/tests/native-lib/ptr_write_access.c
+++ b/src/tools/miri/tests/native-lib/ptr_write_access.c
@@ -1,23 +1,24 @@
 #include <stddef.h>
+#include <stdint.h>
 
 // See comments in build_native_lib()
 #define EXPORT __attribute__((visibility("default")))
 
 /* Test: test_increment_int */
 
-EXPORT void increment_int(int *ptr) {
+EXPORT void increment_int(int32_t *ptr) {
   *ptr += 1;
 }
 
 /* Test: test_init_int */
 
-EXPORT void init_int(int *ptr, int val) {
+EXPORT void init_int(int32_t *ptr, int32_t val) {
   *ptr = val;
 }
 
 /* Test: test_init_array */
 
-EXPORT void init_array(int *array, size_t len, int val) {
+EXPORT void init_array(int32_t *array, size_t len, int32_t val) {
   for (size_t i = 0; i < len; i++) {
     array[i] = val;
   }
@@ -26,28 +27,28 @@ EXPORT void init_array(int *array, size_t len, int val) {
 /* Test: test_init_static_inner */
 
 typedef struct SyncPtr {
-    int *ptr;
+    int32_t *ptr;
 } SyncPtr;
 
-EXPORT void init_static_inner(const SyncPtr *s_ptr, int val) {
+EXPORT void init_static_inner(const SyncPtr *s_ptr, int32_t val) {
   *(s_ptr->ptr) = val;
 }
 
 /* Tests: test_exposed, test_pass_dangling */
 
-EXPORT void ignore_ptr(__attribute__((unused)) const int *ptr) {
+EXPORT void ignore_ptr(__attribute__((unused)) const int32_t *ptr) {
   return;
 }
 
 /* Test: test_expose_int */
-EXPORT void expose_int(const int *int_ptr, const int **pptr) {
+EXPORT void expose_int(const int32_t *int_ptr, const int32_t **pptr) {
   *pptr = int_ptr;
 }
 
 /* Test: test_swap_ptr */
 
-EXPORT void swap_ptr(const int **pptr0, const int **pptr1) {
-  const int *tmp = *pptr0;
+EXPORT void swap_ptr(const int32_t **pptr0, const int32_t **pptr1) {
+  const int32_t *tmp = *pptr0;
   *pptr0 = *pptr1;
   *pptr1 = tmp;
 }
@@ -55,36 +56,54 @@ EXPORT void swap_ptr(const int **pptr0, const int **pptr1) {
 /* Test: test_swap_ptr_tuple */
 
 typedef struct Tuple {
-    int *ptr0;
-    int *ptr1;
+    int32_t *ptr0;
+    int32_t *ptr1;
 } Tuple;
 
 EXPORT void swap_ptr_tuple(Tuple *t_ptr) {
-  int *tmp = t_ptr->ptr0;
+  int32_t *tmp = t_ptr->ptr0;
   t_ptr->ptr0 = t_ptr->ptr1;
   t_ptr->ptr1 = tmp;
 }
 
 /* Test: test_overwrite_dangling */
 
-EXPORT void overwrite_ptr(const int **pptr) {
+EXPORT void overwrite_ptr(const int32_t **pptr) {
   *pptr = NULL;
 }
 
 /* Test: test_swap_ptr_triple_dangling */
 
 typedef struct Triple {
-    int *ptr0;
-    int *ptr1;
-    int *ptr2;
+    int32_t *ptr0;
+    int32_t *ptr1;
+    int32_t *ptr2;
 } Triple;
 
 EXPORT void swap_ptr_triple_dangling(Triple *t_ptr) {
-  int *tmp = t_ptr->ptr0;
+  int32_t *tmp = t_ptr->ptr0;
   t_ptr->ptr0 = t_ptr->ptr2;
   t_ptr->ptr2 = tmp;
 }
 
-EXPORT const int *return_ptr(const int *ptr) {
+EXPORT const int32_t *return_ptr(const int32_t *ptr) {
   return ptr;
 }
+
+/* Test: test_pass_ptr_as_int */
+
+EXPORT void pass_ptr_as_int(uintptr_t ptr, int32_t set_to_val) {
+  *(int32_t*)ptr = set_to_val;
+}
+
+/* Test: test_pass_ptr_via_previously_shared_mem */
+
+int32_t** shared_place;
+
+EXPORT void set_shared_mem(int32_t** ptr) {
+  shared_place = ptr;
+}
+
+EXPORT void init_ptr_stored_in_shared_mem(int32_t val) {
+  **shared_place = val;
+}
diff --git a/src/tools/miri/tests/native-lib/scalar_arguments.c b/src/tools/miri/tests/native-lib/scalar_arguments.c
index 6da730a4987..acccf06f3df 100644
--- a/src/tools/miri/tests/native-lib/scalar_arguments.c
+++ b/src/tools/miri/tests/native-lib/scalar_arguments.c
@@ -1,9 +1,10 @@
 #include <stdio.h>
+#include <stdint.h>
 
 // See comments in build_native_lib()
 #define EXPORT __attribute__((visibility("default")))
 
-EXPORT int add_one_int(int x) {
+EXPORT int32_t add_one_int(int32_t x) {
   return 2 + x;
 }
 
@@ -13,23 +14,23 @@ EXPORT void printer(void) {
 
 // function with many arguments, to test functionality when some args are stored
 // on the stack
-EXPORT int test_stack_spill(int a, int b, int c, int d, int e, int f, int g, int h, int i, int j, int k, int l) {
+EXPORT int32_t test_stack_spill(int32_t a, int32_t b, int32_t c, int32_t d, int32_t e, int32_t f, int32_t g, int32_t h, int32_t i, int32_t j, int32_t k, int32_t l) {
   return a+b+c+d+e+f+g+h+i+j+k+l;
 }
 
-EXPORT unsigned int get_unsigned_int(void) {
+EXPORT uint32_t get_unsigned_int(void) {
   return -10;
 }
 
-EXPORT short add_int16(short x) {
+EXPORT short add_int16(int16_t x) {
   return x + 3;
 }
 
-EXPORT long add_short_to_long(short x, long y) {
+EXPORT long add_short_to_long(int16_t x, int64_t y) {
   return x + y;
 }
 
 // To test that functions not marked with EXPORT cannot be called by Miri.
-int not_exported(void) {
+int32_t not_exported(void) {
   return 0;
 }
diff --git a/src/tools/miri/tests/pass/unsized.rs b/src/tools/miri/tests/pass/unsized.rs
index 5c6929882f6..6ad06354302 100644
--- a/src/tools/miri/tests/pass/unsized.rs
+++ b/src/tools/miri/tests/pass/unsized.rs
@@ -1,22 +1,8 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
-#![feature(unsized_tuple_coercion)]
 #![feature(unsized_fn_params)]
 #![feature(custom_mir, core_intrinsics)]
 
-use std::mem;
-
-fn unsized_tuple() {
-    let x: &(i32, i32, [i32]) = &(0, 1, [2, 3]);
-    let y: &(i32, i32, [i32]) = &(0, 1, [2, 3, 4]);
-    let mut a = [y, x];
-    a.sort();
-    assert_eq!(a, [x, y]);
-
-    assert_eq!(&format!("{:?}", a), "[(0, 1, [2, 3]), (0, 1, [2, 3, 4])]");
-    assert_eq!(mem::size_of_val(x), 16);
-}
-
 fn unsized_params() {
     pub fn f0(_f: dyn FnOnce()) {}
     pub fn f1(_s: str) {}
@@ -56,7 +42,6 @@ fn unsized_field_projection() {
 }
 
 fn main() {
-    unsized_tuple();
     unsized_params();
     unsized_field_projection();
 }
diff --git a/src/tools/opt-dist/src/main.rs b/src/tools/opt-dist/src/main.rs
index 565721a9093..3111149f2ae 100644
--- a/src/tools/opt-dist/src/main.rs
+++ b/src/tools/opt-dist/src/main.rs
@@ -389,6 +389,7 @@ fn main() -> anyhow::Result<()> {
             "clippy",
             "miri",
             "rustfmt",
+            "gcc",
         ] {
             build_args.extend(["--skip".to_string(), target.to_string()]);
         }
diff --git a/src/tools/opt-dist/src/metrics.rs b/src/tools/opt-dist/src/metrics.rs
index 89c4cb12d4c..0a745566eb5 100644
--- a/src/tools/opt-dist/src/metrics.rs
+++ b/src/tools/opt-dist/src/metrics.rs
@@ -1,33 +1,10 @@
 use std::time::Duration;
 
-use build_helper::metrics::{JsonNode, JsonRoot};
+use build_helper::metrics::{BuildStep, JsonRoot, format_build_steps};
 use camino::Utf8Path;
 
 use crate::timer::TimerSection;
 
-#[derive(Clone, Debug)]
-pub struct BuildStep {
-    r#type: String,
-    children: Vec<BuildStep>,
-    duration: Duration,
-}
-
-impl BuildStep {
-    pub fn find_all_by_type(&self, r#type: &str) -> Vec<&BuildStep> {
-        let mut result = Vec::new();
-        self.find_by_type(r#type, &mut result);
-        result
-    }
-    fn find_by_type<'a>(&'a self, r#type: &str, result: &mut Vec<&'a BuildStep>) {
-        if self.r#type == r#type {
-            result.push(self);
-        }
-        for child in &self.children {
-            child.find_by_type(r#type, result);
-        }
-    }
-}
-
 /// Loads the metrics of the most recent bootstrap execution from a metrics.json file.
 pub fn load_metrics(path: &Utf8Path) -> anyhow::Result<BuildStep> {
     let content = std::fs::read(path.as_std_path())?;
@@ -37,30 +14,7 @@ pub fn load_metrics(path: &Utf8Path) -> anyhow::Result<BuildStep> {
         .pop()
         .ok_or_else(|| anyhow::anyhow!("No bootstrap invocation found in metrics file"))?;
 
-    fn parse(node: JsonNode) -> Option<BuildStep> {
-        match node {
-            JsonNode::RustbuildStep {
-                type_: kind,
-                children,
-                duration_excluding_children_sec,
-                ..
-            } => {
-                let children: Vec<_> = children.into_iter().filter_map(parse).collect();
-                let children_duration = children.iter().map(|c| c.duration).sum::<Duration>();
-                Some(BuildStep {
-                    r#type: kind.to_string(),
-                    children,
-                    duration: children_duration
-                        + Duration::from_secs_f64(duration_excluding_children_sec),
-                })
-            }
-            JsonNode::TestSuite(_) => None,
-        }
-    }
-
-    let duration = Duration::from_secs_f64(invocation.duration_including_children_sec);
-    let children: Vec<_> = invocation.children.into_iter().filter_map(parse).collect();
-    Ok(BuildStep { r#type: "root".to_string(), children, duration })
+    Ok(BuildStep::from_invocation(&invocation))
 }
 
 /// Logs the individual metrics in a table and add Rustc and LLVM durations to the passed
@@ -82,27 +36,6 @@ pub fn record_metrics(metrics: &BuildStep, timer: &mut TimerSection) {
         timer.add_duration("Rustc", rustc_duration);
     }
 
-    log_metrics(metrics);
-}
-
-fn log_metrics(metrics: &BuildStep) {
-    use std::fmt::Write;
-
-    let mut substeps: Vec<(u32, &BuildStep)> = Vec::new();
-
-    fn visit<'a>(step: &'a BuildStep, level: u32, substeps: &mut Vec<(u32, &'a BuildStep)>) {
-        substeps.push((level, step));
-        for child in &step.children {
-            visit(child, level + 1, substeps);
-        }
-    }
-
-    visit(metrics, 0, &mut substeps);
-
-    let mut output = String::new();
-    for (level, step) in substeps {
-        let label = format!("{}{}", ".".repeat(level as usize), step.r#type);
-        writeln!(output, "{label:<65}{:>8.2}s", step.duration.as_secs_f64()).unwrap();
-    }
+    let output = format_build_steps(metrics);
     log::info!("Build step durations\n{output}");
 }
diff --git a/src/tools/run-make-support/src/artifact_names.rs b/src/tools/run-make-support/src/artifact_names.rs
index 0d7b5cb9838..8968f831542 100644
--- a/src/tools/run-make-support/src/artifact_names.rs
+++ b/src/tools/run-make-support/src/artifact_names.rs
@@ -8,23 +8,6 @@ use crate::targets::is_msvc;
 /// Construct the static library name based on the target.
 #[must_use]
 pub fn static_lib_name(name: &str) -> String {
-    // See tools.mk (irrelevant lines omitted):
-    //
-    // ```makefile
-    // ifeq ($(UNAME),Darwin)
-    //     STATICLIB = $(TMPDIR)/lib$(1).a
-    // else
-    //     ifdef IS_WINDOWS
-    //         ifdef IS_MSVC
-    //             STATICLIB = $(TMPDIR)/$(1).lib
-    //         else
-    //             STATICLIB = $(TMPDIR)/lib$(1).a
-    //         endif
-    //     else
-    //         STATICLIB = $(TMPDIR)/lib$(1).a
-    //     endif
-    // endif
-    // ```
     assert!(!name.contains(char::is_whitespace), "static library name cannot contain whitespace");
 
     if is_msvc() { format!("{name}.lib") } else { format!("lib{name}.a") }
diff --git a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs
index becb91ae989..0e6d6ea6075 100644
--- a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs
+++ b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/cc.rs
@@ -80,17 +80,6 @@ impl Cc {
 
     /// Specify `-o` or `-Fe`/`-Fo` depending on platform/compiler.
     pub fn out_exe(&mut self, name: &str) -> &mut Self {
-        // Ref: tools.mk (irrelevant lines omitted):
-        //
-        // ```makefile
-        // ifdef IS_MSVC
-        //     OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \
-        //         -Fo:`cygpath -w $(TMPDIR)/$(1).obj`
-        // else
-        //     OUT_EXE=-o $(TMPDIR)/$(1)
-        // endif
-        // ```
-
         let mut path = std::path::PathBuf::from(name);
 
         if is_msvc() {
diff --git a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs
index 49210d75e06..ca6ab3275c4 100644
--- a/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs
+++ b/src/tools/run-make-support/src/external_deps/c_cxx_compiler/extras.rs
@@ -2,36 +2,6 @@ use crate::{is_msvc, is_windows, uname};
 
 /// `EXTRACFLAGS`
 pub fn extra_c_flags() -> Vec<&'static str> {
-    // Adapted from tools.mk (trimmed):
-    //
-    // ```makefile
-    // ifdef IS_WINDOWS
-    //     ifdef IS_MSVC
-    //         EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib bcrypt.lib ntdll.lib synchronization.lib
-    //     else
-    //         EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt -lntdll -lsynchronization
-    //     endif
-    // else
-    //     ifeq ($(UNAME),Darwin)
-    //         EXTRACFLAGS := -lresolv
-    //     else
-    //         ifeq ($(UNAME),FreeBSD)
-    //             EXTRACFLAGS := -lm -lpthread -lgcc_s
-    //         else
-    //             ifeq ($(UNAME),SunOS)
-    //                 EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket -lresolv
-    //             else
-    //                 ifeq ($(UNAME),OpenBSD)
-    //                     EXTRACFLAGS := -lm -lpthread -lc++abi
-    //                 else
-    //                     EXTRACFLAGS := -lm -lrt -ldl -lpthread
-    //                 endif
-    //             endif
-    //         endif
-    //     endif
-    // endif
-    // ```
-
     if is_windows() {
         if is_msvc() {
             vec![
@@ -60,31 +30,6 @@ pub fn extra_c_flags() -> Vec<&'static str> {
 
 /// `EXTRACXXFLAGS`
 pub fn extra_cxx_flags() -> Vec<&'static str> {
-    // Adapted from tools.mk (trimmed):
-    //
-    // ```makefile
-    // ifdef IS_WINDOWS
-    //     ifdef IS_MSVC
-    //     else
-    //         EXTRACXXFLAGS := -lstdc++
-    //     endif
-    // else
-    //     ifeq ($(UNAME),Darwin)
-    //         EXTRACXXFLAGS := -lc++
-    //     else
-    //         ifeq ($(UNAME),FreeBSD)
-    //         else
-    //             ifeq ($(UNAME),SunOS)
-    //             else
-    //                 ifeq ($(UNAME),OpenBSD)
-    //                 else
-    //                     EXTRACXXFLAGS := -lstdc++
-    //                 endif
-    //             endif
-    //         endif
-    //     endif
-    // endif
-    // ```
     if is_windows() {
         if is_msvc() { vec![] } else { vec!["-lstdc++"] }
     } else {
diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs
index 710ba025830..0e2239147f1 100644
--- a/src/tools/run-make-support/src/external_deps/rustc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustc.rs
@@ -5,7 +5,7 @@ use std::str::FromStr as _;
 use crate::command::Command;
 use crate::env::env_var;
 use crate::path_helpers::cwd;
-use crate::util::set_host_rpath;
+use crate::util::set_host_compiler_dylib_path;
 use crate::{is_aix, is_darwin, is_msvc, is_windows, uname};
 
 /// Construct a new `rustc` invocation. This will automatically set the library
@@ -15,8 +15,8 @@ pub fn rustc() -> Rustc {
     Rustc::new()
 }
 
-/// Construct a plain `rustc` invocation with no flags set. Note that [`set_host_rpath`]
-/// still presets the environment variable `HOST_RPATH_DIR` by default.
+/// Construct a plain `rustc` invocation with no flags set. Note that [`set_host_compiler_dylib_path`]
+/// still presets the environment variable `HOST_RUSTC_DYLIB_PATH` by default.
 #[track_caller]
 pub fn bare_rustc() -> Rustc {
     Rustc::bare()
@@ -44,7 +44,7 @@ pub fn rustc_path() -> String {
 #[track_caller]
 fn setup_common() -> Command {
     let mut cmd = Command::new(rustc_path());
-    set_host_rpath(&mut cmd);
+    set_host_compiler_dylib_path(&mut cmd);
     cmd
 }
 
@@ -365,31 +365,6 @@ impl Rustc {
 
     /// `EXTRARSCXXFLAGS`
     pub fn extra_rs_cxx_flags(&mut self) -> &mut Self {
-        // Adapted from tools.mk (trimmed):
-        //
-        // ```makefile
-        // ifdef IS_WINDOWS
-        //     ifdef IS_MSVC
-        //     else
-        //         EXTRARSCXXFLAGS := -lstatic:-bundle=stdc++
-        //     endif
-        // else
-        //     ifeq ($(UNAME),Darwin)
-        //         EXTRARSCXXFLAGS := -lc++
-        //     else
-        //         ifeq ($(UNAME),FreeBSD)
-        //         else
-        //             ifeq ($(UNAME),SunOS)
-        //             else
-        //                 ifeq ($(UNAME),OpenBSD)
-        //                 else
-        //                     EXTRARSCXXFLAGS := -lstdc++
-        //                 endif
-        //             endif
-        //         endif
-        //     endif
-        // endif
-        // ```
         if is_windows() {
             // So this is a bit hacky: we can't use the DLL version of libstdc++ because
             // it pulls in the DLL version of libgcc, which means that we end up with 2
diff --git a/src/tools/run-make-support/src/external_deps/rustdoc.rs b/src/tools/run-make-support/src/external_deps/rustdoc.rs
index 3c0e9c82f0b..433a57cd9fa 100644
--- a/src/tools/run-make-support/src/external_deps/rustdoc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustdoc.rs
@@ -2,16 +2,10 @@ use std::ffi::OsStr;
 use std::path::Path;
 
 use crate::command::Command;
-use crate::env::{env_var, env_var_os};
-use crate::util::set_host_rpath;
+use crate::env::env_var;
+use crate::util::set_host_compiler_dylib_path;
 
-/// Construct a plain `rustdoc` invocation with no flags set.
-#[track_caller]
-pub fn bare_rustdoc() -> Rustdoc {
-    Rustdoc::bare()
-}
-
-/// Construct a new `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set.
+/// Construct a new `rustdoc` invocation.
 #[track_caller]
 pub fn rustdoc() -> Rustdoc {
     Rustdoc::new()
@@ -29,23 +23,15 @@ crate::macros::impl_common_helpers!(Rustdoc);
 fn setup_common() -> Command {
     let rustdoc = env_var("RUSTDOC");
     let mut cmd = Command::new(rustdoc);
-    set_host_rpath(&mut cmd);
+    set_host_compiler_dylib_path(&mut cmd);
     cmd
 }
 
 impl Rustdoc {
     /// Construct a bare `rustdoc` invocation.
     #[track_caller]
-    pub fn bare() -> Self {
-        let cmd = setup_common();
-        Self { cmd }
-    }
-
-    /// Construct a `rustdoc` invocation with `-L $(TARGET_RPATH_DIR)` set.
-    #[track_caller]
     pub fn new() -> Self {
-        let mut cmd = setup_common();
-        cmd.arg("-L").arg(env_var_os("TARGET_RPATH_DIR"));
+        let cmd = setup_common();
         Self { cmd }
     }
 
@@ -132,4 +118,11 @@ impl Rustdoc {
         self.cmd.arg(format);
         self
     }
+
+    /// Specify type(s) of output files to generate.
+    pub fn emit<S: AsRef<str>>(&mut self, kinds: S) -> &mut Self {
+        let kinds = kinds.as_ref();
+        self.cmd.arg(format!("--emit={kinds}"));
+        self
+    }
 }
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 7e63ab3159a..d40ec9c4116 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -67,7 +67,7 @@ pub use llvm::{
 };
 pub use python::python_command;
 pub use rustc::{aux_build, bare_rustc, rustc, rustc_path, Rustc};
-pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
+pub use rustdoc::{rustdoc, Rustdoc};
 
 /// [`diff`][mod@diff] is implemented in terms of the [similar] library.
 ///
diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs
index 3eeba6fd526..7812863ccc2 100644
--- a/src/tools/run-make-support/src/run.rs
+++ b/src/tools/run-make-support/src/run.rs
@@ -1,10 +1,10 @@
 use std::ffi::OsStr;
-use std::path::{Path, PathBuf};
+use std::path::PathBuf;
 use std::{env, panic};
 
 use crate::command::{Command, CompletedProcess};
-use crate::util::{handle_failed_output, set_host_rpath};
-use crate::{cwd, env_var, is_windows};
+use crate::util::handle_failed_output;
+use crate::{cwd, env_var};
 
 #[track_caller]
 fn run_common(name: &str, args: Option<&[&str]>) -> Command {
@@ -18,10 +18,11 @@ fn run_common(name: &str, args: Option<&[&str]>) -> Command {
             cmd.arg(arg);
         }
     }
+
     cmd.env(&ld_lib_path_envvar, {
         let mut paths = vec![];
         paths.push(cwd());
-        for p in env::split_paths(&env_var("TARGET_RPATH_ENV")) {
+        for p in env::split_paths(&env_var("TARGET_EXE_DYLIB_PATH")) {
             paths.push(p.to_path_buf());
         }
         for p in env::split_paths(&env_var(&ld_lib_path_envvar)) {
@@ -31,15 +32,6 @@ fn run_common(name: &str, args: Option<&[&str]>) -> Command {
     });
     cmd.env("LC_ALL", "C"); // force english locale
 
-    if is_windows() {
-        let mut paths = vec![];
-        for p in env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) {
-            paths.push(p.to_path_buf());
-        }
-        paths.push(Path::new(&env_var("TARGET_RPATH_DIR")).to_path_buf());
-        cmd.env("PATH", env::join_paths(paths.iter()).unwrap());
-    }
-
     cmd
 }
 
@@ -84,7 +76,6 @@ pub fn run_fail(name: &str) -> CompletedProcess {
 #[track_caller]
 pub fn cmd<S: AsRef<OsStr>>(program: S) -> Command {
     let mut command = Command::new(program);
-    set_host_rpath(&mut command);
     command.env("LC_ALL", "C"); // force english locale
     command
 }
diff --git a/src/tools/run-make-support/src/util.rs b/src/tools/run-make-support/src/util.rs
index 703e3ad1c6c..af01758447b 100644
--- a/src/tools/run-make-support/src/util.rs
+++ b/src/tools/run-make-support/src/util.rs
@@ -24,13 +24,13 @@ pub(crate) fn handle_failed_output(
     std::process::exit(1)
 }
 
-/// Set the runtime library path as needed for running the host rustc/rustdoc/etc.
-pub(crate) fn set_host_rpath(cmd: &mut Command) {
+/// Set the runtime library paths as needed for running the host compilers (rustc/rustdoc/etc).
+pub(crate) fn set_host_compiler_dylib_path(cmd: &mut Command) {
     let ld_lib_path_envvar = env_var("LD_LIB_PATH_ENVVAR");
     cmd.env(&ld_lib_path_envvar, {
         let mut paths = vec![];
         paths.push(cwd());
-        paths.push(PathBuf::from(env_var("HOST_RPATH_DIR")));
+        paths.push(PathBuf::from(env_var("HOST_RUSTC_DYLIB_PATH")));
         for p in std::env::split_paths(&env_var(&ld_lib_path_envvar)) {
             paths.push(p.to_path_buf());
         }
diff --git a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
index e4fa94643ba..d3f0499e434 100644
--- a/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/autopublish.yaml
@@ -11,7 +11,7 @@ on:
 
 jobs:
   publish:
-    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }}
+    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }}
     name: publish
     runs-on: ubuntu-latest
     steps:
diff --git a/src/tools/rust-analyzer/.github/workflows/ci.yaml b/src/tools/rust-analyzer/.github/workflows/ci.yaml
index 81b55712d7f..bc770dbe71e 100644
--- a/src/tools/rust-analyzer/.github/workflows/ci.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/ci.yaml
@@ -174,7 +174,7 @@ jobs:
       - name: Install Nodejs
         uses: actions/setup-node@v4
         with:
-          node-version: 18
+          node-version: 22
         if: needs.changes.outputs.typescript == 'true'
 
       - name: Install xvfb
diff --git a/src/tools/rust-analyzer/.github/workflows/fuzz.yml b/src/tools/rust-analyzer/.github/workflows/fuzz.yml
index f88c7f95d5c..7acfcbe351f 100644
--- a/src/tools/rust-analyzer/.github/workflows/fuzz.yml
+++ b/src/tools/rust-analyzer/.github/workflows/fuzz.yml
@@ -19,7 +19,7 @@ env:
 
 jobs:
   rust:
-    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }}
+    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }}
     name: Rust
     runs-on: ubuntu-latest
     env:
diff --git a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml
index 5023a634fde..93ae5675a71 100644
--- a/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/publish-libs.yaml
@@ -9,7 +9,7 @@ on:
 
 jobs:
   publish-libs:
-    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }}
+    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }}
     name: publish
     runs-on: ubuntu-latest
     steps:
diff --git a/src/tools/rust-analyzer/.github/workflows/release.yaml b/src/tools/rust-analyzer/.github/workflows/release.yaml
index fe090267dc9..c8e6de72ce9 100644
--- a/src/tools/rust-analyzer/.github/workflows/release.yaml
+++ b/src/tools/rust-analyzer/.github/workflows/release.yaml
@@ -17,12 +17,12 @@ env:
   RUSTUP_MAX_RETRIES: 10
   FETCH_DEPTH: 0 # pull in the tags for the version string
   MACOSX_DEPLOYMENT_TARGET: 13.0
-  CARGO_TARGET_AARCH64_UNKNOWN_LINUX_GNU_LINKER: aarch64-linux-gnu-gcc
-  CARGO_TARGET_ARM_UNKNOWN_LINUX_GNUEABIHF_LINKER: arm-linux-gnueabihf-gcc
+  ZIG_VERSION: 0.13.0
+  ZIGBUILD_VERSION: 0.19.8
 
 jobs:
   dist:
-    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }}
+    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }}
     strategy:
       matrix:
         include:
@@ -36,13 +36,15 @@ jobs:
             code-target: win32-arm64
           - os: ubuntu-latest
             target: x86_64-unknown-linux-gnu
+            zig_target: x86_64-unknown-linux-gnu.2.28
             code-target: linux-x64
-            container: rockylinux:8
           - os: ubuntu-latest
             target: aarch64-unknown-linux-gnu
+            zig_target: aarch64-unknown-linux-gnu.2.28
             code-target: linux-arm64
           - os: ubuntu-latest
             target: arm-unknown-linux-gnueabihf
+            zig_target: arm-unknown-linux-gnueabihf.2.28
             code-target: linux-armhf
           - os: macos-13
             target: x86_64-apple-darwin
@@ -64,40 +66,33 @@ jobs:
         with:
           fetch-depth: ${{ env.FETCH_DEPTH }}
 
-      - name: Install toolchain dependencies
-        if: matrix.container == 'rockylinux:8'
-        shell: bash
-        run: |
-          dnf install -y gcc
-          curl --proto '=https' --tlsv1.2 --retry 10 --retry-connrefused -fsSL "https://sh.rustup.rs" | sh -s -- --profile minimal --default-toolchain none -y
-          echo "${CARGO_HOME:-$HOME/.cargo}/bin" >> $GITHUB_PATH
+      - name: Install Node.js toolchain
+        uses: actions/setup-node@v4
+        with:
+          node-version: 22
 
       - name: Install Rust toolchain
         run: |
           rustup update --no-self-update stable
-          rustup target add ${{ matrix.target }}
           rustup component add rust-src
+          rustup target add ${{ matrix.target }}
 
-      - name: Install Node.js
-        uses: actions/setup-node@v4
-        with:
-          node-version: 18
-
-      - name: Update apt repositories
-        if: matrix.target == 'aarch64-unknown-linux-gnu' || matrix.target == 'arm-unknown-linux-gnueabihf'
-        run: sudo apt-get update
-
-      - name: Install AArch64 target toolchain
-        if: matrix.target == 'aarch64-unknown-linux-gnu'
-        run: sudo apt-get install gcc-aarch64-linux-gnu
-
-      - name: Install ARM target toolchain
-        if: matrix.target == 'arm-unknown-linux-gnueabihf'
-        run: sudo apt-get install gcc-arm-linux-gnueabihf
+      - name: Install Zig toolchain
+        if: ${{ matrix.zig_target }}
+        run: |
+          which cargo
+          curl -L "https://ziglang.org/download/${ZIG_VERSION}/zig-linux-$(uname -m)-${ZIG_VERSION}.tar.xz" | sudo tar JxC /usr/local
+          sudo ln -s "/usr/local/zig-linux-$(uname -m)-${ZIG_VERSION}/zig" /usr/local/bin/zig
+          curl -L "https://github.com/rust-cross/cargo-zigbuild/releases/download/v${ZIGBUILD_VERSION}/cargo-zigbuild-v${ZIGBUILD_VERSION}.x86_64-unknown-linux-musl.tar.gz" | tar zxC ~/.cargo/bin
 
-      - name: Dist
+      - name: Dist (plain)
+        if: ${{ !matrix.zig_target }}
         run: cargo xtask dist --client-patch-version ${{ github.run_number }}
 
+      - name: Dist (using zigbuild)
+        if: ${{ matrix.zig_target }}
+        run: RA_TARGET=${{ matrix.zig_target}} cargo xtask dist --client-patch-version ${{ github.run_number }} --zig
+
       - run: npm ci
         working-directory: editors/code
 
@@ -139,7 +134,7 @@ jobs:
           path: ./dist
 
   dist-x86_64-unknown-linux-musl:
-    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }}
+    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }}
     name: dist (x86_64-unknown-linux-musl)
     runs-on: ubuntu-latest
     env:
@@ -185,7 +180,7 @@ jobs:
           path: ./dist
 
   publish:
-    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event.action == 'workflow_dispatch' }}
+    if: ${{ github.repository == 'rust-lang/rust-analyzer' || github.event_name == 'workflow_dispatch' }}
     name: publish
     runs-on: ubuntu-latest
     needs: ["dist", "dist-x86_64-unknown-linux-musl"]
@@ -193,7 +188,7 @@ jobs:
       - name: Install Nodejs
         uses: actions/setup-node@v4
         with:
-          node-version: 20
+          node-version: 22
 
       - run: echo "TAG=$(date --iso -u)" >> $GITHUB_ENV
         if: github.ref == 'refs/heads/release'
diff --git a/src/tools/rust-analyzer/.typos.toml b/src/tools/rust-analyzer/.typos.toml
index 0f2f9b1b275..e938bddd4b1 100644
--- a/src/tools/rust-analyzer/.typos.toml
+++ b/src/tools/rust-analyzer/.typos.toml
@@ -18,6 +18,8 @@ extend-ignore-re = [
     "INOUT",
     "optin",
     "=Pn",
+    # ignore `// spellchecker:off` until `// spellchecker:on`
+    "(?s)(#|//)\\s*spellchecker:off.*?\\n\\s*(#|//)\\s*spellchecker:on",
 ]
 
 [default.extend-words]
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 01e6a39f7c9..c57953ba654 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -22,9 +22,6 @@ name = "always-assert"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a1078fa1ce1e34b1872d8611ad921196d76bdd7027e949fbe31231abde201892"
-dependencies = [
- "tracing",
-]
 
 [[package]]
 name = "anyhow"
@@ -1507,9 +1504,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_abi"
-version = "0.97.0"
+version = "0.98.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3829c3355d1681ffeaf1450ec71edcdace6820fe2e86469d8fc1ad45e2c96460"
+checksum = "4b42cccfff8091a4c3397736518774dbad619e82f8def6f70d8e46dbbe396007"
 dependencies = [
  "bitflags 2.7.0",
  "ra-ap-rustc_hashes",
@@ -1519,18 +1516,18 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_hashes"
-version = "0.97.0"
+version = "0.98.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1bd4d6d4c434bec08e02370a4f64a4985312097215a62e82d0f757f3a98e502e"
+checksum = "46d8bd34ed6552c8cac1764106ef5adbeef3e5c7700e0ceb4c83a47a631894fe"
 dependencies = [
  "rustc-stable-hash",
 ]
 
 [[package]]
 name = "ra-ap-rustc_index"
-version = "0.97.0"
+version = "0.98.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bad6fc4bd7522e31096e2de5b0351144fe0684b608791ee26c842bf2da1b19ae"
+checksum = "93799e4dccbbd47f8b66bc0aa42effc1b7077aaee09d8a40b86b8d659b80c7b7"
 dependencies = [
  "ra-ap-rustc_index_macros",
  "smallvec",
@@ -1538,9 +1535,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_index_macros"
-version = "0.97.0"
+version = "0.98.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "cfb234e1f84b92be45276c3025bee18789e9bc95bec8789bec961e78edb01c52"
+checksum = "30baa5d00f94ba437a9dcaf7ae074ebe4f367bb05a4c2835e0aa2e7af3463aac"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1549,9 +1546,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_lexer"
-version = "0.97.0"
+version = "0.98.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7a3a40bd11dc43d1cb110e730b80620cf8102f4cca8920a02b65954da0ed931f"
+checksum = "3004d1d1b50afe3e1f9cdd428a282da7ffbf5f26dd8bf04af0d651d44e4873d8"
 dependencies = [
  "memchr",
  "unicode-properties",
@@ -1560,9 +1557,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_parse_format"
-version = "0.97.0"
+version = "0.98.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5feb877478994cb4c0c0c7a5116a352eefc0634aefc8636feb00a893fa5b7135"
+checksum = "cb57e5124a64aaaf92c06130fbc1b8e1d547b5a2a96081f1f848e31c211df5d2"
 dependencies = [
  "ra-ap-rustc_index",
  "ra-ap-rustc_lexer",
@@ -1570,9 +1567,9 @@ dependencies = [
 
 [[package]]
 name = "ra-ap-rustc_pattern_analysis"
-version = "0.97.0"
+version = "0.98.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a76774d35934d464c4115908cde16f76a4f7e540fe1eea6b79336c556e37bdd3"
+checksum = "e427c3d30e4bdff28abd6b0ef3e6f4dfab44acd9468a4954eeff8717d8df8819"
 dependencies = [
  "ra-ap-rustc_index",
  "rustc-hash 2.0.0",
@@ -1940,13 +1937,13 @@ dependencies = [
 name = "stdx"
 version = "0.0.0"
 dependencies = [
- "always-assert",
  "backtrace",
  "crossbeam-channel",
  "itertools",
  "jod-thread",
  "libc",
  "miow",
+ "tracing",
  "windows-sys 0.59.0",
 ]
 
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index 1ff36a68e8f..1132acb6474 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -25,7 +25,6 @@ salsa.opt-level = 3
 miniz_oxide.opt-level = 3
 
 [profile.release]
-incremental = true
 # Set this to 1 or 2 to get more useful backtraces in debugger.
 debug = 0
 
@@ -86,12 +85,12 @@ vfs-notify = { path = "./crates/vfs-notify", version = "0.0.0" }
 vfs = { path = "./crates/vfs", version = "0.0.0" }
 edition = { path = "./crates/edition", version = "0.0.0" }
 
-ra-ap-rustc_hashes = { version = "0.97", default-features = false }
-ra-ap-rustc_lexer = { version = "0.97", default-features = false }
-ra-ap-rustc_parse_format = { version = "0.97", default-features = false }
-ra-ap-rustc_index = { version = "0.97", default-features = false }
-ra-ap-rustc_abi = { version = "0.97", default-features = false }
-ra-ap-rustc_pattern_analysis = { version = "0.97", default-features = false }
+ra-ap-rustc_hashes = { version = "0.98", default-features = false }
+ra-ap-rustc_lexer = { version = "0.98", default-features = false }
+ra-ap-rustc_parse_format = { version = "0.98", default-features = false }
+ra-ap-rustc_index = { version = "0.98", default-features = false }
+ra-ap-rustc_abi = { version = "0.98", default-features = false }
+ra-ap-rustc_pattern_analysis = { version = "0.98", default-features = false }
 
 # local crates that aren't published to crates.io. These should not have versions.
 
diff --git a/src/tools/rust-analyzer/crates/base-db/Cargo.toml b/src/tools/rust-analyzer/crates/base-db/Cargo.toml
index 788ceb8857e..042dd36488a 100644
--- a/src/tools/rust-analyzer/crates/base-db/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/base-db/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 lz4_flex = { version = "0.11", default-features = false }
diff --git a/src/tools/rust-analyzer/crates/cfg/Cargo.toml b/src/tools/rust-analyzer/crates/cfg/Cargo.toml
index 040bddbd7fd..e887368ef28 100644
--- a/src/tools/rust-analyzer/crates/cfg/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/cfg/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 rustc-hash.workspace = true
diff --git a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml
index 9a448ec14ea..a22961c26c8 100644
--- a/src/tools/rust-analyzer/crates/hir-def/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir-def/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 arrayvec.workspace = true
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs
index e9318d146dd..8868bc0cd95 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/dyn_map.rs
@@ -5,7 +5,9 @@
 //!
 //! It is used like this:
 //!
-//! ```
+//! ```ignore
+//! # use hir_def::dyn_map::DynMap;
+//! # use hir_def::dyn_map::Key;
 //! // keys define submaps of a `DynMap`
 //! const STRING_TO_U32: Key<String, u32> = Key::new();
 //! const U32_TO_VEC: Key<u32, Vec<bool>> = Key::new();
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 8d5b3eeb28e..382afbcb1dd 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
@@ -883,20 +883,20 @@ pub struct UseTree {
 
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub enum UseTreeKind {
-    /// ```
+    /// ```ignore
     /// use path::to::Item;
     /// use path::to::Item as Renamed;
     /// use path::to::Trait as _;
     /// ```
     Single { path: Interned<ModPath>, alias: Option<ImportAlias> },
 
-    /// ```
+    /// ```ignore
     /// use *;  // (invalid, but can occur in nested tree)
     /// use path::*;
     /// ```
     Glob { path: Option<Interned<ModPath>> },
 
-    /// ```
+    /// ```ignore
     /// use prefix::{self, Item, ...};
     /// ```
     Prefixed { prefix: Option<Interned<ModPath>>, list: Box<[UseTree]> },
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
index 408d03ff718..a2d0ba3deb8 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/macro_expansion_tests/mod.rs
@@ -22,7 +22,7 @@ use hir_expand::{
     db::ExpandDatabase,
     proc_macro::{ProcMacro, ProcMacroExpander, ProcMacroExpansionError, ProcMacroKind},
     span_map::SpanMapRef,
-    InFile, MacroCallKind, MacroFileId, MacroFileIdExt,
+    InFile, MacroCallKind, MacroFileId, MacroFileIdExt, MacroKind,
 };
 use intern::Symbol;
 use itertools::Itertools;
@@ -211,7 +211,11 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
 
         if let Some(src) = src {
             if let Some(file_id) = src.file_id.macro_file() {
-                if file_id.is_attr_macro(&db) || file_id.is_custom_derive(&db) {
+                if let MacroKind::Derive
+                | MacroKind::DeriveBuiltIn
+                | MacroKind::Attr
+                | MacroKind::AttrBuiltIn = file_id.kind(&db)
+                {
                     let call = file_id.call_node(&db);
                     let mut show_spans = false;
                     let mut show_ctxt = false;
@@ -236,7 +240,7 @@ pub fn identity_when_valid(_attr: TokenStream, item: TokenStream) -> TokenStream
     for impl_id in def_map[local_id].scope.impls() {
         let src = impl_id.lookup(&db).source(&db);
         if let Some(macro_file) = src.file_id.macro_file() {
-            if macro_file.is_builtin_derive(&db) {
+            if let MacroKind::DeriveBuiltIn | MacroKind::Derive = macro_file.kind(&db) {
                 let pp = pretty_print_macro_expansion(
                     src.value.syntax().clone(),
                     db.span_map(macro_file.into()).as_ref(),
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs
index afee42ecec0..17d09bcbd04 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/nameres/mod_resolution.rs
@@ -134,7 +134,7 @@ impl DirPath {
     /// So this is the case which doesn't really work I think if we try to be
     /// 100% platform agnostic:
     ///
-    /// ```
+    /// ```ignore
     /// mod a {
     ///     #[path="C://sad/face"]
     ///     mod b { mod c; }
diff --git a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
index 9dfb6e3cc4b..e5774b48044 100644
--- a/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
+++ b/src/tools/rust-analyzer/crates/hir-def/src/resolver.rs
@@ -532,16 +532,17 @@ impl Resolver {
     /// Note that in Rust one name can be bound to several items:
     ///
     /// ```
+    /// # #![allow(non_camel_case_types)]
     /// macro_rules! t { () => (()) }
     /// type t = t!();
-    /// const t: t = t!()
+    /// const t: t = t!();
     /// ```
     ///
     /// That's why we return a multimap.
     ///
     /// The shadowing is accounted for: in
     ///
-    /// ```
+    /// ```ignore
     /// let it = 92;
     /// {
     ///     let it = 92;
diff --git a/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml b/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml
index b193a34a01d..7d561e0527d 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir-expand/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 cov-mark = "2.0.0-pre.1"
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs
index f250620e775..e9dc17a28f6 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/builtin/attr_macro.rs
@@ -101,7 +101,7 @@ fn dummy_gate_test_expand(
 /// somewhat inconsistently resolve derive attributes.
 ///
 /// As such, we expand `#[derive(Foo, bar::Bar)]` into
-/// ```
+/// ```ignore
 ///  #![Foo]
 ///  #![bar::Bar]
 /// ```
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs
index 13ddb0d4acc..f3bcc772682 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/files.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/files.rs
@@ -10,7 +10,7 @@ use syntax::{AstNode, AstPtr, SyntaxNode, SyntaxNodePtr, SyntaxToken, TextRange,
 
 use crate::{
     db::{self, ExpandDatabase},
-    map_node_range_up, map_node_range_up_rooted, span_for_offset, MacroFileIdExt,
+    map_node_range_up, map_node_range_up_rooted, span_for_offset, MacroFileIdExt, MacroKind,
 };
 
 /// `InFile<T>` stores a value of `T` inside a particular file/syntax tree.
@@ -276,7 +276,11 @@ impl<SN: Borrow<SyntaxNode>> InFile<SN> {
             HirFileIdRepr::FileId(file_id) => {
                 return Some(InRealFile { file_id, value: self.value.borrow().clone() })
             }
-            HirFileIdRepr::MacroFile(m) if m.is_attr_macro(db) => m,
+            HirFileIdRepr::MacroFile(m)
+                if matches!(m.kind(db), MacroKind::Attr | MacroKind::AttrBuiltIn) =>
+            {
+                m
+            }
             _ => return None,
         };
 
@@ -453,7 +457,7 @@ impl<N: AstNode> InFile<N> {
             }
             HirFileIdRepr::MacroFile(m) => m,
         };
-        if !file_id.is_attr_macro(db) {
+        if !matches!(file_id.kind(db), MacroKind::Attr | MacroKind::AttrBuiltIn) {
             return None;
         }
 
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
index 2c664029f61..41603e3c92e 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/lib.rs
@@ -416,6 +416,24 @@ impl HirFileIdExt for HirFileId {
     }
 }
 
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub enum MacroKind {
+    /// `macro_rules!` or Macros 2.0 macro.
+    Declarative,
+    /// A built-in function-like macro.
+    DeclarativeBuiltIn,
+    /// A custom derive.
+    Derive,
+    /// A builtin-in derive.
+    DeriveBuiltIn,
+    /// A procedural attribute macro.
+    Attr,
+    /// A built-in attribute macro.
+    AttrBuiltIn,
+    /// A function-like procedural macro.
+    ProcMacro,
+}
+
 pub trait MacroFileIdExt {
     fn is_env_or_option_env(&self, db: &dyn ExpandDatabase) -> bool;
     fn is_include_like_macro(&self, db: &dyn ExpandDatabase) -> bool;
@@ -427,15 +445,12 @@ pub trait MacroFileIdExt {
 
     fn expansion_info(self, db: &dyn ExpandDatabase) -> ExpansionInfo;
 
-    fn is_builtin_derive(&self, db: &dyn ExpandDatabase) -> bool;
-    fn is_custom_derive(&self, db: &dyn ExpandDatabase) -> bool;
+    fn kind(&self, db: &dyn ExpandDatabase) -> MacroKind;
 
     /// Return whether this file is an include macro
     fn is_include_macro(&self, db: &dyn ExpandDatabase) -> bool;
 
     fn is_eager(&self, db: &dyn ExpandDatabase) -> bool;
-    /// Return whether this file is an attr macro
-    fn is_attr_macro(&self, db: &dyn ExpandDatabase) -> bool;
 
     /// Return whether this file is the pseudo expansion of the derive attribute.
     /// See [`crate::builtin_attr_macro::derive_attr_expand`].
@@ -468,18 +483,18 @@ impl MacroFileIdExt for MacroFileId {
         ExpansionInfo::new(db, self)
     }
 
-    fn is_custom_derive(&self, db: &dyn ExpandDatabase) -> bool {
-        matches!(
-            db.lookup_intern_macro_call(self.macro_call_id).def.kind,
-            MacroDefKind::ProcMacro(_, _, ProcMacroKind::CustomDerive)
-        )
-    }
-
-    fn is_builtin_derive(&self, db: &dyn ExpandDatabase) -> bool {
-        matches!(
-            db.lookup_intern_macro_call(self.macro_call_id).def.kind,
-            MacroDefKind::BuiltInDerive(..)
-        )
+    fn kind(&self, db: &dyn ExpandDatabase) -> MacroKind {
+        match db.lookup_intern_macro_call(self.macro_call_id).def.kind {
+            MacroDefKind::Declarative(..) => MacroKind::Declarative,
+            MacroDefKind::BuiltIn(..) | MacroDefKind::BuiltInEager(..) => {
+                MacroKind::DeclarativeBuiltIn
+            }
+            MacroDefKind::BuiltInDerive(..) => MacroKind::DeriveBuiltIn,
+            MacroDefKind::ProcMacro(_, _, ProcMacroKind::CustomDerive) => MacroKind::Derive,
+            MacroDefKind::ProcMacro(_, _, ProcMacroKind::Attr) => MacroKind::Attr,
+            MacroDefKind::ProcMacro(_, _, ProcMacroKind::Bang) => MacroKind::ProcMacro,
+            MacroDefKind::BuiltInAttr(..) => MacroKind::AttrBuiltIn,
+        }
     }
 
     fn is_include_macro(&self, db: &dyn ExpandDatabase) -> bool {
@@ -507,13 +522,6 @@ impl MacroFileIdExt for MacroFileId {
         }
     }
 
-    fn is_attr_macro(&self, db: &dyn ExpandDatabase) -> bool {
-        matches!(
-            db.lookup_intern_macro_call(self.macro_call_id).def.kind,
-            MacroDefKind::BuiltInAttr(..) | MacroDefKind::ProcMacro(_, _, ProcMacroKind::Attr)
-        )
-    }
-
     fn is_derive_attr_pseudo_expansion(&self, db: &dyn ExpandDatabase) -> bool {
         let loc = db.lookup_intern_macro_call(self.macro_call_id);
         loc.def.is_attribute_derive()
diff --git a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
index 4d36de0b383..27849f3b449 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir-ty/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 cov-mark = "2.0.0-pre.1"
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs
index c1ac7ae173b..ee375d60deb 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/consteval/tests/intrinsics.rs
@@ -354,12 +354,43 @@ fn overflowing_add() {
 fn needs_drop() {
     check_number(
         r#"
-        //- minicore: copy, sized
+        //- minicore: drop, manually_drop, copy, sized
+        use core::mem::ManuallyDrop;
         extern "rust-intrinsic" {
             pub fn needs_drop<T: ?Sized>() -> bool;
         }
         struct X;
-        const GOAL: bool = !needs_drop::<i32>() && needs_drop::<X>();
+        struct NeedsDrop;
+        impl Drop for NeedsDrop {
+            fn drop(&mut self) {}
+        }
+        enum Enum<T> {
+            A(T),
+            B(X),
+        }
+        const fn val_needs_drop<T>(_v: T) -> bool { needs_drop::<T>() }
+        const fn closure_needs_drop() -> bool {
+            let a = NeedsDrop;
+            let b = X;
+            !val_needs_drop(|| &a) && val_needs_drop(move || &a) && !val_needs_drop(move || &b)
+        }
+        const fn opaque() -> impl Sized {
+            || {}
+        }
+        const fn opaque_copy() -> impl Sized + Copy {
+            || {}
+        }
+        trait Everything {}
+        impl<T> Everything for T {}
+        const GOAL: bool = !needs_drop::<i32>() && !needs_drop::<X>()
+            && needs_drop::<NeedsDrop>() && !needs_drop::<ManuallyDrop<NeedsDrop>>()
+            && needs_drop::<[NeedsDrop; 1]>() && !needs_drop::<[NeedsDrop; 0]>()
+            && needs_drop::<(X, NeedsDrop)>()
+            && needs_drop::<Enum<NeedsDrop>>() && !needs_drop::<Enum<X>>()
+            && closure_needs_drop()
+            && !val_needs_drop(opaque()) && !val_needs_drop(opaque_copy())
+            && needs_drop::<[NeedsDrop]>() && needs_drop::<dyn Everything>()
+            && !needs_drop::<&dyn Everything>() && !needs_drop::<str>();
         "#,
         1,
     );
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs
index 6b056826670..76031491d9a 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/db.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/db.rs
@@ -13,6 +13,7 @@ use hir_def::{
     ConstParamId, DefWithBodyId, EnumVariantId, FunctionId, GeneralConstId, GenericDefId, ImplId,
     LifetimeParamId, LocalFieldId, StaticId, TraitId, TypeAliasId, TypeOrConstParamId, VariantId,
 };
+use hir_expand::name::Name;
 use la_arena::ArenaMap;
 use smallvec::SmallVec;
 use triomphe::Arc;
@@ -20,6 +21,7 @@ use triomphe::Arc;
 use crate::{
     chalk_db,
     consteval::ConstEvalError,
+    drop::DropGlue,
     dyn_compatibility::DynCompatibilityViolation,
     layout::{Layout, LayoutError},
     lower::{Diagnostics, GenericDefaults, GenericPredicates},
@@ -28,7 +30,6 @@ use crate::{
     Binders, ClosureId, Const, FnDefId, ImplTraitId, ImplTraits, InferenceResult, Interner,
     PolyFnSig, Substitution, TraitEnvironment, TraitRef, Ty, TyDefId, ValueTyDefId,
 };
-use hir_expand::name::Name;
 
 #[ra_salsa::query_group(HirDatabaseStorage)]
 pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
@@ -305,6 +306,10 @@ pub trait HirDatabase: DefDatabase + Upcast<dyn DefDatabase> {
         block: Option<BlockId>,
         env: chalk_ir::Environment<Interner>,
     ) -> chalk_ir::ProgramClauses<Interner>;
+
+    #[ra_salsa::invoke(crate::drop::has_drop_glue)]
+    #[ra_salsa::cycle(crate::drop::has_drop_glue_recover)]
+    fn has_drop_glue(&self, ty: Ty, env: Arc<TraitEnvironment>) -> DropGlue {}
 }
 
 #[test]
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
index ae8fbe2ce6d..49f061813d1 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/display.rs
@@ -95,7 +95,7 @@ pub struct HirFormatter<'a> {
 enum BoundsFormattingCtx {
     Entered {
         /// We can have recursive bounds like the following case:
-        /// ```rust
+        /// ```ignore
         /// where
         ///     T: Foo,
         ///     T::FooAssoc: Baz<<T::FooAssoc as Bar>::BarAssoc> + Bar
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs
new file mode 100644
index 00000000000..351926c86c4
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/drop.rs
@@ -0,0 +1,209 @@
+//! Utilities for computing drop info about types.
+
+use base_db::ra_salsa;
+use chalk_ir::cast::Cast;
+use hir_def::data::adt::StructFlags;
+use hir_def::lang_item::LangItem;
+use hir_def::AdtId;
+use stdx::never;
+use triomphe::Arc;
+
+use crate::{
+    db::HirDatabase, method_resolution::TyFingerprint, AliasTy, Canonical, CanonicalVarKinds,
+    InEnvironment, Interner, ProjectionTy, TraitEnvironment, Ty, TyBuilder, TyKind,
+};
+use crate::{ConcreteConst, ConstScalar, ConstValue};
+
+fn has_destructor(db: &dyn HirDatabase, adt: AdtId) -> bool {
+    let module = match adt {
+        AdtId::EnumId(id) => db.lookup_intern_enum(id).container,
+        AdtId::StructId(id) => db.lookup_intern_struct(id).container,
+        AdtId::UnionId(id) => db.lookup_intern_union(id).container,
+    };
+    let Some(drop_trait) =
+        db.lang_item(module.krate(), LangItem::Drop).and_then(|it| it.as_trait())
+    else {
+        return false;
+    };
+    let impls = match module.containing_block() {
+        Some(block) => match db.trait_impls_in_block(block) {
+            Some(it) => it,
+            None => return false,
+        },
+        None => db.trait_impls_in_crate(module.krate()),
+    };
+    let result = impls.for_trait_and_self_ty(drop_trait, TyFingerprint::Adt(adt)).next().is_some();
+    result
+}
+
+#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+pub enum DropGlue {
+    // Order of variants is important.
+    None,
+    /// May have a drop glue if some type parameter has it.
+    ///
+    /// For the compiler this is considered as a positive result, IDE distinguishes this from "yes".
+    DependOnParams,
+    HasDropGlue,
+}
+
+pub(crate) fn has_drop_glue(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironment>) -> DropGlue {
+    match ty.kind(Interner) {
+        TyKind::Adt(adt, subst) => {
+            if has_destructor(db, adt.0) {
+                return DropGlue::HasDropGlue;
+            }
+            match adt.0 {
+                AdtId::StructId(id) => {
+                    if db.struct_data(id).flags.contains(StructFlags::IS_MANUALLY_DROP) {
+                        return DropGlue::None;
+                    }
+                    db.field_types(id.into())
+                        .iter()
+                        .map(|(_, field_ty)| {
+                            db.has_drop_glue(
+                                field_ty.clone().substitute(Interner, subst),
+                                env.clone(),
+                            )
+                        })
+                        .max()
+                        .unwrap_or(DropGlue::None)
+                }
+                // Unions cannot have fields with destructors.
+                AdtId::UnionId(_) => DropGlue::None,
+                AdtId::EnumId(id) => db
+                    .enum_data(id)
+                    .variants
+                    .iter()
+                    .map(|&(variant, _)| {
+                        db.field_types(variant.into())
+                            .iter()
+                            .map(|(_, field_ty)| {
+                                db.has_drop_glue(
+                                    field_ty.clone().substitute(Interner, subst),
+                                    env.clone(),
+                                )
+                            })
+                            .max()
+                            .unwrap_or(DropGlue::None)
+                    })
+                    .max()
+                    .unwrap_or(DropGlue::None),
+            }
+        }
+        TyKind::Tuple(_, subst) => subst
+            .iter(Interner)
+            .map(|ty| ty.assert_ty_ref(Interner))
+            .map(|ty| db.has_drop_glue(ty.clone(), env.clone()))
+            .max()
+            .unwrap_or(DropGlue::None),
+        TyKind::Array(ty, len) => {
+            if let ConstValue::Concrete(ConcreteConst { interned: ConstScalar::Bytes(len, _) }) =
+                &len.data(Interner).value
+            {
+                match (&**len).try_into() {
+                    Ok(len) => {
+                        let len = usize::from_le_bytes(len);
+                        if len == 0 {
+                            // Arrays of size 0 don't have drop glue.
+                            return DropGlue::None;
+                        }
+                    }
+                    Err(_) => {
+                        never!("const array size with non-usize len");
+                    }
+                }
+            }
+            db.has_drop_glue(ty.clone(), env)
+        }
+        TyKind::Slice(ty) => db.has_drop_glue(ty.clone(), env),
+        TyKind::Closure(closure_id, subst) => {
+            let owner = db.lookup_intern_closure((*closure_id).into()).0;
+            let infer = db.infer(owner);
+            let (captures, _) = infer.closure_info(closure_id);
+            let env = db.trait_environment_for_body(owner);
+            captures
+                .iter()
+                .map(|capture| db.has_drop_glue(capture.ty(subst), env.clone()))
+                .max()
+                .unwrap_or(DropGlue::None)
+        }
+        // FIXME: Handle coroutines.
+        TyKind::Coroutine(..) | TyKind::CoroutineWitness(..) => DropGlue::None,
+        TyKind::Ref(..)
+        | TyKind::Raw(..)
+        | TyKind::FnDef(..)
+        | TyKind::Str
+        | TyKind::Never
+        | TyKind::Scalar(_)
+        | TyKind::Function(_)
+        | TyKind::Foreign(_)
+        | TyKind::Error => DropGlue::None,
+        TyKind::Dyn(_) => DropGlue::HasDropGlue,
+        TyKind::AssociatedType(assoc_type_id, subst) => projection_has_drop_glue(
+            db,
+            env,
+            ProjectionTy { associated_ty_id: *assoc_type_id, substitution: subst.clone() },
+            ty,
+        ),
+        TyKind::Alias(AliasTy::Projection(projection)) => {
+            projection_has_drop_glue(db, env, projection.clone(), ty)
+        }
+        TyKind::OpaqueType(..) | TyKind::Alias(AliasTy::Opaque(_)) => {
+            if is_copy(db, ty, env) {
+                DropGlue::None
+            } else {
+                DropGlue::HasDropGlue
+            }
+        }
+        TyKind::Placeholder(_) | TyKind::BoundVar(_) => {
+            if is_copy(db, ty, env) {
+                DropGlue::None
+            } else {
+                DropGlue::DependOnParams
+            }
+        }
+        TyKind::InferenceVar(..) => unreachable!("inference vars shouldn't exist out of inference"),
+    }
+}
+
+fn projection_has_drop_glue(
+    db: &dyn HirDatabase,
+    env: Arc<TraitEnvironment>,
+    projection: ProjectionTy,
+    ty: Ty,
+) -> DropGlue {
+    let normalized = db.normalize_projection(projection, env.clone());
+    match normalized.kind(Interner) {
+        TyKind::Alias(AliasTy::Projection(_)) | TyKind::AssociatedType(..) => {
+            if is_copy(db, ty, env) {
+                DropGlue::None
+            } else {
+                DropGlue::DependOnParams
+            }
+        }
+        _ => db.has_drop_glue(normalized, env),
+    }
+}
+
+fn is_copy(db: &dyn HirDatabase, ty: Ty, env: Arc<TraitEnvironment>) -> bool {
+    let Some(copy_trait) = db.lang_item(env.krate, LangItem::Copy).and_then(|it| it.as_trait())
+    else {
+        return false;
+    };
+    let trait_ref = TyBuilder::trait_ref(db, copy_trait).push(ty).build();
+    let goal = Canonical {
+        value: InEnvironment::new(&env.env, trait_ref.cast(Interner)),
+        binders: CanonicalVarKinds::empty(Interner),
+    };
+    db.trait_solve(env.krate, env.block, goal).is_some()
+}
+
+pub(crate) fn has_drop_glue_recover(
+    _db: &dyn HirDatabase,
+    _cycle: &ra_salsa::Cycle,
+    _ty: &Ty,
+    _env: &Arc<TraitEnvironment>,
+) -> DropGlue {
+    DropGlue::None
+}
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
index 0cb7002f446..556091c4046 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer.rs
@@ -335,7 +335,7 @@ impl Default for InternedStandardTypes {
 ///    sized struct to a dynamically sized one. E.g., &[i32; 4] -> &[i32] is
 ///    represented by:
 ///
-///    ```
+///    ```ignore
 ///    Deref(None) -> [i32; 4],
 ///    Borrow(AutoBorrow::Ref) -> &[i32; 4],
 ///    Unsize -> &[i32],
@@ -481,9 +481,10 @@ pub struct InferenceResult {
     /// or pattern can have multiple binding modes. For example:
     /// ```
     /// fn foo(mut slice: &[u32]) -> usize {
-    ///    slice = match slice {
-    ///        [0, rest @ ..] | rest => rest,
-    ///    };
+    ///     slice = match slice {
+    ///         [0, rest @ ..] | rest => rest,
+    ///     };
+    ///     0
     /// }
     /// ```
     /// the first `rest` has implicit `ref` binding mode, but the second `rest` binding mode is `move`.
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 a4e49e0aa10..7af31dabe45 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/layout.rs
@@ -133,40 +133,22 @@ fn layout_of_simd_ty(
     env: Arc<TraitEnvironment>,
     dl: &TargetDataLayout,
 ) -> Result<Arc<Layout>, LayoutError> {
-    let fields = db.field_types(id.into());
-
-    // Supported SIMD vectors are homogeneous ADTs with at least one field:
+    // Supported SIMD vectors are homogeneous ADTs with exactly one array field:
     //
-    // * #[repr(simd)] struct S(T, T, T, T);
-    // * #[repr(simd)] struct S { it: T, y: T, z: T, w: T }
     // * #[repr(simd)] struct S([T; 4])
     //
     // where T is a primitive scalar (integer/float/pointer).
-
-    let f0_ty = match fields.iter().next() {
-        Some(it) => it.1.clone().substitute(Interner, subst),
-        None => return Err(LayoutError::InvalidSimdType),
+    let fields = db.field_types(id.into());
+    let mut fields = fields.iter();
+    let Some(TyKind::Array(e_ty, e_len)) = fields
+        .next()
+        .filter(|_| fields.next().is_none())
+        .map(|f| f.1.clone().substitute(Interner, subst).kind(Interner).clone())
+    else {
+        return Err(LayoutError::InvalidSimdType);
     };
 
-    // The element type and number of elements of the SIMD vector
-    // are obtained from:
-    //
-    // * the element type and length of the single array field, if
-    // the first field is of array type, or
-    //
-    // * the homogeneous field type and the number of fields.
-    let (e_ty, e_len, is_array) = if let TyKind::Array(e_ty, _) = f0_ty.kind(Interner) {
-        // Extract the number of elements from the layout of the array field:
-        let FieldsShape::Array { count, .. } = db.layout_of_ty(f0_ty.clone(), env.clone())?.fields
-        else {
-            return Err(LayoutError::Unknown);
-        };
-
-        (e_ty.clone(), count, true)
-    } else {
-        // First ADT field is not an array:
-        (f0_ty, fields.iter().count() as u64, false)
-    };
+    let e_len = try_const_usize(db, &e_len).ok_or(LayoutError::HasErrorConst)? as u64;
 
     // Compute the ABI of the element type:
     let e_ly = db.layout_of_ty(e_ty, env)?;
@@ -182,16 +164,9 @@ fn layout_of_simd_ty(
     let align = dl.llvmlike_vector_align(size);
     let size = size.align_to(align.abi);
 
-    // Compute the placement of the vector fields:
-    let fields = if is_array {
-        FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() }
-    } else {
-        FieldsShape::Array { stride: e_ly.size, count: e_len }
-    };
-
     Ok(Arc::new(Layout {
         variants: Variants::Single { index: struct_variant_idx() },
-        fields,
+        fields: FieldsShape::Arbitrary { offsets: [Size::ZERO].into(), memory_index: [0].into() },
         backend_repr: BackendRepr::SimdVector { element: e_abi, count: e_len },
         largest_niche: e_ly.largest_niche,
         uninhabited: false,
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 daddcf0b242..707c4377726 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/lib.rs
@@ -30,11 +30,13 @@ extern crate ra_ap_rustc_hashes as rustc_hashes;
 mod builder;
 mod chalk_db;
 mod chalk_ext;
+mod drop;
 mod infer;
 mod inhabitedness;
 mod interner;
 mod lower;
 mod mapping;
+mod target_feature;
 mod tls;
 mod utils;
 
@@ -87,6 +89,7 @@ use crate::{
 pub use autoderef::autoderef;
 pub use builder::{ParamKind, TyBuilder};
 pub use chalk_ext::*;
+pub use drop::DropGlue;
 pub use infer::{
     cast::CastError,
     closure::{CaptureKind, CapturedItem},
@@ -105,10 +108,9 @@ pub use mapping::{
     to_foreign_def_id, to_placeholder_idx,
 };
 pub use method_resolution::check_orphan_rules;
+pub use target_feature::TargetFeatures;
 pub use traits::TraitEnvironment;
-pub use utils::{
-    all_super_traits, direct_super_traits, is_fn_unsafe_to_call, TargetFeatures, Unsafety,
-};
+pub use utils::{all_super_traits, direct_super_traits, is_fn_unsafe_to_call, Unsafety};
 pub use variance::Variance;
 
 pub use chalk_ir::{
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
index 38b189a517f..7d3376f56be 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/mir/eval/shim.rs
@@ -11,6 +11,7 @@ use hir_def::{
 };
 use hir_expand::name::Name;
 use intern::{sym, Symbol};
+use stdx::never;
 
 use crate::{
     error_lifetime,
@@ -20,6 +21,7 @@ use crate::{
         LangItem, Layout, Locals, Lookup, MirEvalError, MirSpan, Mutability, Result, Substitution,
         Ty, TyBuilder, TyExt,
     },
+    DropGlue,
 };
 
 mod simd;
@@ -853,7 +855,14 @@ impl Evaluator<'_> {
                         "size_of generic arg is not provided".into(),
                     ));
                 };
-                let result = !ty.clone().is_copy(self.db, locals.body.owner);
+                let result = match self.db.has_drop_glue(ty.clone(), self.trait_env.clone()) {
+                    DropGlue::HasDropGlue => true,
+                    DropGlue::None => false,
+                    DropGlue::DependOnParams => {
+                        never!("should be fully monomorphized now");
+                        true
+                    }
+                };
                 destination.write_from_bytes(self, &[u8::from(result)])
             }
             "ptr_guaranteed_cmp" => {
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs b/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs
new file mode 100644
index 00000000000..fe9416c6cfc
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/target_feature.rs
@@ -0,0 +1,261 @@
+//! Stuff for handling `#[target_feature]` (needed for unsafe check).
+
+use std::sync::LazyLock;
+
+use hir_def::attr::Attrs;
+use hir_def::tt;
+use intern::{sym, Symbol};
+use rustc_hash::{FxHashMap, FxHashSet};
+
+#[derive(Debug, Default)]
+pub struct TargetFeatures {
+    pub(crate) enabled: FxHashSet<Symbol>,
+}
+
+impl TargetFeatures {
+    pub fn from_attrs(attrs: &Attrs) -> Self {
+        let mut result = TargetFeatures::from_attrs_no_implications(attrs);
+        result.expand_implications();
+        result
+    }
+
+    fn expand_implications(&mut self) {
+        let all_implications = LazyLock::force(&TARGET_FEATURE_IMPLICATIONS);
+        let mut queue = self.enabled.iter().cloned().collect::<Vec<_>>();
+        while let Some(feature) = queue.pop() {
+            if let Some(implications) = all_implications.get(&feature) {
+                for implication in implications {
+                    if self.enabled.insert(implication.clone()) {
+                        queue.push(implication.clone());
+                    }
+                }
+            }
+        }
+    }
+
+    /// Retrieves the target features from the attributes, and does not expand the target features implied by them.
+    pub(crate) fn from_attrs_no_implications(attrs: &Attrs) -> Self {
+        let enabled = attrs
+            .by_key(&sym::target_feature)
+            .tt_values()
+            .filter_map(|tt| {
+                match tt.token_trees().flat_tokens() {
+                    [
+                        tt::TokenTree::Leaf(tt::Leaf::Ident(enable_ident)),
+                        tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '=', .. })),
+                        tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { kind: tt::LitKind::Str, symbol: features, .. })),
+                    ] if enable_ident.sym == sym::enable => Some(features),
+                    _ => None,
+                }
+            })
+            .flat_map(|features| features.as_str().split(',').map(Symbol::intern))
+            .collect();
+        Self { enabled }
+    }
+}
+
+// List of the target features each target feature implies.
+// Ideally we'd depend on rustc for this, but rustc_target doesn't compile on stable,
+// and t-compiler prefers for it to stay this way.
+
+static TARGET_FEATURE_IMPLICATIONS: LazyLock<FxHashMap<Symbol, Box<[Symbol]>>> =
+    LazyLock::new(|| {
+        let mut result = FxHashMap::<Symbol, FxHashSet<Symbol>>::default();
+        for &(feature_str, implications) in TARGET_FEATURE_IMPLICATIONS_RAW {
+            let feature = Symbol::intern(feature_str);
+            let implications = implications.iter().copied().map(Symbol::intern);
+            // Some target features appear in two archs, e.g. Arm and x86.
+            // Sometimes they contain different implications, e.g. `aes`.
+            // We should probably choose by the active arch, but for now just merge them.
+            result.entry(feature).or_default().extend(implications);
+        }
+        let mut result = result
+            .into_iter()
+            .map(|(feature, implications)| (feature, Box::from_iter(implications)))
+            .collect::<FxHashMap<_, _>>();
+        result.shrink_to_fit();
+        result
+    });
+
+// spellchecker:off
+const TARGET_FEATURE_IMPLICATIONS_RAW: &[(&str, &[&str])] = &[
+    // Arm
+    ("aes", &["neon"]),
+    ("dotprod", &["neon"]),
+    ("fp-armv8", &["vfp4"]),
+    ("fp16", &["neon"]),
+    ("i8mm", &["neon"]),
+    ("neon", &["vfp3"]),
+    ("sha2", &["neon"]),
+    ("v6", &["v5te"]),
+    ("v6k", &["v6"]),
+    ("v6t2", &["v6k", "thumb2"]),
+    ("v7", &["v6t2"]),
+    ("v8", &["v7"]),
+    ("vfp3", &["vfp2", "d32"]),
+    ("vfp4", &["vfp3"]),
+    // Aarch64
+    ("aes", &["neon"]),
+    ("dotprod", &["neon"]),
+    ("dpb2", &["dpb"]),
+    ("f32mm", &["sve"]),
+    ("f64mm", &["sve"]),
+    ("fcma", &["neon"]),
+    ("fhm", &["fp16"]),
+    ("fp16", &["neon"]),
+    ("fp8", &["faminmax", "lut", "bf16"]),
+    ("fp8dot2", &["fp8dot4"]),
+    ("fp8dot4", &["fp8fma"]),
+    ("fp8fma", &["fp8"]),
+    ("jsconv", &["neon"]),
+    ("lse128", &["lse"]),
+    ("rcpc2", &["rcpc"]),
+    ("rcpc3", &["rcpc2"]),
+    ("rdm", &["neon"]),
+    ("sha2", &["neon"]),
+    ("sha3", &["sha2"]),
+    ("sm4", &["neon"]),
+    ("sme", &["bf16"]),
+    ("sme-b16b16", &["bf16", "sme2", "sve-b16b16"]),
+    ("sme-f16f16", &["sme2"]),
+    ("sme-f64f64", &["sme"]),
+    ("sme-f8f16", &["sme-f8f32"]),
+    ("sme-f8f32", &["sme2", "fp8"]),
+    ("sme-fa64", &["sme", "sve2"]),
+    ("sme-i16i64", &["sme"]),
+    ("sme2", &["sme"]),
+    ("sme2p1", &["sme2"]),
+    ("ssve-fp8dot2", &["ssve-fp8dot4"]),
+    ("ssve-fp8dot4", &["ssve-fp8fma"]),
+    ("ssve-fp8fma", &["sme2", "fp8"]),
+    ("sve", &["neon"]),
+    ("sve-b16b16", &["bf16"]),
+    ("sve2", &["sve"]),
+    ("sve2-aes", &["sve2", "aes"]),
+    ("sve2-bitperm", &["sve2"]),
+    ("sve2-sha3", &["sve2", "sha3"]),
+    ("sve2-sm4", &["sve2", "sm4"]),
+    ("sve2p1", &["sve2"]),
+    ("v8.1a", &["crc", "lse", "rdm", "pan", "lor", "vh"]),
+    ("v8.2a", &["v8.1a", "ras", "dpb"]),
+    ("v8.3a", &["v8.2a", "rcpc", "paca", "pacg", "jsconv"]),
+    ("v8.4a", &["v8.3a", "dotprod", "dit", "flagm"]),
+    ("v8.5a", &["v8.4a", "ssbs", "sb", "dpb2", "bti"]),
+    ("v8.6a", &["v8.5a", "bf16", "i8mm"]),
+    ("v8.7a", &["v8.6a", "wfxt"]),
+    ("v8.8a", &["v8.7a", "hbc", "mops"]),
+    ("v8.9a", &["v8.8a", "cssc"]),
+    ("v9.1a", &["v9a", "v8.6a"]),
+    ("v9.2a", &["v9.1a", "v8.7a"]),
+    ("v9.3a", &["v9.2a", "v8.8a"]),
+    ("v9.4a", &["v9.3a", "v8.9a"]),
+    ("v9.5a", &["v9.4a"]),
+    ("v9a", &["v8.5a", "sve2"]),
+    // x86
+    ("aes", &["sse2"]),
+    ("amx-bf16", &["amx-tile"]),
+    ("amx-complex", &["amx-tile"]),
+    ("amx-fp16", &["amx-tile"]),
+    ("amx-int8", &["amx-tile"]),
+    ("avx", &["sse4.2"]),
+    ("avx2", &["avx"]),
+    ("avx512bf16", &["avx512bw"]),
+    ("avx512bitalg", &["avx512bw"]),
+    ("avx512bw", &["avx512f"]),
+    ("avx512cd", &["avx512f"]),
+    ("avx512dq", &["avx512f"]),
+    ("avx512f", &["avx2", "fma", "f16c"]),
+    ("avx512fp16", &["avx512bw", "avx512vl", "avx512dq"]),
+    ("avx512ifma", &["avx512f"]),
+    ("avx512vbmi", &["avx512bw"]),
+    ("avx512vbmi2", &["avx512bw"]),
+    ("avx512vl", &["avx512f"]),
+    ("avx512vnni", &["avx512f"]),
+    ("avx512vp2intersect", &["avx512f"]),
+    ("avx512vpopcntdq", &["avx512f"]),
+    ("avxifma", &["avx2"]),
+    ("avxneconvert", &["avx2"]),
+    ("avxvnni", &["avx2"]),
+    ("avxvnniint16", &["avx2"]),
+    ("avxvnniint8", &["avx2"]),
+    ("f16c", &["avx"]),
+    ("fma", &["avx"]),
+    ("gfni", &["sse2"]),
+    ("kl", &["sse2"]),
+    ("pclmulqdq", &["sse2"]),
+    ("sha", &["sse2"]),
+    ("sha512", &["avx2"]),
+    ("sm3", &["avx"]),
+    ("sm4", &["avx2"]),
+    ("sse2", &["sse"]),
+    ("sse3", &["sse2"]),
+    ("sse4.1", &["ssse3"]),
+    ("sse4.2", &["sse4.1"]),
+    ("sse4a", &["sse3"]),
+    ("ssse3", &["sse3"]),
+    ("vaes", &["avx2", "aes"]),
+    ("vpclmulqdq", &["avx", "pclmulqdq"]),
+    ("widekl", &["kl"]),
+    ("xop", &[/*"fma4", */ "avx", "sse4a"]),
+    ("xsavec", &["xsave"]),
+    ("xsaveopt", &["xsave"]),
+    ("xsaves", &["xsave"]),
+    // Hexagon
+    ("hvx-length128b", &["hvx"]),
+    // PowerPC
+    ("power10-vector", &["power9-vector"]),
+    ("power8-altivec", &["altivec"]),
+    ("power8-crypto", &["power8-altivec"]),
+    ("power8-vector", &["vsx", "power8-altivec"]),
+    ("power9-altivec", &["power8-altivec"]),
+    ("power9-vector", &["power8-vector", "power9-altivec"]),
+    ("vsx", &["altivec"]),
+    // MIPS
+    // RISC-V
+    ("a", &["zaamo", "zalrsc"]),
+    ("d", &["f"]),
+    ("zabha", &["zaamo"]),
+    ("zdinx", &["zfinx"]),
+    ("zfh", &["zfhmin"]),
+    ("zfhmin", &["f"]),
+    ("zhinx", &["zhinxmin"]),
+    ("zhinxmin", &["zfinx"]),
+    ("zk", &["zkn", "zkr", "zkt"]),
+    ("zkn", &["zbkb", "zbkc", "zbkx", "zkne", "zknd", "zknh"]),
+    ("zks", &["zbkb", "zbkc", "zbkx", "zksed", "zksh"]),
+    // WASM
+    ("relaxed-simd", &["simd128"]),
+    // BPF
+    ("alu32", &[]),
+    // CSKY
+    ("10e60", &["7e10"]),
+    ("2e3", &["e2"]),
+    ("3e3r2", &["3e3r1", "doloop"]),
+    ("3e3r3", &["doloop"]),
+    ("3e7", &["2e3"]),
+    ("7e10", &["3e7"]),
+    ("e1", &["elrw"]),
+    ("e2", &["e2"]),
+    ("mp", &["2e3"]),
+    ("mp1e2", &["3e7"]),
+    // LoongArch
+    ("d", &["f"]),
+    ("lasx", &["lsx"]),
+    ("lsx", &["d"]),
+    // IBM Z
+    ("nnp-assist", &["vector"]),
+    ("vector-enhancements-1", &["vector"]),
+    ("vector-enhancements-2", &["vector-enhancements-1"]),
+    ("vector-packed-decimal", &["vector"]),
+    ("vector-packed-decimal-enhancement", &["vector-packed-decimal"]),
+    ("vector-packed-decimal-enhancement-2", &["vector-packed-decimal-enhancement"]),
+    // SPARC
+    // m68k
+    ("isa-68010", &["isa-68000"]),
+    ("isa-68020", &["isa-68010"]),
+    ("isa-68030", &["isa-68020"]),
+    ("isa-68040", &["isa-68030", "isa-68882"]),
+    ("isa-68060", &["isa-68040"]),
+    ("isa-68882", &["isa-68881"]),
+];
+// spellchecker:on
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 c131e97bc4c..89d89fe2230 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/utils.rs
@@ -9,18 +9,16 @@ use chalk_ir::{
     DebruijnIndex,
 };
 use hir_def::{
-    attr::Attrs,
     db::DefDatabase,
     generics::{WherePredicate, WherePredicateTypeTarget},
     lang_item::LangItem,
     resolver::{HasResolver, TypeNs},
-    tt,
     type_ref::{TraitBoundModifier, TypeRef},
     EnumId, EnumVariantId, FunctionId, Lookup, OpaqueInternableThing, TraitId, TypeAliasId,
     TypeOrConstParamId,
 };
 use hir_expand::name::Name;
-use intern::{sym, Symbol};
+use intern::sym;
 use rustc_abi::TargetDataLayout;
 use rustc_hash::FxHashSet;
 use smallvec::{smallvec, SmallVec};
@@ -32,8 +30,8 @@ use crate::{
     db::HirDatabase,
     layout::{Layout, TagEncoding},
     mir::pad16,
-    ChalkTraitId, Const, ConstScalar, GenericArg, Interner, Substitution, TraitRef, TraitRefExt,
-    Ty, WhereClause,
+    ChalkTraitId, Const, ConstScalar, GenericArg, Interner, Substitution, TargetFeatures, TraitRef,
+    TraitRefExt, Ty, WhereClause,
 };
 
 pub(crate) fn fn_traits(
@@ -267,32 +265,6 @@ impl<'a> ClosureSubst<'a> {
     }
 }
 
-#[derive(Debug, Default)]
-pub struct TargetFeatures {
-    enabled: FxHashSet<Symbol>,
-}
-
-impl TargetFeatures {
-    pub fn from_attrs(attrs: &Attrs) -> Self {
-        let enabled = attrs
-            .by_key(&sym::target_feature)
-            .tt_values()
-            .filter_map(|tt| {
-                match tt.token_trees().flat_tokens() {
-                    [
-                        tt::TokenTree::Leaf(tt::Leaf::Ident(enable_ident)),
-                        tt::TokenTree::Leaf(tt::Leaf::Punct(tt::Punct { char: '=', .. })),
-                        tt::TokenTree::Leaf(tt::Leaf::Literal(tt::Literal { kind: tt::LitKind::Str, symbol: features, .. })),
-                    ] if enable_ident.sym == sym::enable => Some(features),
-                    _ => None,
-                }
-            })
-            .flat_map(|features| features.as_str().split(',').map(Symbol::intern))
-            .collect();
-        Self { enabled }
-    }
-}
-
 #[derive(Debug, Clone, Copy, PartialEq, Eq)]
 pub enum Unsafety {
     Safe,
@@ -314,7 +286,8 @@ pub fn is_fn_unsafe_to_call(
 
     if data.has_target_feature() {
         // RFC 2396 <https://rust-lang.github.io/rfcs/2396-target-feature-1.1.html>.
-        let callee_target_features = TargetFeatures::from_attrs(&db.attrs(func.into()));
+        let callee_target_features =
+            TargetFeatures::from_attrs_no_implications(&db.attrs(func.into()));
         if !caller_target_features.enabled.is_superset(&callee_target_features.enabled) {
             return Unsafety::Unsafe;
         }
diff --git a/src/tools/rust-analyzer/crates/hir/Cargo.toml b/src/tools/rust-analyzer/crates/hir/Cargo.toml
index c68ff706e48..2af3c2e4c35 100644
--- a/src/tools/rust-analyzer/crates/hir/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/hir/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 rustc-hash.workspace = true
diff --git a/src/tools/rust-analyzer/crates/hir/src/lib.rs b/src/tools/rust-analyzer/crates/hir/src/lib.rs
index 5923a1bc30e..55448d4ae86 100644
--- a/src/tools/rust-analyzer/crates/hir/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/lib.rs
@@ -142,7 +142,7 @@ pub use {
         name::Name,
         prettify_macro_expansion,
         proc_macro::{ProcMacros, ProcMacrosBuilder},
-        tt, ExpandResult, HirFileId, HirFileIdExt, MacroFileId, MacroFileIdExt,
+        tt, ExpandResult, HirFileId, HirFileIdExt, MacroFileId, MacroFileIdExt, MacroKind,
     },
     hir_ty::{
         consteval::ConstEvalError,
@@ -152,7 +152,7 @@ pub use {
         layout::LayoutError,
         method_resolution::TyFingerprint,
         mir::{MirEvalError, MirLowerError},
-        CastError, FnAbi, PointerCast, Safety, Variance,
+        CastError, DropGlue, FnAbi, PointerCast, Safety, Variance,
     },
     // FIXME: Properly encapsulate mir
     hir_ty::{mir, Interner as ChalkTyInterner},
@@ -699,7 +699,10 @@ impl Module {
             let source_map = tree_source_maps.impl_(loc.id.value).item();
             let node = &tree[loc.id.value];
             let file_id = loc.id.file_id();
-            if file_id.macro_file().is_some_and(|it| it.is_builtin_derive(db.upcast())) {
+            if file_id
+                .macro_file()
+                .is_some_and(|it| it.kind(db.upcast()) == MacroKind::DeriveBuiltIn)
+            {
                 // these expansion come from us, diagnosing them is a waste of resources
                 // FIXME: Once we diagnose the inputs to builtin derives, we should at least extract those diagnostics somehow
                 continue;
@@ -1391,6 +1394,10 @@ impl Struct {
         Type::from_def(db, self.id)
     }
 
+    pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type {
+        Type::from_def_placeholders(db, self.id)
+    }
+
     pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type {
         Type::from_value_def(db, self.id)
     }
@@ -1436,6 +1443,10 @@ impl Union {
         Type::from_def(db, self.id)
     }
 
+    pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type {
+        Type::from_def_placeholders(db, self.id)
+    }
+
     pub fn constructor_ty(self, db: &dyn HirDatabase) -> Type {
         Type::from_value_def(db, self.id)
     }
@@ -1490,6 +1501,10 @@ impl Enum {
         Type::from_def(db, self.id)
     }
 
+    pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type {
+        Type::from_def_placeholders(db, self.id)
+    }
+
     /// The type of the enum variant bodies.
     pub fn variant_body_ty(self, db: &dyn HirDatabase) -> Type {
         Type::new_for_crate(
@@ -2929,6 +2944,10 @@ impl TypeAlias {
         Type::from_def(db, self.id)
     }
 
+    pub fn ty_placeholders(self, db: &dyn HirDatabase) -> Type {
+        Type::from_def_placeholders(db, self.id)
+    }
+
     pub fn name(self, db: &dyn HirDatabase) -> Name {
         db.type_alias_data(self.id).name.clone()
     }
@@ -3034,20 +3053,6 @@ impl BuiltinType {
 }
 
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
-pub enum MacroKind {
-    /// `macro_rules!` or Macros 2.0 macro.
-    Declarative,
-    /// A built-in or custom derive.
-    Derive,
-    /// A built-in function-like macro.
-    BuiltIn,
-    /// A procedural attribute macro.
-    Attr,
-    /// A function-like procedural macro.
-    ProcMacro,
-}
-
-#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub struct Macro {
     pub(crate) id: MacroId,
 }
@@ -3077,15 +3082,19 @@ impl Macro {
         match self.id {
             MacroId::Macro2Id(it) => match it.lookup(db.upcast()).expander {
                 MacroExpander::Declarative => MacroKind::Declarative,
-                MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => MacroKind::BuiltIn,
-                MacroExpander::BuiltInAttr(_) => MacroKind::Attr,
-                MacroExpander::BuiltInDerive(_) => MacroKind::Derive,
+                MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => {
+                    MacroKind::DeclarativeBuiltIn
+                }
+                MacroExpander::BuiltInAttr(_) => MacroKind::AttrBuiltIn,
+                MacroExpander::BuiltInDerive(_) => MacroKind::DeriveBuiltIn,
             },
             MacroId::MacroRulesId(it) => match it.lookup(db.upcast()).expander {
                 MacroExpander::Declarative => MacroKind::Declarative,
-                MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => MacroKind::BuiltIn,
-                MacroExpander::BuiltInAttr(_) => MacroKind::Attr,
-                MacroExpander::BuiltInDerive(_) => MacroKind::Derive,
+                MacroExpander::BuiltIn(_) | MacroExpander::BuiltInEager(_) => {
+                    MacroKind::DeclarativeBuiltIn
+                }
+                MacroExpander::BuiltInAttr(_) => MacroKind::AttrBuiltIn,
+                MacroExpander::BuiltInDerive(_) => MacroKind::DeriveBuiltIn,
             },
             MacroId::ProcMacroId(it) => match it.lookup(db.upcast()).kind {
                 ProcMacroKind::CustomDerive => MacroKind::Derive,
@@ -3096,10 +3105,10 @@ impl Macro {
     }
 
     pub fn is_fn_like(&self, db: &dyn HirDatabase) -> bool {
-        match self.kind(db) {
-            MacroKind::Declarative | MacroKind::BuiltIn | MacroKind::ProcMacro => true,
-            MacroKind::Attr | MacroKind::Derive => false,
-        }
+        matches!(
+            self.kind(db),
+            MacroKind::Declarative | MacroKind::DeclarativeBuiltIn | MacroKind::ProcMacro
+        )
     }
 
     pub fn is_builtin_derive(&self, db: &dyn HirDatabase) -> bool {
@@ -3139,11 +3148,11 @@ impl Macro {
     }
 
     pub fn is_attr(&self, db: &dyn HirDatabase) -> bool {
-        matches!(self.kind(db), MacroKind::Attr)
+        matches!(self.kind(db), MacroKind::Attr | MacroKind::AttrBuiltIn)
     }
 
     pub fn is_derive(&self, db: &dyn HirDatabase) -> bool {
-        matches!(self.kind(db), MacroKind::Derive)
+        matches!(self.kind(db), MacroKind::Derive | MacroKind::DeriveBuiltIn)
     }
 }
 
@@ -4708,6 +4717,19 @@ impl Type {
         Type::new(db, def, ty.substitute(Interner, &substs))
     }
 
+    fn from_def_placeholders(db: &dyn HirDatabase, def: impl Into<TyDefId> + HasResolver) -> Type {
+        let ty = db.ty(def.into());
+        let substs = TyBuilder::placeholder_subst(
+            db,
+            match def.into() {
+                TyDefId::AdtId(it) => GenericDefId::AdtId(it),
+                TyDefId::TypeAliasId(it) => GenericDefId::TypeAliasId(it),
+                TyDefId::BuiltinType(_) => return Type::new(db, def, ty.skip_binders().clone()),
+            },
+        );
+        Type::new(db, def, ty.substitute(Interner, &substs))
+    }
+
     fn from_value_def(db: &dyn HirDatabase, def: impl Into<ValueTyDefId> + HasResolver) -> Type {
         let Some(ty) = db.value_ty(def.into()) else {
             return Type::new(db, def, TyKind::Error.intern(Interner));
@@ -5737,6 +5759,10 @@ impl Type {
         db.layout_of_ty(self.ty.clone(), self.env.clone())
             .map(|layout| Layout(layout, db.target_data_layout(self.env.krate).unwrap()))
     }
+
+    pub fn drop_glue(&self, db: &dyn HirDatabase) -> DropGlue {
+        db.has_drop_glue(self.ty.clone(), self.env.clone())
+    }
 }
 
 #[derive(Debug, PartialEq, Eq, Copy, Clone, Hash)]
diff --git a/src/tools/rust-analyzer/crates/hir/src/semantics.rs b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
index c9145f7d212..bb67fa63a1d 100644
--- a/src/tools/rust-analyzer/crates/hir/src/semantics.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/semantics.rs
@@ -508,9 +508,7 @@ impl<'db> SemanticsImpl<'db> {
         })
     }
 
-    pub fn is_derive_annotated(&self, adt: &ast::Adt) -> bool {
-        let file_id = self.find_file(adt.syntax()).file_id;
-        let adt = InFile::new(file_id, adt);
+    pub fn is_derive_annotated(&self, adt: InFile<&ast::Adt>) -> bool {
         self.with_ctx(|ctx| ctx.has_derives(adt))
     }
 
@@ -551,10 +549,8 @@ impl<'db> SemanticsImpl<'db> {
         res.is_empty().not().then_some(res)
     }
 
-    pub fn is_attr_macro_call(&self, item: &ast::Item) -> bool {
-        let file_id = self.find_file(item.syntax()).file_id;
-        let src = InFile::new(file_id, item);
-        self.with_ctx(|ctx| ctx.item_to_macro_call(src).is_some())
+    pub fn is_attr_macro_call(&self, item: InFile<&ast::Item>) -> bool {
+        self.with_ctx(|ctx| ctx.item_to_macro_call(item).is_some())
     }
 
     /// Expand the macro call with a different token tree, mapping the `token_to_map` down into the
@@ -1526,8 +1522,13 @@ impl<'db> SemanticsImpl<'db> {
         self.analyze(field.syntax())?.resolve_record_pat_field(self.db, field)
     }
 
+    // FIXME: Replace this with `resolve_macro_call2`
     pub fn resolve_macro_call(&self, macro_call: &ast::MacroCall) -> Option<Macro> {
         let macro_call = self.find_file(macro_call.syntax()).with_value(macro_call);
+        self.resolve_macro_call2(macro_call)
+    }
+
+    pub fn resolve_macro_call2(&self, macro_call: InFile<&ast::MacroCall>) -> Option<Macro> {
         self.with_ctx(|ctx| {
             ctx.macro_call_to_macro_call(macro_call)
                 .and_then(|call| macro_call_to_macro_id(ctx, call))
@@ -1538,8 +1539,8 @@ impl<'db> SemanticsImpl<'db> {
         })
     }
 
-    pub fn is_proc_macro_call(&self, macro_call: &ast::MacroCall) -> bool {
-        self.resolve_macro_call(macro_call)
+    pub fn is_proc_macro_call(&self, macro_call: InFile<&ast::MacroCall>) -> bool {
+        self.resolve_macro_call2(macro_call)
             .is_some_and(|m| matches!(m.id, MacroId::ProcMacroId(..)))
     }
 
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 4481b8855fd..18cbaa15aea 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
@@ -5,7 +5,7 @@
 //!
 //! This module solves the following problem:
 //!
-//!     Given a piece of syntax, find the corresponding semantic definition (def).
+//! > Given a piece of syntax, find the corresponding semantic definition (def).
 //!
 //! This problem is a part of more-or-less every IDE feature implemented. Every
 //! IDE functionality (like goto to definition), conceptually starts with a
diff --git a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs
index 6ad074e8e5c..d2070f0e18b 100644
--- a/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs
+++ b/src/tools/rust-analyzer/crates/hir/src/term_search/expr.rs
@@ -40,7 +40,7 @@ fn mod_item_path_str(
 /// Type tree shows how can we get from set of types to some type.
 ///
 /// Consider the following code as an example
-/// ```
+/// ```ignore
 /// fn foo(x: i32, y: bool) -> Option<i32> { None }
 /// fn bar() {
 ///    let a = 1;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/Cargo.toml b/src/tools/rust-analyzer/crates/ide-assists/Cargo.toml
index ba215868710..3768c2257ca 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-assists/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 cov-mark = "2.0.0-pre.1"
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs
index 64e77b2d698..b1189f0d0b0 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/assist_context.rs
@@ -52,6 +52,10 @@ pub(crate) struct AssistContext<'a> {
     frange: FileRange,
     trimmed_range: TextRange,
     source_file: SourceFile,
+    // We cache this here to speed up things slightly
+    token_at_offset: TokenAtOffset<SyntaxToken>,
+    // We cache this here to speed up things slightly
+    covering_element: SyntaxElement,
 }
 
 impl<'a> AssistContext<'a> {
@@ -78,8 +82,18 @@ impl<'a> AssistContext<'a> {
             // Selection solely consists of whitespace so just fall back to the original
             _ => frange.range,
         };
-
-        AssistContext { config, sema, frange, source_file, trimmed_range }
+        let token_at_offset = source_file.syntax().token_at_offset(frange.range.start());
+        let covering_element = source_file.syntax().covering_element(trimmed_range);
+
+        AssistContext {
+            config,
+            sema,
+            frange,
+            source_file,
+            trimmed_range,
+            token_at_offset,
+            covering_element,
+        }
     }
 
     pub(crate) fn db(&self) -> &RootDatabase {
@@ -114,7 +128,7 @@ impl<'a> AssistContext<'a> {
     }
 
     pub(crate) fn token_at_offset(&self) -> TokenAtOffset<SyntaxToken> {
-        self.source_file.syntax().token_at_offset(self.offset())
+        self.token_at_offset.clone()
     }
     pub(crate) fn find_token_syntax_at_offset(&self, kind: SyntaxKind) -> Option<SyntaxToken> {
         self.token_at_offset().find(|it| it.kind() == kind)
@@ -136,7 +150,7 @@ impl<'a> AssistContext<'a> {
     }
     /// Returns the element covered by the selection range, this excludes trailing whitespace in the selection.
     pub(crate) fn covering_element(&self) -> SyntaxElement {
-        self.source_file.syntax().covering_element(self.selection_trimmed())
+        self.covering_element.clone()
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
index 4a9e2256e9b..37f5f44dfa0 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/add_missing_match_arms.rs
@@ -76,6 +76,8 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
 
     let cfg = ctx.config.import_path_config();
 
+    let make = SyntaxFactory::new();
+
     let module = ctx.sema.scope(expr.syntax())?.module();
     let (mut missing_pats, is_non_exhaustive, has_hidden_variants): (
         Peekable<Box<dyn Iterator<Item = (ast::Pat, bool)>>>,
@@ -93,7 +95,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
             .into_iter()
             .filter_map(|variant| {
                 Some((
-                    build_pat(ctx, module, variant, cfg)?,
+                    build_pat(ctx, &make, module, variant, cfg)?,
                     variant.should_be_hidden(ctx.db(), module.krate()),
                 ))
             })
@@ -144,10 +146,11 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
                 let is_hidden = variants
                     .iter()
                     .any(|variant| variant.should_be_hidden(ctx.db(), module.krate()));
-                let patterns =
-                    variants.into_iter().filter_map(|variant| build_pat(ctx, module, variant, cfg));
+                let patterns = variants
+                    .into_iter()
+                    .filter_map(|variant| build_pat(ctx, &make, module, variant, cfg));
 
-                (ast::Pat::from(make::tuple_pat(patterns)), is_hidden)
+                (ast::Pat::from(make.tuple_pat(patterns)), is_hidden)
             })
             .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat));
         (
@@ -176,9 +179,11 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
                 let is_hidden = variants
                     .iter()
                     .any(|variant| variant.should_be_hidden(ctx.db(), module.krate()));
-                let patterns =
-                    variants.into_iter().filter_map(|variant| build_pat(ctx, module, variant, cfg));
-                (ast::Pat::from(make::slice_pat(patterns)), is_hidden)
+                let patterns = variants
+                    .into_iter()
+                    .filter_map(|variant| build_pat(ctx, &make, module, variant, cfg));
+
+                (ast::Pat::from(make.slice_pat(patterns)), is_hidden)
             })
             .filter(|(variant_pat, _)| is_variant_missing(&top_lvl_pats, variant_pat));
         (
@@ -203,8 +208,6 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
         "Fill match arms",
         ctx.sema.original_range(match_expr.syntax()).range,
         |builder| {
-            let make = SyntaxFactory::new();
-
             // having any hidden variants means that we need a catch-all arm
             needs_catch_all_arm |= has_hidden_variants;
 
@@ -243,7 +246,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
 
             if needs_catch_all_arm && !has_catch_all_arm {
                 cov_mark::hit!(added_wildcard_pattern);
-                let arm = make.match_arm(make::wildcard_pat().into(), None, make::ext::expr_todo());
+                let arm = make.match_arm(make.wildcard_pat().into(), None, make::ext::expr_todo());
                 arms.push(arm);
             }
 
@@ -290,7 +293,7 @@ pub(crate) fn add_missing_match_arms(acc: &mut Assists, ctx: &AssistContext<'_>)
                 }
             }
 
-            editor.add_mappings(make.finish_with_mappings());
+            editor.add_mappings(make.take());
             builder.add_file_edits(ctx.file_id(), editor);
         },
     )
@@ -445,6 +448,7 @@ fn resolve_array_of_enum_def(
 
 fn build_pat(
     ctx: &AssistContext<'_>,
+    make: &SyntaxFactory,
     module: hir::Module,
     var: ExtendedVariant,
     cfg: ImportPathConfig,
@@ -455,31 +459,32 @@ fn build_pat(
             let edition = module.krate().edition(db);
             let path = mod_path_to_ast(&module.find_path(db, ModuleDef::from(var), cfg)?, edition);
             let fields = var.fields(db);
-            let pat = match var.kind(db) {
+            let pat: ast::Pat = match var.kind(db) {
                 hir::StructKind::Tuple => {
                     let mut name_generator = suggest_name::NameGenerator::new();
                     let pats = fields.into_iter().map(|f| {
                         let name = name_generator.for_type(&f.ty(db), db, edition);
                         match name {
-                            Some(name) => make::ext::simple_ident_pat(make::name(&name)).into(),
-                            None => make::wildcard_pat().into(),
+                            Some(name) => make::ext::simple_ident_pat(make.name(&name)).into(),
+                            None => make.wildcard_pat().into(),
                         }
                     });
-                    make::tuple_struct_pat(path, pats).into()
+                    make.tuple_struct_pat(path, pats).into()
                 }
                 hir::StructKind::Record => {
-                    let pats = fields
+                    let fields = fields
                         .into_iter()
-                        .map(|f| make::name(f.name(db).as_str()))
-                        .map(|name| make::ext::simple_ident_pat(name).into());
-                    make::record_pat(path, pats).into()
+                        .map(|f| make.name_ref(f.name(db).as_str()))
+                        .map(|name_ref| make.record_pat_field_shorthand(name_ref));
+                    let fields = make.record_pat_field_list(fields, None);
+                    make.record_pat_with_fields(path, fields).into()
                 }
-                hir::StructKind::Unit => make::path_pat(path),
+                hir::StructKind::Unit => make.path_pat(path),
             };
             Some(pat)
         }
-        ExtendedVariant::True => Some(ast::Pat::from(make::literal_pat("true"))),
-        ExtendedVariant::False => Some(ast::Pat::from(make::literal_pat("false"))),
+        ExtendedVariant::True => Some(ast::Pat::from(make.literal_pat("true"))),
+        ExtendedVariant::False => Some(ast::Pat::from(make.literal_pat("false"))),
     }
 }
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
index 491727a30a8..77562c588e2 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/apply_demorgan.rs
@@ -3,12 +3,19 @@ use std::collections::VecDeque;
 use ide_db::{
     assists::GroupLabel,
     famous_defs::FamousDefs,
-    source_change::SourceChangeBuilder,
     syntax_helpers::node_ext::{for_each_tail_expr, walk_expr},
 };
 use syntax::{
-    ast::{self, make, AstNode, Expr::BinExpr, HasArgList},
-    ted, SyntaxKind, T,
+    ast::{
+        self,
+        prec::{precedence, ExprPrecedence},
+        syntax_factory::SyntaxFactory,
+        AstNode,
+        Expr::BinExpr,
+        HasArgList,
+    },
+    syntax_editor::{Position, SyntaxEditor},
+    SyntaxKind, T,
 };
 
 use crate::{utils::invert_boolean_expression, AssistContext, AssistId, AssistKind, Assists};
@@ -52,53 +59,60 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
     }
 
     let op = bin_expr.op_kind()?;
-    let inv_token = match op {
-        ast::BinaryOp::LogicOp(ast::LogicOp::And) => SyntaxKind::PIPE2,
-        ast::BinaryOp::LogicOp(ast::LogicOp::Or) => SyntaxKind::AMP2,
+    let (inv_token, prec) = match op {
+        ast::BinaryOp::LogicOp(ast::LogicOp::And) => (SyntaxKind::PIPE2, ExprPrecedence::LOr),
+        ast::BinaryOp::LogicOp(ast::LogicOp::Or) => (SyntaxKind::AMP2, ExprPrecedence::LAnd),
         _ => return None,
     };
 
-    let demorganed = bin_expr.clone_subtree().clone_for_update();
+    let make = SyntaxFactory::new();
+
+    let demorganed = bin_expr.clone_subtree();
+    let mut editor = SyntaxEditor::new(demorganed.syntax().clone());
+    editor.replace(demorganed.op_token()?, make.token(inv_token));
 
-    ted::replace(demorganed.op_token()?, ast::make::token(inv_token));
     let mut exprs = VecDeque::from([
-        (bin_expr.lhs()?, demorganed.lhs()?),
-        (bin_expr.rhs()?, demorganed.rhs()?),
+        (bin_expr.lhs()?, demorganed.lhs()?, prec),
+        (bin_expr.rhs()?, demorganed.rhs()?, prec),
     ]);
 
-    while let Some((expr, dm)) = exprs.pop_front() {
+    while let Some((expr, demorganed, prec)) = exprs.pop_front() {
         if let BinExpr(bin_expr) = &expr {
-            if let BinExpr(cbin_expr) = &dm {
+            if let BinExpr(cbin_expr) = &demorganed {
                 if op == bin_expr.op_kind()? {
-                    ted::replace(cbin_expr.op_token()?, ast::make::token(inv_token));
-                    exprs.push_back((bin_expr.lhs()?, cbin_expr.lhs()?));
-                    exprs.push_back((bin_expr.rhs()?, cbin_expr.rhs()?));
+                    editor.replace(cbin_expr.op_token()?, make.token(inv_token));
+                    exprs.push_back((bin_expr.lhs()?, cbin_expr.lhs()?, prec));
+                    exprs.push_back((bin_expr.rhs()?, cbin_expr.rhs()?, prec));
                 } else {
-                    let mut inv = invert_boolean_expression(expr);
-                    if inv.needs_parens_in(dm.syntax().parent()?) {
-                        inv = ast::make::expr_paren(inv).clone_for_update();
+                    let mut inv = invert_boolean_expression(&make, expr);
+                    if precedence(&inv).needs_parentheses_in(prec) {
+                        inv = make.expr_paren(inv).into();
                     }
-                    ted::replace(dm.syntax(), inv.syntax());
+                    editor.replace(demorganed.syntax(), inv.syntax());
                 }
             } else {
                 return None;
             }
         } else {
-            let mut inv = invert_boolean_expression(dm.clone_subtree()).clone_for_update();
-            if inv.needs_parens_in(dm.syntax().parent()?) {
-                inv = ast::make::expr_paren(inv).clone_for_update();
+            let mut inv = invert_boolean_expression(&make, demorganed.clone());
+            if precedence(&inv).needs_parentheses_in(prec) {
+                inv = make.expr_paren(inv).into();
             }
-            ted::replace(dm.syntax(), inv.syntax());
+            editor.replace(demorganed.syntax(), inv.syntax());
         }
     }
 
+    editor.add_mappings(make.finish_with_mappings());
+    let edit = editor.finish();
+    let demorganed = ast::Expr::cast(edit.new_root().clone())?;
+
     acc.add_group(
         &GroupLabel("Apply De Morgan's law".to_owned()),
         AssistId("apply_demorgan", AssistKind::RefactorRewrite),
         "Apply De Morgan's law",
         op_range,
-        |edit| {
-            let demorganed = ast::Expr::BinExpr(demorganed);
+        |builder| {
+            let make = SyntaxFactory::new();
             let paren_expr = bin_expr.syntax().parent().and_then(ast::ParenExpr::cast);
             let neg_expr = paren_expr
                 .clone()
@@ -107,24 +121,32 @@ pub(crate) fn apply_demorgan(acc: &mut Assists, ctx: &AssistContext<'_>) -> Opti
                 .filter(|prefix_expr| matches!(prefix_expr.op_kind(), Some(ast::UnaryOp::Not)))
                 .map(ast::Expr::PrefixExpr);
 
+            let mut editor;
             if let Some(paren_expr) = paren_expr {
                 if let Some(neg_expr) = neg_expr {
                     cov_mark::hit!(demorgan_double_negation);
                     let parent = neg_expr.syntax().parent();
+                    editor = builder.make_editor(neg_expr.syntax());
 
-                    if parent.is_some_and(|parent| demorganed.needs_parens_in(parent)) {
+                    if parent.is_some_and(|parent| demorganed.needs_parens_in(&parent)) {
                         cov_mark::hit!(demorgan_keep_parens_for_op_precedence2);
-                        edit.replace_ast(neg_expr, make::expr_paren(demorganed));
+                        editor.replace(neg_expr.syntax(), make.expr_paren(demorganed).syntax());
                     } else {
-                        edit.replace_ast(neg_expr, demorganed);
+                        editor.replace(neg_expr.syntax(), demorganed.syntax());
                     };
                 } else {
                     cov_mark::hit!(demorgan_double_parens);
-                    edit.replace_ast(paren_expr.into(), add_bang_paren(demorganed));
+                    editor = builder.make_editor(paren_expr.syntax());
+
+                    editor.replace(paren_expr.syntax(), add_bang_paren(&make, demorganed).syntax());
                 }
             } else {
-                edit.replace_ast(bin_expr.into(), add_bang_paren(demorganed));
+                editor = builder.make_editor(bin_expr.syntax());
+                editor.replace(bin_expr.syntax(), add_bang_paren(&make, demorganed).syntax());
             }
+
+            editor.add_mappings(make.finish_with_mappings());
+            builder.add_file_edits(ctx.file_id(), editor);
         },
     )
 }
@@ -161,7 +183,7 @@ pub(crate) fn apply_demorgan_iterator(acc: &mut Assists, ctx: &AssistContext<'_>
     let (name, arg_expr) = validate_method_call_expr(ctx, &method_call)?;
 
     let ast::Expr::ClosureExpr(closure_expr) = arg_expr else { return None };
-    let closure_body = closure_expr.body()?;
+    let closure_body = closure_expr.body()?.clone_for_update();
 
     let op_range = method_call.syntax().text_range();
     let label = format!("Apply De Morgan's law to `Iterator::{}`", name.text().as_str());
@@ -170,18 +192,19 @@ pub(crate) fn apply_demorgan_iterator(acc: &mut Assists, ctx: &AssistContext<'_>
         AssistId("apply_demorgan_iterator", AssistKind::RefactorRewrite),
         label,
         op_range,
-        |edit| {
+        |builder| {
+            let make = SyntaxFactory::new();
+            let mut editor = builder.make_editor(method_call.syntax());
             // replace the method name
             let new_name = match name.text().as_str() {
-                "all" => make::name_ref("any"),
-                "any" => make::name_ref("all"),
+                "all" => make.name_ref("any"),
+                "any" => make.name_ref("all"),
                 _ => unreachable!(),
-            }
-            .clone_for_update();
-            edit.replace_ast(name, new_name);
+            };
+            editor.replace(name.syntax(), new_name.syntax());
 
             // negate all tail expressions in the closure body
-            let tail_cb = &mut |e: &_| tail_cb_impl(edit, e);
+            let tail_cb = &mut |e: &_| tail_cb_impl(&mut editor, &make, e);
             walk_expr(&closure_body, &mut |expr| {
                 if let ast::Expr::ReturnExpr(ret_expr) = expr {
                     if let Some(ret_expr_arg) = &ret_expr.expr() {
@@ -198,15 +221,15 @@ pub(crate) fn apply_demorgan_iterator(acc: &mut Assists, ctx: &AssistContext<'_>
                 .and_then(ast::PrefixExpr::cast)
                 .filter(|prefix_expr| matches!(prefix_expr.op_kind(), Some(ast::UnaryOp::Not)))
             {
-                edit.delete(
-                    prefix_expr
-                        .op_token()
-                        .expect("prefix expression always has an operator")
-                        .text_range(),
+                editor.delete(
+                    prefix_expr.op_token().expect("prefix expression always has an operator"),
                 );
             } else {
-                edit.insert(method_call.syntax().text_range().start(), "!");
+                editor.insert(Position::before(method_call.syntax()), make.token(SyntaxKind::BANG));
             }
+
+            editor.add_mappings(make.finish_with_mappings());
+            builder.add_file_edits(ctx.file_id(), editor);
         },
     )
 }
@@ -233,26 +256,26 @@ fn validate_method_call_expr(
     it_type.impls_trait(sema.db, iter_trait, &[]).then_some((name_ref, arg_expr))
 }
 
-fn tail_cb_impl(edit: &mut SourceChangeBuilder, e: &ast::Expr) {
+fn tail_cb_impl(editor: &mut SyntaxEditor, make: &SyntaxFactory, e: &ast::Expr) {
     match e {
         ast::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(edit, e))
+                for_each_tail_expr(&break_expr_arg, &mut |e| tail_cb_impl(editor, make, e))
             }
         }
         ast::Expr::ReturnExpr(_) => {
             // all return expressions have already been handled by the walk loop
         }
         e => {
-            let inverted_body = invert_boolean_expression(e.clone());
-            edit.replace(e.syntax().text_range(), inverted_body.syntax().text());
+            let inverted_body = invert_boolean_expression(make, e.clone());
+            editor.replace(e.syntax(), inverted_body.syntax());
         }
     }
 }
 
 /// Add bang and parentheses to the expression.
-fn add_bang_paren(expr: ast::Expr) -> ast::Expr {
-    make::expr_prefix(T![!], make::expr_paren(expr)).into()
+fn add_bang_paren(make: &SyntaxFactory, expr: ast::Expr) -> ast::Expr {
+    make.expr_prefix(T![!], make.expr_paren(expr).into()).into()
 }
 
 #[cfg(test)]
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs
index eb784cd1226..151c71c0a76 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_bool_then.rs
@@ -8,8 +8,9 @@ use ide_db::{
 };
 use itertools::Itertools;
 use syntax::{
-    ast::{self, edit::AstNodeEdit, make, HasArgList},
-    ted, AstNode, SyntaxNode,
+    ast::{self, edit::AstNodeEdit, syntax_factory::SyntaxFactory, HasArgList},
+    syntax_editor::SyntaxEditor,
+    AstNode, SyntaxNode,
 };
 
 use crate::{
@@ -76,9 +77,9 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
         "Convert `if` expression to `bool::then` call",
         target,
         |builder| {
-            let closure_body = closure_body.clone_for_update();
+            let closure_body = closure_body.clone_subtree();
+            let mut editor = SyntaxEditor::new(closure_body.syntax().clone());
             // Rewrite all `Some(e)` in tail position to `e`
-            let mut replacements = Vec::new();
             for_each_tail_expr(&closure_body, &mut |e| {
                 let e = match e {
                     ast::Expr::BreakExpr(e) => e.expr(),
@@ -88,12 +89,16 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
                 if let Some(ast::Expr::CallExpr(call)) = e {
                     if let Some(arg_list) = call.arg_list() {
                         if let Some(arg) = arg_list.args().next() {
-                            replacements.push((call.syntax().clone(), arg.syntax().clone()));
+                            editor.replace(call.syntax(), arg.syntax());
                         }
                     }
                 }
             });
-            replacements.into_iter().for_each(|(old, new)| ted::replace(old, new));
+            let edit = editor.finish();
+            let closure_body = ast::Expr::cast(edit.new_root().clone()).unwrap();
+
+            let mut editor = builder.make_editor(expr.syntax());
+            let make = SyntaxFactory::new();
             let closure_body = match closure_body {
                 ast::Expr::BlockExpr(block) => unwrap_trivial_block(block),
                 e => e,
@@ -119,11 +124,18 @@ pub(crate) fn convert_if_to_bool_then(acc: &mut Assists, ctx: &AssistContext<'_>
                     | ast::Expr::WhileExpr(_)
                     | ast::Expr::YieldExpr(_)
             );
-            let cond = if invert_cond { invert_boolean_expression(cond) } else { cond };
-            let cond = if parenthesize { make::expr_paren(cond) } else { cond };
-            let arg_list = make::arg_list(Some(make::expr_closure(None, closure_body)));
-            let mcall = make::expr_method_call(cond, make::name_ref("then"), arg_list);
-            builder.replace(target, mcall.to_string());
+            let cond = if invert_cond {
+                invert_boolean_expression(&make, cond)
+            } else {
+                cond.clone_for_update()
+            };
+            let cond = if parenthesize { make.expr_paren(cond).into() } else { cond };
+            let arg_list = make.arg_list(Some(make.expr_closure(None, closure_body).into()));
+            let mcall = make.expr_method_call(cond, make.name_ref("then"), arg_list);
+            editor.replace(expr.syntax(), mcall.syntax());
+
+            editor.add_mappings(make.finish_with_mappings());
+            builder.add_file_edits(ctx.file_id(), editor);
         },
     )
 }
@@ -173,16 +185,17 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_>
         "Convert `bool::then` call to `if`",
         target,
         |builder| {
-            let closure_body = match closure_body {
+            let mapless_make = SyntaxFactory::without_mappings();
+            let closure_body = match closure_body.reset_indent() {
                 ast::Expr::BlockExpr(block) => block,
-                e => make::block_expr(None, Some(e)),
+                e => mapless_make.block_expr(None, Some(e)),
             };
 
-            let closure_body = closure_body.clone_for_update();
+            let closure_body = closure_body.clone_subtree();
+            let mut editor = SyntaxEditor::new(closure_body.syntax().clone());
             // Wrap all tails in `Some(...)`
-            let none_path = make::expr_path(make::ext::ident_path("None"));
-            let some_path = make::expr_path(make::ext::ident_path("Some"));
-            let mut replacements = Vec::new();
+            let none_path = mapless_make.expr_path(mapless_make.ident_path("None"));
+            let some_path = mapless_make.expr_path(mapless_make.ident_path("Some"));
             for_each_tail_expr(&ast::Expr::BlockExpr(closure_body.clone()), &mut |e| {
                 let e = match e {
                     ast::Expr::BreakExpr(e) => e.expr(),
@@ -190,28 +203,37 @@ pub(crate) fn convert_bool_then_to_if(acc: &mut Assists, ctx: &AssistContext<'_>
                     _ => Some(e.clone()),
                 };
                 if let Some(expr) = e {
-                    replacements.push((
+                    editor.replace(
                         expr.syntax().clone(),
-                        make::expr_call(some_path.clone(), make::arg_list(Some(expr)))
+                        mapless_make
+                            .expr_call(some_path.clone(), mapless_make.arg_list(Some(expr)))
                             .syntax()
-                            .clone_for_update(),
-                    ));
+                            .clone(),
+                    );
                 }
             });
-            replacements.into_iter().for_each(|(old, new)| ted::replace(old, new));
+            let edit = editor.finish();
+            let closure_body = ast::BlockExpr::cast(edit.new_root().clone()).unwrap();
+
+            let mut editor = builder.make_editor(mcall.syntax());
+            let make = SyntaxFactory::new();
 
             let cond = match &receiver {
                 ast::Expr::ParenExpr(expr) => expr.expr().unwrap_or(receiver),
                 _ => receiver,
             };
-            let if_expr = make::expr_if(
-                cond,
-                closure_body.reset_indent(),
-                Some(ast::ElseBranch::Block(make::block_expr(None, Some(none_path)))),
-            )
-            .indent(mcall.indent_level());
+            let if_expr = make
+                .expr_if(
+                    cond,
+                    closure_body,
+                    Some(ast::ElseBranch::Block(make.block_expr(None, Some(none_path)))),
+                )
+                .indent(mcall.indent_level())
+                .clone_for_update();
+            editor.replace(mcall.syntax().clone(), if_expr.syntax().clone());
 
-            builder.replace(target, if_expr.to_string());
+            editor.add_mappings(make.finish_with_mappings());
+            builder.add_file_edits(ctx.file_id(), editor);
         },
     )
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs
index c7b1314c861..5a9db67a5fb 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_comment_from_or_to_doc.rs
@@ -136,7 +136,7 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem
 
 /// Not all comments are valid candidates for conversion into doc comments. For example, the
 /// comments in the code:
-/// ```rust
+/// ```ignore
 /// // Brilliant module right here
 ///
 /// // Really good right
@@ -148,7 +148,7 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem
 /// mod nice_module {}
 /// ```
 /// can be converted to doc comments. However, the comments in this example:
-/// ```rust
+/// ```ignore
 /// fn foo_bar(foo: Foo /* not bar yet */) -> Bar {
 ///     foo.into_bar()
 ///     // Nicely done
@@ -162,7 +162,7 @@ fn comment_to_doc(acc: &mut Assists, comment: ast::Comment, style: CommentPlacem
 /// are not allowed to become doc comments. Moreover, some comments _are_ allowed, but aren't common
 /// style in Rust. For example, the following comments are allowed to be doc comments, but it is not
 /// common style for them to be:
-/// ```rust
+/// ```ignore
 /// fn foo_bar(foo: Foo) -> Bar {
 ///     // this could be an inner comment with //!
 ///     foo.into_bar()
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
index e1966d476c5..b7a77644496 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_to_guarded_return.rs
@@ -17,7 +17,7 @@ use syntax::{
 
 use crate::{
     assist_context::{AssistContext, Assists},
-    utils::invert_boolean_expression,
+    utils::invert_boolean_expression_legacy,
     AssistId, AssistKind,
 };
 
@@ -139,7 +139,7 @@ fn if_expr_to_guarded_return(
                     let new_expr = {
                         let then_branch =
                             make::block_expr(once(make::expr_stmt(early_expression).into()), None);
-                        let cond = invert_boolean_expression(cond_expr);
+                        let cond = invert_boolean_expression_legacy(cond_expr);
                         make::expr_if(cond, then_branch, None).indent(if_indent_level)
                     };
                     new_expr.syntax().clone_for_update()
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs
index 0b92beefbcd..beec64d13b6 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/convert_while_to_loop.rs
@@ -13,7 +13,7 @@ use syntax::{
 
 use crate::{
     assist_context::{AssistContext, Assists},
-    utils::invert_boolean_expression,
+    utils::invert_boolean_expression_legacy,
     AssistId, AssistKind,
 };
 
@@ -63,7 +63,7 @@ pub(crate) fn convert_while_to_loop(acc: &mut Assists, ctx: &AssistContext<'_>)
                 let stmts = iter::once(make::expr_stmt(if_expr.into()).into());
                 make::block_expr(stmts, None)
             } else {
-                let if_cond = invert_boolean_expression(while_cond);
+                let if_cond = invert_boolean_expression_legacy(while_cond);
                 let if_expr = make::expr_if(if_cond, break_block, None).syntax().clone().into();
                 let elements = while_body.stmt_list().map_or_else(
                     || Either::Left(iter::empty()),
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
index 967da41c15f..751e4a5a571 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/extract_function.rs
@@ -272,7 +272,7 @@ fn make_function_name(semantics_scope: &hir::SemanticsScope<'_>) -> ast::NameRef
 /// * We want whole node, like `loop {}`, `2 + 2`, `{ let n = 1; }` exprs.
 ///   Then we can use `ast::Expr`
 /// * We want a few statements for a block. E.g.
-///   ```rust,no_run
+///   ```ignore
 ///   fn foo() -> i32 {
 ///     let m = 1;
 ///     $0
@@ -386,7 +386,7 @@ struct ContainerInfo {
 /// Control flow that is exported from extracted function
 ///
 /// E.g.:
-/// ```rust,no_run
+/// ```ignore
 /// loop {
 ///     $0
 ///     if 42 == 42 {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs
index 95e035c0537..dd27269b001 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_comma.rs
@@ -1,8 +1,8 @@
 use syntax::{
     algo::non_trivia_sibling,
     ast::{self, syntax_factory::SyntaxFactory},
-    syntax_editor::{Element, SyntaxMapping},
-    AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxToken, T,
+    syntax_editor::SyntaxMapping,
+    AstNode, Direction, NodeOrToken, SyntaxKind, SyntaxToken, T,
 };
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
@@ -39,37 +39,24 @@ pub(crate) fn flip_comma(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
         return None;
     }
 
-    let prev = match prev {
-        SyntaxElement::Node(node) => node.syntax_element(),
-        _ => prev,
-    };
-    let next = match next {
-        SyntaxElement::Node(node) => node.syntax_element(),
-        _ => next,
-    };
-
-    acc.add(
-        AssistId("flip_comma", AssistKind::RefactorRewrite),
-        "Flip comma",
-        comma.text_range(),
-        |builder| {
-            let parent = comma.parent().unwrap();
-            let mut editor = builder.make_editor(&parent);
-
-            if let Some(parent) = ast::TokenTree::cast(parent) {
-                // An attribute. It often contains a path followed by a
-                // token tree (e.g. `align(2)`), so we have to be smarter.
-                let (new_tree, mapping) = flip_tree(parent.clone(), comma);
-                editor.replace(parent.syntax(), new_tree.syntax());
-                editor.add_mappings(mapping);
-            } else {
-                editor.replace(prev.clone(), next.clone());
-                editor.replace(next.clone(), prev.clone());
-            }
-
-            builder.add_file_edits(ctx.file_id(), editor);
-        },
-    )
+    let target = comma.text_range();
+    acc.add(AssistId("flip_comma", AssistKind::RefactorRewrite), "Flip comma", target, |builder| {
+        let parent = comma.parent().unwrap();
+        let mut editor = builder.make_editor(&parent);
+
+        if let Some(parent) = ast::TokenTree::cast(parent) {
+            // An attribute. It often contains a path followed by a
+            // token tree (e.g. `align(2)`), so we have to be smarter.
+            let (new_tree, mapping) = flip_tree(parent.clone(), comma);
+            editor.replace(parent.syntax(), new_tree.syntax());
+            editor.add_mappings(mapping);
+        } else {
+            editor.replace(prev.clone(), next.clone());
+            editor.replace(next.clone(), prev.clone());
+        }
+
+        builder.add_file_edits(ctx.file_id(), editor);
+    })
 }
 
 fn flip_tree(tree: ast::TokenTree, comma: SyntaxToken) -> (ast::TokenTree, SyntaxMapping) {
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs
new file mode 100644
index 00000000000..d9fa03e7191
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_or_pattern.rs
@@ -0,0 +1,80 @@
+use syntax::{
+    algo::non_trivia_sibling,
+    ast::{self, AstNode},
+    Direction, T,
+};
+
+use crate::{AssistContext, AssistId, AssistKind, Assists};
+
+// Assist: flip_or_pattern
+//
+// Flips two patterns in an or-pattern.
+//
+// ```
+// fn foo() {
+//     let (a |$0 b) = 1;
+// }
+// ```
+// ->
+// ```
+// fn foo() {
+//     let (b | a) = 1;
+// }
+// ```
+pub(crate) fn flip_or_pattern(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
+    // Only flip on the `|` token
+    let pipe = ctx.find_token_syntax_at_offset(T![|])?;
+
+    let parent = ast::OrPat::cast(pipe.parent()?)?;
+
+    let before = non_trivia_sibling(pipe.clone().into(), Direction::Prev)?.into_node()?;
+    let after = non_trivia_sibling(pipe.clone().into(), Direction::Next)?.into_node()?;
+
+    let target = pipe.text_range();
+    acc.add(
+        AssistId("flip_or_pattern", AssistKind::RefactorRewrite),
+        "Flip patterns",
+        target,
+        |builder| {
+            let mut editor = builder.make_editor(parent.syntax());
+            editor.replace(before.clone(), after.clone());
+            editor.replace(after, before);
+            builder.add_file_edits(ctx.file_id(), editor);
+        },
+    )
+}
+
+#[cfg(test)]
+mod tests {
+    use super::*;
+
+    use crate::tests::{check_assist, check_assist_not_applicable, check_assist_target};
+
+    #[test]
+    fn flip_or_pattern_assist_available() {
+        check_assist_target(flip_or_pattern, "fn main(a |$0 b: ()) {}", "|")
+    }
+
+    #[test]
+    fn flip_or_pattern_not_applicable_for_leading_pipe() {
+        check_assist_not_applicable(flip_or_pattern, "fn main(|$0 b: ()) {}")
+    }
+
+    #[test]
+    fn flip_or_pattern_works() {
+        check_assist(
+            flip_or_pattern,
+            "fn foo() { let (a | b |$0 c | d) = 1; }",
+            "fn foo() { let (a | c | b | d) = 1; }",
+        )
+    }
+
+    #[test]
+    fn flip_or_pattern_works_match_guard() {
+        check_assist(
+            flip_or_pattern,
+            "fn foo() { match() { a |$0 b if true => () }}",
+            "fn foo() { match() { b | a if true => () }}",
+        )
+    }
+}
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs
index 298e5bd82c9..3528f5e8132 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/flip_trait_bound.rs
@@ -18,17 +18,14 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
 // fn foo<T: Copy + Clone>() { }
 // ```
 pub(crate) fn flip_trait_bound(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
-    // We want to replicate the behavior of `flip_binexpr` by only suggesting
-    // the assist when the cursor is on a `+`
+    // Only flip on the `+` token
     let plus = ctx.find_token_syntax_at_offset(T![+])?;
 
     // Make sure we're in a `TypeBoundList`
     let parent = ast::TypeBoundList::cast(plus.parent()?)?;
 
-    let (before, after) = (
-        non_trivia_sibling(plus.clone().into(), Direction::Prev)?.into_node()?,
-        non_trivia_sibling(plus.clone().into(), Direction::Next)?.into_node()?,
-    );
+    let before = non_trivia_sibling(plus.clone().into(), Direction::Prev)?.into_node()?;
+    let after = non_trivia_sibling(plus.clone().into(), Direction::Next)?.into_node()?;
 
     let target = plus.text_range();
     acc.add(
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
index 8f5daa4125a..91e248a1de5 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_function.rs
@@ -1037,7 +1037,7 @@ fn filter_bounds_in_scope(
 
 /// Makes duplicate argument names unique by appending incrementing numbers.
 ///
-/// ```
+/// ```ignore
 /// let mut names: Vec<String> =
 ///     vec!["foo".into(), "foo".into(), "bar".into(), "baz".into(), "bar".into()];
 /// deduplicate_arg_names(&mut names);
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs
index 7b7dac9a3d6..4439830947a 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/generate_impl.rs
@@ -78,7 +78,7 @@ pub(crate) fn generate_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Optio
 //     data: T,
 // }
 //
-// impl<T: Clone> ${0:_} for Ctx<T> {}
+// impl<T: Clone> ${1:_} for Ctx<T> {$0}
 // ```
 pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
     let nominal = ctx.find_node_at_offset::<ast::Adt>()?;
@@ -102,6 +102,10 @@ pub(crate) fn generate_trait_impl(acc: &mut Assists, ctx: &AssistContext<'_>) ->
                 if let Some(trait_) = impl_.trait_() {
                     edit.add_placeholder_snippet(cap, trait_);
                 }
+
+                if let Some(l_curly) = impl_.assoc_item_list().and_then(|it| it.l_curly_token()) {
+                    edit.add_tabstop_after_token(cap, l_curly);
+                }
             }
 
             insert_impl(impl_, &edit.make_mut(nominal));
@@ -278,7 +282,7 @@ mod tests {
             r#"
                 struct Foo {}
 
-                impl ${0:_} for Foo {}
+                impl ${1:_} for Foo {$0}
             "#,
         );
     }
@@ -293,7 +297,7 @@ mod tests {
             r#"
                 struct Foo<T: Clone> {}
 
-                impl<T: Clone> ${0:_} for Foo<T> {}
+                impl<T: Clone> ${1:_} for Foo<T> {$0}
             "#,
         );
     }
@@ -308,7 +312,7 @@ mod tests {
             r#"
                 struct Foo<'a, T: Foo<'a>> {}
 
-                impl<'a, T: Foo<'a>> ${0:_} for Foo<'a, T> {}
+                impl<'a, T: Foo<'a>> ${1:_} for Foo<'a, T> {$0}
             "#,
         );
     }
@@ -326,7 +330,7 @@ mod tests {
                 struct Foo<'a, T: Foo<'a>> {}
 
                 #[cfg(feature = "foo")]
-                impl<'a, T: Foo<'a>> ${0:_} for Foo<'a, T> {}
+                impl<'a, T: Foo<'a>> ${1:_} for Foo<'a, T> {$0}
             "#,
         );
     }
@@ -341,7 +345,7 @@ mod tests {
             r#"
                 struct Defaulted<T = i32> {}
 
-                impl<T> ${0:_} for Defaulted<T> {}
+                impl<T> ${1:_} for Defaulted<T> {$0}
             "#,
         );
     }
@@ -356,7 +360,7 @@ mod tests {
             r#"
                 struct Defaulted<'a, 'b: 'a, T: Debug + Clone + 'a + 'b = String, const S: usize> {}
 
-                impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b, const S: usize> ${0:_} for Defaulted<'a, 'b, T, S> {}
+                impl<'a, 'b: 'a, T: Debug + Clone + 'a + 'b, const S: usize> ${1:_} for Defaulted<'a, 'b, T, S> {$0}
             "#,
         );
     }
@@ -371,7 +375,7 @@ mod tests {
             r#"
                 struct Defaulted<const N: i32 = 0> {}
 
-                impl<const N: i32> ${0:_} for Defaulted<N> {}
+                impl<const N: i32> ${1:_} for Defaulted<N> {$0}
             "#,
         );
     }
@@ -398,10 +402,10 @@ mod tests {
                     inner: T,
                 }
 
-                impl<T> ${0:_} for Struct<T>
+                impl<T> ${1:_} for Struct<T>
                 where
                     T: Trait,
-                {
+                {$0
                 }
             "#,
         );
@@ -476,7 +480,7 @@ mod tests {
                 mod foo {
                     struct Bar {}
 
-                    impl ${0:_} for Bar {}
+                    impl ${1:_} for Bar {$0}
                 }
             "#,
         );
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs
index c92c22378f8..139078eee7c 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_const_as_literal.rs
@@ -39,25 +39,10 @@ pub(crate) fn inline_const_as_literal(acc: &mut Assists, ctx: &AssistContext<'_>
         // FIXME: Add support to handle type aliases for builtin scalar types.
         validate_type_recursively(ctx, Some(&konst_ty), false, fuel)?;
 
-        let expr = konst.value(ctx.sema.db)?;
-
-        let value = match expr {
-            ast::Expr::BlockExpr(_)
-            | ast::Expr::Literal(_)
-            | ast::Expr::RefExpr(_)
-            | ast::Expr::ArrayExpr(_)
-            | ast::Expr::TupleExpr(_)
-            | ast::Expr::IfExpr(_)
-            | ast::Expr::ParenExpr(_)
-            | ast::Expr::MatchExpr(_)
-            | ast::Expr::MacroExpr(_)
-            | ast::Expr::BinExpr(_)
-            | ast::Expr::CallExpr(_) => konst
-                .eval(ctx.sema.db)
-                .ok()?
-                .render(ctx.sema.db, konst.krate(ctx.sema.db).edition(ctx.sema.db)),
-            _ => return None,
-        };
+        let value = konst
+            .eval(ctx.sema.db)
+            .ok()?
+            .render(ctx.sema.db, konst.krate(ctx.sema.db).edition(ctx.sema.db));
 
         let id = AssistId("inline_const_as_literal", AssistKind::RefactorInline);
 
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs
index b9fc075ae83..cc7bea5152b 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_local_variable.rs
@@ -73,39 +73,12 @@ pub(crate) fn inline_local_variable(acc: &mut Assists, ctx: &AssistContext<'_>)
             }
             let usage_node =
                 name_ref.syntax().ancestors().find(|it| ast::PathExpr::can_cast(it.kind()));
-            let usage_parent_option =
-                usage_node.and_then(|it| it.parent()).and_then(ast::Expr::cast);
+            let usage_parent_option = usage_node.and_then(|it| it.parent());
             let usage_parent = match usage_parent_option {
                 Some(u) => u,
                 None => return Some((range, name_ref, false)),
             };
-            let initializer = matches!(
-                initializer_expr,
-                ast::Expr::CallExpr(_)
-                    | ast::Expr::IndexExpr(_)
-                    | ast::Expr::MethodCallExpr(_)
-                    | ast::Expr::FieldExpr(_)
-                    | ast::Expr::TryExpr(_)
-                    | ast::Expr::Literal(_)
-                    | ast::Expr::TupleExpr(_)
-                    | ast::Expr::ArrayExpr(_)
-                    | ast::Expr::ParenExpr(_)
-                    | ast::Expr::PathExpr(_)
-                    | ast::Expr::BlockExpr(_),
-            );
-            let parent = matches!(
-                usage_parent,
-                ast::Expr::TupleExpr(_)
-                    | ast::Expr::ArrayExpr(_)
-                    | ast::Expr::ParenExpr(_)
-                    | ast::Expr::ForExpr(_)
-                    | ast::Expr::WhileExpr(_)
-                    | ast::Expr::BreakExpr(_)
-                    | ast::Expr::ReturnExpr(_)
-                    | ast::Expr::MatchExpr(_)
-                    | ast::Expr::BlockExpr(_)
-            );
-            Some((range, name_ref, !(initializer || parent)))
+            Some((range, name_ref, initializer_expr.needs_parens_in(&usage_parent)))
         })
         .collect::<Option<Vec<_>>>()?;
 
@@ -281,11 +254,11 @@ fn foo() {
             r"
 fn bar(a: usize) {}
 fn foo() {
-    (1 + 1) + 1;
-    if (1 + 1) > 10 {
+    1 + 1 + 1;
+    if 1 + 1 > 10 {
     }
 
-    while (1 + 1) > 10 {
+    while 1 + 1 > 10 {
 
     }
     let b = (1 + 1) * 10;
@@ -350,14 +323,14 @@ fn foo() {
             r"
 fn bar(a: usize) -> usize { a }
 fn foo() {
-    (bar(1) as u64) + 1;
-    if (bar(1) as u64) > 10 {
+    bar(1) as u64 + 1;
+    if bar(1) as u64 > 10 {
     }
 
-    while (bar(1) as u64) > 10 {
+    while bar(1) as u64 > 10 {
 
     }
-    let b = (bar(1) as u64) * 10;
+    let b = bar(1) as u64 * 10;
     bar(bar(1) as u64);
 }",
         );
@@ -574,7 +547,7 @@ fn foo() {
             r"
 fn foo() {
     let bar = 10;
-    let b = (&bar) * 10;
+    let b = &bar * 10;
 }",
         );
     }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs
index 66dffde505c..76d465b0110 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/inline_type_alias.rs
@@ -276,7 +276,7 @@ impl ConstAndTypeMap {
 /// 1. Map the provided instance's generic args to the type alias's generic
 ///    params:
 ///
-///    ```
+///    ```ignore
 ///    type A<'a, const N: usize, T = u64> = &'a [T; N];
 ///          ^ alias generic params
 ///    let a: A<100>;
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs
index 547158e2977..ac710503d8a 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/invert_if.rs
@@ -6,7 +6,7 @@ use syntax::{
 
 use crate::{
     assist_context::{AssistContext, Assists},
-    utils::invert_boolean_expression,
+    utils::invert_boolean_expression_legacy,
     AssistId, AssistKind,
 };
 
@@ -48,7 +48,7 @@ pub(crate) fn invert_if(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()
     };
 
     acc.add(AssistId("invert_if", AssistKind::RefactorRewrite), "Invert if", if_range, |edit| {
-        let flip_cond = invert_boolean_expression(cond.clone());
+        let flip_cond = invert_boolean_expression_legacy(cond.clone());
         edit.replace_ast(cond, flip_cond);
 
         let else_node = else_block.syntax();
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_mut.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_mut.rs
index 0b299e8349a..43740a5a6d5 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_mut.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_mut.rs
@@ -1,4 +1,4 @@
-use syntax::{SyntaxKind, TextRange, T};
+use syntax::{SyntaxKind, T};
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
 
@@ -19,11 +19,6 @@ use crate::{AssistContext, AssistId, AssistKind, Assists};
 // ```
 pub(crate) fn remove_mut(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<()> {
     let mut_token = ctx.find_token_syntax_at_offset(T![mut])?;
-    let delete_from = mut_token.text_range().start();
-    let delete_to = match mut_token.next_token() {
-        Some(it) if it.kind() == SyntaxKind::WHITESPACE => it.text_range().end(),
-        _ => mut_token.text_range().end(),
-    };
 
     let target = mut_token.text_range();
     acc.add(
@@ -31,7 +26,13 @@ pub(crate) fn remove_mut(acc: &mut Assists, ctx: &AssistContext<'_>) -> Option<(
         "Remove `mut` keyword",
         target,
         |builder| {
-            builder.delete(TextRange::new(delete_from, delete_to));
+            let mut editor = builder.make_editor(&mut_token.parent().unwrap());
+            match mut_token.next_token() {
+                Some(it) if it.kind() == SyntaxKind::WHITESPACE => editor.delete(it),
+                _ => (),
+            }
+            editor.delete(mut_token);
+            builder.add_file_edits(ctx.file_id(), editor);
         },
     )
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs
index f74fc261128..e7beb23bf8e 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_parentheses.rs
@@ -1,4 +1,8 @@
-use syntax::{ast, AstNode, SyntaxKind, T};
+use syntax::{
+    ast::{self, syntax_factory::SyntaxFactory},
+    syntax_editor::Position,
+    AstNode, SyntaxKind, T,
+};
 
 use crate::{AssistContext, AssistId, AssistKind, Assists};
 
@@ -30,7 +34,7 @@ pub(crate) fn remove_parentheses(acc: &mut Assists, ctx: &AssistContext<'_>) ->
     let expr = parens.expr()?;
 
     let parent = parens.syntax().parent()?;
-    if expr.needs_parens_in(parent) {
+    if expr.needs_parens_in(&parent) {
         return None;
     }
 
@@ -40,6 +44,7 @@ pub(crate) fn remove_parentheses(acc: &mut Assists, ctx: &AssistContext<'_>) ->
         "Remove redundant parentheses",
         target,
         |builder| {
+            let mut editor = builder.make_editor(parens.syntax());
             let prev_token = parens.syntax().first_token().and_then(|it| it.prev_token());
             let need_to_add_ws = match prev_token {
                 Some(it) => {
@@ -48,9 +53,13 @@ pub(crate) fn remove_parentheses(acc: &mut Assists, ctx: &AssistContext<'_>) ->
                 }
                 None => false,
             };
-            let expr = if need_to_add_ws { format!(" {expr}") } else { expr.to_string() };
-
-            builder.replace(parens.syntax().text_range(), expr)
+            if need_to_add_ws {
+                let make = SyntaxFactory::new();
+                editor.insert(Position::before(parens.syntax()), make.whitespace(" "));
+                editor.add_mappings(make.finish_with_mappings());
+            }
+            editor.replace(parens.syntax(), expr.syntax());
+            builder.add_file_edits(ctx.file_id(), editor);
         },
     )
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs
index 75120768da0..5ddb17b2072 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/remove_unused_param.rs
@@ -1,8 +1,9 @@
 use ide_db::{defs::Definition, search::FileReference, EditionedFileId};
 use syntax::{
-    algo::find_node_at_range,
+    algo::{find_node_at_range, least_common_ancestor_element},
     ast::{self, HasArgList},
-    AstNode, SourceFile, SyntaxKind, SyntaxNode, TextRange, T,
+    syntax_editor::Element,
+    AstNode, SourceFile, SyntaxElement, SyntaxKind, SyntaxNode, TextRange, T,
 };
 
 use SyntaxKind::WHITESPACE;
@@ -74,15 +75,21 @@ pub(crate) fn remove_unused_param(acc: &mut Assists, ctx: &AssistContext<'_>) ->
         cov_mark::hit!(keep_used);
         return None;
     }
+    let parent = param.syntax().parent()?;
     acc.add(
         AssistId("remove_unused_param", AssistKind::Refactor),
         "Remove unused parameter",
         param.syntax().text_range(),
         |builder| {
-            builder.delete(range_to_remove(param.syntax()));
+            let mut editor = builder.make_editor(&parent);
+            let elements = elements_to_remove(param.syntax());
+            for element in elements {
+                editor.delete(element);
+            }
             for (file_id, references) in fn_def.usages(&ctx.sema).all() {
                 process_usages(ctx, builder, file_id, references, param_position, is_self_present);
             }
+            builder.add_file_edits(ctx.file_id(), editor);
         },
     )
 }
@@ -96,20 +103,24 @@ fn process_usages(
     is_self_present: bool,
 ) {
     let source_file = ctx.sema.parse(file_id);
-    builder.edit_file(file_id);
     let possible_ranges = references
         .into_iter()
         .filter_map(|usage| process_usage(&source_file, usage, arg_to_remove, is_self_present));
 
-    let mut ranges_to_delete: Vec<TextRange> = vec![];
-    for range in possible_ranges {
-        if !ranges_to_delete.iter().any(|it| it.contains_range(range)) {
-            ranges_to_delete.push(range)
+    for element_range in possible_ranges {
+        let Some(SyntaxElement::Node(parent)) = element_range
+            .iter()
+            .cloned()
+            .reduce(|a, b| least_common_ancestor_element(&a, &b).unwrap().syntax_element())
+        else {
+            continue;
+        };
+        let mut editor = builder.make_editor(&parent);
+        for element in element_range {
+            editor.delete(element);
         }
-    }
 
-    for range in ranges_to_delete {
-        builder.delete(range)
+        builder.add_file_edits(file_id, editor);
     }
 }
 
@@ -118,7 +129,7 @@ fn process_usage(
     FileReference { range, .. }: FileReference,
     mut arg_to_remove: usize,
     is_self_present: bool,
-) -> Option<TextRange> {
+) -> Option<Vec<SyntaxElement>> {
     let call_expr_opt: Option<ast::CallExpr> = find_node_at_range(source_file.syntax(), range);
     if let Some(call_expr) = call_expr_opt {
         let call_expr_range = call_expr.expr()?.syntax().text_range();
@@ -127,7 +138,7 @@ fn process_usage(
         }
 
         let arg = call_expr.arg_list()?.args().nth(arg_to_remove)?;
-        return Some(range_to_remove(arg.syntax()));
+        return Some(elements_to_remove(arg.syntax()));
     }
 
     let method_call_expr_opt: Option<ast::MethodCallExpr> =
@@ -143,7 +154,7 @@ fn process_usage(
         }
 
         let arg = method_call_expr.arg_list()?.args().nth(arg_to_remove)?;
-        return Some(range_to_remove(arg.syntax()));
+        return Some(elements_to_remove(arg.syntax()));
     }
 
     None
@@ -174,6 +185,29 @@ pub(crate) fn range_to_remove(node: &SyntaxNode) -> TextRange {
     }
 }
 
+pub(crate) fn elements_to_remove(node: &SyntaxNode) -> Vec<SyntaxElement> {
+    let up_to_comma = next_prev().find_map(|dir| {
+        node.siblings_with_tokens(dir)
+            .filter_map(|it| it.into_token())
+            .find(|it| it.kind() == T![,])
+            .map(|it| (dir, it))
+    });
+    if let Some((dir, token)) = up_to_comma {
+        let after = token.siblings_with_tokens(dir).nth(1).unwrap();
+        let mut result: Vec<_> =
+            node.siblings_with_tokens(dir).take_while(|it| it != &after).collect();
+        if node.next_sibling().is_some() {
+            result.extend(
+                token.siblings_with_tokens(dir).skip(1).take_while(|it| it.kind() == WHITESPACE),
+            );
+        }
+
+        result
+    } else {
+        vec![node.syntax_element()]
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use crate::tests::{check_assist, check_assist_not_applicable};
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs
index 0876246e90b..baf4ddae2fb 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/handlers/unqualify_method_call.rs
@@ -1,6 +1,6 @@
 use ide_db::imports::insert_use::ImportScope;
 use syntax::{
-    ast::{self, make, AstNode, HasArgList},
+    ast::{self, prec::ExprPrecedence, AstNode, HasArgList},
     TextRange,
 };
 
@@ -55,7 +55,7 @@ pub(crate) fn unqualify_method_call(acc: &mut Assists, ctx: &AssistContext<'_>)
         TextRange::new(path.syntax().text_range().start(), l_paren.text_range().end());
 
     // Parens around `expr` if needed
-    let parens = needs_parens_as_receiver(&first_arg).then(|| {
+    let parens = first_arg.precedence().needs_parentheses_in(ExprPrecedence::Postfix).then(|| {
         let range = first_arg.syntax().text_range();
         (range.start(), range.end())
     });
@@ -124,24 +124,6 @@ fn add_import(
     }
 }
 
-fn needs_parens_as_receiver(expr: &ast::Expr) -> bool {
-    // Make `(expr).dummy()`
-    let dummy_call = make::expr_method_call(
-        make::expr_paren(expr.clone()),
-        make::name_ref("dummy"),
-        make::arg_list([]),
-    );
-
-    // Get the `expr` clone with the right parent back
-    // (unreachable!s are fine since we've just constructed the expression)
-    let ast::Expr::MethodCallExpr(call) = &dummy_call else { unreachable!() };
-    let Some(receiver) = call.receiver() else { unreachable!() };
-    let ast::Expr::ParenExpr(parens) = receiver else { unreachable!() };
-    let Some(expr) = parens.expr() else { unreachable!() };
-
-    expr.needs_parens_in(dummy_call.syntax().clone())
-}
-
 #[cfg(test)]
 mod tests {
     use crate::tests::{check_assist, check_assist_not_applicable};
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 179742f91b4..448bcadb8ef 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/lib.rs
@@ -149,6 +149,7 @@ mod handlers {
     mod fix_visibility;
     mod flip_binexpr;
     mod flip_comma;
+    mod flip_or_pattern;
     mod flip_trait_bound;
     mod generate_constant;
     mod generate_default_from_enum_variant;
@@ -279,6 +280,7 @@ mod handlers {
             fix_visibility::fix_visibility,
             flip_binexpr::flip_binexpr,
             flip_comma::flip_comma,
+            flip_or_pattern::flip_or_pattern,
             flip_trait_bound::flip_trait_bound,
             generate_constant::generate_constant,
             generate_default_from_enum_variant::generate_default_from_enum_variant,
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 0662527a387..91c1a3e1bd7 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
@@ -1196,6 +1196,23 @@ fn main() {
 }
 
 #[test]
+fn doctest_flip_or_pattern() {
+    check_doc_test(
+        "flip_or_pattern",
+        r#####"
+fn foo() {
+    let (a |$0 b) = 1;
+}
+"#####,
+        r#####"
+fn foo() {
+    let (b | a) = 1;
+}
+"#####,
+    )
+}
+
+#[test]
 fn doctest_flip_trait_bound() {
     check_doc_test(
         "flip_trait_bound",
@@ -1961,7 +1978,7 @@ struct Ctx<T: Clone> {
     data: T,
 }
 
-impl<T: Clone> ${0:_} for Ctx<T> {}
+impl<T: Clone> ${1:_} for Ctx<T> {$0}
 "#####,
     )
 }
diff --git a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
index c1332d99bff..39686f065a9 100644
--- a/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
+++ b/src/tools/rust-analyzer/crates/ide-assists/src/utils.rs
@@ -17,7 +17,9 @@ use syntax::{
         self,
         edit::{AstNodeEdit, IndentLevel},
         edit_in_place::{AttrsOwnerEdit, Indent, Removable},
-        make, HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace,
+        make,
+        syntax_factory::SyntaxFactory,
+        HasArgList, HasAttrs, HasGenericParams, HasName, HasTypeBounds, Whitespace,
     },
     ted, AstNode, AstToken, Direction, Edition, NodeOrToken, SourceFile,
     SyntaxKind::*,
@@ -245,11 +247,79 @@ pub(crate) fn vis_offset(node: &SyntaxNode) -> TextSize {
         .unwrap_or_else(|| node.text_range().start())
 }
 
-pub(crate) fn invert_boolean_expression(expr: ast::Expr) -> ast::Expr {
-    invert_special_case(&expr).unwrap_or_else(|| make::expr_prefix(T![!], expr).into())
+pub(crate) fn invert_boolean_expression(make: &SyntaxFactory, expr: ast::Expr) -> ast::Expr {
+    invert_special_case(make, &expr).unwrap_or_else(|| make.expr_prefix(T![!], expr).into())
 }
 
-fn invert_special_case(expr: &ast::Expr) -> Option<ast::Expr> {
+// FIXME: Migrate usages of this function to the above function and remove this.
+pub(crate) fn invert_boolean_expression_legacy(expr: ast::Expr) -> ast::Expr {
+    invert_special_case_legacy(&expr).unwrap_or_else(|| make::expr_prefix(T![!], expr).into())
+}
+
+fn invert_special_case(make: &SyntaxFactory, expr: &ast::Expr) -> Option<ast::Expr> {
+    match expr {
+        ast::Expr::BinExpr(bin) => {
+            let op_kind = bin.op_kind()?;
+            let rev_kind = match op_kind {
+                ast::BinaryOp::CmpOp(ast::CmpOp::Eq { negated }) => {
+                    ast::BinaryOp::CmpOp(ast::CmpOp::Eq { negated: !negated })
+                }
+                ast::BinaryOp::CmpOp(ast::CmpOp::Ord { ordering: ast::Ordering::Less, strict }) => {
+                    ast::BinaryOp::CmpOp(ast::CmpOp::Ord {
+                        ordering: ast::Ordering::Greater,
+                        strict: !strict,
+                    })
+                }
+                ast::BinaryOp::CmpOp(ast::CmpOp::Ord {
+                    ordering: ast::Ordering::Greater,
+                    strict,
+                }) => ast::BinaryOp::CmpOp(ast::CmpOp::Ord {
+                    ordering: ast::Ordering::Less,
+                    strict: !strict,
+                }),
+                // Parenthesize other expressions before prefixing `!`
+                _ => {
+                    return Some(
+                        make.expr_prefix(T![!], make.expr_paren(expr.clone()).into()).into(),
+                    );
+                }
+            };
+
+            Some(make.expr_bin(bin.lhs()?, rev_kind, bin.rhs()?).into())
+        }
+        ast::Expr::MethodCallExpr(mce) => {
+            let receiver = mce.receiver()?;
+            let method = mce.name_ref()?;
+            let arg_list = mce.arg_list()?;
+
+            let method = match method.text().as_str() {
+                "is_some" => "is_none",
+                "is_none" => "is_some",
+                "is_ok" => "is_err",
+                "is_err" => "is_ok",
+                _ => return None,
+            };
+
+            Some(make.expr_method_call(receiver, make.name_ref(method), arg_list).into())
+        }
+        ast::Expr::PrefixExpr(pe) if pe.op_kind()? == ast::UnaryOp::Not => match pe.expr()? {
+            ast::Expr::ParenExpr(parexpr) => {
+                parexpr.expr().map(|e| e.clone_subtree().clone_for_update())
+            }
+            _ => pe.expr().map(|e| e.clone_subtree().clone_for_update()),
+        },
+        ast::Expr::Literal(lit) => match lit.kind() {
+            ast::LiteralKind::Bool(b) => match b {
+                true => Some(ast::Expr::Literal(make.expr_literal("false"))),
+                false => Some(ast::Expr::Literal(make.expr_literal("true"))),
+            },
+            _ => None,
+        },
+        _ => None,
+    }
+}
+
+fn invert_special_case_legacy(expr: &ast::Expr) -> Option<ast::Expr> {
     match expr {
         ast::Expr::BinExpr(bin) => {
             let bin = bin.clone_for_update();
diff --git a/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml b/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml
index 1bef82af5ac..68cc7a0b9a6 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-completion/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 cov-mark = "2.0.0-pre.1"
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
index e7101751701..365d2dde7e9 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/completions/expr.rs
@@ -147,7 +147,10 @@ pub(crate) fn complete_expr_path(
             });
             match resolution {
                 hir::PathResolution::Def(hir::ModuleDef::Module(module)) => {
-                    let module_scope = module.scope(ctx.db, Some(ctx.module));
+                    // Set visible_from to None so private items are returned.
+                    // They will be possibly filtered out in add_path_resolution()
+                    // via def_is_visible().
+                    let module_scope = module.scope(ctx.db, None);
                     for (name, def) in module_scope {
                         if scope_def_applicable(def) {
                             acc.add_path_resolution(
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 7862b258789..919b30f7f97 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/context.rs
@@ -249,8 +249,8 @@ pub(crate) enum Qualified {
         /// This would be None, if path is not solely made of
         /// `super` segments, e.g.
         ///
-        /// ```rust
-        ///   use super::foo;
+        /// ```ignore
+        /// use super::foo;
         /// ```
         ///
         /// Otherwise it should be Some(count of `super`)
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 eecd412bc43..1a34548f708 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
@@ -97,7 +97,8 @@ fn token_at_offset_ignore_whitespace(file: &SyntaxNode, offset: TextSize) -> Opt
 /// We do this by recursively expanding all macros and picking the best possible match. We cannot just
 /// choose the first expansion each time because macros can expand to something that does not include
 /// our completion marker, e.g.:
-/// ```
+///
+/// ```ignore
 /// macro_rules! helper { ($v:ident) => {} }
 /// macro_rules! my_macro {
 ///     ($v:ident) => {
@@ -106,7 +107,7 @@ fn token_at_offset_ignore_whitespace(file: &SyntaxNode, offset: TextSize) -> Opt
 ///     };
 /// }
 ///
-/// my_macro!(complete_me_here)
+/// my_macro!(complete_me_here);
 /// ```
 /// If we would expand the first thing we encounter only (which in fact this method used to do), we would
 /// be unable to complete here, because we would be walking directly into the void. So we instead try
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs
index 41a82409597..b3dd8a8d06e 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/item.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/item.rs
@@ -149,9 +149,9 @@ pub struct CompletionRelevance {
     /// This is set when the identifier being completed matches up with the name that is expected,
     /// like in a function argument.
     ///
-    /// ```
+    /// ```ignore
     /// fn f(spam: String) {}
-    /// fn main {
+    /// fn main() {
     ///     let spam = 92;
     ///     f($0) // name of local matches the name of param
     /// }
@@ -161,7 +161,7 @@ pub struct CompletionRelevance {
     pub type_match: Option<CompletionRelevanceTypeMatch>,
     /// Set for local variables.
     ///
-    /// ```
+    /// ```ignore
     /// fn foo(a: u32) {
     ///     let b = 0;
     ///     $0 // `a` and `b` are local
@@ -195,7 +195,7 @@ pub struct CompletionRelevanceTraitInfo {
 pub enum CompletionRelevanceTypeMatch {
     /// This is set in cases like these:
     ///
-    /// ```
+    /// ```ignore
     /// enum Option<T> { Some(T), None }
     /// fn f(a: Option<u32>) {}
     /// fn main {
@@ -205,9 +205,9 @@ pub enum CompletionRelevanceTypeMatch {
     CouldUnify,
     /// This is set in cases where the type matches the expected type, like:
     ///
-    /// ```
+    /// ```ignore
     /// fn f(spam: String) {}
-    /// fn main {
+    /// fn main() {
     ///     let foo = String::new();
     ///     f($0) // type of local matches the type of param
     /// }
@@ -221,7 +221,7 @@ pub enum CompletionRelevancePostfixMatch {
     NonExact,
     /// This is set in cases like these:
     ///
-    /// ```
+    /// ```ignore
     /// (a > b).not$0
     /// ```
     ///
diff --git a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
index a1f2eaeb1b6..a990b39481a 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/lib.rs
@@ -143,7 +143,7 @@ impl CompletionFieldsToResolve {
 /// already present, it should give all possible variants for the identifier at
 /// the caret. In other words, for
 ///
-/// ```no_run
+/// ```ignore
 /// fn f() {
 ///     let foo = 92;
 ///     let _ = bar$0
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 dc7eacbfbaf..4f6c4cb6639 100644
--- a/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
+++ b/src/tools/rust-analyzer/crates/ide-completion/src/render.rs
@@ -628,11 +628,9 @@ fn compute_ref_match(
     let expected_type = ctx.expected_type.as_ref()?;
     let expected_without_ref = expected_type.remove_ref();
     let completion_without_ref = completion_ty.remove_ref();
-
-    if completion_ty == expected_type {
+    if expected_type.could_unify_with(ctx.db, completion_ty) {
         return None;
     }
-
     if let Some(expected_without_ref) = &expected_without_ref {
         if completion_ty.autoderef(ctx.db).any(|ty| ty == *expected_without_ref) {
             cov_mark::hit!(suggest_ref);
@@ -2008,6 +2006,30 @@ fn f() {
     }
 
     #[test]
+    fn test_avoid_redundant_suggestion() {
+        check_relevance(
+            r#"
+struct aa([u8]);
+
+impl aa {
+    fn from_bytes(bytes: &[u8]) -> &Self {
+        unsafe { &*(bytes as *const [u8] as *const aa) }
+    }
+}
+
+fn bb()-> &'static aa {
+    let bytes = b"hello";
+    aa::$0
+}
+"#,
+            expect![[r#"
+                ex bb()  [type]
+                fn from_bytes(…) fn(&[u8]) -> &aa [type_could_unify]
+            "#]],
+        );
+    }
+
+    #[test]
     fn suggest_ref_mut() {
         cov_mark::check!(suggest_ref);
         check_relevance(
diff --git a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml
index c8a8a2d1698..641998c3dac 100644
--- a/src/tools/rust-analyzer/crates/ide-db/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-db/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 cov-mark = "2.0.0-pre.1"
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
index ed9d6c67501..9c983e7c4a6 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/generated/lints.rs
@@ -12317,40 +12317,6 @@ will unnecessarily extend the stack frame.
         deny_since: None,
     },
     Lint {
-        label: "unsized_tuple_coercion",
-        description: r##"# `unsized_tuple_coercion`
-
-The tracking issue for this feature is: [#42877]
-
-[#42877]: https://github.com/rust-lang/rust/issues/42877
-
-------------------------
-
-This is a part of [RFC0401]. According to the RFC, there should be an implementation like this:
-
-```rust,ignore (partial-example)
-impl<..., T, U: ?Sized> Unsized<(..., U)> for (..., T) where T: Unsized<U> {}
-```
-
-This implementation is currently gated behind `#[feature(unsized_tuple_coercion)]` to avoid insta-stability. Therefore you can use it like this:
-
-```rust
-#![feature(unsized_tuple_coercion)]
-
-fn main() {
-    let x : ([i32; 3], [i32; 3]) = ([1, 2, 3], [4, 5, 6]);
-    let y : &([i32; 3], [i32]) = &x;
-    assert_eq!(y.1[0], 4);
-}
-```
-
-[RFC0401]: https://github.com/rust-lang/rfcs/blob/master/text/0401-coercions.md
-"##,
-        default_severity: Severity::Allow,
-        warn_since: None,
-        deny_since: None,
-    },
-    Lint {
         label: "unwrap_infallible",
         description: r##"# `unwrap_infallible`
 
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
index 3a29232d331..96115eee6dc 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/lib.rs
@@ -252,10 +252,10 @@ pub enum SymbolKind {
 impl From<hir::MacroKind> for SymbolKind {
     fn from(it: hir::MacroKind) -> Self {
         match it {
-            hir::MacroKind::Declarative | hir::MacroKind::BuiltIn => SymbolKind::Macro,
+            hir::MacroKind::Declarative | hir::MacroKind::DeclarativeBuiltIn => SymbolKind::Macro,
             hir::MacroKind::ProcMacro => SymbolKind::ProcMacro,
-            hir::MacroKind::Derive => SymbolKind::Derive,
-            hir::MacroKind::Attr => SymbolKind::Attribute,
+            hir::MacroKind::Derive | hir::MacroKind::DeriveBuiltIn => SymbolKind::Derive,
+            hir::MacroKind::Attr | hir::MacroKind::AttrBuiltIn => SymbolKind::Attribute,
         }
     }
 }
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
index f045e44dd31..126b30470b7 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/path_transform.rs
@@ -32,7 +32,7 @@ type DefaultedParam = Either<hir::TypeParam, hir::ConstParam>;
 /// block), you generally want to appropriately qualify the names, and sometimes
 /// you might want to substitute generic parameters as well:
 ///
-/// ```
+/// ```ignore
 /// mod x {
 ///   pub struct A<V>;
 ///   pub trait T<U> { fn foo(&self, _: U) -> A<U>; }
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/search.rs b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
index 7963e8ae4f7..02cd8b8bdf5 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/search.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/search.rs
@@ -373,7 +373,9 @@ impl Definition {
                         SearchScope::krate(db, module.krate())
                     }
                 }
-                hir::MacroKind::BuiltIn => SearchScope::crate_graph(db),
+                hir::MacroKind::AttrBuiltIn
+                | hir::MacroKind::DeriveBuiltIn
+                | hir::MacroKind::DeclarativeBuiltIn => SearchScope::crate_graph(db),
                 hir::MacroKind::Derive | hir::MacroKind::Attr | hir::MacroKind::ProcMacro => {
                     SearchScope::reverse_dependencies(db, module.krate())
                 }
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs
index 27ff91dc19d..34642d7eaf9 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/source_change.rs
@@ -493,7 +493,7 @@ pub enum Snippet {
     Placeholder(TextRange),
     /// A group of placeholder snippets, e.g.
     ///
-    /// ```no_run
+    /// ```ignore
     /// let ${0:new_var} = 4;
     /// fun(1, 2, 3, ${0:new_var});
     /// ```
diff --git a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs
index 0a7141c19b6..e085bf15cb9 100644
--- a/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs
+++ b/src/tools/rust-analyzer/crates/ide-db/src/syntax_helpers/suggest_name.rs
@@ -79,7 +79,9 @@ const USELESS_METHODS: &[&str] = &[
 /// the name, e.g. `a`, `a1`, `a2`, ...
 ///
 /// # Examples
-/// ```rust
+///
+/// ```
+/// # use ide_db::syntax_helpers::suggest_name::NameGenerator;
 /// let mut generator = NameGenerator::new();
 /// assert_eq!(generator.suggest_name("a"), "a");
 /// assert_eq!(generator.suggest_name("a"), "a1");
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml b/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml
index 281a08e5429..483cb6df862 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 cov-mark = "2.0.0-pre.1"
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 323a5723d4a..040aa2949aa 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
@@ -854,7 +854,7 @@ fn main() {
 #[target_feature(enable = "avx")]
 fn foo() {}
 
-#[target_feature(enable = "avx,avx2")]
+#[target_feature(enable = "avx2")]
 fn bar() {
     foo();
 }
diff --git a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
index 3ea41aa7e85..0a55b6e9bee 100644
--- a/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide-diagnostics/src/lib.rs
@@ -697,7 +697,7 @@ struct SeverityAttr {
     /// #[warn(non_snake_case)]
     /// mod foo {
     ///     #[allow(nonstandard_style)]
-    ///     mod bar;
+    ///     mod bar {}
     /// }
     /// ```
     /// We want to not warn on non snake case inside `bar`. If we are traversing this for the first
diff --git a/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml b/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml
index 25614676288..fa75e5a4214 100644
--- a/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide-ssr/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 cov-mark = "2.0.0-pre.1"
diff --git a/src/tools/rust-analyzer/crates/ide/Cargo.toml b/src/tools/rust-analyzer/crates/ide/Cargo.toml
index 7c66b36dc8e..9af56c40e98 100644
--- a/src/tools/rust-analyzer/crates/ide/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/ide/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 cov-mark = "2.0.0-pre.1"
diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
index e35e47e7471..8d2ca33bf25 100644
--- a/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/doc_links.rs
@@ -379,13 +379,15 @@ fn rewrite_intra_doc_link(
     let resolved = resolve_doc_path_for_def(db, def, link, ns)?;
     let mut url = get_doc_base_urls(db, resolved, None, None).0?;
 
-    let (_, file, _) = filename_and_frag_for_def(db, resolved)?;
+    let (_, file, frag) = filename_and_frag_for_def(db, resolved)?;
     if let Some(path) = mod_path_of_def(db, resolved) {
         url = url.join(&path).ok()?;
     }
 
+    let frag = anchor.or(frag.as_deref());
+
     url = url.join(&file).ok()?;
-    url.set_fragment(anchor);
+    url.set_fragment(frag);
 
     Some((url.into(), strip_prefixes_suffixes(title).to_owned()))
 }
@@ -621,11 +623,9 @@ fn filename_and_frag_for_def(
             format!("fn.{}.html", f.name(db).as_str())
         }
         Definition::Variant(ev) => {
-            format!(
-                "enum.{}.html#variant.{}",
-                ev.parent_enum(db).name(db).as_str(),
-                ev.name(db).as_str()
-            )
+            let def = Definition::Adt(ev.parent_enum(db).into());
+            let (_, file, _) = filename_and_frag_for_def(db, def)?;
+            return Some((def, file, Some(format!("variant.{}", ev.name(db).as_str()))));
         }
         Definition::Const(c) => {
             format!("const.{}.html", c.name(db)?.as_str())
@@ -635,12 +635,13 @@ fn filename_and_frag_for_def(
         }
         Definition::Macro(mac) => match mac.kind(db) {
             hir::MacroKind::Declarative
-            | hir::MacroKind::BuiltIn
+            | hir::MacroKind::AttrBuiltIn
+            | hir::MacroKind::DeclarativeBuiltIn
             | hir::MacroKind::Attr
             | hir::MacroKind::ProcMacro => {
                 format!("macro.{}.html", mac.name(db).as_str())
             }
-            hir::MacroKind::Derive => {
+            hir::MacroKind::Derive | hir::MacroKind::DeriveBuiltIn => {
                 format!("derive.{}.html", mac.name(db).as_str())
             }
         },
diff --git a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs
index d7291c4b9f3..b09e3a3c804 100644
--- a/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/doc_links/tests.rs
@@ -686,3 +686,95 @@ fn rewrite_intra_doc_link_with_anchor() {
         expect!["[PartialEq#derivable](https://doc.rust-lang.org/stable/core/cmp/trait.PartialEq.html#derivable)"],
     );
 }
+
+#[test]
+fn rewrite_intra_doc_link_to_associated_item() {
+    check_rewrite(
+        r#"
+//- /main.rs crate:foo
+/// [Foo::bar]
+pub struct $0Foo;
+
+impl Foo {
+    fn bar() {}
+}
+"#,
+        expect![[r#"[Foo::bar](https://docs.rs/foo/*/foo/struct.Foo.html#method.bar)"#]],
+    );
+    check_rewrite(
+        r#"
+//- /main.rs crate:foo
+/// [Foo::bar]
+pub struct $0Foo {
+    bar: ()
+}
+"#,
+        expect![[r#"[Foo::bar](https://docs.rs/foo/*/foo/struct.Foo.html#structfield.bar)"#]],
+    );
+    check_rewrite(
+        r#"
+//- /main.rs crate:foo
+/// [Foo::Bar]
+pub enum $0Foo {
+    Bar
+}
+"#,
+        expect![[r#"[Foo::Bar](https://docs.rs/foo/*/foo/enum.Foo.html#variant.Bar)"#]],
+    );
+    check_rewrite(
+        r#"
+//- /main.rs crate:foo
+/// [Foo::BAR]
+pub struct $0Foo;
+
+impl Foo {
+    const BAR: () = ();
+}
+"#,
+        expect![[
+            r#"[Foo::BAR](https://docs.rs/foo/*/foo/struct.Foo.html#associatedconstant.BAR)"#
+        ]],
+    );
+    check_rewrite(
+        r#"
+//- /main.rs crate:foo
+/// [Foo::bar]
+pub trait $0Foo {
+    fn bar();
+}
+"#,
+        expect![[r#"[Foo::bar](https://docs.rs/foo/*/foo/trait.Foo.html#tymethod.bar)"#]],
+    );
+    check_rewrite(
+        r#"
+//- /main.rs crate:foo
+/// [Foo::Bar]
+pub trait $0Foo {
+    type Bar;
+}
+"#,
+        expect![[r#"[Foo::Bar](https://docs.rs/foo/*/foo/trait.Foo.html#associatedtype.Bar)"#]],
+    );
+    check_rewrite(
+        r#"
+//- /main.rs crate:foo
+/// [Foo::bar#anchor]
+pub struct $0Foo {
+    bar: (),
+}
+"#,
+        expect![[r#"[Foo::bar#anchor](https://docs.rs/foo/*/foo/struct.Foo.html#anchor)"#]],
+    );
+    check_rewrite(
+        r#"
+//- /main.rs crate:foo
+/// [method](Foo::bar)
+pub struct $0Foo;
+
+impl Foo {
+    fn bar() {}
+}
+"#,
+        expect![[r#"[method](https://docs.rs/foo/*/foo/struct.Foo.html#method.bar)"#]],
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover.rs b/src/tools/rust-analyzer/crates/ide/src/hover.rs
index 95a720e7e45..9a3e77f3a93 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover.rs
@@ -38,6 +38,7 @@ pub struct HoverConfig {
     pub max_fields_count: Option<usize>,
     pub max_enum_variants_count: Option<usize>,
     pub max_subst_ty_len: SubstTyLen,
+    pub show_drop_glue: bool,
 }
 
 #[derive(Clone, Debug, PartialEq, Eq)]
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
index c996230c3a1..c5a83e58cea 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/render.rs
@@ -3,7 +3,7 @@ use std::{env, mem, ops::Not};
 
 use either::Either;
 use hir::{
-    db::ExpandDatabase, Adt, AsAssocItem, AsExternAssocItem, CaptureKind,
+    db::ExpandDatabase, Adt, AsAssocItem, AsExternAssocItem, CaptureKind, DropGlue,
     DynCompatibilityViolation, HasCrate, HasSource, HirDisplay, Layout, LayoutError,
     MethodViolationCode, Name, Semantics, Symbol, Trait, Type, TypeInfo, VariantDef,
 };
@@ -629,6 +629,89 @@ pub(super) fn definition(
         _ => None,
     };
 
+    let drop_info = || {
+        if !config.show_drop_glue {
+            return None;
+        }
+        let drop_info = match def {
+            Definition::Field(field) => {
+                DropInfo { drop_glue: field.ty(db).drop_glue(db), has_dtor: None }
+            }
+            Definition::Adt(Adt::Struct(strukt)) => {
+                let struct_drop_glue = strukt.ty_placeholders(db).drop_glue(db);
+                let mut fields_drop_glue = strukt
+                    .fields(db)
+                    .iter()
+                    .map(|field| field.ty(db).drop_glue(db))
+                    .max()
+                    .unwrap_or(DropGlue::None);
+                let has_dtor = match (fields_drop_glue, struct_drop_glue) {
+                    (DropGlue::None, _) => struct_drop_glue != DropGlue::None,
+                    (_, DropGlue::None) => {
+                        // This is `ManuallyDrop`.
+                        fields_drop_glue = DropGlue::None;
+                        false
+                    }
+                    (_, _) => struct_drop_glue > fields_drop_glue,
+                };
+                DropInfo { drop_glue: fields_drop_glue, has_dtor: Some(has_dtor) }
+            }
+            // Unions cannot have fields with drop glue.
+            Definition::Adt(Adt::Union(union)) => DropInfo {
+                drop_glue: DropGlue::None,
+                has_dtor: Some(union.ty_placeholders(db).drop_glue(db) != DropGlue::None),
+            },
+            Definition::Adt(Adt::Enum(enum_)) => {
+                let enum_drop_glue = enum_.ty_placeholders(db).drop_glue(db);
+                let fields_drop_glue = enum_
+                    .variants(db)
+                    .iter()
+                    .map(|variant| {
+                        variant
+                            .fields(db)
+                            .iter()
+                            .map(|field| field.ty(db).drop_glue(db))
+                            .max()
+                            .unwrap_or(DropGlue::None)
+                    })
+                    .max()
+                    .unwrap_or(DropGlue::None);
+                DropInfo {
+                    drop_glue: fields_drop_glue,
+                    has_dtor: Some(enum_drop_glue > fields_drop_glue),
+                }
+            }
+            Definition::Variant(variant) => {
+                let fields_drop_glue = variant
+                    .fields(db)
+                    .iter()
+                    .map(|field| field.ty(db).drop_glue(db))
+                    .max()
+                    .unwrap_or(DropGlue::None);
+                DropInfo { drop_glue: fields_drop_glue, has_dtor: None }
+            }
+            Definition::TypeAlias(type_alias) => {
+                DropInfo { drop_glue: type_alias.ty_placeholders(db).drop_glue(db), has_dtor: None }
+            }
+            Definition::Local(local) => {
+                DropInfo { drop_glue: local.ty(db).drop_glue(db), has_dtor: None }
+            }
+            _ => return None,
+        };
+        let rendered_drop_glue = match drop_info.drop_glue {
+            DropGlue::None => "does not contain types with destructors (drop glue)",
+            DropGlue::DependOnParams => {
+                "may contain types with destructors (drop glue) depending on type parameters"
+            }
+            DropGlue::HasDropGlue => "contain types with destructors (drop glue)",
+        };
+        Some(match drop_info.has_dtor {
+            Some(true) => format!("{}; has a destructor", rendered_drop_glue),
+            Some(false) => format!("{}; doesn't have a destructor", rendered_drop_glue),
+            None => rendered_drop_glue.to_owned(),
+        })
+    };
+
     let dyn_compatibility_info = || match def {
         Definition::Trait(it) => {
             let mut dyn_compatibility_info = String::new();
@@ -661,6 +744,10 @@ pub(super) fn definition(
             extra.push_str("\n___\n");
             extra.push_str(&dyn_compatibility_info);
         }
+        if let Some(drop_info) = drop_info() {
+            extra.push_str("\n___\n");
+            extra.push_str(&drop_info);
+        }
     }
     let mut desc = String::new();
     desc.push_str(&label);
@@ -703,6 +790,12 @@ pub(super) fn definition(
     )
 }
 
+#[derive(Debug)]
+struct DropInfo {
+    drop_glue: DropGlue,
+    has_dtor: Option<bool>,
+}
+
 pub(super) fn literal(
     sema: &Semantics<'_, RootDatabase>,
     token: SyntaxToken,
diff --git a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
index 8c32cc9720a..7c720d97cb6 100644
--- a/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/hover/tests.rs
@@ -21,6 +21,7 @@ const HOVER_BASE_CONFIG: HoverConfig = HoverConfig {
     max_fields_count: Some(5),
     max_enum_variants_count: Some(5),
     max_subst_ty_len: super::SubstTyLen::Unlimited,
+    show_drop_glue: true,
 };
 
 fn check_hover_no_result(#[rust_analyzer::rust_fixture] ra_fixture: &str) {
@@ -567,6 +568,10 @@ fn main() {
             ---
 
             size = 8, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -812,6 +817,10 @@ struct Foo { fiel$0d_a: u8, field_b: i32, field_c: i16 }
             ---
 
             size = 1, align = 1, offset = 6
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -863,6 +872,10 @@ fn main() {
             ---
 
             size = 4, align = 4, offset = 0
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -933,6 +946,10 @@ struct Foo$0(pub u32) where u32: Copy;
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
 }
@@ -959,6 +976,10 @@ struct Foo$0 { field: u32 }
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
     check(
@@ -984,6 +1005,10 @@ struct Foo$0 where u32: Copy { field: u32 }
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
 }
@@ -1013,6 +1038,10 @@ fn hover_record_struct_limit() {
             ---
 
             size = 12 (0xC), align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
     check_hover_fields_limit(
@@ -1036,6 +1065,10 @@ fn hover_record_struct_limit() {
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
     check_hover_fields_limit(
@@ -1062,6 +1095,10 @@ fn hover_record_struct_limit() {
             ---
 
             size = 16 (0x10), align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
     check_hover_fields_limit(
@@ -1083,6 +1120,10 @@ fn hover_record_struct_limit() {
             ---
 
             size = 12 (0xC), align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
     check_hover_fields_limit(
@@ -1104,6 +1145,10 @@ fn hover_record_struct_limit() {
             ---
 
             size = 12 (0xC), align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
 
@@ -1127,6 +1172,10 @@ fn hover_record_struct_limit() {
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
 }
@@ -1152,6 +1201,10 @@ fn hover_record_variant_limit() {
             ---
 
             size = 12 (0xC), align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
     check_hover_fields_limit(
@@ -1173,6 +1226,10 @@ fn hover_record_variant_limit() {
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
     check_hover_fields_limit(
@@ -1194,6 +1251,10 @@ fn hover_record_variant_limit() {
             ---
 
             size = 16 (0x10), align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
     check_hover_fields_limit(
@@ -1215,6 +1276,10 @@ fn hover_record_variant_limit() {
             ---
 
             size = 12 (0xC), align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
     check_hover_fields_limit(
@@ -1236,6 +1301,10 @@ fn hover_record_variant_limit() {
             ---
 
             size = 12 (0xC), align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -1262,6 +1331,10 @@ fn hover_enum_limit() {
             ---
 
             size = 1, align = 1, niches = 254
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
     check_hover_enum_variants_limit(
@@ -1284,6 +1357,10 @@ fn hover_enum_limit() {
             ---
 
             size = 1, align = 1, niches = 254
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
     check_hover_enum_variants_limit(
@@ -1303,6 +1380,10 @@ fn hover_enum_limit() {
             ---
 
             size = 1, align = 1, niches = 254
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
     check_hover_enum_variants_limit(
@@ -1322,6 +1403,10 @@ fn hover_enum_limit() {
             ---
 
             size = 1, align = 1, niches = 254
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
     check_hover_enum_variants_limit(
@@ -1359,6 +1444,10 @@ fn hover_enum_limit() {
             ---
 
             size = 12 (0xC), align = 4, niches = a lot
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
 }
@@ -1385,6 +1474,10 @@ fn hover_union_limit() {
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
     check_hover_fields_limit(
@@ -1407,6 +1500,10 @@ fn hover_union_limit() {
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
     check_hover_fields_limit(
@@ -1426,6 +1523,10 @@ fn hover_union_limit() {
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
     check_hover_fields_limit(
@@ -1445,6 +1546,10 @@ fn hover_union_limit() {
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
 }
@@ -1471,6 +1576,10 @@ struct Foo$0 where u32: Copy;
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
 }
@@ -1493,6 +1602,10 @@ type Fo$0o: Trait = S where T: Trait;
             where
                 T: Trait,
             ```
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -1642,6 +1755,10 @@ fn main() {
             ---
 
             size = 8, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
     check_hover_range(
@@ -1697,6 +1814,10 @@ fn main() { let b$0ar = Some(12); }
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -1724,6 +1845,10 @@ enum Option<T> {
 
             ---
 
+            does not contain types with destructors (drop glue)
+
+            ---
+
             The None variant
         "#]],
     );
@@ -1784,6 +1909,10 @@ fn hover_for_local_variable_pat() {
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     )
 }
@@ -1816,6 +1945,10 @@ fn hover_for_param_edge() {
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     )
 }
@@ -1838,6 +1971,10 @@ fn hover_for_param_with_multiple_traits() {
             ```rust
             _x: impl Deref<Target = u8> + DerefMut<Target = u8>
             ```
+
+            ---
+
+            may contain types with destructors (drop glue) depending on type parameters
         "#]],
     )
 }
@@ -1864,6 +2001,10 @@ fn main() { let foo_$0test = Thing::new(); }
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     )
 }
@@ -2613,6 +2754,10 @@ fn test_hover_function_pointer_show_identifiers() {
             ---
 
             size = 8, align = 8, niches = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -2635,6 +2780,10 @@ fn test_hover_function_pointer_no_identifier() {
             ---
 
             size = 8, align = 8, niches = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -2881,6 +3030,10 @@ pub struct B$0ar
 
             ---
 
+            does not contain types with destructors (drop glue); doesn't have a destructor
+
+            ---
+
             [external](https://www.google.com)
         "#]],
     );
@@ -2912,6 +3065,10 @@ pub struct B$0ar
 
             ---
 
+            does not contain types with destructors (drop glue); doesn't have a destructor
+
+            ---
+
             [baz](Baz)
         "#]],
     );
@@ -3002,6 +3159,10 @@ fn test_hover_layout_of_variant() {
             ---
 
             size = 4, align = 2
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -3023,6 +3184,10 @@ fn test_hover_layout_of_variant_generic() {
             ```rust
             None
             ```
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -3048,6 +3213,10 @@ struct S$0<T>(core::marker::PhantomData<T>);
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
 }
@@ -3076,6 +3245,10 @@ fn test_hover_layout_of_enum() {
             ---
 
             size = 16 (0x10), align = 8, niches = 254
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     );
 }
@@ -3094,6 +3267,10 @@ fn test_hover_no_memory_layout() {
             ```rust
             field_a: u8
             ```
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 
@@ -4405,6 +4582,10 @@ fn main() {
 
             ---
 
+            does not contain types with destructors (drop glue)
+
+            ---
+
             ```rust
             ra_test_fixture::S
             ```
@@ -4416,6 +4597,10 @@ fn main() {
             ---
 
             size = 4, align = 4, offset = 0
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -4441,6 +4626,10 @@ struct S$0T<const C: usize = 1, T = Foo>(T);
             ---
 
             size = 0, align = 1
+
+            ---
+
+            may contain types with destructors (drop glue) depending on type parameters; doesn't have a destructor
         "#]],
     );
 }
@@ -4466,6 +4655,10 @@ struct S$0T<const C: usize = {40 + 2}, T = Foo>(T);
             ---
 
             size = 0, align = 1
+
+            ---
+
+            may contain types with destructors (drop glue) depending on type parameters; doesn't have a destructor
         "#]],
     );
 }
@@ -4492,6 +4685,10 @@ struct S$0T<const C: usize = VAL, T = Foo>(T);
             ---
 
             size = 0, align = 1
+
+            ---
+
+            may contain types with destructors (drop glue) depending on type parameters; doesn't have a destructor
         "#]],
     );
 }
@@ -4516,6 +4713,10 @@ fn main() {
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -4540,6 +4741,10 @@ fn main() {
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -4564,6 +4769,10 @@ fn main() {
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -4588,6 +4797,10 @@ fn main() {
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -4612,6 +4825,10 @@ fn main() {
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -4635,6 +4852,10 @@ impl Foo {
             ---
 
             size = 8, align = 8, niches = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -4659,6 +4880,10 @@ impl Foo {
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -5149,6 +5374,10 @@ type Fo$0o2 = Foo<2>;
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -5202,6 +5431,10 @@ enum E {
 
             ---
 
+            does not contain types with destructors (drop glue)
+
+            ---
+
             This is a doc
         "#]],
     );
@@ -5231,6 +5464,10 @@ enum E {
 
             ---
 
+            does not contain types with destructors (drop glue)
+
+            ---
+
             This is a doc
         "#]],
     );
@@ -5261,6 +5498,10 @@ enum E {
 
             ---
 
+            does not contain types with destructors (drop glue)
+
+            ---
+
             This is a doc
         "#]],
     );
@@ -5291,6 +5532,10 @@ enum E {
 
             ---
 
+            does not contain types with destructors (drop glue)
+
+            ---
+
             This is a doc
         "#]],
     );
@@ -6219,6 +6464,10 @@ fn main() {
             ---
 
             size = 32 (0x20), align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -7518,6 +7767,10 @@ enum Enum {
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -7544,6 +7797,10 @@ enum Enum {
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -8214,6 +8471,10 @@ fn test() {
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -8863,6 +9124,10 @@ fn main(notable$0: u32) {}
             ---
 
             size = 4, align = 4
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -8955,6 +9220,10 @@ extern "C" {
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -9101,6 +9370,10 @@ struct Pedro$0<'a> {
             ---
 
             size = 16 (0x10), align = 8, niches = 1
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
         "#]],
     )
 }
@@ -9118,6 +9391,10 @@ fn main(a$0: impl T) {}
             ```rust
             a: impl T + ?Sized
             ```
+
+            ---
+
+            may contain types with destructors (drop glue) depending on type parameters
         "#]],
     );
 }
@@ -9139,6 +9416,10 @@ fn main(a$0: T) {}
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -9192,6 +9473,10 @@ fn main() {
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -9529,6 +9814,10 @@ type A$0 = B;
 
             ---
 
+            does not contain types with destructors (drop glue)
+
+            ---
+
             *This is the documentation for* `struct B`
 
             Docs for B
@@ -9562,6 +9851,10 @@ type A$0 = B;
 
             ---
 
+            does not contain types with destructors (drop glue)
+
+            ---
+
             *This is the documentation for* `struct C`
 
             Docs for C
@@ -9596,6 +9889,10 @@ type A$0 = B;
 
             ---
 
+            does not contain types with destructors (drop glue)
+
+            ---
+
             *This is the documentation for* `struct C`
 
             Docs for C
@@ -9625,6 +9922,10 @@ type A$0 = B;
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 
@@ -9749,6 +10050,10 @@ fn main() {
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 
@@ -9777,6 +10082,10 @@ fn main() {
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 
@@ -9812,6 +10121,10 @@ fn main() {
             ---
 
             size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
         "#]],
     );
 }
@@ -10134,6 +10447,10 @@ fn bar() {
 
             ---
 
+            does not contain types with destructors (drop glue)
+
+            ---
+
             ```rust
             ra_test_fixture::Foo
             ```
@@ -10144,6 +10461,10 @@ fn bar() {
 
             ---
 
+            may contain types with destructors (drop glue) depending on type parameters
+
+            ---
+
             `T` = `i32`
         "#]],
     );
@@ -10353,3 +10674,276 @@ macro_rules! str {
         "#]],
     );
 }
+
+#[test]
+fn drop_glue() {
+    check(
+        r#"
+struct NoDrop$0;
+    "#,
+        expect![[r#"
+            *NoDrop*
+
+            ```rust
+            ra_test_fixture
+            ```
+
+            ```rust
+            struct NoDrop
+            ```
+
+            ---
+
+            size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
+        "#]],
+    );
+    check(
+        r#"
+//- minicore: drop
+struct NeedsDrop$0;
+impl Drop for NeedsDrop {
+    fn drop(&mut self) {}
+}
+    "#,
+        expect![[r#"
+            *NeedsDrop*
+
+            ```rust
+            ra_test_fixture
+            ```
+
+            ```rust
+            struct NeedsDrop
+            ```
+
+            ---
+
+            size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue); has a destructor
+        "#]],
+    );
+    check(
+        r#"
+//- minicore: manually_drop, drop
+struct NeedsDrop;
+impl Drop for NeedsDrop {
+    fn drop(&mut self) {}
+}
+type NoDrop$0 = core::mem::ManuallyDrop<NeedsDrop>;
+    "#,
+        expect![[r#"
+            *NoDrop*
+
+            ```rust
+            ra_test_fixture
+            ```
+
+            ```rust
+            type NoDrop = core::mem::ManuallyDrop<NeedsDrop>
+            ```
+
+            ---
+
+            size = 0, align = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
+        "#]],
+    );
+    check(
+        r#"
+//- minicore: drop
+struct NeedsDrop;
+impl Drop for NeedsDrop {
+    fn drop(&mut self) {}
+}
+struct DropField$0 {
+    _x: i32,
+    _y: NeedsDrop,
+}
+    "#,
+        expect![[r#"
+            *DropField*
+
+            ```rust
+            ra_test_fixture
+            ```
+
+            ```rust
+            struct DropField {
+                _x: i32,
+                _y: NeedsDrop,
+            }
+            ```
+
+            ---
+
+            size = 4, align = 4
+
+            ---
+
+            contain types with destructors (drop glue); doesn't have a destructor
+        "#]],
+    );
+    check(
+        r#"
+//- minicore: sized
+type Foo$0 = impl Sized;
+    "#,
+        expect![[r#"
+            *Foo*
+
+            ```rust
+            ra_test_fixture
+            ```
+
+            ```rust
+            type Foo = impl Sized
+            ```
+
+            ---
+
+            contain types with destructors (drop glue)
+        "#]],
+    );
+    check(
+        r#"
+//- minicore: drop
+struct NeedsDrop;
+impl Drop for NeedsDrop {
+    fn drop(&mut self) {}
+}
+enum Enum {
+    A$0(&'static str),
+    B(NeedsDrop)
+}
+    "#,
+        expect![[r#"
+            *A*
+
+            ```rust
+            ra_test_fixture::Enum
+            ```
+
+            ```rust
+            A(&'static str)
+            ```
+
+            ---
+
+            size = 16 (0x10), align = 8, niches = 1
+
+            ---
+
+            does not contain types with destructors (drop glue)
+        "#]],
+    );
+    check(
+        r#"
+struct Foo$0<T>(T);
+    "#,
+        expect![[r#"
+            *Foo*
+
+            ```rust
+            ra_test_fixture
+            ```
+
+            ```rust
+            struct Foo<T>(T)
+            ```
+
+            ---
+
+            may contain types with destructors (drop glue) depending on type parameters; doesn't have a destructor
+        "#]],
+    );
+    check(
+        r#"
+//- minicore: copy
+struct Foo$0<T: Copy>(T);
+    "#,
+        expect![[r#"
+            *Foo*
+
+            ```rust
+            ra_test_fixture
+            ```
+
+            ```rust
+            struct Foo<T>(T)
+            where
+                T: Copy,
+            ```
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
+        "#]],
+    );
+    check(
+        r#"
+//- minicore: copy
+trait Trait {
+    type Assoc: Copy;
+}
+struct Foo$0<T: Trait>(T::Assoc);
+    "#,
+        expect![[r#"
+            *Foo*
+
+            ```rust
+            ra_test_fixture
+            ```
+
+            ```rust
+            struct Foo<T>(<T as Trait>::Assoc)
+            where
+                T: Trait,
+            ```
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
+        "#]],
+    );
+    check(
+        r#"
+#[rustc_coherence_is_core]
+
+#[lang = "manually_drop"]
+#[repr(transparent)]
+pub struct ManuallyDrop$0<T: ?Sized> {
+    value: T,
+}
+    "#,
+        expect![[r#"
+            *ManuallyDrop*
+
+            ```rust
+            ra_test_fixture
+            ```
+
+            ```rust
+            pub struct ManuallyDrop<T>
+            where
+                T: ?Sized,
+            {
+                value: T,
+            }
+            ```
+
+            ---
+
+            does not contain types with destructors (drop glue); doesn't have a destructor
+        "#]],
+    );
+}
diff --git a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
index d3b95750f7e..8522ef0a6d5 100644
--- a/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/inlay_hints/adjustment.rs
@@ -258,27 +258,25 @@ fn mode_and_needs_parens_for_adjustment_hints(
 fn needs_parens_for_adjustment_hints(expr: &ast::Expr, postfix: bool) -> (bool, bool) {
     let prec = expr.precedence();
     if postfix {
-        // postfix ops have higher precedence than any other operator, so we need to wrap
-        // any inner expression that is below (except for jumps if they don't have a value)
-        let needs_inner_parens = prec < ExprPrecedence::Unambiguous && {
-            prec != ExprPrecedence::Jump || !expr.is_ret_like_with_no_value()
-        };
+        let needs_inner_parens = prec.needs_parentheses_in(ExprPrecedence::Postfix);
         // given we are the higher precedence, no parent expression will have stronger requirements
         let needs_outer_parens = false;
         (needs_outer_parens, needs_inner_parens)
     } else {
-        // We need to wrap all binary like things, thats everything below prefix except for jumps
-        let needs_inner_parens = prec < ExprPrecedence::Prefix && prec != ExprPrecedence::Jump;
+        let needs_inner_parens = prec.needs_parentheses_in(ExprPrecedence::Prefix);
         let parent = expr
             .syntax()
             .parent()
             .and_then(ast::Expr::cast)
             // if we are already wrapped, great, no need to wrap again
             .filter(|it| !matches!(it, ast::Expr::ParenExpr(_)))
-            .map(|it| it.precedence());
+            .map(|it| it.precedence())
+            .filter(|&prec| prec != ExprPrecedence::Unambiguous);
+
         // if we have no parent, we don't need outer parens to disambiguate
         // otherwise anything with higher precedence than what we insert needs to wrap us
-        let needs_outer_parens = parent.is_some_and(|prec| prec > ExprPrecedence::Prefix);
+        let needs_outer_parens = parent
+            .is_some_and(|parent_prec| ExprPrecedence::Prefix.needs_parentheses_in(parent_prec));
         (needs_outer_parens, needs_inner_parens)
     }
 }
@@ -291,7 +289,7 @@ mod tests {
     };
 
     #[test]
-    fn adjustment_hints() {
+    fn adjustment_hints_prefix() {
         check_with_config(
             InlayHintsConfig { adjustment_hints: AdjustmentHints::Always, ..DISABLED_CONFIG },
             r#"
@@ -381,6 +379,8 @@ fn main() {
     &mut Struct[0];
        //^^^^^^(&mut $
        //^^^^^^)
+    let _: (&mut (),) = (&mut (),);
+                       //^^^^^^^&mut *
 }
 
 #[derive(Copy, Clone)]
@@ -472,6 +472,9 @@ fn main() {
   //^^^^^^.&
     &mut Struct[0];
        //^^^^^^.&mut
+    let _: (&mut (),) = (&mut (),);
+                       //^^^^^^^(
+                       //^^^^^^^).*.&mut
 }
 
 #[derive(Copy, Clone)]
diff --git a/src/tools/rust-analyzer/crates/ide/src/lib.rs b/src/tools/rust-analyzer/crates/ide/src/lib.rs
index 27a1a510b4f..8ac1a96cc65 100644
--- a/src/tools/rust-analyzer/crates/ide/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/lib.rs
@@ -104,7 +104,7 @@ pub use crate::{
     navigation_target::{NavigationTarget, TryToNav, UpmappingResult},
     references::ReferenceSearchResult,
     rename::RenameError,
-    runnables::{Runnable, RunnableKind, TestId},
+    runnables::{Runnable, RunnableKind, TestId, UpdateTest},
     signature_help::SignatureHelp,
     static_index::{
         StaticIndex, StaticIndexedFile, TokenId, TokenStaticData, VendoredLibrariesConfig,
diff --git a/src/tools/rust-analyzer/crates/ide/src/moniker.rs b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
index 66ea49a98a0..25d12a4c0b4 100644
--- a/src/tools/rust-analyzer/crates/ide/src/moniker.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/moniker.rs
@@ -184,11 +184,11 @@ pub(crate) fn def_to_kind(db: &RootDatabase, def: Definition) -> SymbolInformati
 
     match def {
         Definition::Macro(it) => match it.kind(db) {
-            MacroKind::Declarative => Macro,
-            MacroKind::Derive => Attribute,
-            MacroKind::BuiltIn => Macro,
-            MacroKind::Attr => Attribute,
-            MacroKind::ProcMacro => Macro,
+            MacroKind::Derive
+            | MacroKind::DeriveBuiltIn
+            | MacroKind::AttrBuiltIn
+            | MacroKind::Attr => Attribute,
+            MacroKind::Declarative | MacroKind::DeclarativeBuiltIn | MacroKind::ProcMacro => Macro,
         },
         Definition::Field(..) | Definition::TupleField(..) => Field,
         Definition::Module(..) | Definition::Crate(..) => Module,
diff --git a/src/tools/rust-analyzer/crates/ide/src/static_index.rs b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
index 07553a87d28..41957bad7e0 100644
--- a/src/tools/rust-analyzer/crates/ide/src/static_index.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/static_index.rs
@@ -187,6 +187,7 @@ impl StaticIndex<'_> {
             max_fields_count: Some(5),
             max_enum_variants_count: Some(5),
             max_subst_ty_len: SubstTyLen::Unlimited,
+            show_drop_glue: true,
         };
         let tokens = tokens.filter(|token| {
             matches!(
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
index 1853e3a3407..519133e3ad1 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting.rs
@@ -7,7 +7,6 @@ mod escape;
 mod format;
 mod highlight;
 mod inject;
-mod macro_;
 
 mod html;
 #[cfg(test)]
@@ -15,14 +14,14 @@ mod tests;
 
 use std::ops::ControlFlow;
 
-use hir::{InRealFile, Name, Semantics};
+use hir::{HirFileIdExt, InFile, InRealFile, MacroFileIdExt, MacroKind, Name, Semantics};
 use ide_db::{FxHashMap, Ranker, RootDatabase, SymbolKind};
 use span::EditionedFileId;
 use syntax::{
     ast::{self, IsString},
     AstNode, AstToken, NodeOrToken,
     SyntaxKind::*,
-    SyntaxNode, TextRange, WalkEvent, T,
+    SyntaxNode, SyntaxToken, TextRange, WalkEvent, T,
 };
 
 use crate::{
@@ -30,7 +29,6 @@ use crate::{
         escape::{highlight_escape_byte, highlight_escape_char, highlight_escape_string},
         format::highlight_format_string,
         highlights::Highlights,
-        macro_::MacroHighlighter,
         tags::Highlight,
     },
     FileId, HlMod, HlOperator, HlPunct, HlTag,
@@ -221,7 +219,7 @@ pub(crate) fn highlight(
         Some(it) => it.krate(),
         None => return hl.to_vec(),
     };
-    traverse(&mut hl, &sema, config, file_id, &root, krate, range_to_highlight);
+    traverse(&mut hl, &sema, config, InRealFile::new(file_id, &root), krate, range_to_highlight);
     hl.to_vec()
 }
 
@@ -229,8 +227,7 @@ fn traverse(
     hl: &mut Highlights,
     sema: &Semantics<'_, RootDatabase>,
     config: HighlightConfig,
-    file_id: EditionedFileId,
-    root: &SyntaxNode,
+    InRealFile { file_id, value: root }: InRealFile<&SyntaxNode>,
     krate: hir::Crate,
     range_to_highlight: TextRange,
 ) {
@@ -252,18 +249,15 @@ fn traverse(
 
     let mut tt_level = 0;
     let mut attr_or_derive_item = None;
-    let mut current_macro: Option<ast::Macro> = None;
-    let mut macro_highlighter = MacroHighlighter::default();
 
     // FIXME: these are not perfectly accurate, we determine them by the real file's syntax tree
     // an attribute nested in a macro call will not emit `inside_attribute`
     let mut inside_attribute = false;
-    let mut inside_macro_call = false;
-    let mut inside_proc_macro_call = false;
 
     // Walk all nodes, keeping track of whether we are inside a macro or not.
     // If in macro, expand it first and highlight the expanded code.
-    for event in root.preorder_with_tokens() {
+    let mut preorder = root.preorder_with_tokens();
+    while let Some(event) = preorder.next() {
         use WalkEvent::{Enter, Leave};
 
         let range = match &event {
@@ -275,16 +269,11 @@ fn traverse(
             continue;
         }
 
-        // set macro and attribute highlighting states
         match event.clone() {
-            Enter(NodeOrToken::Node(node))
-                if current_macro.is_none() && ast::TokenTree::can_cast(node.kind()) =>
-            {
+            Enter(NodeOrToken::Node(node)) if ast::TokenTree::can_cast(node.kind()) => {
                 tt_level += 1;
             }
-            Leave(NodeOrToken::Node(node))
-                if current_macro.is_none() && ast::TokenTree::can_cast(node.kind()) =>
-            {
+            Leave(NodeOrToken::Node(node)) if ast::TokenTree::can_cast(node.kind()) => {
                 tt_level -= 1;
             }
             Enter(NodeOrToken::Node(node)) if ast::Attr::can_cast(node.kind()) => {
@@ -297,28 +286,14 @@ fn traverse(
             Enter(NodeOrToken::Node(node)) => {
                 if let Some(item) = ast::Item::cast(node.clone()) {
                     match item {
-                        ast::Item::MacroRules(mac) => {
-                            macro_highlighter.init();
-                            current_macro = Some(mac.into());
-                            continue;
-                        }
-                        ast::Item::MacroDef(mac) => {
-                            macro_highlighter.init();
-                            current_macro = Some(mac.into());
-                            continue;
-                        }
                         ast::Item::Fn(_) | ast::Item::Const(_) | ast::Item::Static(_) => {
                             bindings_shadow_count.clear()
                         }
-                        ast::Item::MacroCall(ref macro_call) => {
-                            inside_macro_call = true;
-                            inside_proc_macro_call = sema.is_proc_macro_call(macro_call);
-                        }
                         _ => (),
                     }
 
                     if attr_or_derive_item.is_none() {
-                        if sema.is_attr_macro_call(&item) {
+                        if sema.is_attr_macro_call(InFile::new(file_id.into(), &item)) {
                             attr_or_derive_item = Some(AttrOrDerive::Attr(item));
                         } else {
                             let adt = match item {
@@ -328,7 +303,10 @@ fn traverse(
                                 _ => None,
                             };
                             match adt {
-                                Some(adt) if sema.is_derive_annotated(&adt) => {
+                                Some(adt)
+                                    if sema
+                                        .is_derive_annotated(InFile::new(file_id.into(), &adt)) =>
+                                {
                                     attr_or_derive_item =
                                         Some(AttrOrDerive::Derive(ast::Item::from(adt)));
                                 }
@@ -340,25 +318,11 @@ fn traverse(
             }
             Leave(NodeOrToken::Node(node)) if ast::Item::can_cast(node.kind()) => {
                 match ast::Item::cast(node.clone()) {
-                    Some(ast::Item::MacroRules(mac)) => {
-                        assert_eq!(current_macro, Some(mac.into()));
-                        current_macro = None;
-                        macro_highlighter = MacroHighlighter::default();
-                    }
-                    Some(ast::Item::MacroDef(mac)) => {
-                        assert_eq!(current_macro, Some(mac.into()));
-                        current_macro = None;
-                        macro_highlighter = MacroHighlighter::default();
-                    }
                     Some(item)
                         if attr_or_derive_item.as_ref().is_some_and(|it| *it.item() == item) =>
                     {
                         attr_or_derive_item = None;
                     }
-                    Some(ast::Item::MacroCall(_)) => {
-                        inside_macro_call = false;
-                        inside_proc_macro_call = false;
-                    }
                     _ => (),
                 }
             }
@@ -379,12 +343,6 @@ fn traverse(
             }
         };
 
-        if current_macro.is_some() {
-            if let Some(tok) = element.as_token() {
-                macro_highlighter.advance(tok);
-            }
-        }
-
         let element = match element.clone() {
             NodeOrToken::Node(n) => match ast::NameLike::cast(n) {
                 Some(n) => NodeOrToken::Node(n),
@@ -392,7 +350,7 @@ fn traverse(
             },
             NodeOrToken::Token(t) => NodeOrToken::Token(t),
         };
-        let token = element.as_token().cloned();
+        let original_token = element.as_token().cloned();
 
         // Descending tokens into macros is expensive even if no descending occurs, so make sure
         // that we actually are in a position where descending is possible.
@@ -405,144 +363,52 @@ fn traverse(
 
         let descended_element = if in_macro {
             // Attempt to descend tokens into macro-calls.
-            let res = match element {
-                NodeOrToken::Token(token) if token.kind() != COMMENT => {
-                    let ranker = Ranker::from_token(&token);
-
-                    let mut t = None;
-                    let mut r = 0;
-                    sema.descend_into_macros_breakable(
-                        InRealFile::new(file_id, token.clone()),
-                        |tok, _ctx| {
-                            // FIXME: Consider checking ctx transparency for being opaque?
-                            let tok = tok.value;
-                            let my_rank = ranker.rank_token(&tok);
-
-                            if my_rank >= Ranker::MAX_RANK {
-                                // a rank of 0b1110 means that we have found a maximally interesting
-                                // token so stop early.
-                                t = Some(tok);
-                                return ControlFlow::Break(());
-                            }
-
-                            // r = r.max(my_rank);
-                            // t = Some(t.take_if(|_| r < my_rank).unwrap_or(tok));
-                            match &mut t {
-                                Some(prev) if r < my_rank => {
-                                    *prev = tok;
-                                    r = my_rank;
-                                }
-                                Some(_) => (),
-                                None => {
-                                    r = my_rank;
-                                    t = Some(tok)
-                                }
-                            }
-                            ControlFlow::Continue(())
-                        },
-                    );
-
-                    let token = t.unwrap_or(token);
-                    match token.parent().and_then(ast::NameLike::cast) {
-                        // Remap the token into the wrapping single token nodes
-                        Some(parent) => match (token.kind(), parent.syntax().kind()) {
-                            (T![self] | T![ident], NAME | NAME_REF) => NodeOrToken::Node(parent),
-                            (T![self] | T![super] | T![crate] | T![Self], NAME_REF) => {
-                                NodeOrToken::Node(parent)
-                            }
-                            (INT_NUMBER, NAME_REF) => NodeOrToken::Node(parent),
-                            (LIFETIME_IDENT, LIFETIME) => NodeOrToken::Node(parent),
-                            _ => NodeOrToken::Token(token),
-                        },
-                        None => NodeOrToken::Token(token),
-                    }
-                }
-                e => e,
-            };
-            res
+            match element {
+                NodeOrToken::Token(token) => descend_token(sema, InRealFile::new(file_id, token)),
+                n => InFile::new(file_id.into(), n),
+            }
         } else {
-            element
+            InFile::new(file_id.into(), element)
         };
 
-        // FIXME: do proper macro def highlighting https://github.com/rust-lang/rust-analyzer/issues/6232
-        // Skip metavariables from being highlighted to prevent keyword highlighting in them
-        if descended_element.as_token().and_then(|t| macro_highlighter.highlight(t)).is_some() {
-            continue;
+        // string highlight injections
+        if let (Some(original_token), Some(descended_token)) =
+            (original_token, descended_element.value.as_token())
+        {
+            let control_flow = string_injections(
+                hl,
+                sema,
+                config,
+                file_id,
+                krate,
+                original_token,
+                descended_token,
+            );
+            if control_flow.is_break() {
+                continue;
+            }
         }
 
-        // string highlight injections, note this does not use the descended element as proc-macros
-        // can rewrite string literals which invalidates our indices
-        if let (Some(token), Some(descended_token)) = (token, descended_element.as_token()) {
-            if ast::String::can_cast(token.kind()) && ast::String::can_cast(descended_token.kind())
-            {
-                let string = ast::String::cast(token);
-                let string_to_highlight = ast::String::cast(descended_token.clone());
-                if let Some((string, expanded_string)) = string.zip(string_to_highlight) {
-                    if string.is_raw()
-                        && inject::ra_fixture(hl, sema, config, &string, &expanded_string).is_some()
-                    {
-                        continue;
-                    }
-                    highlight_format_string(
-                        hl,
-                        sema,
-                        krate,
-                        &string,
-                        &expanded_string,
-                        range,
-                        file_id.edition(),
-                    );
-
-                    if !string.is_raw() {
-                        highlight_escape_string(hl, &string, range.start());
-                    }
-                }
-            } else if ast::ByteString::can_cast(token.kind())
-                && ast::ByteString::can_cast(descended_token.kind())
-            {
-                if let Some(byte_string) = ast::ByteString::cast(token) {
-                    if !byte_string.is_raw() {
-                        highlight_escape_string(hl, &byte_string, range.start());
-                    }
+        let edition = descended_element.file_id.edition(sema.db);
+        let element = match descended_element.value {
+            NodeOrToken::Node(name_like) => {
+                let hl = highlight::name_like(
+                    sema,
+                    krate,
+                    &mut bindings_shadow_count,
+                    config.syntactic_name_ref_highlighting,
+                    name_like,
+                    edition,
+                );
+                if hl.is_some() && !in_macro {
+                    // skip highlighting the contained token of our name-like node
+                    // as that would potentially overwrite our result
+                    preorder.skip_subtree();
                 }
-            } else if ast::CString::can_cast(token.kind())
-                && ast::CString::can_cast(descended_token.kind())
-            {
-                if let Some(c_string) = ast::CString::cast(token) {
-                    if !c_string.is_raw() {
-                        highlight_escape_string(hl, &c_string, range.start());
-                    }
-                }
-            } else if ast::Char::can_cast(token.kind())
-                && ast::Char::can_cast(descended_token.kind())
-            {
-                let Some(char) = ast::Char::cast(token) else {
-                    continue;
-                };
-
-                highlight_escape_char(hl, &char, range.start())
-            } else if ast::Byte::can_cast(token.kind())
-                && ast::Byte::can_cast(descended_token.kind())
-            {
-                let Some(byte) = ast::Byte::cast(token) else {
-                    continue;
-                };
-
-                highlight_escape_byte(hl, &byte, range.start())
+                hl
             }
-        }
-
-        let element = match descended_element {
-            NodeOrToken::Node(name_like) => highlight::name_like(
-                sema,
-                krate,
-                &mut bindings_shadow_count,
-                config.syntactic_name_ref_highlighting,
-                name_like,
-                file_id.edition(),
-            ),
             NodeOrToken::Token(token) => {
-                highlight::token(sema, token, file_id.edition()).zip(Some(None))
+                highlight::token(sema, token, edition, tt_level > 0).zip(Some(None))
             }
         };
         if let Some((mut highlight, binding_hash)) = element {
@@ -551,13 +417,6 @@ fn traverse(
                 // let the editor do its highlighting for these tokens instead
                 continue;
             }
-            if highlight.tag == HlTag::UnresolvedReference
-                && matches!(attr_or_derive_item, Some(AttrOrDerive::Derive(_)) if inside_attribute)
-            {
-                // do not emit unresolved references in derive helpers if the token mapping maps to
-                // something unresolvable. FIXME: There should be a way to prevent that
-                continue;
-            }
 
             // apply config filtering
             if !filter_by_config(&mut highlight, config) {
@@ -567,8 +426,9 @@ fn traverse(
             if inside_attribute {
                 highlight |= HlMod::Attribute
             }
-            if inside_macro_call && tt_level > 0 {
-                if inside_proc_macro_call {
+            if let Some(m) = descended_element.file_id.macro_file() {
+                if let MacroKind::ProcMacro | MacroKind::Attr | MacroKind::Derive = m.kind(sema.db)
+                {
                     highlight |= HlMod::ProcMacro
                 }
                 highlight |= HlMod::Macro
@@ -579,6 +439,99 @@ fn traverse(
     }
 }
 
+fn string_injections(
+    hl: &mut Highlights,
+    sema: &Semantics<'_, RootDatabase>,
+    config: HighlightConfig,
+    file_id: EditionedFileId,
+    krate: hir::Crate,
+    token: SyntaxToken,
+    descended_token: &SyntaxToken,
+) -> ControlFlow<()> {
+    if !matches!(token.kind(), STRING | BYTE_STRING | BYTE | CHAR | C_STRING) {
+        return ControlFlow::Continue(());
+    }
+    if let Some(string) = ast::String::cast(token.clone()) {
+        if let Some(descended_string) = ast::String::cast(descended_token.clone()) {
+            if string.is_raw()
+                && inject::ra_fixture(hl, sema, config, &string, &descended_string).is_some()
+            {
+                return ControlFlow::Break(());
+            }
+            highlight_format_string(hl, sema, krate, &string, &descended_string, file_id.edition());
+
+            if !string.is_raw() {
+                highlight_escape_string(hl, &string);
+            }
+        }
+    } else if let Some(byte_string) = ast::ByteString::cast(token.clone()) {
+        if !byte_string.is_raw() {
+            highlight_escape_string(hl, &byte_string);
+        }
+    } else if let Some(c_string) = ast::CString::cast(token.clone()) {
+        if !c_string.is_raw() {
+            highlight_escape_string(hl, &c_string);
+        }
+    } else if let Some(char) = ast::Char::cast(token.clone()) {
+        highlight_escape_char(hl, &char)
+    } else if let Some(byte) = ast::Byte::cast(token) {
+        highlight_escape_byte(hl, &byte)
+    }
+    ControlFlow::Continue(())
+}
+
+fn descend_token(
+    sema: &Semantics<'_, RootDatabase>,
+    token: InRealFile<SyntaxToken>,
+) -> InFile<NodeOrToken<ast::NameLike, SyntaxToken>> {
+    if token.value.kind() == COMMENT {
+        return token.map(NodeOrToken::Token).into();
+    }
+    let ranker = Ranker::from_token(&token.value);
+
+    let mut t = None;
+    let mut r = 0;
+    sema.descend_into_macros_breakable(token.clone(), |tok, _ctx| {
+        // FIXME: Consider checking ctx transparency for being opaque?
+        let my_rank = ranker.rank_token(&tok.value);
+
+        if my_rank >= Ranker::MAX_RANK {
+            // a rank of 0b1110 means that we have found a maximally interesting
+            // token so stop early.
+            t = Some(tok);
+            return ControlFlow::Break(());
+        }
+
+        // r = r.max(my_rank);
+        // t = Some(t.take_if(|_| r < my_rank).unwrap_or(tok));
+        match &mut t {
+            Some(prev) if r < my_rank => {
+                *prev = tok;
+                r = my_rank;
+            }
+            Some(_) => (),
+            None => {
+                r = my_rank;
+                t = Some(tok)
+            }
+        }
+        ControlFlow::Continue(())
+    });
+
+    let token = t.unwrap_or_else(|| token.into());
+    token.map(|token| match token.parent().and_then(ast::NameLike::cast) {
+        // Remap the token into the wrapping single token nodes
+        Some(parent) => match (token.kind(), parent.syntax().kind()) {
+            (T![ident] | T![self], NAME)
+            | (T![ident] | T![self] | T![super] | T![crate] | T![Self], NAME_REF)
+            | (INT_NUMBER, NAME_REF)
+            | (LIFETIME_IDENT, LIFETIME) => NodeOrToken::Node(parent),
+            _ => NodeOrToken::Token(token),
+        },
+        None => NodeOrToken::Token(token),
+    })
+}
+
 fn filter_by_config(highlight: &mut Highlight, config: HighlightConfig) -> bool {
     match &mut highlight.tag {
         HlTag::StringLiteral if !config.strings => return false,
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs
index 552ce9cd8c3..094f88f3a86 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/escape.rs
@@ -4,12 +4,9 @@ use crate::{HlRange, HlTag};
 use syntax::ast::{Byte, Char, IsString};
 use syntax::{AstToken, TextRange, TextSize};
 
-pub(super) fn highlight_escape_string<T: IsString>(
-    stack: &mut Highlights,
-    string: &T,
-    start: TextSize,
-) {
+pub(super) fn highlight_escape_string<T: IsString>(stack: &mut Highlights, string: &T) {
     let text = string.text();
+    let start = string.syntax().text_range().start();
     string.escaped_char_ranges(&mut |piece_range, char| {
         if text[piece_range.start().into()..].starts_with('\\') {
             let highlight = match char {
@@ -25,7 +22,7 @@ pub(super) fn highlight_escape_string<T: IsString>(
     });
 }
 
-pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char, start: TextSize) {
+pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char) {
     if char.value().is_err() {
         // We do not emit invalid escapes highlighting here. The lexer would likely be in a bad
         // state and this token contains junk, since `'` is not a reliable delimiter (consider
@@ -42,11 +39,14 @@ pub(super) fn highlight_escape_char(stack: &mut Highlights, char: &Char, start:
         return;
     };
 
-    let range = TextRange::at(start + TextSize::from(1), TextSize::from(text.len() as u32));
+    let range = TextRange::at(
+        char.syntax().text_range().start() + TextSize::from(1),
+        TextSize::from(text.len() as u32),
+    );
     stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None })
 }
 
-pub(super) fn highlight_escape_byte(stack: &mut Highlights, byte: &Byte, start: TextSize) {
+pub(super) fn highlight_escape_byte(stack: &mut Highlights, byte: &Byte) {
     if byte.value().is_err() {
         // See `highlight_escape_char` for why no error highlighting here.
         return;
@@ -61,6 +61,9 @@ pub(super) fn highlight_escape_byte(stack: &mut Highlights, byte: &Byte, start:
         return;
     };
 
-    let range = TextRange::at(start + TextSize::from(2), TextSize::from(text.len() as u32));
+    let range = TextRange::at(
+        byte.syntax().text_range().start() + TextSize::from(2),
+        TextSize::from(text.len() as u32),
+    );
     stack.add(HlRange { range, highlight: HlTag::EscapeSequence.into(), binding_hash: None })
 }
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs
index 43a6bdad7e9..c63043621c2 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/format.rs
@@ -5,7 +5,7 @@ use ide_db::{
     SymbolKind,
 };
 use span::Edition;
-use syntax::{ast, TextRange};
+use syntax::{ast, AstToken};
 
 use crate::{
     syntax_highlighting::{highlight::highlight_def, highlights::Highlights},
@@ -18,15 +18,15 @@ pub(super) fn highlight_format_string(
     krate: hir::Crate,
     string: &ast::String,
     expanded_string: &ast::String,
-    range: TextRange,
     edition: Edition,
 ) {
     if is_format_string(expanded_string) {
+        let start = string.syntax().text_range().start();
         // FIXME: Replace this with the HIR info we have now.
         lex_format_specifiers(string, &mut |piece_range, kind| {
             if let Some(highlight) = highlight_format_specifier(kind) {
                 stack.add(HlRange {
-                    range: piece_range + range.start(),
+                    range: piece_range + start,
                     highlight: highlight.into(),
                     binding_hash: None,
                 });
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
index 194fde11601..127861a04bd 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/highlight.rs
@@ -23,6 +23,7 @@ pub(super) fn token(
     sema: &Semantics<'_, RootDatabase>,
     token: SyntaxToken,
     edition: Edition,
+    in_tt: bool,
 ) -> Option<Highlight> {
     if let Some(comment) = ast::Comment::cast(token.clone()) {
         let h = HlTag::Comment;
@@ -40,13 +41,20 @@ pub(super) fn token(
         INT_NUMBER | FLOAT_NUMBER => HlTag::NumericLiteral.into(),
         BYTE => HlTag::ByteLiteral.into(),
         CHAR => HlTag::CharLiteral.into(),
-        IDENT if token.parent().and_then(ast::TokenTree::cast).is_some() => {
+        IDENT if in_tt => {
             // from this point on we are inside a token tree, this only happens for identifiers
             // that were not mapped down into macro invocations
             HlTag::None.into()
         }
         p if p.is_punct() => punctuation(sema, token, p),
-        k if k.is_keyword(edition) => keyword(sema, token, k)?,
+        k if k.is_keyword(edition) => {
+            if in_tt && token.prev_token().is_some_and(|t| t.kind() == T![$]) {
+                // we are likely within a macro definition where our keyword is a fragment name
+                HlTag::None.into()
+            } else {
+                keyword(sema, token, k)?
+            }
+        }
         _ => return None,
     };
     Some(highlight)
@@ -81,7 +89,7 @@ pub(super) fn name_like(
             Some(IdentClass::NameRefClass(NameRefClass::Definition(def, _))) => {
                 highlight_def(sema, krate, def, edition)
             }
-            // FIXME: Fallback for 'static and '_, as we do not resolve these yet
+            // FIXME: Fallback for '_, as we do not resolve these yet
             _ => SymbolKind::LifetimeParam.into(),
         },
     };
@@ -214,12 +222,6 @@ fn keyword(
         T![true] | T![false] => HlTag::BoolLiteral.into(),
         // crate is handled just as a token if it's in an `extern crate`
         T![crate] if parent_matches::<ast::ExternCrate>(&token) => h,
-        // self, crate, super and `Self` are handled as either a Name or NameRef already, unless they
-        // are inside unmapped token trees
-        T![self] | T![crate] | T![super] | T![Self] if parent_matches::<ast::NameRef>(&token) => {
-            return None
-        }
-        T![self] if parent_matches::<ast::Name>(&token) => return None,
         T![ref] => match token.parent().and_then(ast::IdentPat::cast) {
             Some(ident) if sema.is_unsafe_ident_pat(&ident) => h | HlMod::Unsafe,
             _ => h,
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/macro_.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/macro_.rs
deleted file mode 100644
index b441b4cc90e..00000000000
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/macro_.rs
+++ /dev/null
@@ -1,128 +0,0 @@
-//! Syntax highlighting for macro_rules!.
-use syntax::{SyntaxKind, SyntaxToken, TextRange, T};
-
-use crate::{HlRange, HlTag};
-
-#[derive(Default)]
-pub(super) struct MacroHighlighter {
-    state: Option<MacroMatcherParseState>,
-}
-
-impl MacroHighlighter {
-    pub(super) fn init(&mut self) {
-        self.state = Some(MacroMatcherParseState::default());
-    }
-
-    pub(super) fn advance(&mut self, token: &SyntaxToken) {
-        if let Some(state) = self.state.as_mut() {
-            update_macro_state(state, token);
-        }
-    }
-
-    pub(super) fn highlight(&self, token: &SyntaxToken) -> Option<HlRange> {
-        if let Some(state) = self.state.as_ref() {
-            if matches!(state.rule_state, RuleState::Matcher | RuleState::Expander) {
-                if let Some(range) = is_metavariable(token) {
-                    return Some(HlRange {
-                        range,
-                        highlight: HlTag::UnresolvedReference.into(),
-                        binding_hash: None,
-                    });
-                }
-            }
-        }
-        None
-    }
-}
-
-struct MacroMatcherParseState {
-    /// Opening and corresponding closing bracket of the matcher or expander of the current rule
-    paren_ty: Option<(SyntaxKind, SyntaxKind)>,
-    paren_level: usize,
-    rule_state: RuleState,
-    /// Whether we are inside the outer `{` `}` macro block that holds the rules
-    in_invoc_body: bool,
-}
-
-impl Default for MacroMatcherParseState {
-    fn default() -> Self {
-        MacroMatcherParseState {
-            paren_ty: None,
-            paren_level: 0,
-            in_invoc_body: false,
-            rule_state: RuleState::None,
-        }
-    }
-}
-
-#[derive(Copy, Clone, Debug, PartialEq)]
-enum RuleState {
-    Matcher,
-    Expander,
-    Between,
-    None,
-}
-
-impl RuleState {
-    fn transition(&mut self) {
-        *self = match self {
-            RuleState::Matcher => RuleState::Between,
-            RuleState::Expander => RuleState::None,
-            RuleState::Between => RuleState::Expander,
-            RuleState::None => RuleState::Matcher,
-        };
-    }
-}
-
-fn update_macro_state(state: &mut MacroMatcherParseState, tok: &SyntaxToken) {
-    if !state.in_invoc_body {
-        if tok.kind() == T!['{'] || tok.kind() == T!['('] {
-            state.in_invoc_body = true;
-        }
-        return;
-    }
-
-    match state.paren_ty {
-        Some((open, close)) => {
-            if tok.kind() == open {
-                state.paren_level += 1;
-            } else if tok.kind() == close {
-                state.paren_level -= 1;
-                if state.paren_level == 0 {
-                    state.rule_state.transition();
-                    state.paren_ty = None;
-                }
-            }
-        }
-        None => {
-            match tok.kind() {
-                T!['('] => {
-                    state.paren_ty = Some((T!['('], T![')']));
-                }
-                T!['{'] => {
-                    state.paren_ty = Some((T!['{'], T!['}']));
-                }
-                T!['['] => {
-                    state.paren_ty = Some((T!['['], T![']']));
-                }
-                _ => (),
-            }
-            if state.paren_ty.is_some() {
-                state.paren_level = 1;
-                state.rule_state.transition();
-            }
-        }
-    }
-}
-
-fn is_metavariable(token: &SyntaxToken) -> Option<TextRange> {
-    match token.kind() {
-        kind if kind.is_any_identifier() => {
-            if let Some(_dollar) = token.prev_token().filter(|t| t.kind() == T![$]) {
-                return Some(token.text_range());
-            }
-        }
-        _ => (),
-    };
-    None
-}
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html
index 15a6386aa3c..2bc22f960bd 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_asm.html
@@ -49,26 +49,26 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="keyword unsafe">unsafe</span> <span class="brace">{</span>
         <span class="keyword">let</span> <span class="variable declaration">foo</span> <span class="operator">=</span> <span class="numeric_literal">1</span><span class="semicolon">;</span>
         <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">o</span> <span class="operator">=</span> <span class="numeric_literal">0</span><span class="semicolon">;</span>
-        <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>
+        <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis">(</span>
             <span class="string_literal macro">"%input = OpLoad _ {</span><span class="variable">0</span><span class="string_literal macro">}"</span><span class="comma macro">,</span>
             <span class="macro default_library library macro">concat</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"%result = "</span><span class="comma macro">,</span> <span class="string_literal macro">"bar"</span><span class="comma macro">,</span> <span class="string_literal macro">" _ %input"</span><span class="parenthesis macro">)</span><span class="comma macro">,</span>
             <span class="string_literal macro">"OpStore {</span><span class="variable">1</span><span class="string_literal macro">} %result"</span><span class="comma macro">,</span>
             <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="operator macro">&</span><span class="variable macro">foo</span><span class="comma macro">,</span>
             <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="operator macro">&</span><span class="keyword macro">mut</span> <span class="variable macro mutable">o</span><span class="comma macro">,</span>
-        <span class="parenthesis macro">)</span><span class="semicolon">;</span>
+        <span class="parenthesis">)</span><span class="semicolon">;</span>
 
         <span class="keyword">let</span> <span class="variable declaration">thread_id</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
-        <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"
+        <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"
             mov {</span><span class="variable">0</span><span class="string_literal macro">}, gs:[0x30]
             mov {</span><span class="variable">0</span><span class="string_literal macro">}, [{</span><span class="variable">0</span><span class="string_literal macro">}+0x48]
-        "</span><span class="comma macro">,</span> <span class="keyword macro">out</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="variable macro">thread_id</span><span class="comma macro">,</span> <span class="keyword macro">options</span><span class="parenthesis macro">(</span><span class="keyword macro">pure</span><span class="comma macro">,</span> <span class="keyword macro">readonly</span><span class="comma macro">,</span> <span class="keyword macro">nostack</span><span class="parenthesis macro">)</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+        "</span><span class="comma macro">,</span> <span class="keyword macro">out</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="variable macro">thread_id</span><span class="comma macro">,</span> <span class="keyword macro">options</span><span class="parenthesis macro">(</span><span class="keyword macro">pure</span><span class="comma macro">,</span> <span class="keyword macro">readonly</span><span class="comma macro">,</span> <span class="keyword macro">nostack</span><span class="parenthesis macro">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 
         <span class="keyword">static</span> <span class="static declaration">UNMAP_BASE</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
         <span class="keyword const">const</span> <span class="constant const declaration">MEM_RELEASE</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
         <span class="keyword">static</span> <span class="static declaration">VirtualFree</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
         <span class="keyword const">const</span> <span class="constant const declaration">OffPtr</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
         <span class="keyword const">const</span> <span class="constant const declaration">OffFn</span><span class="colon">:</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
-        <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"
+        <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"
             push {</span><span class="variable">free_type</span><span class="string_literal macro">}
             push {</span><span class="variable">free_size</span><span class="string_literal macro">}
             push {</span><span class="variable">base</span><span class="string_literal macro">}
@@ -92,7 +92,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
             <span class="variable declaration macro">base</span> <span class="operator macro">=</span> <span class="keyword macro">sym</span> <span class="static macro">UNMAP_BASE</span><span class="comma macro">,</span>
             <span class="keyword macro">options</span><span class="parenthesis macro">(</span><span class="keyword macro">noreturn</span><span class="parenthesis macro">)</span><span class="comma macro">,</span>
-        <span class="parenthesis macro">)</span><span class="semicolon">;</span>
+        <span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="brace">}</span>
 <span class="brace">}</span>
 <span class="comment">// taken from https://github.com/rust-embedded/cortex-m/blob/47921b51f8b960344fcfa1255a50a0d19efcde6d/cortex-m/src/asm.rs#L254-L274</span>
@@ -101,19 +101,19 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="comment">// Ensure thumb mode is set.</span>
     <span class="keyword">let</span> <span class="variable declaration">rv</span> <span class="operator">=</span> <span class="parenthesis">(</span><span class="value_param">rv</span> <span class="keyword">as</span> <span class="builtin_type">u32</span><span class="parenthesis">)</span> <span class="bitwise">|</span> <span class="numeric_literal">1</span><span class="semicolon">;</span>
     <span class="keyword">let</span> <span class="variable declaration">msp</span> <span class="operator">=</span> <span class="value_param">msp</span> <span class="keyword">as</span> <span class="builtin_type">u32</span><span class="semicolon">;</span>
-    <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>
+    <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis">(</span>
         <span class="string_literal macro">"mrs {</span><span class="variable">tmp</span><span class="string_literal macro">}, CONTROL"</span><span class="comma macro">,</span>
         <span class="string_literal macro">"bics {</span><span class="variable">tmp</span><span class="string_literal macro">}, {</span><span class="variable">spsel</span><span class="string_literal macro">}"</span><span class="comma macro">,</span>
         <span class="string_literal macro">"msr CONTROL, {</span><span class="variable">tmp</span><span class="string_literal macro">}"</span><span class="comma macro">,</span>
         <span class="string_literal macro">"isb"</span><span class="comma macro">,</span>
         <span class="string_literal macro">"msr MSP, {</span><span class="variable">msp</span><span class="string_literal macro">}"</span><span class="comma macro">,</span>
         <span class="string_literal macro">"bx {</span><span class="variable">rv</span><span class="string_literal macro">}"</span><span class="comma macro">,</span>
-        <span class="comment macro">// `out(reg) _` is not permitted in a `noreturn` asm! call,</span>
-        <span class="comment macro">// so instead use `in(reg) 0` and don't restore it afterwards.</span>
+        <span class="comment">// `out(reg) _` is not permitted in a `noreturn` asm! call,</span>
+        <span class="comment">// so instead use `in(reg) 0` and don't restore it afterwards.</span>
         <span class="variable declaration macro">tmp</span> <span class="operator macro">=</span> <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="numeric_literal macro">0</span><span class="comma macro">,</span>
         <span class="variable declaration macro">spsel</span> <span class="operator macro">=</span> <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="numeric_literal macro">2</span><span class="comma macro">,</span>
         <span class="variable declaration macro">msp</span> <span class="operator macro">=</span> <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="variable macro">msp</span><span class="comma macro">,</span>
         <span class="variable declaration macro">rv</span> <span class="operator macro">=</span> <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="variable macro">rv</span><span class="comma macro">,</span>
         <span class="keyword macro">options</span><span class="parenthesis macro">(</span><span class="keyword macro">noreturn</span><span class="comma macro">,</span> <span class="keyword macro">nomem</span><span class="comma macro">,</span> <span class="keyword macro">nostack</span><span class="parenthesis macro">)</span><span class="comma macro">,</span>
-    <span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="parenthesis">)</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/ide/src/syntax_highlighting/test_data/highlight_attributes.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html
index 485d44f97e1..e1d51dc0b71 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_attributes.html
@@ -45,20 +45,20 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 .invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
 .unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
 </style>
-<pre><code><span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">allow</span><span class="parenthesis attribute">(</span><span class="none attribute">dead_code</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
-<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="tool_module attribute">rustfmt</span><span class="operator attribute">::</span><span class="tool_module attribute">skip</span><span class="attribute_bracket attribute">]</span>
+<pre><code><span class="attribute_bracket attribute macro proc_macro">#</span><span class="attribute_bracket attribute macro proc_macro">[</span><span class="builtin_attr attribute macro proc_macro">allow</span><span class="parenthesis attribute macro proc_macro">(</span><span class="none attribute macro proc_macro">dead_code</span><span class="parenthesis attribute macro proc_macro">)</span><span class="attribute_bracket attribute macro proc_macro">]</span>
+<span class="attribute_bracket attribute macro proc_macro">#</span><span class="attribute_bracket attribute macro proc_macro">[</span><span class="tool_module attribute macro proc_macro">rustfmt</span><span class="operator attribute macro proc_macro">::</span><span class="tool_module attribute macro proc_macro">skip</span><span class="attribute_bracket attribute macro proc_macro">]</span>
 <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="module attribute crate_root library">proc_macros</span><span class="operator attribute">::</span><span class="attribute attribute library">identity</span><span class="attribute_bracket attribute">]</span>
-<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="attribute attribute default_library library">derive</span><span class="parenthesis attribute">(</span><span class="derive attribute default_library library">Default</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
+<span class="attribute_bracket attribute macro proc_macro">#</span><span class="attribute_bracket attribute macro proc_macro">[</span><span class="attribute attribute default_library library macro proc_macro">derive</span><span class="parenthesis attribute macro proc_macro">(</span><span class="derive attribute default_library library macro">Default</span><span class="parenthesis attribute macro proc_macro">)</span><span class="attribute_bracket attribute macro proc_macro">]</span>
 <span class="comment documentation">/// This is a doc comment</span>
 <span class="comment">// This is a normal comment</span>
 <span class="comment documentation">/// This is a doc comment</span>
-<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="attribute attribute default_library library">derive</span><span class="parenthesis attribute">(</span><span class="derive attribute default_library library">Copy</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
+<span class="attribute_bracket attribute macro proc_macro">#</span><span class="attribute_bracket attribute macro proc_macro">[</span><span class="attribute attribute default_library library macro proc_macro">derive</span><span class="parenthesis attribute macro proc_macro">(</span><span class="derive attribute default_library library macro">Copy</span><span class="parenthesis attribute macro proc_macro">)</span><span class="attribute_bracket attribute macro proc_macro">]</span>
 <span class="comment">// This is another normal comment</span>
 <span class="comment documentation">/// This is another doc comment</span>
 <span class="comment">// This is another normal comment</span>
-<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="attribute attribute default_library library">derive</span><span class="parenthesis attribute">(</span><span class="derive attribute default_library library">Copy</span><span class="comma attribute">,</span> <span class="unresolved_reference attribute">Unresolved</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
+<span class="attribute_bracket attribute macro proc_macro">#</span><span class="attribute_bracket attribute macro proc_macro">[</span><span class="attribute attribute default_library library macro proc_macro">derive</span><span class="parenthesis attribute macro proc_macro">(</span><span class="derive attribute default_library library macro">Copy</span><span class="comma attribute macro proc_macro">,</span> <span class="unresolved_reference attribute macro">Unresolved</span><span class="parenthesis attribute macro proc_macro">)</span><span class="attribute_bracket attribute macro proc_macro">]</span>
 <span class="comment">// The reason for these being here is to test AttrIds</span>
-<span class="keyword">enum</span> <span class="enum declaration">Foo</span> <span class="brace">{</span>
-    <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="derive_helper attribute default_library library">default</span><span class="attribute_bracket attribute">]</span>
-    <span class="enum_variant declaration">Bar</span>
-<span class="brace">}</span></code></pre>
\ No newline at end of file
+<span class="keyword macro proc_macro">enum</span> <span class="enum declaration macro proc_macro">Foo</span> <span class="brace macro proc_macro">{</span>
+    <span class="attribute_bracket attribute macro proc_macro">#</span><span class="attribute_bracket attribute macro proc_macro">[</span><span class="derive_helper attribute default_library library macro proc_macro">default</span><span class="attribute_bracket attribute macro proc_macro">]</span>
+    <span class="enum_variant declaration macro proc_macro">Bar</span>
+<span class="brace macro proc_macro">}</span></code></pre>
\ No newline at end of file
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html
index c6eab90e42b..af29af3f03c 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_block_mod_items.html
@@ -53,9 +53,9 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="brace">}</span><span class="semicolon">;</span>
 <span class="brace">}</span>
 <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
-    <span class="macro public">foo</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="struct declaration macro public">Foo</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro public">foo</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="struct declaration macro public">Foo</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="keyword">mod</span> <span class="module declaration">module</span> <span class="brace">{</span>
-        <span class="macro public">foo</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="struct declaration macro public">Bar</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+        <span class="macro public">foo</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="struct declaration macro public">Bar</span><span class="parenthesis">)</span><span class="semicolon">;</span>
         <span class="keyword">fn</span> <span class="function declaration">func</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="module">y</span><span class="operator">::</span><span class="struct public">Bar</span><span class="parenthesis">)</span> <span class="brace">{</span>
             <span class="keyword">mod</span> <span class="module declaration">inner</span> <span class="brace">{</span>
                 <span class="keyword">struct</span> <span class="struct declaration">Innerest</span><span class="angle">&lt;</span><span class="keyword">const</span> <span class="const_param const declaration">C</span><span class="colon">:</span> <span class="unresolved_reference">usize</span><span class="angle">&gt;</span> <span class="brace">{</span> <span class="field declaration">field</span><span class="colon">:</span> <span class="bracket">[</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span> <span class="brace">{</span><span class="const_param const">C</span><span class="brace">}</span><span class="bracket">]</span> <span class="brace">}</span>
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_const.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_const.html
index 96cdb532dd5..6d8f6b3c6e3 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_const.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_const.html
@@ -57,7 +57,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="keyword const">const</span> <span class="brace">{</span>
         <span class="keyword">const</span> <span class="punctuation">|</span><span class="punctuation">|</span> <span class="brace">{</span><span class="brace">}</span>
     <span class="brace">}</span>
-    <span class="macro public">id</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>
+    <span class="macro public">id</span><span class="macro_bang">!</span><span class="parenthesis">(</span>
         <span class="constant const macro">CONST_ITEM</span><span class="semicolon macro">;</span>
         <span class="const_param const macro">CONST_PARAM</span><span class="semicolon macro">;</span>
         <span class="keyword const macro">const</span> <span class="brace macro">{</span>
@@ -65,7 +65,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
         <span class="brace macro">}</span><span class="semicolon macro">;</span>
         <span class="operator macro">&</span><span class="keyword macro">raw</span> <span class="keyword macro">const</span> <span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="semicolon macro">;</span>
         <span class="keyword macro">const</span>
-    <span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="operator">.</span><span class="method const consuming trait">assoc_const_method</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="brace">}</span>
 <span class="keyword">trait</span> <span class="trait declaration">ConstTrait</span> <span class="brace">{</span>
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
index eb77c14c2a5..263e4545fb5 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_doctest.html
@@ -105,7 +105,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">foo</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="function injected">new</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span>
     <span class="comment documentation">///</span>
     <span class="comment documentation">///</span><span class="comment documentation"> </span><span class="comment injected">// calls bar on foo</span>
-    <span class="comment documentation">///</span><span class="comment documentation"> </span><span class="macro injected">assert</span><span class="macro_bang injected">!</span><span class="parenthesis injected macro">(</span><span class="none injected macro">foo</span><span class="operator injected macro">.</span><span class="none injected macro">bar</span><span class="parenthesis injected macro">(</span><span class="parenthesis injected macro">)</span><span class="parenthesis injected macro">)</span><span class="semicolon injected">;</span>
+    <span class="comment documentation">///</span><span class="comment documentation"> </span><span class="macro injected">assert</span><span class="macro_bang injected">!</span><span class="parenthesis injected">(</span><span class="none injected">foo</span><span class="operator injected">.</span><span class="none injected">bar</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span>
     <span class="comment documentation">///</span>
     <span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="variable declaration injected">bar</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="variable injected">foo</span><span class="operator injected">.</span><span class="field injected">bar</span><span class="none injected"> </span><span class="logical injected">||</span><span class="none injected"> </span><span class="struct injected">Foo</span><span class="operator injected">::</span><span class="constant injected">bar</span><span class="semicolon injected">;</span>
     <span class="comment documentation">///</span>
@@ -156,8 +156,8 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="brace">}</span>
 
 <span class="comment documentation">/// ```</span>
-<span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">macro_rules</span><span class="macro_bang injected">!</span><span class="none injected"> </span><span class="macro declaration injected public">noop</span><span class="none injected"> </span><span class="brace injected">{</span><span class="none injected"> </span><span class="parenthesis injected">(</span><span class="punctuation injected">$</span><span class="none injected">expr</span><span class="colon injected">:</span><span class="none injected">expr</span><span class="parenthesis injected">)</span><span class="none injected"> </span><span class="operator injected">=</span><span class="operator injected">&gt;</span><span class="none injected"> </span><span class="brace injected">{</span><span class="none injected"> </span><span class="punctuation injected">$</span><span class="none injected">expr </span><span class="brace injected">}</span><span class="brace injected">}</span>
-<span class="comment documentation">///</span><span class="comment documentation"> </span><span class="macro injected public">noop</span><span class="macro_bang injected">!</span><span class="parenthesis injected macro">(</span><span class="numeric_literal injected macro">1</span><span class="parenthesis injected macro">)</span><span class="semicolon injected">;</span>
+<span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">macro_rules</span><span class="macro_bang injected">!</span><span class="none injected"> </span><span class="macro declaration injected public">noop</span><span class="none injected"> </span><span class="brace injected">{</span><span class="none injected"> </span><span class="parenthesis injected">(</span><span class="punctuation injected">$</span><span class="none injected">expr</span><span class="colon injected">:</span><span class="none injected">expr</span><span class="parenthesis injected">)</span><span class="none injected"> </span><span class="operator injected">=</span><span class="operator injected">&gt;</span><span class="none injected"> </span><span class="brace injected">{</span><span class="none injected"> </span><span class="punctuation injected">$</span><span class="none injected">expr</span><span class="none injected"> </span><span class="brace injected">}</span><span class="brace injected">}</span>
+<span class="comment documentation">///</span><span class="comment documentation"> </span><span class="macro injected public">noop</span><span class="macro_bang injected">!</span><span class="parenthesis injected">(</span><span class="numeric_literal injected macro">1</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span>
 <span class="comment documentation">/// ```</span>
 <span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration public">noop</span> <span class="brace">{</span>
     <span class="parenthesis">(</span><span class="punctuation">$</span>expr<span class="colon">:</span>expr<span class="parenthesis">)</span> <span class="operator">=</span><span class="operator">&gt;</span> <span class="brace">{</span>
@@ -177,7 +177,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="comment documentation">///</span>
 <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">cfg_attr</span><span class="parenthesis attribute">(</span><span class="none attribute">feature</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"alloc"</span><span class="comma attribute">,</span> <span class="none attribute">doc</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"```rust"</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
 <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="builtin_attr attribute">cfg_attr</span><span class="parenthesis attribute">(</span><span class="none attribute">not</span><span class="parenthesis attribute">(</span><span class="none attribute">feature</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"alloc"</span><span class="parenthesis attribute">)</span><span class="comma attribute">,</span> <span class="none attribute">doc</span> <span class="operator attribute">=</span> <span class="string_literal attribute">"```ignore"</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
-<span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="punctuation injected">_</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="function injected">example</span><span class="parenthesis injected">(</span><span class="operator injected">&</span><span class="module injected">alloc</span><span class="operator injected">::</span><span class="macro injected">vec</span><span class="macro_bang injected">!</span><span class="bracket injected macro">[</span><span class="numeric_literal injected macro">1</span><span class="comma injected macro">,</span><span class="none injected"> </span><span class="numeric_literal injected macro">2</span><span class="comma injected macro">,</span><span class="none injected"> </span><span class="numeric_literal injected macro">3</span><span class="bracket injected macro">]</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span>
+<span class="comment documentation">///</span><span class="comment documentation"> </span><span class="keyword injected">let</span><span class="none injected"> </span><span class="punctuation injected">_</span><span class="none injected"> </span><span class="operator injected">=</span><span class="none injected"> </span><span class="function injected">example</span><span class="parenthesis injected">(</span><span class="operator injected">&</span><span class="module injected">alloc</span><span class="operator injected">::</span><span class="macro injected">vec</span><span class="macro_bang injected">!</span><span class="bracket injected">[</span><span class="numeric_literal injected">1</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">2</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">3</span><span class="bracket injected">]</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span>
 <span class="comment documentation">/// ```</span>
 <span class="keyword">pub</span> <span class="keyword">fn</span> <span class="function declaration public">mix_and_match</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
 
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
index 9477d0d1b87..eb532a5639d 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_general.html
@@ -78,7 +78,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
 <span class="keyword">use</span> <span class="self_keyword crate_root public">self</span><span class="operator">::</span><span class="struct">FooCopy</span><span class="operator">::</span><span class="brace">{</span><span class="self_keyword">self</span> <span class="keyword">as</span> <span class="struct declaration">BarCopy</span><span class="brace">}</span><span class="semicolon">;</span>
 
-<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="attribute attribute default_library library">derive</span><span class="parenthesis attribute">(</span><span class="derive attribute default_library library">Copy</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
+<span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="attribute attribute default_library library">derive</span><span class="parenthesis attribute">(</span><span class="derive attribute default_library library macro">Copy</span><span class="parenthesis attribute">)</span><span class="attribute_bracket attribute">]</span>
 <span class="keyword">struct</span> <span class="struct declaration">FooCopy</span> <span class="brace">{</span>
     <span class="field declaration">x</span><span class="colon">:</span> <span class="builtin_type">u32</span><span class="comma">,</span>
 <span class="brace">}</span>
@@ -151,7 +151,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="keyword">let</span> <span class="variable callable declaration">bar</span> <span class="operator">=</span> <span class="struct">Foo</span><span class="operator">::</span><span class="method associated consuming">baz</span><span class="semicolon">;</span>
 
     <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="parenthesis">(</span><span class="numeric_literal">-</span><span class="numeric_literal">42</span><span class="comma">,</span><span class="parenthesis">)</span><span class="semicolon">;</span>
-    <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="operator">-</span><span class="variable">baz</span><span class="operator">.</span><span class="field">0</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="variable declaration">baz</span> <span class="operator">=</span> <span class="operator">-</span><span class="variable">baz</span><span class="operator">.</span><span class="field library">0</span><span class="semicolon">;</span>
 
     <span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="logical">!</span><span class="bool_literal">true</span><span class="semicolon">;</span>
 
@@ -170,7 +170,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="keyword">impl</span><span class="angle">&lt;</span><span class="type_param declaration">T</span><span class="angle">&gt;</span> <span class="enum">Option</span><span class="angle">&lt;</span><span class="type_param">T</span><span class="angle">&gt;</span> <span class="brace">{</span>
     <span class="keyword">fn</span> <span class="method associated consuming declaration">and</span><span class="angle">&lt;</span><span class="type_param declaration">U</span><span class="angle">&gt;</span><span class="parenthesis">(</span><span class="self_keyword declaration">self</span><span class="comma">,</span> <span class="value_param declaration">other</span><span class="colon">:</span> <span class="enum">Option</span><span class="angle">&lt;</span><span class="type_param">U</span><span class="angle">&gt;</span><span class="parenthesis">)</span> <span class="operator">-&gt;</span> <span class="enum">Option</span><span class="angle">&lt;</span><span class="parenthesis">(</span><span class="type_param">T</span><span class="comma">,</span> <span class="type_param">U</span><span class="parenthesis">)</span><span class="angle">&gt;</span> <span class="brace">{</span>
         <span class="keyword control">match</span> <span class="value_param">other</span> <span class="brace">{</span>
-            <span class="enum_variant">None</span> <span class="operator">=&gt;</span> <span class="unresolved_reference">unimplemented</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="comma">,</span>
+            <span class="enum_variant">None</span> <span class="operator">=&gt;</span> <span class="unresolved_reference">unimplemented</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="comma">,</span>
             <span class="variable declaration">Nope</span> <span class="operator">=&gt;</span> <span class="variable">Nope</span><span class="comma">,</span>
         <span class="brace">}</span>
     <span class="brace">}</span>
@@ -184,7 +184,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="keyword async">async</span> <span class="keyword">fn</span> <span class="function async declaration">async_main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
     <span class="keyword">let</span> <span class="variable declaration">f1</span> <span class="operator">=</span> <span class="function async">learn_and_sing</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="keyword">let</span> <span class="variable declaration">f2</span> <span class="operator">=</span> <span class="unresolved_reference">dance</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
-    <span class="unresolved_reference">futures</span><span class="operator">::</span><span class="unresolved_reference">join</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">f1</span><span class="comma macro">,</span> <span class="none macro">f2</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="unresolved_reference">futures</span><span class="operator">::</span><span class="unresolved_reference">join</span><span class="macro_bang">!</span><span class="parenthesis">(</span>f1<span class="comma">,</span> f2<span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="brace">}</span>
 
 <span class="keyword">fn</span> <span class="function declaration">use_foo_items</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
@@ -196,7 +196,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="keyword">let</span> <span class="variable declaration">control_flow</span> <span class="operator">=</span> <span class="module crate_root library">foo</span><span class="operator">::</span><span class="function library">identity</span><span class="parenthesis">(</span><span class="module crate_root library">foo</span><span class="operator">::</span><span class="enum library">ControlFlow</span><span class="operator">::</span><span class="enum_variant library">Continue</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 
     <span class="keyword control">if</span> <span class="variable">control_flow</span><span class="operator">.</span><span class="method consuming library">should_die</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
-        <span class="module crate_root library">foo</span><span class="operator">::</span><span class="unresolved_reference">die</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+        <span class="module crate_root library">foo</span><span class="operator">::</span><span class="unresolved_reference">die</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="brace">}</span>
 <span class="brace">}</span>
 
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
index 5fbed35192b..1f9422161de 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_injection.html
@@ -51,7 +51,7 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="function">fixture</span><span class="parenthesis">(</span><span class="string_literal">r#"</span><span class="none injected">
 </span><span class="keyword injected">trait</span><span class="none injected"> </span><span class="trait declaration injected">Foo</span><span class="none injected"> </span><span class="brace injected">{</span><span class="none injected">
     </span><span class="keyword injected">fn</span><span class="none injected"> </span><span class="function associated declaration injected static trait">foo</span><span class="parenthesis injected">(</span><span class="parenthesis injected">)</span><span class="none injected"> </span><span class="brace injected">{</span><span class="none injected">
-        </span><span class="unresolved_reference injected">println</span><span class="macro_bang injected">!</span><span class="parenthesis injected macro">(</span><span class="string_literal injected macro">"2 + 2 = {}"</span><span class="comma injected macro">,</span><span class="none injected"> </span><span class="numeric_literal injected macro">4</span><span class="parenthesis injected macro">)</span><span class="semicolon injected">;</span><span class="none injected">
+        </span><span class="unresolved_reference injected">println</span><span class="macro_bang injected">!</span><span class="parenthesis injected">(</span><span class="string_literal injected">"2 + 2 = {}"</span><span class="comma injected">,</span><span class="none injected"> </span><span class="numeric_literal injected">4</span><span class="parenthesis injected">)</span><span class="semicolon injected">;</span><span class="none injected">
     </span><span class="brace injected">}</span><span class="none injected">
 </span><span class="brace injected">}</span><span class="string_literal">"#</span>
     <span class="parenthesis">)</span><span class="semicolon">;</span>
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html
index 06817af1b1f..a846addba3f 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_issue_18089.html
@@ -46,8 +46,8 @@ 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="macro public">template</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">template</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro public">template</span><span class="macro_bang">!</span><span class="parenthesis">(</span>template<span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="brace">}</span>
 
 <span class="attribute_bracket attribute">#</span><span class="attribute_bracket attribute">[</span><span class="module attribute crate_root library">proc_macros</span><span class="operator attribute">::</span><span class="attribute attribute library">issue_18089</span><span class="attribute_bracket attribute">]</span>
-<span class="keyword">fn</span> <span class="macro declaration public">template</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span></code></pre>
\ No newline at end of file
+<span class="keyword macro proc_macro">fn</span> <span class="macro declaration macro proc_macro public">template</span><span class="parenthesis macro proc_macro">(</span><span class="parenthesis macro proc_macro">)</span> <span class="brace macro proc_macro">{</span><span class="brace macro proc_macro">}</span></code></pre>
\ No newline at end of file
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html
index 2d3407dbcda..c3377614d72 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2015.html
@@ -54,21 +54,21 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="brace">}</span>
 
 <span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration public">void</span> <span class="brace">{</span>
-    <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="operator">&gt;</span> <span class="brace">{</span><span class="brace">}</span>
+    <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="operator">&gt;</span> <span class="brace">{</span>discard<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span><span class="brace">}</span>
 <span class="brace">}</span>
 
 <span class="keyword">struct</span> <span class="struct declaration">__</span> <span class="keyword">where</span> <span class="self_type_keyword">Self</span><span class="colon">:</span><span class="semicolon">;</span>
 <span class="keyword">fn</span> <span class="function declaration">__</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="unresolved_reference">Self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">Self</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">Self</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 
 <span class="comment">// edition dependent</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">try</span> <span class="none macro">async</span> <span class="none macro">await</span> <span class="none macro">gen</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">try</span> <span class="none macro">async</span> <span class="none macro">await</span> <span class="none macro">gen</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// edition and context dependent</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">dyn</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">dyn</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// builtin custom syntax</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">builtin</span> <span class="none macro">offset_of</span> <span class="none macro">format_args</span> <span class="none macro">asm</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">builtin</span> <span class="none macro">offset_of</span> <span class="none macro">format_args</span> <span class="none macro">asm</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// contextual</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">macro_rules</span><span class="comma macro">,</span> <span class="none macro">union</span><span class="comma macro">,</span> <span class="none macro">default</span><span class="comma macro">,</span> <span class="none macro">raw</span><span class="comma macro">,</span> <span class="none macro">auto</span><span class="comma macro">,</span> <span class="none macro">yeet</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">macro_rules</span><span class="comma macro">,</span> <span class="none macro">union</span><span class="comma macro">,</span> <span class="none macro">default</span><span class="comma macro">,</span> <span class="none macro">raw</span><span class="comma macro">,</span> <span class="none macro">auto</span><span class="comma macro">,</span> <span class="none macro">yeet</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// reserved</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">abstract</span> <span class="keyword macro">become</span> <span class="keyword macro">box</span> <span class="keyword macro">do</span> <span class="keyword macro">final</span> <span class="keyword macro">macro</span> <span class="keyword macro">override</span> <span class="keyword macro">priv</span> <span class="keyword macro">typeof</span> <span class="keyword macro">unsized</span> <span class="keyword macro">virtual</span> <span class="keyword control macro">yield</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>'static 'self 'unsafe<span class="parenthesis macro">)</span></code></pre>
\ No newline at end of file
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">abstract</span> <span class="keyword macro">become</span> <span class="keyword macro">box</span> <span class="keyword macro">do</span> <span class="keyword macro">final</span> <span class="keyword macro">macro</span> <span class="keyword macro">override</span> <span class="keyword macro">priv</span> <span class="keyword macro">typeof</span> <span class="keyword macro">unsized</span> <span class="keyword macro">virtual</span> <span class="keyword control macro">yield</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span>'static 'self 'unsafe<span class="parenthesis">)</span></code></pre>
\ No newline at end of file
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html
index f8eb5d068a8..9b22500396b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2018.html
@@ -54,21 +54,21 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="brace">}</span>
 
 <span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration public">void</span> <span class="brace">{</span>
-    <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="operator">&gt;</span> <span class="brace">{</span><span class="brace">}</span>
+    <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="operator">&gt;</span> <span class="brace">{</span>discard<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span><span class="brace">}</span>
 <span class="brace">}</span>
 
 <span class="keyword">struct</span> <span class="struct declaration">__</span> <span class="keyword">where</span> <span class="self_type_keyword">Self</span><span class="colon">:</span><span class="semicolon">;</span>
 <span class="keyword">fn</span> <span class="function declaration">__</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="unresolved_reference">Self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">Self</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">Self</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 
 <span class="comment">// edition dependent</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">try</span> <span class="keyword async macro">async</span> <span class="keyword async control macro">await</span> <span class="none macro">gen</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">try</span> <span class="keyword async macro">async</span> <span class="keyword async control macro">await</span> <span class="none macro">gen</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// edition and context dependent</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">dyn</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">dyn</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// builtin custom syntax</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">builtin</span> <span class="none macro">offset_of</span> <span class="none macro">format_args</span> <span class="none macro">asm</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">builtin</span> <span class="none macro">offset_of</span> <span class="none macro">format_args</span> <span class="none macro">asm</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// contextual</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">macro_rules</span><span class="comma macro">,</span> <span class="none macro">union</span><span class="comma macro">,</span> <span class="none macro">default</span><span class="comma macro">,</span> <span class="none macro">raw</span><span class="comma macro">,</span> <span class="none macro">auto</span><span class="comma macro">,</span> <span class="none macro">yeet</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">macro_rules</span><span class="comma macro">,</span> <span class="none macro">union</span><span class="comma macro">,</span> <span class="none macro">default</span><span class="comma macro">,</span> <span class="none macro">raw</span><span class="comma macro">,</span> <span class="none macro">auto</span><span class="comma macro">,</span> <span class="none macro">yeet</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// reserved</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">abstract</span> <span class="keyword macro">become</span> <span class="keyword macro">box</span> <span class="keyword macro">do</span> <span class="keyword macro">final</span> <span class="keyword macro">macro</span> <span class="keyword macro">override</span> <span class="keyword macro">priv</span> <span class="keyword macro">typeof</span> <span class="keyword macro">unsized</span> <span class="keyword macro">virtual</span> <span class="keyword control macro">yield</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>'static 'self 'unsafe<span class="parenthesis macro">)</span></code></pre>
\ No newline at end of file
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">abstract</span> <span class="keyword macro">become</span> <span class="keyword macro">box</span> <span class="keyword macro">do</span> <span class="keyword macro">final</span> <span class="keyword macro">macro</span> <span class="keyword macro">override</span> <span class="keyword macro">priv</span> <span class="keyword macro">typeof</span> <span class="keyword macro">unsized</span> <span class="keyword macro">virtual</span> <span class="keyword control macro">yield</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span>'static 'self 'unsafe<span class="parenthesis">)</span></code></pre>
\ No newline at end of file
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html
index f8eb5d068a8..9b22500396b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2021.html
@@ -54,21 +54,21 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="brace">}</span>
 
 <span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration public">void</span> <span class="brace">{</span>
-    <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="operator">&gt;</span> <span class="brace">{</span><span class="brace">}</span>
+    <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="operator">&gt;</span> <span class="brace">{</span>discard<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span><span class="brace">}</span>
 <span class="brace">}</span>
 
 <span class="keyword">struct</span> <span class="struct declaration">__</span> <span class="keyword">where</span> <span class="self_type_keyword">Self</span><span class="colon">:</span><span class="semicolon">;</span>
 <span class="keyword">fn</span> <span class="function declaration">__</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="unresolved_reference">Self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">Self</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">Self</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 
 <span class="comment">// edition dependent</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">try</span> <span class="keyword async macro">async</span> <span class="keyword async control macro">await</span> <span class="none macro">gen</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">try</span> <span class="keyword async macro">async</span> <span class="keyword async control macro">await</span> <span class="none macro">gen</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// edition and context dependent</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">dyn</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">dyn</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// builtin custom syntax</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">builtin</span> <span class="none macro">offset_of</span> <span class="none macro">format_args</span> <span class="none macro">asm</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">builtin</span> <span class="none macro">offset_of</span> <span class="none macro">format_args</span> <span class="none macro">asm</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// contextual</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">macro_rules</span><span class="comma macro">,</span> <span class="none macro">union</span><span class="comma macro">,</span> <span class="none macro">default</span><span class="comma macro">,</span> <span class="none macro">raw</span><span class="comma macro">,</span> <span class="none macro">auto</span><span class="comma macro">,</span> <span class="none macro">yeet</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">macro_rules</span><span class="comma macro">,</span> <span class="none macro">union</span><span class="comma macro">,</span> <span class="none macro">default</span><span class="comma macro">,</span> <span class="none macro">raw</span><span class="comma macro">,</span> <span class="none macro">auto</span><span class="comma macro">,</span> <span class="none macro">yeet</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// reserved</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">abstract</span> <span class="keyword macro">become</span> <span class="keyword macro">box</span> <span class="keyword macro">do</span> <span class="keyword macro">final</span> <span class="keyword macro">macro</span> <span class="keyword macro">override</span> <span class="keyword macro">priv</span> <span class="keyword macro">typeof</span> <span class="keyword macro">unsized</span> <span class="keyword macro">virtual</span> <span class="keyword control macro">yield</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>'static 'self 'unsafe<span class="parenthesis macro">)</span></code></pre>
\ No newline at end of file
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">abstract</span> <span class="keyword macro">become</span> <span class="keyword macro">box</span> <span class="keyword macro">do</span> <span class="keyword macro">final</span> <span class="keyword macro">macro</span> <span class="keyword macro">override</span> <span class="keyword macro">priv</span> <span class="keyword macro">typeof</span> <span class="keyword macro">unsized</span> <span class="keyword macro">virtual</span> <span class="keyword control macro">yield</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span>'static 'self 'unsafe<span class="parenthesis">)</span></code></pre>
\ No newline at end of file
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html
index fca84017069..ac8353120e8 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_2024.html
@@ -54,21 +54,21 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 <span class="brace">}</span>
 
 <span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration public">void</span> <span class="brace">{</span>
-    <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="operator">&gt;</span> <span class="brace">{</span><span class="brace">}</span>
+    <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="operator">&gt;</span> <span class="brace">{</span>discard<span class="punctuation">!</span><span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span><span class="brace">}</span>
 <span class="brace">}</span>
 
 <span class="keyword">struct</span> <span class="struct declaration">__</span> <span class="keyword">where</span> <span class="self_type_keyword">Self</span><span class="colon">:</span><span class="semicolon">;</span>
 <span class="keyword">fn</span> <span class="function declaration">__</span><span class="parenthesis">(</span><span class="punctuation">_</span><span class="colon">:</span> <span class="unresolved_reference">Self</span><span class="parenthesis">)</span> <span class="brace">{</span><span class="brace">}</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">Self</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">Self</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 
 <span class="comment">// edition dependent</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">try</span> <span class="keyword async macro">async</span> <span class="keyword async control macro">await</span> <span class="keyword macro">gen</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">try</span> <span class="keyword async macro">async</span> <span class="keyword async control macro">await</span> <span class="keyword macro">gen</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// edition and context dependent</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">dyn</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">dyn</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// builtin custom syntax</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">builtin</span> <span class="none macro">offset_of</span> <span class="none macro">format_args</span> <span class="none macro">asm</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">builtin</span> <span class="none macro">offset_of</span> <span class="none macro">format_args</span> <span class="none macro">asm</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// contextual</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="none macro">macro_rules</span><span class="comma macro">,</span> <span class="none macro">union</span><span class="comma macro">,</span> <span class="none macro">default</span><span class="comma macro">,</span> <span class="none macro">raw</span><span class="comma macro">,</span> <span class="none macro">auto</span><span class="comma macro">,</span> <span class="none macro">yeet</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="none macro">macro_rules</span><span class="comma macro">,</span> <span class="none macro">union</span><span class="comma macro">,</span> <span class="none macro">default</span><span class="comma macro">,</span> <span class="none macro">raw</span><span class="comma macro">,</span> <span class="none macro">auto</span><span class="comma macro">,</span> <span class="none macro">yeet</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="comment">// reserved</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="keyword macro">abstract</span> <span class="keyword macro">become</span> <span class="keyword macro">box</span> <span class="keyword macro">do</span> <span class="keyword macro">final</span> <span class="keyword macro">macro</span> <span class="keyword macro">override</span> <span class="keyword macro">priv</span> <span class="keyword macro">typeof</span> <span class="keyword macro">unsized</span> <span class="keyword macro">virtual</span> <span class="keyword control macro">yield</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>'static 'self 'unsafe<span class="parenthesis macro">)</span></code></pre>
\ No newline at end of file
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">abstract</span> <span class="keyword macro">become</span> <span class="keyword macro">box</span> <span class="keyword macro">do</span> <span class="keyword macro">final</span> <span class="keyword macro">macro</span> <span class="keyword macro">override</span> <span class="keyword macro">priv</span> <span class="keyword macro">typeof</span> <span class="keyword macro">unsized</span> <span class="keyword macro">virtual</span> <span class="keyword control macro">yield</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+<span class="macro public">void</span><span class="macro_bang">!</span><span class="parenthesis">(</span>'static 'self 'unsafe<span class="parenthesis">)</span></code></pre>
\ No newline at end of file
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html
new file mode 100644
index 00000000000..694e54d2fa8
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_keywords_macros.html
@@ -0,0 +1,50 @@
+
+<style>
+body                { margin: 0; }
+pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padding: 0.4em; }
+
+.lifetime           { color: #DFAF8F; font-style: italic; }
+.label              { color: #DFAF8F; font-style: italic; }
+.comment            { color: #7F9F7F; }
+.documentation      { color: #629755; }
+.intra_doc_link     { font-style: italic; }
+.injected           { opacity: 0.65 ; }
+.struct, .enum      { color: #7CB8BB; }
+.enum_variant       { color: #BDE0F3; }
+.string_literal     { color: #CC9393; }
+.field              { color: #94BFF3; }
+.function           { color: #93E0E3; }
+.function.unsafe    { color: #BC8383; }
+.trait.unsafe       { color: #BC8383; }
+.operator.unsafe    { color: #BC8383; }
+.mutable.unsafe     { color: #BC8383; text-decoration: underline; }
+.keyword.unsafe     { color: #BC8383; font-weight: bold; }
+.macro.unsafe       { color: #BC8383; }
+.parameter          { color: #94BFF3; }
+.text               { color: #DCDCCC; }
+.type               { color: #7CB8BB; }
+.builtin_type       { color: #8CD0D3; }
+.type_param         { color: #DFAF8F; }
+.attribute          { color: #94BFF3; }
+.numeric_literal    { color: #BFEBBF; }
+.bool_literal       { color: #BFE6EB; }
+.macro              { color: #94BFF3; }
+.proc_macro         { color: #94BFF3; text-decoration: underline; }
+.derive             { color: #94BFF3; font-style: italic; }
+.module             { color: #AFD8AF; }
+.value_param        { color: #DCDCCC; }
+.variable           { color: #DCDCCC; }
+.format_specifier   { color: #CC696B; }
+.mutable            { text-decoration: underline; }
+.escape_sequence    { color: #94BFF3; }
+.keyword            { color: #F0DFAF; font-weight: bold; }
+.control            { font-style: italic; }
+.reference          { font-style: italic; font-weight: bold; }
+.const              { font-weight: bolder; }
+
+.invalid_escape_sequence { color: #FC5555; text-decoration: wavy underline; }
+.unresolved_reference    { color: #FC5555; text-decoration: wavy underline; }
+</style>
+<pre><code><span class="module crate_root library">lib2015</span><span class="operator">::</span><span class="macro library">void_2015</span><span class="macro_bang">!</span><span class="parenthesis">(</span>try async await <span class="none macro">gen</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+<span class="module crate_root library">lib2024</span><span class="operator">::</span><span class="macro library">void_2024</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="keyword macro">try</span> <span class="keyword async macro">async</span> <span class="keyword async control macro">await</span> <span class="none macro">gen</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+</code></pre>
\ No newline at end of file
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html
index f640a5e6ca7..f224435e961 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_macros.html
@@ -47,21 +47,21 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 </style>
 <pre><code><span class="keyword">use</span> <span class="module crate_root library">proc_macros</span><span class="operator">::</span><span class="brace">{</span><span class="function library">mirror</span><span class="comma">,</span> <span class="function library">identity</span><span class="comma">,</span> <span class="derive library">DeriveIdentity</span><span class="brace">}</span><span class="semicolon">;</span>
 
-<span class="proc_macro library">mirror</span><span class="macro_bang">!</span> <span class="brace macro proc_macro">{</span>
+<span class="proc_macro library">mirror</span><span class="macro_bang">!</span> <span class="brace">{</span>
     <span class="brace macro proc_macro">{</span>
         <span class="comma macro proc_macro">,</span><span class="builtin_type macro proc_macro">i32</span> <span class="colon macro proc_macro">:</span><span class="field declaration macro proc_macro public">x</span> <span class="keyword macro proc_macro">pub</span>
         <span class="comma macro proc_macro">,</span><span class="builtin_type macro proc_macro">i32</span> <span class="colon macro proc_macro">:</span><span class="field declaration macro proc_macro public">y</span> <span class="keyword macro proc_macro">pub</span>
     <span class="brace macro proc_macro">}</span> <span class="struct declaration macro proc_macro">Foo</span> <span class="keyword macro proc_macro">struct</span>
-<span class="brace macro proc_macro">}</span>
+<span class="brace">}</span>
 <span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration public">def_fn</span> <span class="brace">{</span>
     <span class="parenthesis">(</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="colon">:</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="operator">&gt;</span> <span class="brace">{</span><span class="punctuation">$</span><span class="parenthesis">(</span><span class="punctuation">$</span>tt<span class="parenthesis">)</span><span class="punctuation">*</span><span class="brace">}</span>
 <span class="brace">}</span>
 
-<span class="macro public">def_fn</span><span class="macro_bang">!</span> <span class="brace macro">{</span>
+<span class="macro public">def_fn</span><span class="macro_bang">!</span> <span class="brace">{</span>
     <span class="keyword macro">fn</span> <span class="function declaration macro">bar</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span> <span class="operator macro">-</span><span class="operator macro">&gt;</span> <span class="builtin_type macro">u32</span> <span class="brace macro">{</span>
         <span class="numeric_literal macro">100</span>
     <span class="brace macro">}</span>
-<span class="brace macro">}</span>
+<span class="brace">}</span>
 
 <span class="keyword">macro_rules</span><span class="macro_bang">!</span> <span class="macro declaration public">dont_color_me_braces</span> <span class="brace">{</span>
     <span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">=</span><span class="operator">&gt;</span> <span class="brace">{</span><span class="numeric_literal">0</span><span class="brace">}</span>
@@ -100,16 +100,16 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="brace">}</span><span class="semicolon">;</span>
 <span class="brace">}</span>
 
-<span class="macro default_library library">include</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="macro default_library library macro">concat</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"foo/"</span><span class="comma macro">,</span> <span class="string_literal macro">"foo.rs"</span><span class="parenthesis macro">)</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+<span class="macro default_library library">include</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="macro default_library library macro">concat</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"foo/"</span><span class="comma macro">,</span> <span class="string_literal macro">"foo.rs"</span><span class="parenthesis macro">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 
 <span class="keyword">struct</span> <span class="struct declaration">S</span><span class="angle">&lt;</span><span class="type_param declaration">T</span><span class="angle">&gt;</span><span class="parenthesis">(</span><span class="type_param">T</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 <span class="keyword">fn</span> <span class="function declaration">main</span><span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="brace">{</span>
     <span class="keyword">struct</span> <span class="struct declaration">TestLocal</span><span class="semicolon">;</span>
     <span class="comment">// regression test, TestLocal here used to not resolve</span>
-    <span class="keyword">let</span> <span class="punctuation">_</span><span class="colon">:</span> <span class="struct">S</span><span class="angle">&lt;</span><span class="macro public">id</span><span class="macro_bang">!</span><span class="bracket macro">[</span><span class="struct macro">TestLocal</span><span class="bracket macro">]</span><span class="angle">&gt;</span><span class="semicolon">;</span>
+    <span class="keyword">let</span> <span class="punctuation">_</span><span class="colon">:</span> <span class="struct">S</span><span class="angle">&lt;</span><span class="macro public">id</span><span class="macro_bang">!</span><span class="bracket">[</span><span class="struct macro">TestLocal</span><span class="bracket">]</span><span class="angle">&gt;</span><span class="semicolon">;</span>
 
-    <span class="macro default_library library">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello, </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="parenthesis macro">(</span><span class="numeric_literal macro">92</span><span class="comma macro">,</span><span class="parenthesis macro">)</span><span class="operator macro">.</span><span class="field library macro">0</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">dont_color_me_braces</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">noop</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="macro macro public">noop</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro default_library library">format_args</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello, </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="parenthesis macro">(</span><span class="numeric_literal macro">92</span><span class="comma macro">,</span><span class="parenthesis macro">)</span><span class="operator macro">.</span><span class="field library macro">0</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">dont_color_me_braces</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">noop</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="macro macro public">noop</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="parenthesis">)</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/ide/src/syntax_highlighting/test_data/highlight_strings.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
index 1794d7dbfe2..539c74f6b57 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_strings.html
@@ -99,86 +99,86 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
 
     <span class="keyword">let</span> <span class="variable declaration">a</span> <span class="operator">=</span> <span class="byte_literal">b'</span><span class="escape_sequence">\xFF</span><span class="byte_literal">'</span><span class="semicolon">;</span>
 
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="escape_sequence">{{</span><span class="string_literal macro">Hello</span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="escape_sequence">{{</span><span class="string_literal macro">Hello</span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="comment">// from https://doc.rust-lang.org/std/fmt/index.html</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>                 <span class="comment">// =&gt; "Hello"</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello, </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"world"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>   <span class="comment">// =&gt; "Hello, world!"</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"The number is </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>   <span class="comment">// =&gt; "The number is 1"</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">?</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="parenthesis macro">(</span><span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="numeric_literal macro">4</span><span class="parenthesis macro">)</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>          <span class="comment">// =&gt; "(3, 4)"</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">value</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">value</span><span class="operator macro">=</span><span class="numeric_literal macro">4</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>      <span class="comment">// =&gt; "4"</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="comma macro">,</span> <span class="numeric_literal macro">2</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>           <span class="comment">// =&gt; "1 2"</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">4</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">42</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>             <span class="comment">// =&gt; "0042" with leading zerosV</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="comma macro">,</span> <span class="numeric_literal macro">2</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>   <span class="comment">// =&gt; "2 1 1 2"</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">argument</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">argument</span> <span class="operator macro">=</span> <span class="string_literal macro">"test"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>   <span class="comment">// =&gt; "test"</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="comma macro">,</span> <span class="variable declaration macro">name</span> <span class="operator macro">=</span> <span class="numeric_literal macro">2</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>          <span class="comment">// =&gt; "2 1"</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">a</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">c</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">b</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">a</span><span class="operator macro">=</span><span class="string_literal macro">"a"</span><span class="comma macro">,</span> <span class="variable declaration macro">b</span><span class="operator macro">=</span><span class="char_literal macro">'b'</span><span class="comma macro">,</span> <span class="variable declaration macro">c</span><span class="operator macro">=</span><span class="numeric_literal macro">3</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>  <span class="comment">// =&gt; "a 3 b"</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="escape_sequence">{{</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">2</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>                       <span class="comment">// =&gt; "{2}"</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">1</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="variable">width</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="variable declaration macro">width</span> <span class="operator macro">=</span> <span class="numeric_literal macro">5</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">&lt;</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">-</span><span class="format_specifier">&lt;</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">^</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">&gt;</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">+</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">#</span><span class="variable">x</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">27</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">-</span><span class="numeric_literal macro">5</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">#</span><span class="numeric_literal">0</span><span class="numeric_literal">10</span><span class="variable">x</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">27</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="numeric_literal">2</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="numeric_literal">0</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="numeric_literal">2</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="numeric_literal">1</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span>    <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="numeric_literal">2</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span>   <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="variable">number</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="variable">prec</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="variable declaration macro">prec</span> <span class="operator macro">=</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="variable declaration macro">number</span> <span class="operator macro">=</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">` has 3 fractional digits"</span><span class="comma macro">,</span> <span class="string_literal macro">"Hello"</span><span class="comma macro">,</span> <span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="variable declaration macro">name</span><span class="operator macro">=</span><span class="numeric_literal macro">1234.56</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">` has 3 characters"</span><span class="comma macro">,</span> <span class="string_literal macro">"Hello"</span><span class="comma macro">,</span> <span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="variable declaration macro">name</span><span class="operator macro">=</span><span class="string_literal macro">"1234.56"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">&gt;</span><span class="numeric_literal">8</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">` has 3 right-aligned characters"</span><span class="comma macro">,</span> <span class="string_literal macro">"Hello"</span><span class="comma macro">,</span> <span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="variable declaration macro">name</span><span class="operator macro">=</span><span class="string_literal macro">"1234.56"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello"</span><span class="parenthesis">)</span><span class="semicolon">;</span>                 <span class="comment">// =&gt; "Hello"</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello, </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"world"</span><span class="parenthesis">)</span><span class="semicolon">;</span>   <span class="comment">// =&gt; "Hello, world!"</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"The number is </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis">)</span><span class="semicolon">;</span>   <span class="comment">// =&gt; "The number is 1"</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">?</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="parenthesis macro">(</span><span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="numeric_literal macro">4</span><span class="parenthesis macro">)</span><span class="parenthesis">)</span><span class="semicolon">;</span>          <span class="comment">// =&gt; "(3, 4)"</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">value</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">value</span><span class="operator macro">=</span><span class="numeric_literal macro">4</span><span class="parenthesis">)</span><span class="semicolon">;</span>      <span class="comment">// =&gt; "4"</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="comma macro">,</span> <span class="numeric_literal macro">2</span><span class="parenthesis">)</span><span class="semicolon">;</span>           <span class="comment">// =&gt; "1 2"</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">4</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">42</span><span class="parenthesis">)</span><span class="semicolon">;</span>             <span class="comment">// =&gt; "0042" with leading zerosV</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="comma macro">,</span> <span class="numeric_literal macro">2</span><span class="parenthesis">)</span><span class="semicolon">;</span>   <span class="comment">// =&gt; "2 1 1 2"</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">argument</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">argument</span> <span class="operator macro">=</span> <span class="string_literal macro">"test"</span><span class="parenthesis">)</span><span class="semicolon">;</span>   <span class="comment">// =&gt; "test"</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="comma macro">,</span> <span class="variable declaration macro">name</span> <span class="operator macro">=</span> <span class="numeric_literal macro">2</span><span class="parenthesis">)</span><span class="semicolon">;</span>          <span class="comment">// =&gt; "2 1"</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">a</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">c</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">b</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">a</span><span class="operator macro">=</span><span class="string_literal macro">"a"</span><span class="comma macro">,</span> <span class="variable declaration macro">b</span><span class="operator macro">=</span><span class="char_literal macro">'b'</span><span class="comma macro">,</span> <span class="variable declaration macro">c</span><span class="operator macro">=</span><span class="numeric_literal macro">3</span><span class="parenthesis">)</span><span class="semicolon">;</span>  <span class="comment">// =&gt; "a 3 b"</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="escape_sequence">{{</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">2</span><span class="parenthesis">)</span><span class="semicolon">;</span>                       <span class="comment">// =&gt; "{2}"</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">1</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="variable">width</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="variable declaration macro">width</span> <span class="operator macro">=</span> <span class="numeric_literal macro">5</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">&lt;</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">-</span><span class="format_specifier">&lt;</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">^</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">&gt;</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">+</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">#</span><span class="variable">x</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">27</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="numeric_literal">0</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">-</span><span class="numeric_literal macro">5</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">#</span><span class="numeric_literal">0</span><span class="numeric_literal">10</span><span class="variable">x</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="numeric_literal macro">27</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="numeric_literal">5</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">1</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="numeric_literal">2</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="numeric_literal">0</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="numeric_literal">0</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="numeric_literal">2</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="numeric_literal">1</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span>    <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="numeric_literal">2</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span>   <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> is </span><span class="format_specifier">{</span><span class="variable">number</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="variable">prec</span><span class="format_specifier">$</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="string_literal macro">"x"</span><span class="comma macro">,</span> <span class="variable declaration macro">prec</span> <span class="operator macro">=</span> <span class="numeric_literal macro">5</span><span class="comma macro">,</span> <span class="variable declaration macro">number</span> <span class="operator macro">=</span> <span class="numeric_literal macro">0.01</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">` has 3 fractional digits"</span><span class="comma macro">,</span> <span class="string_literal macro">"Hello"</span><span class="comma macro">,</span> <span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="variable declaration macro">name</span><span class="operator macro">=</span><span class="numeric_literal macro">1234.56</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">` has 3 characters"</span><span class="comma macro">,</span> <span class="string_literal macro">"Hello"</span><span class="comma macro">,</span> <span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="variable declaration macro">name</span><span class="operator macro">=</span><span class="string_literal macro">"1234.56"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">, `</span><span class="format_specifier">{</span><span class="variable">name</span><span class="format_specifier">:</span><span class="format_specifier">&gt;</span><span class="numeric_literal">8</span><span class="format_specifier">.</span><span class="format_specifier">*</span><span class="format_specifier">}</span><span class="string_literal macro">` has 3 right-aligned characters"</span><span class="comma macro">,</span> <span class="string_literal macro">"Hello"</span><span class="comma macro">,</span> <span class="numeric_literal macro">3</span><span class="comma macro">,</span> <span class="variable declaration macro">name</span><span class="operator macro">=</span><span class="string_literal macro">"1234.56"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 
     <span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="string_literal">"{}"</span>
     <span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="string_literal">"{{}}"</span><span class="semicolon">;</span>
 
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="escape_sequence">{{</span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="escape_sequence">{{</span><span class="string_literal macro"> Hello"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello </span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="escape_sequence">{{</span><span class="string_literal macro">Hello</span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="escape_sequence">{{</span><span class="string_literal macro"> Hello </span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="escape_sequence">{{</span><span class="string_literal macro">Hello </span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="escape_sequence">{{</span><span class="string_literal macro"> Hello</span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="escape_sequence">{{</span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="escape_sequence">{{</span><span class="string_literal macro"> Hello"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello </span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="escape_sequence">{{</span><span class="string_literal macro">Hello</span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="escape_sequence">{{</span><span class="string_literal macro"> Hello </span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="escape_sequence">{{</span><span class="string_literal macro">Hello </span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="escape_sequence">{{</span><span class="string_literal macro"> Hello</span><span class="escape_sequence">}}</span><span class="string_literal macro">"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">r"Hello, </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"world"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">r"Hello, </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">!"</span><span class="comma macro">,</span> <span class="string_literal macro">"world"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 
     <span class="comment">// escape sequences</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"Hello</span><span class="escape_sequence">\n</span><span class="string_literal macro">World"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="escape_sequence">\u{48}</span><span class="escape_sequence">\x65</span><span class="escape_sequence">\x6C</span><span class="escape_sequence">\x6C</span><span class="escape_sequence">\x6F</span><span class="string_literal macro"> World"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"Hello</span><span class="escape_sequence">\n</span><span class="string_literal macro">World"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="escape_sequence">\u{48}</span><span class="escape_sequence">\x65</span><span class="escape_sequence">\x6C</span><span class="escape_sequence">\x6C</span><span class="escape_sequence">\x6F</span><span class="string_literal macro"> World"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 
     <span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="string_literal">"</span><span class="escape_sequence">\x28</span><span class="escape_sequence">\x28</span><span class="escape_sequence">\x00</span><span class="escape_sequence">\x63</span><span class="invalid_escape_sequence">\xFF</span><span class="escape_sequence">\u{FF}</span><span class="escape_sequence">\n</span><span class="string_literal">"</span><span class="semicolon">;</span> <span class="comment">// invalid non-UTF8 escape sequences</span>
     <span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="string_literal">b"</span><span class="escape_sequence">\x28</span><span class="escape_sequence">\x28</span><span class="escape_sequence">\x00</span><span class="escape_sequence">\x63</span><span class="escape_sequence">\xFF</span><span class="invalid_escape_sequence">\u{FF}</span><span class="escape_sequence">\n</span><span class="string_literal">"</span><span class="semicolon">;</span> <span class="comment">// valid bytes, invalid unicodes</span>
     <span class="keyword">let</span> <span class="punctuation">_</span> <span class="operator">=</span> <span class="string_literal">c"</span><span class="escape_sequence">\u{FF}</span><span class="escape_sequence">\xFF</span><span class="string_literal">"</span><span class="semicolon">;</span> <span class="comment">// valid bytes, valid unicodes</span>
     <span class="keyword">let</span> <span class="variable declaration reference">backslash</span> <span class="operator">=</span> <span class="string_literal">r"\\"</span><span class="semicolon">;</span>
 
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="escape_sequence">\x41</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">A</span> <span class="operator macro">=</span> <span class="numeric_literal macro">92</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">ничоси</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">ничоси</span> <span class="operator macro">=</span> <span class="numeric_literal macro">92</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="escape_sequence">\x41</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">A</span> <span class="operator macro">=</span> <span class="numeric_literal macro">92</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">ничоси</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable declaration macro">ничоси</span> <span class="operator macro">=</span> <span class="numeric_literal macro">92</span><span class="parenthesis">)</span><span class="semicolon">;</span>
 
-    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="variable">x</span><span class="format_specifier">?</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> "</span><span class="comma macro">,</span> <span class="unresolved_reference macro">thingy</span><span class="comma macro">,</span> <span class="unresolved_reference macro">n2</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro default_library library">panic</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"{}"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro default_library library">panic</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"more </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro default_library library">assert</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="bool_literal macro">true</span><span class="comma macro">,</span> <span class="string_literal macro">"{}"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro default_library library">assert</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="bool_literal macro">true</span><span class="comma macro">,</span> <span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> asdasd"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">toho</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"{}fmt"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro public">println</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">:</span><span class="variable">x</span><span class="format_specifier">?</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> "</span><span class="comma macro">,</span> <span class="unresolved_reference macro">thingy</span><span class="comma macro">,</span> <span class="unresolved_reference macro">n2</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro default_library library">panic</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"{}"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro default_library library">panic</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"more </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro default_library library">assert</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="bool_literal macro">true</span><span class="comma">,</span> <span class="string_literal macro">"{}"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro default_library library">assert</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="bool_literal macro">true</span><span class="comma">,</span> <span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> asdasd"</span><span class="comma macro">,</span> <span class="numeric_literal macro">1</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">toho</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"{}fmt"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis">)</span><span class="semicolon">;</span>
     <span class="keyword">let</span> <span class="variable declaration">i</span><span class="colon">:</span> <span class="builtin_type">u64</span> <span class="operator">=</span> <span class="numeric_literal">3</span><span class="semicolon">;</span>
     <span class="keyword">let</span> <span class="variable declaration">o</span><span class="colon">:</span> <span class="builtin_type">u64</span><span class="semicolon">;</span>
-    <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span>
+    <span class="module crate_root default_library library">core</span><span class="operator">::</span><span class="module default_library library">arch</span><span class="operator">::</span><span class="macro default_library library unsafe">asm</span><span class="macro_bang">!</span><span class="parenthesis">(</span>
         <span class="string_literal macro">"mov {</span><span class="variable">0</span><span class="string_literal macro">}, {</span><span class="variable">1</span><span class="string_literal macro">}"</span><span class="comma macro">,</span>
         <span class="string_literal macro">"add {</span><span class="variable">0</span><span class="string_literal macro">}, 5"</span><span class="comma macro">,</span>
         <span class="keyword macro">out</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="variable macro">o</span><span class="comma macro">,</span>
         <span class="keyword control macro">in</span><span class="parenthesis macro">(</span><span class="reg library macro">reg</span><span class="parenthesis macro">)</span> <span class="variable macro">i</span><span class="comma macro">,</span>
-    <span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="parenthesis">)</span><span class="semicolon">;</span>
 
     <span class="keyword const">const</span> <span class="constant const declaration">CONSTANT</span><span class="colon">:</span> <span class="parenthesis">(</span><span class="parenthesis">)</span> <span class="operator">=</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="colon">:</span>
     <span class="keyword">let</span> <span class="keyword">mut</span> <span class="variable declaration mutable">m</span> <span class="operator">=</span> <span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
-    <span class="macro default_library library">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="macro default_library library macro">concat</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"{}"</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="string_literal macro">"{}"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro default_library library">format_args</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">backslash</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">CONSTANT</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">m</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="comma macro">,</span> <span class="macro default_library library macro">format_args</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="unresolved_reference macro">foo</span><span class="comma macro">,</span> <span class="string_literal macro">"bar"</span><span class="comma macro">,</span> <span class="macro macro public">toho</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-    <span class="macro public">reuse_twice</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">backslash</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
+    <span class="macro default_library library">format_args</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="macro default_library library macro">concat</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"{}"</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="string_literal macro">"{}"</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro default_library library">format_args</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">backslash</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">CONSTANT</span><span class="format_specifier">}</span><span class="string_literal macro"> </span><span class="format_specifier">{</span><span class="variable">m</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="comma macro">,</span> <span class="macro default_library library macro">format_args</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="comma macro">,</span> <span class="numeric_literal macro">0</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="unresolved_reference macro">foo</span><span class="comma macro">,</span> <span class="string_literal macro">"bar"</span><span class="comma macro">,</span> <span class="macro macro public">toho</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="comma macro">,</span> <span class="variable macro reference">backslash</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+    <span class="macro public">reuse_twice</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="string_literal macro">"</span><span class="format_specifier">{</span><span class="variable">backslash</span><span class="format_specifier">}</span><span class="string_literal macro">"</span><span class="parenthesis">)</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/ide/src/syntax_highlighting/test_data/highlight_unsafe.html b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
index d9beac30898..9a46d9f4025 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/test_data/highlight_unsafe.html
@@ -92,13 +92,13 @@ pre                 { color: #DCDCCC; background: #3F3F3F; font-size: 22px; padd
     <span class="keyword">let</span> <span class="variable declaration">x</span> <span class="operator">=</span> <span class="operator">&</span><span class="numeric_literal">5</span> <span class="keyword">as</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="punctuation">_</span> <span class="keyword">as</span> <span class="keyword">*</span><span class="keyword">const</span> <span class="builtin_type">usize</span><span class="semicolon">;</span>
     <span class="keyword">let</span> <span class="variable declaration">u</span> <span class="operator">=</span> <span class="union">Union</span> <span class="brace">{</span> <span class="field">b</span><span class="colon">:</span> <span class="numeric_literal">0</span> <span class="brace">}</span><span class="semicolon">;</span>
 
-    <span class="macro public">id</span><span class="macro_bang">!</span> <span class="brace macro">{</span>
+    <span class="macro public">id</span><span class="macro_bang">!</span> <span class="brace">{</span>
         <span class="keyword macro unsafe">unsafe</span> <span class="brace macro">{</span> <span class="macro macro public unsafe">unsafe_deref</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span> <span class="brace macro">}</span>
-    <span class="brace macro">}</span><span class="semicolon">;</span>
+    <span class="brace">}</span><span class="semicolon">;</span>
 
     <span class="keyword unsafe">unsafe</span> <span class="brace">{</span>
-        <span class="macro public unsafe">unsafe_deref</span><span class="macro_bang">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span><span class="semicolon">;</span>
-        <span class="macro public unsafe">id</span><span class="macro_bang">!</span> <span class="brace macro">{</span> <span class="macro macro public unsafe">unsafe_deref</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span> <span class="brace macro">}</span><span class="semicolon">;</span>
+        <span class="macro public unsafe">unsafe_deref</span><span class="macro_bang">!</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
+        <span class="macro public unsafe">id</span><span class="macro_bang">!</span> <span class="brace">{</span> <span class="macro macro public unsafe">unsafe_deref</span><span class="macro_bang macro">!</span><span class="parenthesis macro">(</span><span class="parenthesis macro">)</span> <span class="brace">}</span><span class="semicolon">;</span>
 
         <span class="comment">// unsafe fn and method calls</span>
         <span class="function unsafe">unsafe_fn</span><span class="parenthesis">(</span><span class="parenthesis">)</span><span class="semicolon">;</span>
diff --git a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
index 3775265f234..e48ca86c46b 100644
--- a/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
+++ b/src/tools/rust-analyzer/crates/ide/src/syntax_highlighting/tests.rs
@@ -386,7 +386,7 @@ mod __ {
 }
 
 macro_rules! void {
-    ($($tt:tt)*) => {}
+    ($($tt:tt)*) => {discard!($($tt:tt)*)}
 }
 
 struct __ where Self:;
@@ -412,6 +412,31 @@ void!('static 'self 'unsafe)
 }
 
 #[test]
+fn test_keyword_macro_edition_highlighting() {
+    check_highlighting(
+        r#"
+//- /main.rs crate:main edition:2018 deps:lib2015,lib2024
+lib2015::void_2015!(try async await gen);
+lib2024::void_2024!(try async await gen);
+//- /lib2015.rs crate:lib2015 edition:2015
+#[macro_export]
+macro_rules! void_2015 {
+    ($($tt:tt)*) => {discard!($($tt:tt)*)}
+}
+
+//- /lib2024.rs crate:lib2024 edition:2024
+#[macro_export]
+macro_rules! void_2024 {
+    ($($tt:tt)*) => {discard!($($tt:tt)*)}
+}
+
+"#,
+        expect_file![format!("./test_data/highlight_keywords_macros.html")],
+        false,
+    );
+}
+
+#[test]
 fn test_string_highlighting() {
     // The format string detection is based on macro-expansion,
     // thus, we have to copy the macro definition from `std`
diff --git a/src/tools/rust-analyzer/crates/intern/Cargo.toml b/src/tools/rust-analyzer/crates/intern/Cargo.toml
index c0358ef929b..397eba09296 100644
--- a/src/tools/rust-analyzer/crates/intern/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/intern/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 
 [dependencies]
diff --git a/src/tools/rust-analyzer/crates/mbe/Cargo.toml b/src/tools/rust-analyzer/crates/mbe/Cargo.toml
index b37d57f2801..e6fbb298ebd 100644
--- a/src/tools/rust-analyzer/crates/mbe/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/mbe/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 cov-mark = "2.0.0-pre.1"
diff --git a/src/tools/rust-analyzer/crates/mbe/src/parser.rs b/src/tools/rust-analyzer/crates/mbe/src/parser.rs
index 16d55492a04..0a670053c98 100644
--- a/src/tools/rust-analyzer/crates/mbe/src/parser.rs
+++ b/src/tools/rust-analyzer/crates/mbe/src/parser.rs
@@ -13,8 +13,8 @@ use crate::ParseError;
 /// Consider
 ///
 /// ```
-/// macro_rules! an_macro {
-///     ($x:expr + $y:expr) => ($y * $x)
+/// macro_rules! a_macro {
+///     ($x:expr, $y:expr) => ($y * $x)
 /// }
 /// ```
 ///
diff --git a/src/tools/rust-analyzer/crates/parser/Cargo.toml b/src/tools/rust-analyzer/crates/parser/Cargo.toml
index 48436ec71f7..a36a39dbee6 100644
--- a/src/tools/rust-analyzer/crates/parser/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/parser/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 drop_bomb = "0.1.5"
diff --git a/src/tools/rust-analyzer/crates/parser/src/input.rs b/src/tools/rust-analyzer/crates/parser/src/input.rs
index c90b358cfbb..cabdff214df 100644
--- a/src/tools/rust-analyzer/crates/parser/src/input.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/input.rs
@@ -36,7 +36,7 @@ impl Input {
     /// the *previous* token was joint, with mbe, you know whether the *current*
     /// one is joint. This API allows for styles of usage:
     ///
-    /// ```
+    /// ```ignore
     /// // In text:
     /// tokens.was_joint(prev_joint);
     /// tokens.push(curr);
diff --git a/src/tools/rust-analyzer/crates/parser/src/lib.rs b/src/tools/rust-analyzer/crates/parser/src/lib.rs
index e461492cc6f..398ad7cf66c 100644
--- a/src/tools/rust-analyzer/crates/parser/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/lib.rs
@@ -59,7 +59,7 @@ pub use crate::{
 ///
 /// That is, for something like
 ///
-/// ```
+/// ```ignore
 /// quick_check! {
 ///    fn prop() {}
 /// }
diff --git a/src/tools/rust-analyzer/crates/parser/src/output.rs b/src/tools/rust-analyzer/crates/parser/src/output.rs
index 386d03a62cc..0ea15a656c1 100644
--- a/src/tools/rust-analyzer/crates/parser/src/output.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/output.rs
@@ -16,8 +16,9 @@ pub struct Output {
     /// 32-bit encoding of events. If LSB is zero, then that's an index into the
     /// error vector. Otherwise, it's one of the thee other variants, with data encoded as
     ///
-    ///     |16 bit kind|8 bit n_input_tokens|4 bit tag|4 bit leftover|
-    ///
+    /// ```text
+    /// |16 bit kind|8 bit n_input_tokens|4 bit tag|4 bit leftover|
+    /// ``````
     event: Vec<u32>,
     error: Vec<String>,
 }
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 79900425a17..e56e09eeb66 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
@@ -147,9 +147,6 @@ pub enum SyntaxKind {
     C_STRING,
     FLOAT_NUMBER,
     INT_NUMBER,
-    RAW_BYTE_STRING,
-    RAW_C_STRING,
-    RAW_STRING,
     STRING,
     COMMENT,
     ERROR,
@@ -343,9 +340,6 @@ impl SyntaxKind {
             | C_STRING
             | FLOAT_NUMBER
             | INT_NUMBER
-            | RAW_BYTE_STRING
-            | RAW_C_STRING
-            | RAW_STRING
             | STRING
             | ABI
             | ADT
@@ -898,18 +892,7 @@ impl SyntaxKind {
         )
     }
     pub fn is_literal(self) -> bool {
-        matches!(
-            self,
-            BYTE | BYTE_STRING
-                | CHAR
-                | C_STRING
-                | FLOAT_NUMBER
-                | INT_NUMBER
-                | RAW_BYTE_STRING
-                | RAW_C_STRING
-                | RAW_STRING
-                | STRING
-        )
+        matches!(self, BYTE | BYTE_STRING | CHAR | C_STRING | FLOAT_NUMBER | INT_NUMBER | STRING)
     }
     pub fn from_keyword(ident: &str, edition: Edition) -> Option<SyntaxKind> {
         let kw = match ident {
diff --git a/src/tools/rust-analyzer/crates/paths/Cargo.toml b/src/tools/rust-analyzer/crates/paths/Cargo.toml
index f0dafab70c1..4cc70726da0 100644
--- a/src/tools/rust-analyzer/crates/paths/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/paths/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 camino.workspace = true
diff --git a/src/tools/rust-analyzer/crates/paths/src/lib.rs b/src/tools/rust-analyzer/crates/paths/src/lib.rs
index 00842441616..3d722b1ff11 100644
--- a/src/tools/rust-analyzer/crates/paths/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/paths/src/lib.rs
@@ -232,7 +232,7 @@ impl AbsPath {
     /// - Removes trailing slashes: `/a/b/` becomes `/a/b`.
     ///
     /// # Example
-    /// ```
+    /// ```ignore
     /// # use paths::AbsPathBuf;
     /// let abs_path_buf = AbsPathBuf::assert("/a/../../b/.//c//".into());
     /// let normalized = abs_path_buf.normalize();
diff --git a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml
index dac8e094357..f5ba40a994b 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-api/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 serde.workspace = true
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
index 191535ac55e..d3b56b402ea 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 object.workspace = true
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml
index 7c6a1ba46b5..16fcc929620 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/Cargo.toml
@@ -7,7 +7,6 @@ edition = "2021"
 license = "MIT OR Apache-2.0"
 
 [lib]
-doctest = false
 
 [build-dependencies]
 cargo_metadata = "0.18.1"
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml
index fa189752b76..fb98d758a8b 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/proc-macro-test/imp/Cargo.toml
@@ -6,7 +6,6 @@ edition = "2021"
 publish = false
 
 [lib]
-doctest = false
 proc-macro = true
 
 [dependencies]
diff --git a/src/tools/rust-analyzer/crates/profile/Cargo.toml b/src/tools/rust-analyzer/crates/profile/Cargo.toml
index 3179c810f69..9384fe26558 100644
--- a/src/tools/rust-analyzer/crates/profile/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/profile/Cargo.toml
@@ -10,14 +10,13 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 cfg-if = "1.0.0"
 libc.workspace = true
 jemalloc-ctl = { version = "0.5.0", package = "tikv-jemalloc-ctl", optional = true }
 
-[target.'cfg(target_os = "linux")'.dependencies]
+[target.'cfg(all(target_os = "linux", not(target_env = "ohos")))'.dependencies]
 perf-event = "=0.4.7"
 
 [target.'cfg(windows)'.dependencies]
diff --git a/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs b/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs
index 0a803959eed..9f3e636ef81 100644
--- a/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs
+++ b/src/tools/rust-analyzer/crates/profile/src/stop_watch.rs
@@ -11,7 +11,7 @@ use crate::MemoryUsage;
 
 pub struct StopWatch {
     time: Instant,
-    #[cfg(target_os = "linux")]
+    #[cfg(all(target_os = "linux", not(target_env = "ohos")))]
     counter: Option<perf_event::Counter>,
     memory: MemoryUsage,
 }
@@ -24,7 +24,7 @@ pub struct StopWatchSpan {
 
 impl StopWatch {
     pub fn start() -> StopWatch {
-        #[cfg(target_os = "linux")]
+        #[cfg(all(target_os = "linux", not(target_env = "ohos")))]
         let counter = {
             // When debugging rust-analyzer using rr, the perf-related syscalls cause it to abort.
             // We allow disabling perf by setting the env var `RA_DISABLE_PERF`.
@@ -51,7 +51,7 @@ impl StopWatch {
         let time = Instant::now();
         StopWatch {
             time,
-            #[cfg(target_os = "linux")]
+            #[cfg(all(target_os = "linux", not(target_env = "ohos")))]
             counter,
             memory,
         }
@@ -60,10 +60,12 @@ impl StopWatch {
     pub fn elapsed(&mut self) -> StopWatchSpan {
         let time = self.time.elapsed();
 
-        #[cfg(target_os = "linux")]
+        #[cfg(all(target_os = "linux", not(target_env = "ohos")))]
         let instructions = self.counter.as_mut().and_then(|it| {
             it.read().map_err(|err| eprintln!("Failed to read perf counter: {err}")).ok()
         });
+        #[cfg(all(target_os = "linux", target_env = "ohos"))]
+        let instructions = None;
         #[cfg(not(target_os = "linux"))]
         let instructions = None;
 
diff --git a/src/tools/rust-analyzer/crates/project-model/Cargo.toml b/src/tools/rust-analyzer/crates/project-model/Cargo.toml
index ed647950e66..83def0e6b2a 100644
--- a/src/tools/rust-analyzer/crates/project-model/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/project-model/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 anyhow.workspace = true
diff --git a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
index b5f4e43a115..40ab8c53fae 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/cargo_workspace.rs
@@ -594,7 +594,9 @@ impl CargoWorkspace {
             .filter_map(|package| {
                 let package = &self[package];
                 if package.is_member {
-                    Some(package.features.keys().cloned())
+                    Some(package.features.keys().cloned().chain(
+                        package.features.keys().map(|key| format!("{}/{key}", package.name)),
+                    ))
                 } else {
                     None
                 }
diff --git a/src/tools/rust-analyzer/crates/project-model/src/lib.rs b/src/tools/rust-analyzer/crates/project-model/src/lib.rs
index 0c734474682..21a993c5a5e 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/lib.rs
@@ -262,7 +262,7 @@ fn parse_cfg(s: &str) -> Result<cfg::CfgAtom, String> {
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum RustSourceWorkspaceConfig {
     CargoMetadata(CargoMetadataConfig),
-    Stitched,
+    Json(ProjectJson),
 }
 
 impl Default for RustSourceWorkspaceConfig {
diff --git a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
index 2f9612e3a47..0282a714645 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/project_json.rs
@@ -65,6 +65,8 @@ pub struct ProjectJson {
     pub(crate) sysroot: Option<AbsPathBuf>,
     /// e.g. `path/to/sysroot/lib/rustlib/src/rust/library`
     pub(crate) sysroot_src: Option<AbsPathBuf>,
+    /// A nested project describing the layout of the sysroot
+    pub(crate) sysroot_project: Option<Box<ProjectJson>>,
     project_root: AbsPathBuf,
     /// The path to the rust-project.json file. May be None if this
     /// data was generated by the discoverConfig command.
@@ -91,9 +93,16 @@ impl ProjectJson {
         data: ProjectJsonData,
     ) -> ProjectJson {
         let absolutize_on_base = |p| base.absolutize(p);
+        let sysroot_src = data.sysroot_src.map(absolutize_on_base);
+        let sysroot_project =
+            data.sysroot_project.zip(sysroot_src.clone()).map(|(sysroot_data, sysroot_src)| {
+                Box::new(ProjectJson::new(None, &sysroot_src, *sysroot_data))
+            });
+
         ProjectJson {
             sysroot: data.sysroot.map(absolutize_on_base),
-            sysroot_src: data.sysroot_src.map(absolutize_on_base),
+            sysroot_src,
+            sysroot_project,
             project_root: base.to_path_buf(),
             manifest,
             runnables: data.runnables.into_iter().map(Runnable::from).collect(),
@@ -330,6 +339,7 @@ pub enum RunnableKind {
 pub struct ProjectJsonData {
     sysroot: Option<Utf8PathBuf>,
     sysroot_src: Option<Utf8PathBuf>,
+    sysroot_project: Option<Box<ProjectJsonData>>,
     #[serde(default)]
     cfg_groups: FxHashMap<String, CfgList>,
     crates: Vec<CrateData>,
diff --git a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs
index fb752fe47b3..1e3c5a94786 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/sysroot.rs
@@ -4,24 +4,17 @@
 //! but we can't process `.rlib` and need source code instead. The source code
 //! is typically installed with `rustup component add rust-src` command.
 
-use std::{
-    env, fs,
-    ops::{self, Not},
-    path::Path,
-    process::Command,
-};
+use std::{env, fs, ops::Not, path::Path, process::Command};
 
 use anyhow::{format_err, Result};
-use base_db::CrateName;
 use itertools::Itertools;
-use la_arena::{Arena, Idx};
 use paths::{AbsPath, AbsPathBuf, Utf8PathBuf};
 use rustc_hash::FxHashMap;
 use stdx::format_to;
 use toolchain::{probe_for_binary, Tool};
 
 use crate::{
-    cargo_workspace::CargoMetadataConfig, utf8_stdout, CargoWorkspace, ManifestPath,
+    cargo_workspace::CargoMetadataConfig, utf8_stdout, CargoWorkspace, ManifestPath, ProjectJson,
     RustSourceWorkspaceConfig,
 };
 
@@ -36,58 +29,10 @@ pub struct Sysroot {
 #[derive(Debug, Clone, Eq, PartialEq)]
 pub enum RustLibSrcWorkspace {
     Workspace(CargoWorkspace),
-    Stitched(Stitched),
+    Json(ProjectJson),
     Empty,
 }
 
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub struct Stitched {
-    crates: Arena<RustLibSrcCrateData>,
-}
-
-impl ops::Index<RustLibSrcCrate> for Stitched {
-    type Output = RustLibSrcCrateData;
-    fn index(&self, index: RustLibSrcCrate) -> &RustLibSrcCrateData {
-        &self.crates[index]
-    }
-}
-
-impl Stitched {
-    pub(crate) fn public_deps(
-        &self,
-    ) -> impl Iterator<Item = (CrateName, RustLibSrcCrate, bool)> + '_ {
-        // core is added as a dependency before std in order to
-        // mimic rustcs dependency order
-        [("core", true), ("alloc", false), ("std", true), ("test", false)].into_iter().filter_map(
-            move |(name, prelude)| {
-                Some((CrateName::new(name).unwrap(), self.by_name(name)?, prelude))
-            },
-        )
-    }
-
-    pub(crate) fn proc_macro(&self) -> Option<RustLibSrcCrate> {
-        self.by_name("proc_macro")
-    }
-
-    pub(crate) fn crates(&self) -> impl ExactSizeIterator<Item = RustLibSrcCrate> + '_ {
-        self.crates.iter().map(|(id, _data)| id)
-    }
-
-    fn by_name(&self, name: &str) -> Option<RustLibSrcCrate> {
-        let (id, _data) = self.crates.iter().find(|(_id, data)| data.name == name)?;
-        Some(id)
-    }
-}
-
-pub(crate) type RustLibSrcCrate = Idx<RustLibSrcCrateData>;
-
-#[derive(Debug, Clone, Eq, PartialEq)]
-pub(crate) struct RustLibSrcCrateData {
-    pub(crate) name: String,
-    pub(crate) root: ManifestPath,
-    pub(crate) deps: Vec<RustLibSrcCrate>,
-}
-
 impl Sysroot {
     pub const fn empty() -> Sysroot {
         Sysroot {
@@ -114,7 +59,7 @@ impl Sysroot {
     pub fn is_rust_lib_src_empty(&self) -> bool {
         match &self.workspace {
             RustLibSrcWorkspace::Workspace(ws) => ws.packages().next().is_none(),
-            RustLibSrcWorkspace::Stitched(stitched) => stitched.crates.is_empty(),
+            RustLibSrcWorkspace::Json(project_json) => project_json.n_crates() == 0,
             RustLibSrcWorkspace::Empty => true,
         }
     }
@@ -126,7 +71,7 @@ impl Sysroot {
     pub fn num_packages(&self) -> usize {
         match &self.workspace {
             RustLibSrcWorkspace::Workspace(ws) => ws.packages().count(),
-            RustLibSrcWorkspace::Stitched(c) => c.crates().count(),
+            RustLibSrcWorkspace::Json(project_json) => project_json.n_crates(),
             RustLibSrcWorkspace::Empty => 0,
         }
     }
@@ -252,52 +197,11 @@ impl Sysroot {
                     return Some(loaded);
                 }
             }
-        }
-        tracing::debug!("Stitching sysroot library: {src_root}");
-
-        let mut stitched = Stitched { crates: Arena::default() };
-
-        for path in SYSROOT_CRATES.trim().lines() {
-            let name = path.split('/').last().unwrap();
-            let root = [format!("{path}/src/lib.rs"), format!("lib{path}/lib.rs")]
-                .into_iter()
-                .map(|it| src_root.join(it))
-                .filter_map(|it| ManifestPath::try_from(it).ok())
-                .find(|it| fs::metadata(it).is_ok());
-
-            if let Some(root) = root {
-                stitched.crates.alloc(RustLibSrcCrateData {
-                    name: name.into(),
-                    root,
-                    deps: Vec::new(),
-                });
-            }
-        }
-
-        if let Some(std) = stitched.by_name("std") {
-            for dep in STD_DEPS.trim().lines() {
-                if let Some(dep) = stitched.by_name(dep) {
-                    stitched.crates[std].deps.push(dep)
-                }
-            }
-        }
-
-        if let Some(alloc) = stitched.by_name("alloc") {
-            for dep in ALLOC_DEPS.trim().lines() {
-                if let Some(dep) = stitched.by_name(dep) {
-                    stitched.crates[alloc].deps.push(dep)
-                }
-            }
+        } else if let RustSourceWorkspaceConfig::Json(project_json) = sysroot_source_config {
+            return Some(RustLibSrcWorkspace::Json(project_json.clone()));
         }
 
-        if let Some(proc_macro) = stitched.by_name("proc_macro") {
-            for dep in PROC_MACRO_DEPS.trim().lines() {
-                if let Some(dep) = stitched.by_name(dep) {
-                    stitched.crates[proc_macro].deps.push(dep)
-                }
-            }
-        }
-        Some(RustLibSrcWorkspace::Stitched(stitched))
+        None
     }
 
     pub fn set_workspace(&mut self, workspace: RustLibSrcWorkspace) {
@@ -308,7 +212,10 @@ impl Sysroot {
                     RustLibSrcWorkspace::Workspace(ws) => {
                         ws.packages().any(|p| ws[p].name == "core")
                     }
-                    RustLibSrcWorkspace::Stitched(stitched) => stitched.by_name("core").is_some(),
+                    RustLibSrcWorkspace::Json(project_json) => project_json
+                        .crates()
+                        .filter_map(|(_, krate)| krate.display_name.clone())
+                        .any(|name| name.canonical_name().as_str() == "core"),
                     RustLibSrcWorkspace::Empty => true,
                 };
                 if !has_core {
@@ -484,33 +391,3 @@ fn get_rust_lib_src(sysroot_path: &AbsPath) -> Option<AbsPathBuf> {
         None
     }
 }
-
-const SYSROOT_CRATES: &str = "
-alloc
-backtrace
-core
-panic_abort
-panic_unwind
-proc_macro
-profiler_builtins
-std
-stdarch/crates/std_detect
-test
-unwind";
-
-const ALLOC_DEPS: &str = "core";
-
-const STD_DEPS: &str = "
-alloc
-panic_unwind
-panic_abort
-core
-profiler_builtins
-unwind
-std_detect
-test";
-
-// core is required for our builtin derives to work in the proc_macro lib currently
-const PROC_MACRO_DEPS: &str = "
-std
-core";
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 54eb0e3478a..cfc666970bd 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/tests.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/tests.rs
@@ -1,5 +1,3 @@
-use std::ops::Deref;
-
 use base_db::{CrateGraph, ProcMacroPaths};
 use cargo_metadata::Metadata;
 use cfg::{CfgAtom, CfgDiff};
@@ -226,18 +224,6 @@ fn rust_project_cfg_groups() {
 }
 
 #[test]
-fn rust_project_is_proc_macro_has_proc_macro_dep() {
-    let (crate_graph, _proc_macros) = load_rust_project("is-proc-macro-project.json");
-    // Since the project only defines one crate (outside the sysroot crates),
-    // it should be the one with the biggest Id.
-    let crate_id = crate_graph.iter().max().unwrap();
-    let crate_data = &crate_graph[crate_id];
-    // Assert that the project crate with `is_proc_macro` has a dependency
-    // on the proc_macro sysroot crate.
-    crate_data.dependencies.iter().find(|&dep| *dep.name.deref() == sym::proc_macro).unwrap();
-}
-
-#[test]
 fn crate_graph_dedup_identical() {
     let (mut crate_graph, proc_macros) = load_cargo("regex-metadata.json");
 
diff --git a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
index 16b5bb11afa..2c9f41e828e 100644
--- a/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
+++ b/src/tools/rust-analyzer/crates/project-model/src/workspace.rs
@@ -23,7 +23,7 @@ use crate::{
     cargo_workspace::{CargoMetadataConfig, DepKind, PackageData, RustLibSource},
     env::{cargo_config_env, inject_cargo_env, inject_cargo_package_env, inject_rustc_tool_env},
     project_json::{Crate, CrateArrayIdx},
-    sysroot::{RustLibSrcCrate, RustLibSrcWorkspace},
+    sysroot::RustLibSrcWorkspace,
     toolchain_info::{rustc_cfg, target_data_layout, target_tuple, version, QueryConfig},
     CargoConfig, CargoWorkspace, CfgOverrides, InvocationStrategy, ManifestPath, Package,
     ProjectJson, ProjectManifest, RustSourceWorkspaceConfig, Sysroot, TargetData, TargetKind,
@@ -69,6 +69,7 @@ pub struct ProjectWorkspace {
 }
 
 #[derive(Clone)]
+#[allow(clippy::large_enum_variant)]
 pub enum ProjectWorkspaceKind {
     /// Project workspace was discovered by running `cargo metadata` and `rustc --print sysroot`.
     Cargo {
@@ -400,20 +401,17 @@ impl ProjectWorkspace {
     }
 
     pub fn load_inline(
-        project_json: ProjectJson,
+        mut project_json: ProjectJson,
         config: &CargoConfig,
         progress: &dyn Fn(String),
     ) -> ProjectWorkspace {
         progress("Discovering sysroot".to_owned());
         let mut sysroot =
             Sysroot::new(project_json.sysroot.clone(), project_json.sysroot_src.clone());
-        let loaded_sysroot = sysroot.load_workspace(&RustSourceWorkspaceConfig::Stitched);
-        if let Some(loaded_sysroot) = loaded_sysroot {
-            sysroot.set_workspace(loaded_sysroot);
-        }
 
         tracing::info!(workspace = %project_json.manifest_or_root(), src_root = ?sysroot.rust_lib_src_root(), root = ?sysroot.root(), "Using sysroot");
         progress("Querying project metadata".to_owned());
+        let sysroot_project = project_json.sysroot_project.take();
         let query_config = QueryConfig::Rustc(&sysroot, project_json.path().as_ref());
         let targets = target_tuple::get(query_config, config.target.as_deref(), &config.extra_env)
             .unwrap_or_default();
@@ -435,14 +433,33 @@ impl ProjectWorkspace {
                     &config.extra_env,
                 )
             });
-            thread::Result::Ok((toolchain.join()?, rustc_cfg.join()?, data_layout.join()?))
+            let loaded_sysroot = s.spawn(|| {
+                if let Some(sysroot_project) = sysroot_project {
+                    sysroot.load_workspace(&RustSourceWorkspaceConfig::Json(*sysroot_project))
+                } else {
+                    sysroot.load_workspace(&RustSourceWorkspaceConfig::CargoMetadata(
+                        sysroot_metadata_config(&config.extra_env, &targets),
+                    ))
+                }
+            });
+
+            thread::Result::Ok((
+                toolchain.join()?,
+                rustc_cfg.join()?,
+                data_layout.join()?,
+                loaded_sysroot.join()?,
+            ))
         });
 
-        let (toolchain, rustc_cfg, target_layout) = match join {
+        let (toolchain, rustc_cfg, target_layout, loaded_sysroot) = match join {
             Ok(it) => it,
             Err(e) => std::panic::resume_unwind(e),
         };
 
+        if let Some(loaded_sysroot) = loaded_sysroot {
+            sysroot.set_workspace(loaded_sysroot);
+        }
+
         ProjectWorkspace {
             kind: ProjectWorkspaceKind::Json(project_json),
             sysroot,
@@ -667,7 +684,15 @@ impl ProjectWorkspace {
                         Some(PackageRoot { is_local: false, include, exclude })
                     })
                     .collect(),
-                RustLibSrcWorkspace::Stitched(_) | RustLibSrcWorkspace::Empty => vec![],
+                RustLibSrcWorkspace::Json(project_json) => project_json
+                    .crates()
+                    .map(|(_, krate)| PackageRoot {
+                        is_local: false,
+                        include: krate.include.clone(),
+                        exclude: krate.exclude.clone(),
+                    })
+                    .collect(),
+                RustLibSrcWorkspace::Empty => vec![],
             };
 
             r.push(PackageRoot {
@@ -1069,8 +1094,7 @@ fn cargo_to_crate_graph(
 ) -> (CrateGraph, ProcMacroPaths) {
     let _p = tracing::info_span!("cargo_to_crate_graph").entered();
     let mut res = (CrateGraph::default(), ProcMacroPaths::default());
-    let crate_graph = &mut res.0;
-    let proc_macros = &mut res.1;
+    let (crate_graph, proc_macros) = &mut res;
     let (public_deps, libproc_macro) =
         sysroot_to_crate_graph(crate_graph, sysroot, rustc_cfg.clone(), load);
 
@@ -1490,6 +1514,69 @@ impl SysrootPublicDeps {
     }
 }
 
+fn extend_crate_graph_with_sysroot(
+    crate_graph: &mut CrateGraph,
+    mut sysroot_crate_graph: CrateGraph,
+    mut sysroot_proc_macros: ProcMacroPaths,
+) -> (SysrootPublicDeps, Option<CrateId>) {
+    let mut pub_deps = vec![];
+    let mut libproc_macro = None;
+    let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag(sym::test.clone())]).unwrap();
+    for (cid, c) in sysroot_crate_graph.iter_mut() {
+        // uninject `test` flag so `core` keeps working.
+        Arc::make_mut(&mut c.cfg_options).apply_diff(diff.clone());
+        // patch the origin
+        if c.origin.is_local() {
+            let lang_crate = LangCrateOrigin::from(
+                c.display_name.as_ref().map_or("", |it| it.canonical_name().as_str()),
+            );
+            c.origin = CrateOrigin::Lang(lang_crate);
+            match lang_crate {
+                LangCrateOrigin::Test
+                | LangCrateOrigin::Alloc
+                | LangCrateOrigin::Core
+                | LangCrateOrigin::Std => pub_deps.push((
+                    CrateName::normalize_dashes(&lang_crate.to_string()),
+                    cid,
+                    !matches!(lang_crate, LangCrateOrigin::Test | LangCrateOrigin::Alloc),
+                )),
+                LangCrateOrigin::ProcMacro => libproc_macro = Some(cid),
+                LangCrateOrigin::Other => (),
+            }
+        }
+    }
+
+    let mut marker_set = vec![];
+    for &(_, cid, _) in pub_deps.iter() {
+        marker_set.extend(sysroot_crate_graph.transitive_deps(cid));
+    }
+    if let Some(cid) = libproc_macro {
+        marker_set.extend(sysroot_crate_graph.transitive_deps(cid));
+    }
+
+    marker_set.sort();
+    marker_set.dedup();
+
+    // Remove all crates except the ones we are interested in to keep the sysroot graph small.
+    let removed_mapping = sysroot_crate_graph.remove_crates_except(&marker_set);
+    sysroot_proc_macros = sysroot_proc_macros
+        .into_iter()
+        .filter_map(|(k, v)| Some((removed_mapping[k.into_raw().into_u32() as usize]?, v)))
+        .collect();
+    let mapping = crate_graph.extend(sysroot_crate_graph, &mut sysroot_proc_macros);
+
+    // Map the id through the removal mapping first, then through the crate graph extension mapping.
+    pub_deps.iter_mut().for_each(|(_, cid, _)| {
+        *cid = mapping[&removed_mapping[cid.into_raw().into_u32() as usize].unwrap()]
+    });
+    if let Some(libproc_macro) = &mut libproc_macro {
+        *libproc_macro =
+            mapping[&removed_mapping[libproc_macro.into_raw().into_u32() as usize].unwrap()];
+    }
+
+    (SysrootPublicDeps { deps: pub_deps }, libproc_macro)
+}
+
 fn sysroot_to_crate_graph(
     crate_graph: &mut CrateGraph,
     sysroot: &Sysroot,
@@ -1499,7 +1586,7 @@ fn sysroot_to_crate_graph(
     let _p = tracing::info_span!("sysroot_to_crate_graph").entered();
     match sysroot.workspace() {
         RustLibSrcWorkspace::Workspace(cargo) => {
-            let (mut cg, mut pm) = cargo_to_crate_graph(
+            let (cg, pm) = cargo_to_crate_graph(
                 load,
                 None,
                 cargo,
@@ -1520,113 +1607,32 @@ fn sysroot_to_crate_graph(
                 false,
             );
 
-            let mut pub_deps = vec![];
-            let mut libproc_macro = None;
-            let diff = CfgDiff::new(vec![], vec![CfgAtom::Flag(sym::test.clone())]).unwrap();
-            for (cid, c) in cg.iter_mut() {
-                // uninject `test` flag so `core` keeps working.
-                Arc::make_mut(&mut c.cfg_options).apply_diff(diff.clone());
-                // patch the origin
-                if c.origin.is_local() {
-                    let lang_crate = LangCrateOrigin::from(
-                        c.display_name.as_ref().map_or("", |it| it.canonical_name().as_str()),
-                    );
-                    c.origin = CrateOrigin::Lang(lang_crate);
-                    match lang_crate {
-                        LangCrateOrigin::Test
-                        | LangCrateOrigin::Alloc
-                        | LangCrateOrigin::Core
-                        | LangCrateOrigin::Std => pub_deps.push((
-                            CrateName::normalize_dashes(&lang_crate.to_string()),
-                            cid,
-                            !matches!(lang_crate, LangCrateOrigin::Test | LangCrateOrigin::Alloc),
-                        )),
-                        LangCrateOrigin::ProcMacro => libproc_macro = Some(cid),
-                        LangCrateOrigin::Other => (),
-                    }
-                }
-            }
-
-            let mut marker_set = vec![];
-            for &(_, cid, _) in pub_deps.iter() {
-                marker_set.extend(cg.transitive_deps(cid));
-            }
-            if let Some(cid) = libproc_macro {
-                marker_set.extend(cg.transitive_deps(cid));
-            }
-
-            marker_set.sort();
-            marker_set.dedup();
-
-            // Remove all crates except the ones we are interested in to keep the sysroot graph small.
-            let removed_mapping = cg.remove_crates_except(&marker_set);
-            let mapping = crate_graph.extend(cg, &mut pm);
-
-            // Map the id through the removal mapping first, then through the crate graph extension mapping.
-            pub_deps.iter_mut().for_each(|(_, cid, _)| {
-                *cid = mapping[&removed_mapping[cid.into_raw().into_u32() as usize].unwrap()]
-            });
-            if let Some(libproc_macro) = &mut libproc_macro {
-                *libproc_macro = mapping
-                    [&removed_mapping[libproc_macro.into_raw().into_u32() as usize].unwrap()];
-            }
-
-            (SysrootPublicDeps { deps: pub_deps }, libproc_macro)
+            extend_crate_graph_with_sysroot(crate_graph, cg, pm)
         }
-        RustLibSrcWorkspace::Stitched(stitched) => {
-            let cfg_options = Arc::new({
-                let mut cfg_options = CfgOptions::default();
-                cfg_options.extend(rustc_cfg);
-                cfg_options.insert_atom(sym::debug_assertions.clone());
-                cfg_options.insert_atom(sym::miri.clone());
-                cfg_options
-            });
-            let sysroot_crates: FxHashMap<RustLibSrcCrate, CrateId> = stitched
-                .crates()
-                .filter_map(|krate| {
-                    let file_id = load(&stitched[krate].root)?;
-
-                    let display_name = CrateDisplayName::from_canonical_name(&stitched[krate].name);
-                    let crate_id = crate_graph.add_crate_root(
-                        file_id,
-                        Edition::CURRENT_FIXME,
-                        Some(display_name),
-                        None,
-                        cfg_options.clone(),
-                        None,
-                        Env::default(),
-                        CrateOrigin::Lang(LangCrateOrigin::from(&*stitched[krate].name)),
-                        false,
-                        None,
-                    );
-                    Some((krate, crate_id))
-                })
-                .collect();
-
-            for from in stitched.crates() {
-                for &to in stitched[from].deps.iter() {
-                    let name = CrateName::new(&stitched[to].name).unwrap();
-                    if let (Some(&from), Some(&to)) =
-                        (sysroot_crates.get(&from), sysroot_crates.get(&to))
-                    {
-                        add_dep(crate_graph, from, name, to);
-                    }
-                }
-            }
-
-            let public_deps = SysrootPublicDeps {
-                deps: stitched
-                    .public_deps()
-                    .filter_map(|(name, idx, prelude)| {
-                        Some((name, *sysroot_crates.get(&idx)?, prelude))
-                    })
-                    .collect::<Vec<_>>(),
-            };
+        RustLibSrcWorkspace::Json(project_json) => {
+            let (cg, pm) = project_json_to_crate_graph(
+                rustc_cfg,
+                load,
+                project_json,
+                &Sysroot::empty(),
+                &FxHashMap::default(),
+                &CfgOverrides {
+                    global: CfgDiff::new(
+                        vec![
+                            CfgAtom::Flag(sym::debug_assertions.clone()),
+                            CfgAtom::Flag(sym::miri.clone()),
+                        ],
+                        vec![],
+                    )
+                    .unwrap(),
+                    ..Default::default()
+                },
+                false,
+            );
 
-            let libproc_macro =
-                stitched.proc_macro().and_then(|it| sysroot_crates.get(&it).copied());
-            (public_deps, libproc_macro)
+            extend_crate_graph_with_sysroot(crate_graph, cg, pm)
         }
+
         RustLibSrcWorkspace::Empty => (SysrootPublicDeps { deps: vec![] }, None),
     }
 }
diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/is-proc-macro-project.json b/src/tools/rust-analyzer/crates/project-model/test_data/is-proc-macro-project.json
deleted file mode 100644
index 5d500a4729f..00000000000
--- a/src/tools/rust-analyzer/crates/project-model/test_data/is-proc-macro-project.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-    "sysroot_src": null,
-    "crates": [
-        {
-            "display_name": "is_proc_macro",
-            "root_module": "$ROOT$src/lib.rs",
-            "edition": "2018",
-            "deps": [],
-            "is_workspace_member": true,
-            "is_proc_macro": true
-        }
-    ]
-}
diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt
index 9b4be19c41c..28ca4eb5348 100644
--- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt
+++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_cfg_groups.txt
@@ -3,417 +3,6 @@
         root_file_id: FileId(
             1,
         ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "alloc",
-                ),
-                canonical_name: "alloc",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [
-            Dependency {
-                crate_id: Idx::<CrateData>(1),
-                name: CrateName(
-                    "core",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-        ],
-        origin: Lang(
-            Alloc,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    1: CrateData {
-        root_file_id: FileId(
-            2,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "core",
-                ),
-                canonical_name: "core",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [],
-        origin: Lang(
-            Core,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    2: CrateData {
-        root_file_id: FileId(
-            3,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "panic_abort",
-                ),
-                canonical_name: "panic_abort",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [],
-        origin: Lang(
-            Other,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    3: CrateData {
-        root_file_id: FileId(
-            4,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "panic_unwind",
-                ),
-                canonical_name: "panic_unwind",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [],
-        origin: Lang(
-            Other,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    4: CrateData {
-        root_file_id: FileId(
-            5,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "proc_macro",
-                ),
-                canonical_name: "proc_macro",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [
-            Dependency {
-                crate_id: Idx::<CrateData>(6),
-                name: CrateName(
-                    "std",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(1),
-                name: CrateName(
-                    "core",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-        ],
-        origin: Lang(
-            ProcMacro,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    5: CrateData {
-        root_file_id: FileId(
-            6,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "profiler_builtins",
-                ),
-                canonical_name: "profiler_builtins",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [],
-        origin: Lang(
-            Other,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    6: CrateData {
-        root_file_id: FileId(
-            7,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "std",
-                ),
-                canonical_name: "std",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [
-            Dependency {
-                crate_id: Idx::<CrateData>(0),
-                name: CrateName(
-                    "alloc",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(3),
-                name: CrateName(
-                    "panic_unwind",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(2),
-                name: CrateName(
-                    "panic_abort",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(1),
-                name: CrateName(
-                    "core",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(5),
-                name: CrateName(
-                    "profiler_builtins",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(9),
-                name: CrateName(
-                    "unwind",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(7),
-                name: CrateName(
-                    "std_detect",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(8),
-                name: CrateName(
-                    "test",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-        ],
-        origin: Lang(
-            Std,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    7: CrateData {
-        root_file_id: FileId(
-            8,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "std_detect",
-                ),
-                canonical_name: "std_detect",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [],
-        origin: Lang(
-            Other,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    8: CrateData {
-        root_file_id: FileId(
-            9,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "test",
-                ),
-                canonical_name: "test",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [],
-        origin: Lang(
-            Test,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    9: CrateData {
-        root_file_id: FileId(
-            10,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "unwind",
-                ),
-                canonical_name: "unwind",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [],
-        origin: Lang(
-            Other,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    10: CrateData {
-        root_file_id: FileId(
-            11,
-        ),
         edition: Edition2018,
         version: None,
         display_name: Some(
@@ -438,48 +27,7 @@
         env: Env {
             entries: {},
         },
-        dependencies: [
-            Dependency {
-                crate_id: Idx::<CrateData>(1),
-                name: CrateName(
-                    "core",
-                ),
-                prelude: true,
-                sysroot: true,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(0),
-                name: CrateName(
-                    "alloc",
-                ),
-                prelude: false,
-                sysroot: true,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(6),
-                name: CrateName(
-                    "std",
-                ),
-                prelude: true,
-                sysroot: true,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(8),
-                name: CrateName(
-                    "test",
-                ),
-                prelude: false,
-                sysroot: true,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(4),
-                name: CrateName(
-                    "proc_macro",
-                ),
-                prelude: false,
-                sysroot: true,
-            },
-        ],
+        dependencies: [],
         origin: Local {
             repo: None,
             name: Some(
@@ -489,9 +37,9 @@
         is_proc_macro: false,
         proc_macro_cwd: None,
     },
-    11: CrateData {
+    1: CrateData {
         root_file_id: FileId(
-            11,
+            1,
         ),
         edition: Edition2018,
         version: None,
@@ -517,48 +65,7 @@
         env: Env {
             entries: {},
         },
-        dependencies: [
-            Dependency {
-                crate_id: Idx::<CrateData>(1),
-                name: CrateName(
-                    "core",
-                ),
-                prelude: true,
-                sysroot: true,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(0),
-                name: CrateName(
-                    "alloc",
-                ),
-                prelude: false,
-                sysroot: true,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(6),
-                name: CrateName(
-                    "std",
-                ),
-                prelude: true,
-                sysroot: true,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(8),
-                name: CrateName(
-                    "test",
-                ),
-                prelude: false,
-                sysroot: true,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(4),
-                name: CrateName(
-                    "proc_macro",
-                ),
-                prelude: false,
-                sysroot: true,
-            },
-        ],
+        dependencies: [],
         origin: Local {
             repo: None,
             name: Some(
diff --git a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt
index 4c8e66e8e96..dde8d3023dc 100644
--- a/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt
+++ b/src/tools/rust-analyzer/crates/project-model/test_data/output/rust_project_hello_world_project_model.txt
@@ -3,417 +3,6 @@
         root_file_id: FileId(
             1,
         ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "alloc",
-                ),
-                canonical_name: "alloc",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [
-            Dependency {
-                crate_id: Idx::<CrateData>(1),
-                name: CrateName(
-                    "core",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-        ],
-        origin: Lang(
-            Alloc,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    1: CrateData {
-        root_file_id: FileId(
-            2,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "core",
-                ),
-                canonical_name: "core",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [],
-        origin: Lang(
-            Core,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    2: CrateData {
-        root_file_id: FileId(
-            3,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "panic_abort",
-                ),
-                canonical_name: "panic_abort",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [],
-        origin: Lang(
-            Other,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    3: CrateData {
-        root_file_id: FileId(
-            4,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "panic_unwind",
-                ),
-                canonical_name: "panic_unwind",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [],
-        origin: Lang(
-            Other,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    4: CrateData {
-        root_file_id: FileId(
-            5,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "proc_macro",
-                ),
-                canonical_name: "proc_macro",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [
-            Dependency {
-                crate_id: Idx::<CrateData>(6),
-                name: CrateName(
-                    "std",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(1),
-                name: CrateName(
-                    "core",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-        ],
-        origin: Lang(
-            ProcMacro,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    5: CrateData {
-        root_file_id: FileId(
-            6,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "profiler_builtins",
-                ),
-                canonical_name: "profiler_builtins",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [],
-        origin: Lang(
-            Other,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    6: CrateData {
-        root_file_id: FileId(
-            7,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "std",
-                ),
-                canonical_name: "std",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [
-            Dependency {
-                crate_id: Idx::<CrateData>(0),
-                name: CrateName(
-                    "alloc",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(3),
-                name: CrateName(
-                    "panic_unwind",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(2),
-                name: CrateName(
-                    "panic_abort",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(1),
-                name: CrateName(
-                    "core",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(5),
-                name: CrateName(
-                    "profiler_builtins",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(9),
-                name: CrateName(
-                    "unwind",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(7),
-                name: CrateName(
-                    "std_detect",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(8),
-                name: CrateName(
-                    "test",
-                ),
-                prelude: true,
-                sysroot: false,
-            },
-        ],
-        origin: Lang(
-            Std,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    7: CrateData {
-        root_file_id: FileId(
-            8,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "std_detect",
-                ),
-                canonical_name: "std_detect",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [],
-        origin: Lang(
-            Other,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    8: CrateData {
-        root_file_id: FileId(
-            9,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "test",
-                ),
-                canonical_name: "test",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [],
-        origin: Lang(
-            Test,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    9: CrateData {
-        root_file_id: FileId(
-            10,
-        ),
-        edition: Edition2021,
-        version: None,
-        display_name: Some(
-            CrateDisplayName {
-                crate_name: CrateName(
-                    "unwind",
-                ),
-                canonical_name: "unwind",
-            },
-        ),
-        cfg_options: CfgOptions(
-            [
-                "debug_assertions",
-                "miri",
-                "true",
-            ],
-        ),
-        potential_cfg_options: None,
-        env: Env {
-            entries: {},
-        },
-        dependencies: [],
-        origin: Lang(
-            Other,
-        ),
-        is_proc_macro: false,
-        proc_macro_cwd: None,
-    },
-    10: CrateData {
-        root_file_id: FileId(
-            11,
-        ),
         edition: Edition2018,
         version: None,
         display_name: Some(
@@ -435,48 +24,7 @@
         env: Env {
             entries: {},
         },
-        dependencies: [
-            Dependency {
-                crate_id: Idx::<CrateData>(1),
-                name: CrateName(
-                    "core",
-                ),
-                prelude: true,
-                sysroot: true,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(0),
-                name: CrateName(
-                    "alloc",
-                ),
-                prelude: false,
-                sysroot: true,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(6),
-                name: CrateName(
-                    "std",
-                ),
-                prelude: true,
-                sysroot: true,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(8),
-                name: CrateName(
-                    "test",
-                ),
-                prelude: false,
-                sysroot: true,
-            },
-            Dependency {
-                crate_id: Idx::<CrateData>(4),
-                name: CrateName(
-                    "proc_macro",
-                ),
-                prelude: false,
-                sysroot: true,
-            },
-        ],
+        dependencies: [],
         origin: Local {
             repo: None,
             name: Some(
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
index b8ce2b7430b..6c81c238fd3 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/Cargo.toml
@@ -13,7 +13,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [[bin]]
 name = "rust-analyzer"
@@ -94,7 +93,7 @@ syntax-bridge.workspace = true
 
 [features]
 jemalloc = ["jemallocator", "profile/jemalloc"]
-force-always-assert = ["always-assert/force"]
+force-always-assert = ["stdx/force-always-assert"]
 sysroot-abi = []
 in-rust-tree = [
   "sysroot-abi",
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
index 1dce0bea1a9..713e28c87cb 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/config.rs
@@ -128,6 +128,8 @@ config_data! {
         /// Whether to show keyword hover popups. Only applies when
         /// `#rust-analyzer.hover.documentation.enable#` is set.
         hover_documentation_keywords_enable: bool  = true,
+        /// Whether to show drop glue information on hover.
+        hover_dropGlue_enable: bool                = true,
         /// Use markdown syntax for links on hover.
         hover_links_enable: bool = true,
         /// Whether to show what types are used as generic arguments in calls etc. on hover, and what is their max length to show such types, beyond it they will be shown with ellipsis.
@@ -1631,6 +1633,7 @@ impl Config {
                 Some(MaxSubstitutionLength::Limit(limit)) => ide::SubstTyLen::LimitTo(*limit),
                 None => ide::SubstTyLen::Unlimited,
             },
+            show_drop_glue: *self.hover_dropGlue_enable(),
         }
     }
 
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
index 1b144d90732..b91a5dbd416 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/handlers/request.rs
@@ -941,9 +941,7 @@ pub(crate) fn handle_runnables(
 
         let update_test = runnable.update_test;
         if let Some(mut runnable) = to_proto::runnable(&snap, runnable)? {
-            if let Some(runnable) =
-                to_proto::make_update_runnable(&runnable, &update_test.label(), &update_test.env())
-            {
+            if let Some(runnable) = to_proto::make_update_runnable(&runnable, update_test) {
                 res.push(runnable);
             }
 
@@ -2158,7 +2156,7 @@ fn runnable_action_links(
 
     if hover_actions_config.update_test && client_commands_config.run_single {
         let label = update_test.label();
-        if let Some(r) = to_proto::make_update_runnable(&r, &label, &update_test.env()) {
+        if let Some(r) = to_proto::make_update_runnable(&r, update_test) {
             let update_command = to_proto::command::run_single(&r, label.unwrap().as_str());
             group.commands.push(to_command_link(update_command, r.label.clone()));
         }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs
index b1136dbbdac..9c6b69d7312 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/capabilities.rs
@@ -165,7 +165,7 @@ pub fn server_capabilities(config: &Config) -> ServerCapabilities {
         })),
         diagnostic_provider: Some(lsp_types::DiagnosticServerCapabilities::Options(
             lsp_types::DiagnosticOptions {
-                identifier: None,
+                identifier: Some("rust-analyzer".to_owned()),
                 inter_file_dependencies: true,
                 // FIXME
                 workspace_diagnostics: false,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs
index bff53cf98b7..446549c9070 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/lsp/to_proto.rs
@@ -14,13 +14,13 @@ use ide::{
     InlayFieldsToResolve, InlayHint, InlayHintLabel, InlayHintLabelPart, InlayKind, LazyProperty,
     Markup, NavigationTarget, ReferenceCategory, RenameError, Runnable, Severity, SignatureHelp,
     SnippetEdit, SourceChange, StructureNodeKind, SymbolKind, TextEdit, TextRange, TextSize,
+    UpdateTest,
 };
 use ide_db::{assists, rust_doc::format_docs, FxHasher};
 use itertools::Itertools;
 use paths::{Utf8Component, Utf8Prefix};
 use semver::VersionReq;
 use serde_json::to_value;
-use syntax::SmolStr;
 use vfs::AbsPath;
 
 use crate::{
@@ -1623,8 +1623,7 @@ pub(crate) fn code_lens(
                     }
                     if lens_config.update_test && client_commands_config.run_single {
                         let label = update_test.label();
-                        let env = update_test.env();
-                        if let Some(r) = make_update_runnable(&r, &label, &env) {
+                        if let Some(r) = make_update_runnable(&r, update_test) {
                             let command = command::run_single(&r, label.unwrap().as_str());
                             acc.push(lsp_types::CodeLens {
                                 range: annotation_range,
@@ -1871,22 +1870,22 @@ pub(crate) mod command {
 
 pub(crate) fn make_update_runnable(
     runnable: &lsp_ext::Runnable,
-    label: &Option<SmolStr>,
-    env: &[(&str, &str)],
+    update_test: UpdateTest,
 ) -> Option<lsp_ext::Runnable> {
-    if !matches!(runnable.args, lsp_ext::RunnableArgs::Cargo(_)) {
-        return None;
-    }
-    let label = label.as_ref()?;
+    let label = update_test.label()?;
 
     let mut runnable = runnable.clone();
     runnable.label = format!("{} + {}", runnable.label, label);
 
     let lsp_ext::RunnableArgs::Cargo(r) = &mut runnable.args else {
-        unreachable!();
+        return None;
     };
 
-    r.environment.extend(env.iter().map(|(k, v)| (k.to_string(), v.to_string())));
+    r.environment.extend(update_test.env().iter().map(|(k, v)| (k.to_string(), v.to_string())));
+
+    if update_test.insta {
+        r.cargo_args.insert(0, "insta".to_owned());
+    }
 
     Some(runnable)
 }
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/op_queue.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/op_queue.rs
index 123f20605ab..709d99bda75 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/op_queue.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/op_queue.rs
@@ -6,7 +6,7 @@ pub(crate) type Cause = String;
 /// A single-item queue that allows callers to request an operation to
 /// be performed later.
 ///
-/// ```
+/// ```ignore
 /// let queue = OpQueue::default();
 ///
 /// // Request work to be done.
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs
index 02ae4186ab6..4f208b6c5dd 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/config.rs
@@ -31,7 +31,7 @@ pub struct Config<T> {
     /// that specify level.
     pub chalk_filter: Option<String>,
     /// Filtering syntax, set in a shell:
-    /// ```
+    /// ```text
     /// env RA_PROFILE=*             // dump everything
     /// env RA_PROFILE=foo|bar|baz   // enabled only selected entries
     /// env RA_PROFILE=*@3>10        // dump everything, up to depth 3, if it takes more than 10
@@ -39,7 +39,7 @@ pub struct Config<T> {
     pub profile_filter: Option<String>,
 
     /// Filtering syntax, set in a shell:
-    /// ```
+    /// ```text
     /// env RA_PROFILE_JSON=foo|bar|baz
     /// ```
     pub json_profile_filter: Option<String>,
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/hprof.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/hprof.rs
index d466acef011..5b18762bb97 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/hprof.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/hprof.rs
@@ -6,7 +6,8 @@
 //!
 //! Usage:
 //!
-//! ```rust
+//! ```ignore
+//! # use tracing_subscriber::Registry;
 //! let layer = hprof::SpanTree::default();
 //! Registry::default().with(layer).init();
 //! ```
diff --git a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/json.rs b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/json.rs
index 9e35990a5bc..f5394d023a1 100644
--- a/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/json.rs
+++ b/src/tools/rust-analyzer/crates/rust-analyzer/src/tracing/json.rs
@@ -2,7 +2,8 @@
 //!
 //! Usage:
 //!
-//! ```rust
+//! ```ignore
+//! # use tracing_subscriber::Registry;
 //! let layer = json::TimingLayer::new(std::io::stderr);
 //! Registry::default().with(layer).init();
 //! ```
diff --git a/src/tools/rust-analyzer/crates/stdx/Cargo.toml b/src/tools/rust-analyzer/crates/stdx/Cargo.toml
index 1ebb48c577a..3727d0c9562 100644
--- a/src/tools/rust-analyzer/crates/stdx/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/stdx/Cargo.toml
@@ -10,15 +10,14 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 backtrace = { version = "0.3.67", optional = true }
-always-assert = { version = "0.2.0", features = ["tracing"] }
 jod-thread = "0.1.2"
 libc.workspace = true
 crossbeam-channel.workspace = true
 itertools.workspace = true
+tracing.workspace = true
 # Think twice before adding anything here
 
 [target.'cfg(windows)'.dependencies]
@@ -28,6 +27,7 @@ windows-sys = { version = "0.59", features = ["Win32_Foundation"] }
 [features]
 # Uncomment to enable for the whole crate graph
 # default = [ "backtrace" ]
+force-always-assert = []
 
 [lints]
 workspace = true
diff --git a/src/tools/rust-analyzer/crates/stdx/src/anymap.rs b/src/tools/rust-analyzer/crates/stdx/src/anymap.rs
index 91fab8e9238..faf2e6c7178 100644
--- a/src/tools/rust-analyzer/crates/stdx/src/anymap.rs
+++ b/src/tools/rust-analyzer/crates/stdx/src/anymap.rs
@@ -83,7 +83,8 @@ pub type RawMap<A> = hash_map::HashMap<TypeId, Box<A>, BuildHasherDefault<TypeId
 /// (Here using the [`AnyMap`] convenience alias; the first line could use
 /// <code>[anymap::Map][Map]::&lt;[core::any::Any]&gt;::new()</code> instead if desired.)
 ///
-/// ```rust
+/// ```
+/// # use stdx::anymap;
 #[doc = "let mut data = anymap::AnyMap::new();"]
 /// assert_eq!(data.get(), None::<&i32>);
 /// ```
diff --git a/src/tools/rust-analyzer/crates/stdx/src/assert.rs b/src/tools/rust-analyzer/crates/stdx/src/assert.rs
new file mode 100644
index 00000000000..91c279798c2
--- /dev/null
+++ b/src/tools/rust-analyzer/crates/stdx/src/assert.rs
@@ -0,0 +1,115 @@
+// Vendored from https://github.com/matklad/always-assert/commit/4cf564eea6fcf18b30c3c3483a611004dc03afbb
+//! Recoverable assertions, inspired by [the use of `assert()` in
+//! SQLite](https://www.sqlite.org/assert.html).
+//!
+//! `never!` and `always!` return the actual value of the condition if
+//! `debug_assertions` are disabled.
+//!
+//! Use them when terminating on assertion failure is worse than continuing.
+//!
+//! One example would be a critical application like a database:
+//!
+//! ```ignore
+//! use stdx::never;
+//!
+//! fn apply_transaction(&mut self, tx: Transaction) -> Result<(), TransactionAborted> {
+//!     let delta = self.compute_delta(&tx);
+//!
+//!     if never!(!self.check_internal_invariant(&delta)) {
+//!         // Ok, something in this transaction messed up our internal state.
+//!         // This really shouldn't be happening, and this signifies a bug.
+//!         // Luckily, we can recover by just rejecting the transaction.
+//!         return abort_transaction(tx);
+//!     }
+//!     self.commit(delta);
+//!     Ok(())
+//! }
+//! ```
+//!
+//! Another example is assertions about non-critical functionality in usual apps
+//!
+//! ```ignore
+//! use stdx::never;
+//!
+//! let english_message = "super app installed!"
+//! let mut local_message = localize(english_message);
+//! if never!(local_message.is_empty(), "missing localization for {}", english_message) {
+//!     // We localized all the messages but this one slipper through the cracks?
+//!     // Better to show the english one then than to fail outright;
+//!     local_message = english_message;
+//! }
+//! println!("{}", local_message);
+//! ```
+
+/// Asserts that the condition is always true and returns its actual value.
+///
+/// If the condition is true does nothing and and evaluates to true.
+///
+/// If the condition is false:
+/// * panics if `force` feature or `debug_assertions` are enabled,
+/// * logs an error if the `tracing` feature is enabled,
+/// * evaluates to false.
+///
+/// Accepts `format!` style arguments.
+#[macro_export]
+macro_rules! always {
+    ($cond:expr) => {
+        $crate::always!($cond, "assertion failed: {}", stringify!($cond))
+    };
+
+    ($cond:expr, $fmt:literal $($arg:tt)*) => {{
+        let cond = $cond;
+        if cfg!(debug_assertions) || $crate::assert::__FORCE {
+            assert!(cond, $fmt $($arg)*);
+        }
+        if !cond {
+            $crate::assert::__tracing_error!($fmt $($arg)*);
+        }
+        cond
+    }};
+}
+
+/// Asserts that the condition is never true and returns its actual value.
+///
+/// If the condition is false does nothing and and evaluates to false.
+///
+/// If the condition is true:
+/// * panics if `force` feature or `debug_assertions` are enabled,
+/// * logs an error if the `tracing` feature is enabled,
+/// * evaluates to true.
+///
+/// Accepts `format!` style arguments.
+///
+/// Empty condition is equivalent to false:
+///
+/// ```ignore
+/// never!("oups") ~= unreachable!("oups")
+/// ```
+#[macro_export]
+macro_rules! never {
+    (true $($tt:tt)*) => { $crate::never!((true) $($tt)*) };
+    (false $($tt:tt)*) => { $crate::never!((false) $($tt)*) };
+    () => { $crate::never!("assertion failed: entered unreachable code") };
+    ($fmt:literal $(, $($arg:tt)*)?) => {{
+        if cfg!(debug_assertions) || $crate::assert::__FORCE {
+            unreachable!($fmt $(, $($arg)*)?);
+        }
+        $crate::assert::__tracing_error!($fmt $(, $($arg)*)?);
+    }};
+
+    ($cond:expr) => {{
+        let cond = !$crate::always!(!$cond);
+        cond
+    }};
+
+    ($cond:expr, $fmt:literal $($arg:tt)*) => {{
+        let cond = !$crate::always!(!$cond, $fmt $($arg)*);
+        cond
+    }};
+}
+
+#[doc(hidden)]
+pub use tracing::error as __tracing_error;
+
+#[doc(hidden)]
+pub const __FORCE: bool = cfg!(feature = "force-always-assert");
diff --git a/src/tools/rust-analyzer/crates/stdx/src/lib.rs b/src/tools/rust-analyzer/crates/stdx/src/lib.rs
index 04c2153abf4..8313e1871f1 100644
--- a/src/tools/rust-analyzer/crates/stdx/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/stdx/src/lib.rs
@@ -4,8 +4,10 @@ use std::io as sio;
 use std::process::Command;
 use std::{cmp::Ordering, ops, time::Instant};
 
-pub mod anymap;
 mod macros;
+
+pub mod anymap;
+pub mod assert;
 pub mod non_empty_vec;
 pub mod panic_context;
 pub mod process;
@@ -13,7 +15,6 @@ pub mod rand;
 pub mod thin_vec;
 pub mod thread;
 
-pub use always_assert::{always, never};
 pub use itertools;
 
 #[inline(always)]
diff --git a/src/tools/rust-analyzer/crates/stdx/src/macros.rs b/src/tools/rust-analyzer/crates/stdx/src/macros.rs
index 85d9008fe12..880e2da70fc 100644
--- a/src/tools/rust-analyzer/crates/stdx/src/macros.rs
+++ b/src/tools/rust-analyzer/crates/stdx/src/macros.rs
@@ -34,7 +34,7 @@ macro_rules! format_to_acc {
 ///
 /// # Example
 ///
-/// ```rust
+/// ```ignore
 /// impl_from!(Struct, Union, Enum for Adt);
 /// ```
 #[macro_export]
diff --git a/src/tools/rust-analyzer/crates/syntax-bridge/Cargo.toml b/src/tools/rust-analyzer/crates/syntax-bridge/Cargo.toml
index f9a9f40541d..3e663422a04 100644
--- a/src/tools/rust-analyzer/crates/syntax-bridge/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/syntax-bridge/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 rustc-hash.workspace = true
diff --git a/src/tools/rust-analyzer/crates/syntax/Cargo.toml b/src/tools/rust-analyzer/crates/syntax/Cargo.toml
index 51eaea54346..3fe6e01dc3c 100644
--- a/src/tools/rust-analyzer/crates/syntax/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/syntax/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 cov-mark = "2.0.0-pre.1"
diff --git a/src/tools/rust-analyzer/crates/syntax/rust.ungram b/src/tools/rust-analyzer/crates/syntax/rust.ungram
index bbb8413cbc0..88d7beb897e 100644
--- a/src/tools/rust-analyzer/crates/syntax/rust.ungram
+++ b/src/tools/rust-analyzer/crates/syntax/rust.ungram
@@ -438,9 +438,9 @@ MacroExpr =
 Literal =
   Attr* value:(
     '@int_number' | '@float_number'
-  | '@string' | '@raw_string'
-  | '@byte_string' | '@raw_byte_string'
-  | '@c_string' | '@raw_c_string'
+  | '@string'
+  | '@byte_string'
+  | '@c_string'
   | '@char' | '@byte'
   | 'true' | 'false'
   )
diff --git a/src/tools/rust-analyzer/crates/syntax/src/algo.rs b/src/tools/rust-analyzer/crates/syntax/src/algo.rs
index 2acb2158318..a8a83893946 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/algo.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/algo.rs
@@ -3,8 +3,8 @@
 use itertools::Itertools;
 
 use crate::{
-    AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TextRange,
-    TextSize,
+    syntax_editor::Element, AstNode, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode,
+    SyntaxToken, TextRange, TextSize,
 };
 
 /// Returns ancestors of the node at the offset, sorted by length. This should
@@ -25,7 +25,7 @@ pub fn ancestors_at_offset(
 /// imprecise: if the cursor is strictly between two nodes of the desired type,
 /// as in
 ///
-/// ```no_run
+/// ```ignore
 /// struct Foo {}|struct Bar;
 /// ```
 ///
@@ -89,6 +89,26 @@ pub fn least_common_ancestor(u: &SyntaxNode, v: &SyntaxNode) -> Option<SyntaxNod
     Some(res)
 }
 
+pub fn least_common_ancestor_element(u: impl Element, v: impl Element) -> Option<SyntaxNode> {
+    let u = u.syntax_element();
+    let v = v.syntax_element();
+    if u == v {
+        return match u {
+            NodeOrToken::Node(node) => Some(node),
+            NodeOrToken::Token(token) => token.parent(),
+        };
+    }
+
+    let u_depth = u.ancestors().count();
+    let v_depth = v.ancestors().count();
+    let keep = u_depth.min(v_depth);
+
+    let u_candidates = u.ancestors().skip(u_depth - keep);
+    let v_candidates = v.ancestors().skip(v_depth - keep);
+    let (res, _) = u_candidates.zip(v_candidates).find(|(x, y)| x == y)?;
+    Some(res)
+}
+
 pub fn neighbor<T: AstNode>(me: &T, direction: Direction) -> Option<T> {
     me.syntax().siblings(direction).skip(1).find_map(T::cast)
 }
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs
index 579f3ba8b4f..052d018e5c9 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/edit.rs
@@ -72,9 +72,9 @@ impl IndentLevel {
     }
 
     /// XXX: this intentionally doesn't change the indent of the very first token.
-    /// Ie, in something like
+    /// For example, in something like:
     /// ```
-    /// fn foo() {
+    /// fn foo() -> i32 {
     ///    92
     /// }
     /// ```
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
index 9dc2d832530..231c21c38f8 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/make.rs
@@ -784,7 +784,7 @@ pub fn record_pat_field_shorthand(name_ref: ast::NameRef) -> ast::RecordPatField
     ast_from_text(&format!("fn f(S {{ {name_ref} }}: ()))"))
 }
 
-/// Returns a `BindPat` if the path has just one segment, a `PathPat` otherwise.
+/// Returns a `IdentPat` if the path has just one segment, a `PathPat` otherwise.
 pub fn path_pat(path: ast::Path) -> ast::Pat {
     return from_text(&path.to_string());
     fn from_text(text: &str) -> ast::Pat {
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs
index 5d33f132ac1..0c4da762992 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/prec.rs
@@ -7,7 +7,7 @@ use crate::{
 
 #[derive(Debug, Clone, Copy, PartialEq, PartialOrd)]
 pub enum ExprPrecedence {
-    // return, break, yield, closures
+    // return val, break val, yield val, closures
     Jump,
     // = += -= *= /= %= &= |= ^= <<= >>=
     Assign,
@@ -35,10 +35,27 @@ pub enum ExprPrecedence {
     Cast,
     // unary - * ! & &mut
     Prefix,
-    // paths, loops, function calls, array indexing, field expressions, method calls
+    // function calls, array indexing, field expressions, method calls
+    Postfix,
+    // paths, loops,
     Unambiguous,
 }
 
+impl ExprPrecedence {
+    pub fn needs_parentheses_in(self, other: ExprPrecedence) -> bool {
+        match other {
+            ExprPrecedence::Unambiguous => false,
+            // postfix ops have higher precedence than any other operator, so we need to wrap
+            // any inner expression that is below
+            ExprPrecedence::Postfix => self < ExprPrecedence::Postfix,
+            // We need to wrap all binary like things, thats everything below prefix except for
+            // jumps (as those are prefix operations as well)
+            ExprPrecedence::Prefix => ExprPrecedence::Jump < self && self < ExprPrecedence::Prefix,
+            parent => self <= parent,
+        }
+    }
+}
+
 #[derive(PartialEq, Debug)]
 pub enum Fixity {
     /// The operator is left-associative
@@ -56,11 +73,18 @@ pub fn precedence(expr: &ast::Expr) -> ExprPrecedence {
             Some(_) => ExprPrecedence::Unambiguous,
         },
 
+        Expr::BreakExpr(e) if e.expr().is_some() => ExprPrecedence::Jump,
+        Expr::BecomeExpr(e) if e.expr().is_some() => ExprPrecedence::Jump,
+        Expr::ReturnExpr(e) if e.expr().is_some() => ExprPrecedence::Jump,
+        Expr::YeetExpr(e) if e.expr().is_some() => ExprPrecedence::Jump,
+        Expr::YieldExpr(e) if e.expr().is_some() => ExprPrecedence::Jump,
+
         Expr::BreakExpr(_)
-        | Expr::ContinueExpr(_)
+        | Expr::BecomeExpr(_)
         | Expr::ReturnExpr(_)
         | Expr::YeetExpr(_)
-        | Expr::YieldExpr(_) => ExprPrecedence::Jump,
+        | Expr::YieldExpr(_)
+        | Expr::ContinueExpr(_) => ExprPrecedence::Unambiguous,
 
         Expr::RangeExpr(..) => ExprPrecedence::Range,
 
@@ -89,27 +113,27 @@ pub fn precedence(expr: &ast::Expr) -> ExprPrecedence {
 
         Expr::LetExpr(_) | Expr::PrefixExpr(_) | Expr::RefExpr(_) => ExprPrecedence::Prefix,
 
+        Expr::AwaitExpr(_)
+        | Expr::CallExpr(_)
+        | Expr::FieldExpr(_)
+        | Expr::IndexExpr(_)
+        | Expr::MethodCallExpr(_)
+        | Expr::TryExpr(_) => ExprPrecedence::Postfix,
+
         Expr::ArrayExpr(_)
         | Expr::AsmExpr(_)
-        | Expr::AwaitExpr(_)
-        | Expr::BecomeExpr(_)
         | Expr::BlockExpr(_)
-        | Expr::CallExpr(_)
-        | Expr::FieldExpr(_)
         | Expr::ForExpr(_)
         | Expr::FormatArgsExpr(_)
         | Expr::IfExpr(_)
-        | Expr::IndexExpr(_)
         | Expr::Literal(_)
         | Expr::LoopExpr(_)
         | Expr::MacroExpr(_)
         | Expr::MatchExpr(_)
-        | Expr::MethodCallExpr(_)
         | Expr::OffsetOfExpr(_)
         | Expr::ParenExpr(_)
         | Expr::PathExpr(_)
         | Expr::RecordExpr(_)
-        | Expr::TryExpr(_)
         | Expr::TupleExpr(_)
         | Expr::UnderscoreExpr(_)
         | Expr::WhileExpr(_) => ExprPrecedence::Unambiguous,
@@ -128,7 +152,7 @@ impl Expr {
     //   - https://github.com/rust-lang/rust/blob/b6852428a8ea9728369b64b9964cad8e258403d3/compiler/rustc_ast/src/util/parser.rs#L296
 
     /// Returns `true` if `self` would need to be wrapped in parentheses given that its parent is `parent`.
-    pub fn needs_parens_in(&self, parent: SyntaxNode) -> bool {
+    pub fn needs_parens_in(&self, parent: &SyntaxNode) -> bool {
         match_ast! {
             match parent {
                 ast::Expr(e) => self.needs_parens_in_expr(&e),
@@ -384,6 +408,7 @@ impl Expr {
             BreakExpr(e) => e.expr().is_none(),
             ContinueExpr(_) => true,
             YieldExpr(e) => e.expr().is_none(),
+            BecomeExpr(e) => e.expr().is_none(),
             _ => false,
         }
     }
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory.rs
index 73bbe49105d..1c517ac2c77 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory.rs
@@ -33,6 +33,11 @@ impl SyntaxFactory {
         self.mappings.unwrap_or_default().into_inner()
     }
 
+    /// Take all of the tracked syntax mappings, leaving `SyntaxMapping::default()` in its place, if any.
+    pub fn take(&self) -> SyntaxMapping {
+        self.mappings.as_ref().map(|mappings| mappings.take()).unwrap_or_default()
+    }
+
     fn mappings(&self) -> Option<RefMut<'_, SyntaxMapping>> {
         self.mappings.as_ref().map(|it| it.borrow_mut())
     }
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs
index 572622db544..85393ca5b4c 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/syntax_factory/constructors.rs
@@ -129,7 +129,7 @@ impl SyntaxFactory {
 
         if let Some(mut mapping) = self.mappings() {
             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
-            builder.map_children(input.into_iter(), ast.segments().map(|it| it.syntax().clone()));
+            builder.map_children(input, ast.segments().map(|it| it.syntax().clone()));
             builder.finish(&mut mapping);
         }
 
@@ -156,6 +156,32 @@ impl SyntaxFactory {
         make::literal_pat(text).clone_for_update()
     }
 
+    pub fn slice_pat(&self, pats: impl IntoIterator<Item = ast::Pat>) -> ast::SlicePat {
+        let (pats, input) = iterator_input(pats);
+        let ast = make::slice_pat(pats).clone_for_update();
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_children(input, ast.pats().map(|it| it.syntax().clone()));
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
+    pub fn tuple_pat(&self, pats: impl IntoIterator<Item = ast::Pat>) -> ast::TuplePat {
+        let (pats, input) = iterator_input(pats);
+        let ast = make::tuple_pat(pats).clone_for_update();
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_children(input, ast.fields().map(|it| it.syntax().clone()));
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
     pub fn tuple_struct_pat(
         &self,
         path: ast::Path,
@@ -167,13 +193,103 @@ impl SyntaxFactory {
         if let Some(mut mapping) = self.mappings() {
             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
             builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone());
-            builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone()));
+            builder.map_children(input, ast.fields().map(|it| it.syntax().clone()));
             builder.finish(&mut mapping);
         }
 
         ast
     }
 
+    pub fn record_pat_with_fields(
+        &self,
+        path: ast::Path,
+        fields: ast::RecordPatFieldList,
+    ) -> ast::RecordPat {
+        let ast = make::record_pat_with_fields(path.clone(), fields.clone()).clone_for_update();
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone());
+            builder.map_node(
+                fields.syntax().clone(),
+                ast.record_pat_field_list().unwrap().syntax().clone(),
+            );
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
+    pub fn record_pat_field_list(
+        &self,
+        fields: impl IntoIterator<Item = ast::RecordPatField>,
+        rest_pat: Option<ast::RestPat>,
+    ) -> ast::RecordPatFieldList {
+        let (fields, input) = iterator_input(fields);
+        let ast = make::record_pat_field_list(fields, rest_pat.clone()).clone_for_update();
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_children(input, ast.fields().map(|it| it.syntax().clone()));
+            if let Some(rest_pat) = rest_pat {
+                builder
+                    .map_node(rest_pat.syntax().clone(), ast.rest_pat().unwrap().syntax().clone());
+            }
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
+    pub fn record_pat_field(self, name_ref: ast::NameRef, pat: ast::Pat) -> ast::RecordPatField {
+        let ast = make::record_pat_field(name_ref.clone(), pat.clone()).clone_for_update();
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_node(name_ref.syntax().clone(), ast.name_ref().unwrap().syntax().clone());
+            builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone());
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
+    pub fn record_pat_field_shorthand(&self, name_ref: ast::NameRef) -> ast::RecordPatField {
+        let ast = make::record_pat_field_shorthand(name_ref.clone()).clone_for_update();
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_node(name_ref.syntax().clone(), ast.pat().unwrap().syntax().clone());
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
+    pub fn path_pat(&self, path: ast::Path) -> ast::Pat {
+        let ast = make::path_pat(path.clone()).clone_for_update();
+
+        match &ast {
+            ast::Pat::PathPat(ast) => {
+                if let Some(mut mapping) = self.mappings() {
+                    let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+                    builder.map_node(path.syntax().clone(), ast.path().unwrap().syntax().clone());
+                    builder.finish(&mut mapping)
+                }
+            }
+            ast::Pat::IdentPat(ast) => {
+                if let Some(mut mapping) = self.mappings() {
+                    let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+                    builder.map_node(path.syntax().clone(), ast.name().unwrap().syntax().clone());
+                    builder.finish(&mut mapping)
+                }
+            }
+            _ => unreachable!(),
+        }
+
+        ast
+    }
+
     pub fn block_expr(
         &self,
         statements: impl IntoIterator<Item = ast::Stmt>,
@@ -199,10 +315,7 @@ impl SyntaxFactory {
                 builder.map_node(last_stmt, ast_tail.syntax().clone());
             }
 
-            builder.map_children(
-                input.into_iter(),
-                stmt_list.statements().map(|it| it.syntax().clone()),
-            );
+            builder.map_children(input, stmt_list.statements().map(|it| it.syntax().clone()));
 
             builder.finish(&mut mapping);
         }
@@ -214,13 +327,28 @@ impl SyntaxFactory {
         make::expr_empty_block().clone_for_update()
     }
 
+    pub fn expr_paren(&self, expr: ast::Expr) -> ast::ParenExpr {
+        // FIXME: `make::expr_paren` should return a `ParenExpr`, not just an `Expr`
+        let ast::Expr::ParenExpr(ast) = make::expr_paren(expr.clone()).clone_for_update() else {
+            unreachable!()
+        };
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_node(expr.syntax().clone(), ast.expr().unwrap().syntax().clone());
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
     pub fn expr_tuple(&self, fields: impl IntoIterator<Item = ast::Expr>) -> ast::TupleExpr {
         let (fields, input) = iterator_input(fields);
         let ast = make::expr_tuple(fields).clone_for_update();
 
         if let Some(mut mapping) = self.mappings() {
             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
-            builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone()));
+            builder.map_children(input, ast.fields().map(|it| it.syntax().clone()));
             builder.finish(&mut mapping);
         }
 
@@ -292,13 +420,38 @@ impl SyntaxFactory {
         ast
     }
 
+    pub fn expr_method_call(
+        &self,
+        receiver: ast::Expr,
+        method: ast::NameRef,
+        arg_list: ast::ArgList,
+    ) -> ast::MethodCallExpr {
+        // FIXME: `make::expr_method_call` should return a `MethodCallExpr`, not just an `Expr`
+        let ast::Expr::MethodCallExpr(ast) =
+            make::expr_method_call(receiver.clone(), method.clone(), arg_list.clone())
+                .clone_for_update()
+        else {
+            unreachable!()
+        };
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_node(receiver.syntax().clone(), ast.receiver().unwrap().syntax().clone());
+            builder.map_node(method.syntax().clone(), ast.name_ref().unwrap().syntax().clone());
+            builder.map_node(arg_list.syntax().clone(), ast.arg_list().unwrap().syntax().clone());
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
     pub fn arg_list(&self, args: impl IntoIterator<Item = ast::Expr>) -> ast::ArgList {
         let (args, input) = iterator_input(args);
         let ast = make::arg_list(args).clone_for_update();
 
         if let Some(mut mapping) = self.mappings() {
             let mut builder = SyntaxMappingBuilder::new(ast.syntax.clone());
-            builder.map_children(input.into_iter(), ast.args().map(|it| it.syntax().clone()));
+            builder.map_children(input, ast.args().map(|it| it.syntax().clone()));
             builder.finish(&mut mapping);
         }
 
@@ -320,6 +473,31 @@ impl SyntaxFactory {
         ast.into()
     }
 
+    pub fn expr_closure(
+        &self,
+        pats: impl IntoIterator<Item = ast::Param>,
+        expr: ast::Expr,
+    ) -> ast::ClosureExpr {
+        let (args, input) = iterator_input(pats);
+        // FIXME: `make::expr_paren` should return a `ClosureExpr`, not just an `Expr`
+        let ast::Expr::ClosureExpr(ast) = make::expr_closure(args, expr.clone()).clone_for_update()
+        else {
+            unreachable!()
+        };
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax.clone());
+            builder.map_children(
+                input,
+                ast.param_list().unwrap().params().map(|param| param.syntax().clone()),
+            );
+            builder.map_node(expr.syntax().clone(), ast.body().unwrap().syntax().clone());
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
     pub fn expr_return(&self, expr: Option<ast::Expr>) -> ast::ReturnExpr {
         let ast::Expr::ReturnExpr(ast) = make::expr_return(expr.clone()).clone_for_update() else {
             unreachable!()
@@ -448,7 +626,7 @@ impl SyntaxFactory {
 
         if let Some(mut mapping) = self.mappings() {
             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
-            builder.map_children(input.into_iter(), ast.arms().map(|it| it.syntax().clone()));
+            builder.map_children(input, ast.arms().map(|it| it.syntax().clone()));
             builder.finish(&mut mapping);
         }
 
@@ -571,6 +749,19 @@ impl SyntaxFactory {
         ast
     }
 
+    pub fn param(&self, pat: ast::Pat, ty: ast::Type) -> ast::Param {
+        let ast = make::param(pat.clone(), ty.clone());
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+            builder.map_node(pat.syntax().clone(), ast.pat().unwrap().syntax().clone());
+            builder.map_node(ty.syntax().clone(), ast.ty().unwrap().syntax().clone());
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
     pub fn generic_arg_list(
         &self,
         generic_args: impl IntoIterator<Item = ast::GenericArg>,
@@ -585,10 +776,7 @@ impl SyntaxFactory {
 
         if let Some(mut mapping) = self.mappings() {
             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
-            builder.map_children(
-                input.into_iter(),
-                ast.generic_args().map(|arg| arg.syntax().clone()),
-            );
+            builder.map_children(input, ast.generic_args().map(|arg| arg.syntax().clone()));
             builder.finish(&mut mapping);
         }
 
@@ -605,7 +793,7 @@ impl SyntaxFactory {
         if let Some(mut mapping) = self.mappings() {
             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
 
-            builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone()));
+            builder.map_children(input, ast.fields().map(|it| it.syntax().clone()));
 
             builder.finish(&mut mapping);
         }
@@ -650,7 +838,7 @@ impl SyntaxFactory {
         if let Some(mut mapping) = self.mappings() {
             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
 
-            builder.map_children(input.into_iter(), ast.fields().map(|it| it.syntax().clone()));
+            builder.map_children(input, ast.fields().map(|it| it.syntax().clone()));
 
             builder.finish(&mut mapping);
         }
@@ -745,7 +933,7 @@ impl SyntaxFactory {
         if let Some(mut mapping) = self.mappings() {
             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
 
-            builder.map_children(input.into_iter(), ast.variants().map(|it| it.syntax().clone()));
+            builder.map_children(input, ast.variants().map(|it| it.syntax().clone()));
 
             builder.finish(&mut mapping);
         }
@@ -797,6 +985,69 @@ impl SyntaxFactory {
         ast
     }
 
+    pub fn fn_(
+        &self,
+        visibility: Option<ast::Visibility>,
+        fn_name: ast::Name,
+        type_params: Option<ast::GenericParamList>,
+        where_clause: Option<ast::WhereClause>,
+        params: ast::ParamList,
+        body: ast::BlockExpr,
+        ret_type: Option<ast::RetType>,
+        is_async: bool,
+        is_const: bool,
+        is_unsafe: bool,
+        is_gen: bool,
+    ) -> ast::Fn {
+        let ast = make::fn_(
+            visibility.clone(),
+            fn_name.clone(),
+            type_params.clone(),
+            where_clause.clone(),
+            params.clone(),
+            body.clone(),
+            ret_type.clone(),
+            is_async,
+            is_const,
+            is_unsafe,
+            is_gen,
+        );
+
+        if let Some(mut mapping) = self.mappings() {
+            let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
+
+            if let Some(visibility) = visibility {
+                builder.map_node(
+                    visibility.syntax().clone(),
+                    ast.visibility().unwrap().syntax().clone(),
+                );
+            }
+            builder.map_node(fn_name.syntax().clone(), ast.name().unwrap().syntax().clone());
+            if let Some(type_params) = type_params {
+                builder.map_node(
+                    type_params.syntax().clone(),
+                    ast.generic_param_list().unwrap().syntax().clone(),
+                );
+            }
+            if let Some(where_clause) = where_clause {
+                builder.map_node(
+                    where_clause.syntax().clone(),
+                    ast.where_clause().unwrap().syntax().clone(),
+                );
+            }
+            builder.map_node(params.syntax().clone(), ast.param_list().unwrap().syntax().clone());
+            builder.map_node(body.syntax().clone(), ast.body().unwrap().syntax().clone());
+            if let Some(ret_type) = ret_type {
+                builder
+                    .map_node(ret_type.syntax().clone(), ast.ret_type().unwrap().syntax().clone());
+            }
+
+            builder.finish(&mut mapping);
+        }
+
+        ast
+    }
+
     pub fn token_tree(
         &self,
         delimiter: SyntaxKind,
@@ -809,10 +1060,7 @@ impl SyntaxFactory {
 
         if let Some(mut mapping) = self.mappings() {
             let mut builder = SyntaxMappingBuilder::new(ast.syntax().clone());
-            builder.map_children(
-                input.into_iter(),
-                ast.token_trees_and_tokens().filter_map(only_nodes),
-            );
+            builder.map_children(input, ast.token_trees_and_tokens().filter_map(only_nodes));
             builder.finish(&mut mapping);
         }
 
diff --git a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs
index 7d5ca270435..df851ab5b25 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/ast/token_ext.rs
@@ -269,7 +269,7 @@ impl ast::ByteString {
             }
             (Ok(c), true) => {
                 buf.reserve_exact(text.len());
-                buf.extend_from_slice(text[..prev_end].as_bytes());
+                buf.extend_from_slice(&text.as_bytes()[..prev_end]);
                 buf.push(c as u8);
             }
             (Err(e), _) => has_error = Some(e),
@@ -333,7 +333,7 @@ impl ast::CString {
             }
             (Ok(u), true) => {
                 buf.reserve_exact(text.len());
-                buf.extend(text[..prev_end].as_bytes());
+                buf.extend(&text.as_bytes()[..prev_end]);
                 extend_unit(&mut buf, u);
             }
             (Err(e), _) => has_error = Some(e),
diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs
index b82181ae13a..48c160b9a9a 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor.rs
@@ -5,6 +5,7 @@
 //! [`SyntaxEditor`]: https://github.com/dotnet/roslyn/blob/43b0b05cc4f492fd5de00f6f6717409091df8daa/src/Workspaces/Core/Portable/Editing/SyntaxEditor.cs
 
 use std::{
+    fmt,
     num::NonZeroU32,
     ops::RangeInclusive,
     sync::atomic::{AtomicU32, Ordering},
@@ -282,6 +283,64 @@ enum ChangeKind {
     Replace,
 }
 
+impl fmt::Display for Change {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Change::Insert(position, node_or_token) => {
+                let parent = position.parent();
+                let mut parent_str = parent.to_string();
+                let target_range = self.target_range().start() - parent.text_range().start();
+
+                parent_str.insert_str(
+                    target_range.into(),
+                    &format!("\x1b[42m{node_or_token}\x1b[0m\x1b[K"),
+                );
+                f.write_str(&parent_str)
+            }
+            Change::InsertAll(position, vec) => {
+                let parent = position.parent();
+                let mut parent_str = parent.to_string();
+                let target_range = self.target_range().start() - parent.text_range().start();
+                let insertion: String = vec.iter().map(|it| it.to_string()).collect();
+
+                parent_str
+                    .insert_str(target_range.into(), &format!("\x1b[42m{insertion}\x1b[0m\x1b[K"));
+                f.write_str(&parent_str)
+            }
+            Change::Replace(old, new) => {
+                if let Some(new) = new {
+                    write!(f, "\x1b[41m{old}\x1b[42m{new}\x1b[0m\x1b[K")
+                } else {
+                    write!(f, "\x1b[41m{old}\x1b[0m\x1b[K")
+                }
+            }
+            Change::ReplaceWithMany(old, vec) => {
+                let new: String = vec.iter().map(|it| it.to_string()).collect();
+                write!(f, "\x1b[41m{old}\x1b[42m{new}\x1b[0m\x1b[K")
+            }
+            Change::ReplaceAll(range, vec) => {
+                let parent = range.start().parent().unwrap();
+                let parent_str = parent.to_string();
+                let pre_range =
+                    TextRange::new(parent.text_range().start(), range.start().text_range().start());
+                let old_range = TextRange::new(
+                    range.start().text_range().start(),
+                    range.end().text_range().end(),
+                );
+                let post_range =
+                    TextRange::new(range.end().text_range().end(), parent.text_range().end());
+
+                let pre_str = &parent_str[pre_range - parent.text_range().start()];
+                let old_str = &parent_str[old_range - parent.text_range().start()];
+                let post_str = &parent_str[post_range - parent.text_range().start()];
+                let new: String = vec.iter().map(|it| it.to_string()).collect();
+
+                write!(f, "{pre_str}\x1b[41m{old_str}\x1b[42m{new}\x1b[0m\x1b[K{post_str}")
+            }
+        }
+    }
+}
+
 /// Utility trait to allow calling syntax editor functions with references or owned
 /// nodes. Do not use outside of this module.
 pub trait Element {
diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs
index 57ecbe57019..fa51fb6eef4 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/edit_algo.rs
@@ -1,9 +1,14 @@
 //! Implementation of applying changes to a syntax tree.
 
-use std::{cmp::Ordering, collections::VecDeque, ops::RangeInclusive};
+use std::{
+    cmp::Ordering,
+    collections::VecDeque,
+    ops::{Range, RangeInclusive},
+};
 
 use rowan::TextRange;
 use rustc_hash::FxHashMap;
+use stdx::format_to;
 
 use crate::{
     syntax_editor::{mapping::MissingMapping, Change, ChangeKind, PositionRepr},
@@ -76,11 +81,9 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
                 || (l.target_range().end() <= r.target_range().start())
         });
 
-    if stdx::never!(
-        !disjoint_replaces_ranges,
-        "some replace change ranges intersect: {:?}",
-        changes
-    ) {
+    if !disjoint_replaces_ranges {
+        report_intersecting_changes(&changes, get_node_depth, &root);
+
         return SyntaxEdit {
             old_root: root.clone(),
             new_root: root,
@@ -99,6 +102,7 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
     let mut changed_ancestors: VecDeque<ChangedAncestor> = VecDeque::new();
     let mut dependent_changes = vec![];
     let mut independent_changes = vec![];
+    let mut outdated_changes = vec![];
 
     for (change_index, change) in changes.iter().enumerate() {
         // Check if this change is dependent on another change (i.e. it's contained within another range)
@@ -113,10 +117,14 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
             // FIXME: Resolve changes that depend on a range of elements
             let ancestor = &changed_ancestors[index];
 
-            dependent_changes.push(DependentChange {
-                parent: ancestor.change_index as u32,
-                child: change_index as u32,
-            });
+            if let Change::Replace(_, None) = changes[ancestor.change_index] {
+                outdated_changes.push(change_index as u32);
+            } else {
+                dependent_changes.push(DependentChange {
+                    parent: ancestor.change_index as u32,
+                    child: change_index as u32,
+                });
+            }
         } else {
             // This change is independent of any other change
 
@@ -192,8 +200,9 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
             Change::Replace(target, Some(new_target)) => {
                 (to_owning_node(target), to_owning_node(new_target))
             }
-            // Silently drop outdated change
-            Change::Replace(_, None) => continue,
+            Change::Replace(_, None) => {
+                unreachable!("deletions should not generate dependent changes")
+            }
             Change::ReplaceAll(_, _) | Change::ReplaceWithMany(_, _) => {
                 unimplemented!("cannot resolve changes that depend on replacing many elements")
             }
@@ -231,6 +240,12 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
         }
     }
 
+    // We reverse here since we pushed to this in ascending order,
+    // and we want to remove elements in descending order
+    for idx in outdated_changes.into_iter().rev() {
+        changes.remove(idx as usize);
+    }
+
     // Apply changes
     let mut root = tree_mutator.mutable_clone;
 
@@ -293,6 +308,78 @@ pub(super) fn apply_edits(editor: SyntaxEditor) -> SyntaxEdit {
     }
 }
 
+fn report_intersecting_changes(
+    changes: &[Change],
+    mut get_node_depth: impl FnMut(rowan::SyntaxNode<crate::RustLanguage>) -> usize,
+    root: &rowan::SyntaxNode<crate::RustLanguage>,
+) {
+    let intersecting_changes = changes
+        .iter()
+        .zip(changes.iter().skip(1))
+        .filter(|(l, r)| {
+            // We only care about checking for disjoint replace ranges.
+            matches!(
+                (l.change_kind(), r.change_kind()),
+                (
+                    ChangeKind::Replace | ChangeKind::ReplaceRange,
+                    ChangeKind::Replace | ChangeKind::ReplaceRange
+                )
+            )
+        })
+        .filter(|(l, r)| {
+            get_node_depth(l.target_parent()) == get_node_depth(r.target_parent())
+                && (l.target_range().end() > r.target_range().start())
+        });
+
+    let mut error_msg = String::from("some replace change ranges intersect!\n");
+
+    let parent_str = root.to_string();
+
+    for (l, r) in intersecting_changes {
+        let mut highlighted_str = parent_str.clone();
+        let l_range = l.target_range();
+        let r_range = r.target_range();
+
+        let i_range = l_range.intersect(r_range).unwrap();
+        let i_str = format!("\x1b[46m{}", &parent_str[i_range]);
+
+        let pre_range: Range<usize> = l_range.start().into()..i_range.start().into();
+        let pre_str = format!("\x1b[44m{}", &parent_str[pre_range]);
+
+        let (highlight_range, highlight_str) = if l_range == r_range {
+            format_to!(error_msg, "\x1b[46mleft change:\x1b[0m  {l:?} {l}\n");
+            format_to!(error_msg, "\x1b[46mequals\x1b[0m\n");
+            format_to!(error_msg, "\x1b[46mright change:\x1b[0m {r:?} {r}\n");
+            let i_highlighted = format!("{i_str}\x1b[0m\x1b[K");
+            let total_range: Range<usize> = i_range.into();
+            (total_range, i_highlighted)
+        } else {
+            format_to!(error_msg, "\x1b[44mleft change:\x1b[0m  {l:?} {l}\n");
+            let range_end = if l_range.contains_range(r_range) {
+                format_to!(error_msg, "\x1b[46mcovers\x1b[0m\n");
+                format_to!(error_msg, "\x1b[46mright change:\x1b[0m {r:?} {r}\n");
+                l_range.end()
+            } else {
+                format_to!(error_msg, "\x1b[46mintersects\x1b[0m\n");
+                format_to!(error_msg, "\x1b[42mright change:\x1b[0m {r:?} {r}\n");
+                r_range.end()
+            };
+
+            let post_range: Range<usize> = i_range.end().into()..range_end.into();
+
+            let post_str = format!("\x1b[42m{}", &parent_str[post_range]);
+            let result = format!("{pre_str}{i_str}{post_str}\x1b[0m\x1b[K");
+            let total_range: Range<usize> = l_range.start().into()..range_end.into();
+            (total_range, result)
+        };
+        highlighted_str.replace_range(highlight_range, &highlight_str);
+
+        format_to!(error_msg, "{highlighted_str}\n");
+    }
+
+    stdx::always!(false, "{}", error_msg);
+}
+
 fn to_owning_node(element: &SyntaxElement) -> SyntaxNode {
     match element {
         SyntaxElement::Node(node) => node.clone(),
diff --git a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs
index 16bc55ed2d4..f71925a7955 100644
--- a/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs
+++ b/src/tools/rust-analyzer/crates/syntax/src/syntax_editor/mapping.rs
@@ -239,10 +239,10 @@ impl SyntaxMappingBuilder {
 
     pub fn map_children(
         &mut self,
-        input: impl Iterator<Item = SyntaxNode>,
-        output: impl Iterator<Item = SyntaxNode>,
+        input: impl IntoIterator<Item = SyntaxNode>,
+        output: impl IntoIterator<Item = SyntaxNode>,
     ) {
-        for pairs in input.zip_longest(output) {
+        for pairs in input.into_iter().zip_longest(output) {
             let (input, output) = match pairs {
                 itertools::EitherOrBoth::Both(l, r) => (l, r),
                 itertools::EitherOrBoth::Left(_) => {
diff --git a/src/tools/rust-analyzer/crates/test-utils/Cargo.toml b/src/tools/rust-analyzer/crates/test-utils/Cargo.toml
index b1457722a92..b99a2c4bd75 100644
--- a/src/tools/rust-analyzer/crates/test-utils/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/test-utils/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 # Avoid adding deps here, this crate is widely used in tests it should compile fast!
diff --git a/src/tools/rust-analyzer/crates/test-utils/src/assert_linear.rs b/src/tools/rust-analyzer/crates/test-utils/src/assert_linear.rs
index 15c30c52a54..f78bf59a2fd 100644
--- a/src/tools/rust-analyzer/crates/test-utils/src/assert_linear.rs
+++ b/src/tools/rust-analyzer/crates/test-utils/src/assert_linear.rs
@@ -11,7 +11,7 @@
 //! Ideally, we should use a proper "model selection" to directly compare
 //! quadratic and linear models, but that sounds rather complicated:
 //!
-//!     https://stats.stackexchange.com/questions/21844/selecting-best-model-based-on-linear-quadratic-and-cubic-fit-of-data
+//! > https://stats.stackexchange.com/questions/21844/selecting-best-model-based-on-linear-quadratic-and-cubic-fit-of-data
 //!
 //! We might get false positives on a VM, but never false negatives. So, if the
 //! first round fails, we repeat the ordeal three more times and fail only if
diff --git a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs
index 7fe26d53bf2..7240069753e 100644
--- a/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs
+++ b/src/tools/rust-analyzer/crates/test-utils/src/fixture.rs
@@ -6,7 +6,8 @@
 //! Use this to test functionality local to one file.
 //!
 //! Simple Example:
-//! ```
+//!
+//! ```ignore
 //! r#"
 //! fn main() {
 //!     println!("Hello World")
@@ -19,7 +20,8 @@
 //! which is also how to define multiple files in a single test fixture
 //!
 //! Example using two files in the same crate:
-//! ```
+//!
+//! ```ignore
 //! "
 //! //- /main.rs
 //! mod foo;
@@ -33,7 +35,8 @@
 //! ```
 //!
 //! Example using two crates with one file each, with one crate depending on the other:
-//! ```
+//!
+//! ```ignore
 //! r#"
 //! //- /main.rs crate:a deps:b
 //! fn main() {
@@ -51,7 +54,8 @@
 //! for the syntax.
 //!
 //! Example using some available metadata:
-//! ```
+//!
+//! ```ignore
 //! "
 //! //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo
 //! fn insert_source_code_here() {}
@@ -214,16 +218,11 @@ impl FixtureWithProjectMeta {
                 );
             }
 
-            if line.starts_with("//-") {
+            if let Some(line) = line.strip_prefix("//-") {
                 let meta = Self::parse_meta_line(line);
                 res.push(meta);
             } else {
-                if line.starts_with("// ")
-                    && line.contains(':')
-                    && !line.contains("::")
-                    && !line.contains('.')
-                    && line.chars().all(|it| !it.is_uppercase())
-                {
+                if matches!(line.strip_prefix("// "), Some(l) if l.trim().starts_with('/')) {
                     panic!("looks like invalid metadata line: {line:?}");
                 }
 
@@ -238,8 +237,7 @@ impl FixtureWithProjectMeta {
 
     //- /lib.rs crate:foo deps:bar,baz cfg:foo=a,bar=b env:OUTDIR=path/to,OTHER=foo
     fn parse_meta_line(meta: &str) -> Fixture {
-        assert!(meta.starts_with("//-"));
-        let meta = meta["//-".len()..].trim();
+        let meta = meta.trim();
         let mut components = meta.split_ascii_whitespace();
 
         let path = components.next().expect("fixture meta must start with a path").to_owned();
diff --git a/src/tools/rust-analyzer/crates/test-utils/src/lib.rs b/src/tools/rust-analyzer/crates/test-utils/src/lib.rs
index e7279fa1f66..d3afac85017 100644
--- a/src/tools/rust-analyzer/crates/test-utils/src/lib.rs
+++ b/src/tools/rust-analyzer/crates/test-utils/src/lib.rs
@@ -421,8 +421,8 @@ pub fn format_diff(chunks: Vec<dissimilar::Chunk<'_>>) -> String {
     for chunk in chunks {
         let formatted = match chunk {
             dissimilar::Chunk::Equal(text) => text.into(),
-            dissimilar::Chunk::Delete(text) => format!("\x1b[41m{text}\x1b[0m"),
-            dissimilar::Chunk::Insert(text) => format!("\x1b[42m{text}\x1b[0m"),
+            dissimilar::Chunk::Delete(text) => format!("\x1b[41m{text}\x1b[0m\x1b[K"),
+            dissimilar::Chunk::Insert(text) => format!("\x1b[42m{text}\x1b[0m\x1b[K"),
         };
         buf.push_str(&formatted);
     }
diff --git a/src/tools/rust-analyzer/crates/toolchain/Cargo.toml b/src/tools/rust-analyzer/crates/toolchain/Cargo.toml
index 87e8efb20fc..38daacdf951 100644
--- a/src/tools/rust-analyzer/crates/toolchain/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/toolchain/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 home = "0.5.4"
diff --git a/src/tools/rust-analyzer/crates/tt/Cargo.toml b/src/tools/rust-analyzer/crates/tt/Cargo.toml
index 82e7c24668f..529fad3244a 100644
--- a/src/tools/rust-analyzer/crates/tt/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/tt/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 arrayvec.workspace = true
diff --git a/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml b/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml
index bc54d7168f0..48b4d22de2f 100644
--- a/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/vfs-notify/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 tracing.workspace = true
diff --git a/src/tools/rust-analyzer/crates/vfs/Cargo.toml b/src/tools/rust-analyzer/crates/vfs/Cargo.toml
index e8a6195036e..546195481c6 100644
--- a/src/tools/rust-analyzer/crates/vfs/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/vfs/Cargo.toml
@@ -10,7 +10,6 @@ license.workspace = true
 rust-version.workspace = true
 
 [lib]
-doctest = false
 
 [dependencies]
 rustc-hash.workspace = true
diff --git a/src/tools/rust-analyzer/crates/vfs/src/anchored_path.rs b/src/tools/rust-analyzer/crates/vfs/src/anchored_path.rs
index db15a2a21cd..1b9fb355b48 100644
--- a/src/tools/rust-analyzer/crates/vfs/src/anchored_path.rs
+++ b/src/tools/rust-analyzer/crates/vfs/src/anchored_path.rs
@@ -2,7 +2,7 @@
 //!
 //! The primary goal of this is to losslessly represent paths like
 //!
-//! ```
+//! ```ignore
 //! #[path = "./bar.rs"]
 //! mod foo;
 //! ```
diff --git a/src/tools/rust-analyzer/crates/vfs/src/vfs_path.rs b/src/tools/rust-analyzer/crates/vfs/src/vfs_path.rs
index 3c8e37413f6..cce8595cc4a 100644
--- a/src/tools/rust-analyzer/crates/vfs/src/vfs_path.rs
+++ b/src/tools/rust-analyzer/crates/vfs/src/vfs_path.rs
@@ -59,7 +59,7 @@ impl VfsPath {
     ///
     /// # Example
     ///
-    /// ```
+    /// ```ignore
     /// # use vfs::{AbsPathBuf, VfsPath};
     /// let mut path = VfsPath::from(AbsPathBuf::assert("/foo/bar".into()));
     /// assert!(path.pop());
diff --git a/src/tools/rust-analyzer/docs/book/src/assists_generated.md b/src/tools/rust-analyzer/docs/book/src/assists_generated.md
index 9d68a873ffe..c2063df5068 100644
--- a/src/tools/rust-analyzer/docs/book/src/assists_generated.md
+++ b/src/tools/rust-analyzer/docs/book/src/assists_generated.md
@@ -257,7 +257,7 @@ fn main() {
 
 
 ### `apply_demorgan`
-**Source:**  [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L16) 
+**Source:**  [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L23) 
 
 Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws).
 This transforms expressions of the form `!l || !r` into `!(l && r)`.
@@ -280,7 +280,7 @@ fn main() {
 
 
 ### `apply_demorgan_iterator`
-**Source:**  [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L132) 
+**Source:**  [apply_demorgan.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/apply_demorgan.rs#L154) 
 
 Apply [De Morgan's law](https://en.wikipedia.org/wiki/De_Morgan%27s_laws) to
 `Iterator::all` and `Iterator::any`.
@@ -419,7 +419,7 @@ Converts comments to documentation.
 
 
 ### `convert_bool_then_to_if`
-**Source:**  [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L131) 
+**Source:**  [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L143) 
 
 Converts a `bool::then` method call to an equivalent if expression.
 
@@ -443,7 +443,7 @@ fn main() {
 
 
 ### `convert_closure_to_fn`
-**Source:**  [convert_closure_to_fn.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_closure_to_fn.rs#L25) 
+**Source:**  [convert_closure_to_fn.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_closure_to_fn.rs#L27) 
 
 This converts a closure to a freestanding function, changing all captures to parameters.
 
@@ -527,7 +527,7 @@ impl TryFrom<usize> for Thing {
 
 
 ### `convert_if_to_bool_then`
-**Source:**  [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L20) 
+**Source:**  [convert_bool_then.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/convert_bool_then.rs#L21) 
 
 Converts an if expression into a corresponding `bool::then` call.
 
@@ -1345,6 +1345,26 @@ fn main() {
 ```
 
 
+### `flip_or_pattern`
+**Source:**  [flip_or_pattern.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/flip_or_pattern.rs#L9) 
+
+Flips two trait bounds.
+
+#### Before
+```rust
+fn foo() {
+    let (a |┃ b) = 1;
+}
+```
+
+#### After
+```rust
+fn foo() {
+    let (b | a) = 1;
+}
+```
+
+
 ### `flip_trait_bound`
 **Source:**  [flip_trait_bound.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/flip_trait_bound.rs#L9) 
 
@@ -2161,7 +2181,7 @@ struct Ctx<T: Clone> {
     data: T,
 }
 
-impl<T: Clone> ${0:_} for Ctx<T> {}
+impl<T: Clone> ${1:_} for Ctx<T> {┃}
 ```
 
 
@@ -2258,7 +2278,7 @@ fn bar() {
 
 
 ### `inline_local_variable`
-**Source:**  [inline_local_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_local_variable.rs#L17) 
+**Source:**  [inline_local_variable.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/inline_local_variable.rs#L21) 
 
 Inlines a local variable.
 
@@ -2974,7 +2994,7 @@ impl Walrus {
 
 
 ### `remove_parentheses`
-**Source:**  [remove_parentheses.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_parentheses.rs#L5) 
+**Source:**  [remove_parentheses.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_parentheses.rs#L9) 
 
 Removes redundant parentheses.
 
@@ -3015,7 +3035,7 @@ mod foo {
 
 
 ### `remove_unused_param`
-**Source:**  [remove_unused_param.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_unused_param.rs#L15) 
+**Source:**  [remove_unused_param.rs](https://github.com/rust-lang/rust-analyzer/blob/master/crates/ide-assists/src/handlers/remove_unused_param.rs#L16) 
 
 Removes unused function parameter.
 
diff --git a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md
index 0c6674b1408..1cbe51836f4 100644
--- a/src/tools/rust-analyzer/docs/book/src/configuration_generated.md
+++ b/src/tools/rust-analyzer/docs/book/src/configuration_generated.md
@@ -559,6 +559,11 @@ also need to add the folders to Code's `files.watcherExclude`.
 `#rust-analyzer.hover.documentation.enable#` is set.
 
 
+**rust-analyzer.hover.dropGlue.enable** (default: true)
+
+ Whether to show drop glue information on hover.
+
+
 **rust-analyzer.hover.links.enable** (default: true)
 
  Use markdown syntax for links on hover.
diff --git a/src/tools/rust-analyzer/docs/book/src/contributing/setup.md b/src/tools/rust-analyzer/docs/book/src/contributing/setup.md
index d8a7840d376..eab65e779ed 100644
--- a/src/tools/rust-analyzer/docs/book/src/contributing/setup.md
+++ b/src/tools/rust-analyzer/docs/book/src/contributing/setup.md
@@ -17,10 +17,13 @@ Since rust-analyzer is a Rust project, you will need to install Rust. You can do
 **Step 04**: Install the language server locally by running the following command:
 
 ```sh
-cargo xtask install --server --code-bin code-insiders --dev-rel
+# Install only the language server  
+cargo xtask install --server \  
+    --code-bin code-insiders \  # Target a specific editor (code, code-exploration, code-insiders, codium, or code-oss)  
+    --dev-rel  # Build in release mode with debug info level 2  
 ```
 
-In the output of this command, there should be a file path provided to the installed binary on  your local machine.
+In the output of this command, there should be a file path provided to the installed binary on your local machine.
 It should look something like the following output below:
 
 ```
@@ -48,9 +51,12 @@ An example debugging statement could go into the `main_loop.rs` file which can b
 ```rs
 eprintln!("Hello, world!");
 ```
+Now, run the following commands to check the project and reinstall the server:  
 
-Now we run `cargo build` and `sh
-cargo xtask install --server --code-bin code-insiders --dev-rel` to reinstall the server.
+```sh  
+cargo check  
+cargo xtask install --server --code-bin code-insiders --dev-rel  
+```  
 
 Now on Visual Studio Code Insiders, we should be able to open the Output tab on our terminal and switch to Rust Analyzer Language Server to see the `eprintln!` statement we just wrote.
 
diff --git a/src/tools/rust-analyzer/editors/code/.eslintignore b/src/tools/rust-analyzer/editors/code/.eslintignore
deleted file mode 100644
index 3a1e8e186f5..00000000000
--- a/src/tools/rust-analyzer/editors/code/.eslintignore
+++ /dev/null
@@ -1,2 +0,0 @@
-node_modules
-.eslintrc.js
diff --git a/src/tools/rust-analyzer/editors/code/.eslintrc.js b/src/tools/rust-analyzer/editors/code/.eslintrc.js
deleted file mode 100644
index 9705c5f5ec6..00000000000
--- a/src/tools/rust-analyzer/editors/code/.eslintrc.js
+++ /dev/null
@@ -1,46 +0,0 @@
-module.exports = {
-    env: {
-        es6: true,
-        node: true,
-    },
-    extends: ["prettier"],
-    parser: "@typescript-eslint/parser",
-    parserOptions: {
-        project: true,
-        tsconfigRootDir: __dirname,
-        sourceType: "module",
-    },
-    plugins: ["@typescript-eslint"],
-    rules: {
-        camelcase: ["error"],
-        eqeqeq: ["error", "always", { null: "ignore" }],
-        curly: ["error", "multi-line"],
-        "no-console": ["error", { allow: ["warn", "error"] }],
-        "prefer-const": "error",
-        "@typescript-eslint/member-delimiter-style": [
-            "error",
-            {
-                multiline: {
-                    delimiter: "semi",
-                    requireLast: true,
-                },
-                singleline: {
-                    delimiter: "semi",
-                    requireLast: false,
-                },
-            },
-        ],
-        "@typescript-eslint/semi": ["error", "always"],
-        "@typescript-eslint/no-unnecessary-type-assertion": "error",
-        "@typescript-eslint/no-floating-promises": "error",
-
-        "@typescript-eslint/consistent-type-imports": [
-            "error",
-            {
-                prefer: "type-imports",
-                fixStyle: "inline-type-imports",
-            },
-        ],
-        "@typescript-eslint/no-import-type-side-effects": "error",
-    },
-};
diff --git a/src/tools/rust-analyzer/editors/code/.prettierrc.js b/src/tools/rust-analyzer/editors/code/.prettierrc.js
deleted file mode 100644
index cafb12f0e6d..00000000000
--- a/src/tools/rust-analyzer/editors/code/.prettierrc.js
+++ /dev/null
@@ -1,5 +0,0 @@
-module.exports = {
-    // use 100 because it's Rustfmt's default
-    // https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#max_width
-    printWidth: 100,
-};
diff --git a/src/tools/rust-analyzer/editors/code/eslint.config.mts b/src/tools/rust-analyzer/editors/code/eslint.config.mts
new file mode 100644
index 00000000000..3520593eef2
--- /dev/null
+++ b/src/tools/rust-analyzer/editors/code/eslint.config.mts
@@ -0,0 +1,48 @@
+import eslintConfigPrettier from "eslint-config-prettier";
+import stylistic from "@stylistic/eslint-plugin";
+import eslint from "@eslint/js";
+import tseslint from "typescript-eslint";
+import stylisticJs from "@stylistic/eslint-plugin-js";
+import { type FlatESLintConfig } from "eslint-define-config";
+
+const config: FlatESLintConfig[] = [
+    eslintConfigPrettier,
+    eslint.configs.recommended,
+    stylisticJs.configs["disable-legacy"],
+    ...tseslint.configs.recommended,
+    stylistic.configs.customize({
+        indent: 4,
+        quotes: "double",
+        semi: true,
+        braceStyle: "1tbs",
+        arrowParens: true,
+    }),
+    {
+        rules: {
+            "no-console": "warn",
+            "@typescript-eslint/no-unused-vars": [
+                "error",
+                {
+                    args: "all",
+                    argsIgnorePattern: "^_",
+                    caughtErrors: "all",
+                    caughtErrorsIgnorePattern: "^_",
+                    destructuredArrayIgnorePattern: "^_",
+                    varsIgnorePattern: "^_",
+                    ignoreRestSiblings: true,
+                },
+            ],
+            // the following stylistic lints conflict with prettier
+            "@stylistic/operator-linebreak": "off",
+            "@stylistic/indent-binary-ops": "off",
+            "@stylistic/indent": "off",
+            "@stylistic/brace-style": "off",
+            "@stylistic/quotes": "off",
+        },
+    },
+    {
+        ignores: ["out/", ".vscode-test/", "node_modules/"],
+    },
+];
+
+export default config;
diff --git a/src/tools/rust-analyzer/editors/code/package-lock.json b/src/tools/rust-analyzer/editors/code/package-lock.json
index 86a066454a5..11a37c218f7 100644
--- a/src/tools/rust-analyzer/editors/code/package-lock.json
+++ b/src/tools/rust-analyzer/editors/code/package-lock.json
@@ -9,39 +9,36 @@
             "version": "0.5.0-dev",
             "license": "MIT OR Apache-2.0",
             "dependencies": {
-                "@hpcc-js/wasm": "^2.13.0",
-                "anser": "^2.1.1",
-                "d3": "^7.8.5",
-                "d3-graphviz": "^5.0.2",
+                "@hpcc-js/wasm": "^2.22.4",
+                "anser": "^2.3.2",
+                "d3": "^7.9.0",
+                "d3-graphviz": "^5.6.0",
+                "jiti": "^2.4.2",
                 "vscode-languageclient": "^9.0.1"
             },
             "devDependencies": {
-                "@tsconfig/strictest": "^2.0.1",
-                "@types/node": "~16.11.7",
-                "@types/vscode": "~1.83",
-                "@typescript-eslint/eslint-plugin": "^6.0.0",
-                "@typescript-eslint/parser": "^6.0.0",
-                "@vscode/test-electron": "^2.3.8",
-                "@vscode/vsce": "^3.0.0",
+                "@eslint/js": "^9.21.0",
+                "@stylistic/eslint-plugin": "^4.1.0",
+                "@stylistic/eslint-plugin-js": "^4.1.0",
+                "@tsconfig/strictest": "^2.0.5",
+                "@types/node": "~22.13.4",
+                "@types/vscode": "~1.93.0",
+                "@typescript-eslint/eslint-plugin": "^8.25.0",
+                "@typescript-eslint/parser": "^8.25.0",
+                "@vscode/test-electron": "^2.4.1",
+                "@vscode/vsce": "^3.2.2",
                 "esbuild": "^0.25.0",
-                "eslint": "^8.44.0",
-                "eslint-config-prettier": "^8.8.0",
-                "ovsx": "^0.8.2",
-                "prettier": "^3.0.0",
-                "tslib": "^2.6.0",
-                "typescript": "^5.6.0"
+                "eslint": "^9.21.0",
+                "eslint-config-prettier": "^10.0.2",
+                "eslint-define-config": "^2.1.0",
+                "ovsx": "0.10.1",
+                "prettier": "^3.5.2",
+                "tslib": "^2.8.1",
+                "typescript": "^5.7.3",
+                "typescript-eslint": "^8.25.0"
             },
             "engines": {
-                "vscode": "^1.83.0"
-            }
-        },
-        "node_modules/@aashutoshrathi/word-wrap": {
-            "version": "1.2.6",
-            "resolved": "https://registry.npmjs.org/@aashutoshrathi/word-wrap/-/word-wrap-1.2.6.tgz",
-            "integrity": "sha512-1Yjs2SvM8TflER/OD3cOjhWWOZb58A2t7wpE2S9XfBYTiIl+XFhQG2bjy4Pu1I+EAlCNUzRDYDdFwFYUKvXcIA==",
-            "dev": true,
-            "engines": {
-                "node": ">=0.10.0"
+                "vscode": "^1.93.0"
             }
         },
         "node_modules/@azure/abort-controller": {
@@ -92,16 +89,16 @@
             }
         },
         "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==",
+            "version": "1.19.0",
+            "resolved": "https://registry.npmjs.org/@azure/core-rest-pipeline/-/core-rest-pipeline-1.19.0.tgz",
+            "integrity": "sha512-bM3308LRyg5g7r3Twprtqww0R/r7+GyVxj4BafcmVPo4WQoGt5JXuaqxHEFjw2o3rvFZcUPiqJMg6WuvEEeVUA==",
             "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/core-util": "^1.11.0",
                 "@azure/logger": "^1.0.0",
                 "http-proxy-agent": "^7.0.0",
                 "https-proxy-agent": "^7.0.0",
@@ -111,47 +108,6 @@
                 "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",
@@ -180,9 +136,9 @@
             }
         },
         "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==",
+            "version": "4.7.0",
+            "resolved": "https://registry.npmjs.org/@azure/identity/-/identity-4.7.0.tgz",
+            "integrity": "sha512-6z/S2KorkbKaZ0DgZFVRdu7RCuATmMSTjKpuhj7YpjxkJ0vnJ7kTM3cpNgzFgk9OPYfZ31wrBEtC/iwAS4jQDA==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
@@ -193,11 +149,11 @@
                 "@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",
+                "@azure/msal-browser": "^4.2.0",
+                "@azure/msal-node": "^3.2.1",
                 "events": "^3.0.0",
                 "jws": "^4.0.0",
-                "open": "^8.0.0",
+                "open": "^10.1.0",
                 "stoppable": "^1.1.0",
                 "tslib": "^2.2.0"
             },
@@ -219,22 +175,22 @@
             }
         },
         "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==",
+            "version": "4.4.0",
+            "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-4.4.0.tgz",
+            "integrity": "sha512-rU6juYXk67CKQmpgi6fDgZoPQ9InZ1760z1BSAH7RbeIc4lHZM/Tu+H0CyRk7cnrfvTkexyYE4pjYhMghpzheA==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "@azure/msal-common": "14.15.0"
+                "@azure/msal-common": "15.2.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==",
+            "version": "15.2.0",
+            "resolved": "https://registry.npmjs.org/@azure/msal-common/-/msal-common-15.2.0.tgz",
+            "integrity": "sha512-HiYfGAKthisUYqHG1nImCf/uzcyS31wng3o+CycWLIM9chnYJ9Lk6jZ30Y6YiYYpTQ9+z/FGUpiKKekd3Arc0A==",
             "dev": true,
             "license": "MIT",
             "engines": {
@@ -242,13 +198,13 @@
             }
         },
         "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==",
+            "version": "3.2.3",
+            "resolved": "https://registry.npmjs.org/@azure/msal-node/-/msal-node-3.2.3.tgz",
+            "integrity": "sha512-0eaPqBIWEAizeYiXdeHb09Iq0tvHJ17ztvNEaLdr/KcJJhJxbpkkEQf09DB+vKlFE0tzYi7j4rYLTXtES/InEQ==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "@azure/msal-common": "14.15.0",
+                "@azure/msal-common": "15.2.0",
                 "jsonwebtoken": "^9.0.0",
                 "uuid": "^8.3.0"
             },
@@ -682,39 +638,110 @@
             }
         },
         "node_modules/@eslint-community/eslint-utils": {
-            "version": "4.4.0",
-            "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
-            "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
+            "version": "4.4.1",
+            "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.1.tgz",
+            "integrity": "sha512-s3O3waFUrMV8P/XaF/+ZTp1X9XBZW1a4B97ZnjQF2KYWaFD2A8KyFBsrsfSjEmjn3RGWAIuvlneuZm3CUK3jbA==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "eslint-visitor-keys": "^3.3.0"
+                "eslint-visitor-keys": "^3.4.3"
             },
             "engines": {
                 "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
             },
+            "funding": {
+                "url": "https://opencollective.com/eslint"
+            },
             "peerDependencies": {
                 "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
             }
         },
+        "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+            "version": "3.4.3",
+            "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+            "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+            "dev": true,
+            "license": "Apache-2.0",
+            "engines": {
+                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+            },
+            "funding": {
+                "url": "https://opencollective.com/eslint"
+            }
+        },
         "node_modules/@eslint-community/regexpp": {
-            "version": "4.5.1",
-            "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.5.1.tgz",
-            "integrity": "sha512-Z5ba73P98O1KUYCCJTUeVpja9RcGoMdncZ6T49FCUl2lN38JtCJ+3WgIDBv0AuY4WChU5PmtJmOCTlN6FZTFKQ==",
+            "version": "4.12.1",
+            "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.1.tgz",
+            "integrity": "sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
             }
         },
+        "node_modules/@eslint/config-array": {
+            "version": "0.19.2",
+            "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.19.2.tgz",
+            "integrity": "sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==",
+            "dev": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "@eslint/object-schema": "^2.1.6",
+                "debug": "^4.3.1",
+                "minimatch": "^3.1.2"
+            },
+            "engines": {
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+            }
+        },
+        "node_modules/@eslint/config-array/node_modules/brace-expansion": {
+            "version": "1.1.11",
+            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+            "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "balanced-match": "^1.0.0",
+                "concat-map": "0.0.1"
+            }
+        },
+        "node_modules/@eslint/config-array/node_modules/minimatch": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+            "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+            "dev": true,
+            "license": "ISC",
+            "dependencies": {
+                "brace-expansion": "^1.1.7"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/@eslint/core": {
+            "version": "0.12.0",
+            "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.12.0.tgz",
+            "integrity": "sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==",
+            "dev": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "@types/json-schema": "^7.0.15"
+            },
+            "engines": {
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+            }
+        },
         "node_modules/@eslint/eslintrc": {
-            "version": "2.1.0",
-            "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz",
-            "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==",
+            "version": "3.3.0",
+            "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.0.tgz",
+            "integrity": "sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "ajv": "^6.12.4",
                 "debug": "^4.3.2",
-                "espree": "^9.6.0",
-                "globals": "^13.19.0",
+                "espree": "^10.0.1",
+                "globals": "^14.0.0",
                 "ignore": "^5.2.0",
                 "import-fresh": "^3.2.1",
                 "js-yaml": "^4.1.0",
@@ -722,166 +749,164 @@
                 "strip-json-comments": "^3.1.1"
             },
             "engines": {
-                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "url": "https://opencollective.com/eslint"
             }
         },
-        "node_modules/@eslint/js": {
-            "version": "8.44.0",
-            "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz",
-            "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==",
+        "node_modules/@eslint/eslintrc/node_modules/brace-expansion": {
+            "version": "1.1.11",
+            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+            "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
             "dev": true,
-            "engines": {
-                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
-            }
-        },
-        "node_modules/@hpcc-js/wasm": {
-            "version": "2.13.0",
-            "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.13.0.tgz",
-            "integrity": "sha512-MvnUPnyMlN3/2IONCXwl/SBVWIfVOFJqvw+kFfI1QcwKjNmkwTAtG+9/m3nvofTymkASUUxNULbBmRDIr2uzIA==",
+            "license": "MIT",
             "dependencies": {
-                "yargs": "17.7.2"
-            },
-            "bin": {
-                "dot-wasm": "bin/dot-wasm.js"
+                "balanced-match": "^1.0.0",
+                "concat-map": "0.0.1"
             }
         },
-        "node_modules/@humanwhocodes/config-array": {
-            "version": "0.11.10",
-            "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
-            "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==",
+        "node_modules/@eslint/eslintrc/node_modules/minimatch": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+            "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
             "dev": true,
+            "license": "ISC",
             "dependencies": {
-                "@humanwhocodes/object-schema": "^1.2.1",
-                "debug": "^4.1.1",
-                "minimatch": "^3.0.5"
+                "brace-expansion": "^1.1.7"
             },
             "engines": {
-                "node": ">=10.10.0"
+                "node": "*"
             }
         },
-        "node_modules/@humanwhocodes/module-importer": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
-            "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+        "node_modules/@eslint/js": {
+            "version": "9.21.0",
+            "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.21.0.tgz",
+            "integrity": "sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==",
             "dev": true,
+            "license": "MIT",
             "engines": {
-                "node": ">=12.22"
-            },
-            "funding": {
-                "type": "github",
-                "url": "https://github.com/sponsors/nzakas"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             }
         },
-        "node_modules/@humanwhocodes/object-schema": {
-            "version": "1.2.1",
-            "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-1.2.1.tgz",
-            "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==",
-            "dev": true
+        "node_modules/@eslint/object-schema": {
+            "version": "2.1.6",
+            "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.6.tgz",
+            "integrity": "sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==",
+            "dev": true,
+            "license": "Apache-2.0",
+            "engines": {
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+            }
         },
-        "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==",
+        "node_modules/@eslint/plugin-kit": {
+            "version": "0.2.7",
+            "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz",
+            "integrity": "sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==",
             "dev": true,
-            "license": "ISC",
+            "license": "Apache-2.0",
             "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"
+                "@eslint/core": "^0.12.0",
+                "levn": "^0.4.1"
             },
             "engines": {
-                "node": ">=12"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             }
         },
-        "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==",
+        "node_modules/@hpcc-js/wasm": {
+            "version": "2.22.4",
+            "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.22.4.tgz",
+            "integrity": "sha512-58JkRkxZffiBAbZhc7z+9iaaAOmn1cyxLL3rRwsUvco/I0Wwb7uVAlHM9HiU6XASe2k11jrIjCFff1t9QKjlqg==",
+            "license": "Apache-2.0",
+            "dependencies": {
+                "yargs": "17.7.2"
+            },
+            "bin": {
+                "dot-wasm": "node ./node_modules/@hpcc-js/wasm-graphviz-cli/bin/index.js"
+            }
+        },
+        "node_modules/@humanfs/core": {
+            "version": "0.19.1",
+            "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+            "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
             "dev": true,
-            "license": "MIT",
+            "license": "Apache-2.0",
             "engines": {
-                "node": ">=12"
+                "node": ">=18.18.0"
+            }
+        },
+        "node_modules/@humanfs/node": {
+            "version": "0.16.6",
+            "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.6.tgz",
+            "integrity": "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw==",
+            "dev": true,
+            "license": "Apache-2.0",
+            "dependencies": {
+                "@humanfs/core": "^0.19.1",
+                "@humanwhocodes/retry": "^0.3.0"
             },
-            "funding": {
-                "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+            "engines": {
+                "node": ">=18.18.0"
             }
         },
-        "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==",
+        "node_modules/@humanfs/node/node_modules/@humanwhocodes/retry": {
+            "version": "0.3.1",
+            "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.3.1.tgz",
+            "integrity": "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==",
             "dev": true,
-            "license": "MIT",
+            "license": "Apache-2.0",
             "engines": {
-                "node": ">=12"
+                "node": ">=18.18"
             },
             "funding": {
-                "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+                "type": "github",
+                "url": "https://github.com/sponsors/nzakas"
             }
         },
-        "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==",
+        "node_modules/@humanwhocodes/module-importer": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+            "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
             "dev": true,
-            "license": "MIT",
-            "dependencies": {
-                "eastasianwidth": "^0.2.0",
-                "emoji-regex": "^9.2.2",
-                "strip-ansi": "^7.0.1"
-            },
+            "license": "Apache-2.0",
             "engines": {
-                "node": ">=12"
+                "node": ">=12.22"
             },
             "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
+                "type": "github",
+                "url": "https://github.com/sponsors/nzakas"
             }
         },
-        "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==",
+        "node_modules/@humanwhocodes/retry": {
+            "version": "0.4.2",
+            "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.2.tgz",
+            "integrity": "sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==",
             "dev": true,
-            "license": "MIT",
-            "dependencies": {
-                "ansi-regex": "^6.0.1"
-            },
+            "license": "Apache-2.0",
             "engines": {
-                "node": ">=12"
+                "node": ">=18.18"
             },
             "funding": {
-                "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+                "type": "github",
+                "url": "https://github.com/sponsors/nzakas"
             }
         },
-        "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==",
+        "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": "MIT",
+            "license": "ISC",
             "dependencies": {
-                "ansi-styles": "^6.1.0",
-                "string-width": "^5.0.1",
-                "strip-ansi": "^7.0.1"
+                "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"
-            },
-            "funding": {
-                "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
             }
         },
         "node_modules/@nodelib/fs.scandir": {
@@ -889,6 +914,7 @@
             "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
             "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "@nodelib/fs.stat": "2.0.5",
                 "run-parallel": "^1.1.9"
@@ -902,6 +928,7 @@
             "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
             "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">= 8"
             }
@@ -911,6 +938,7 @@
             "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
             "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "@nodelib/fs.scandir": "2.1.5",
                 "fastq": "^1.6.0"
@@ -919,121 +947,148 @@
                 "node": ">= 8"
             }
         },
-        "node_modules/@tootallnate/once": {
-            "version": "1.1.2",
-            "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz",
-            "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==",
+        "node_modules/@stylistic/eslint-plugin": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin/-/eslint-plugin-4.1.0.tgz",
+            "integrity": "sha512-bytbL7qiici7yPyEiId0fGPK9kjQbzcPMj2aftPfzTCyJ/CRSKdtI+iVjM0LSGzGxfunflI+MDDU9vyIIeIpoQ==",
             "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@typescript-eslint/utils": "^8.23.0",
+                "eslint-visitor-keys": "^4.2.0",
+                "espree": "^10.3.0",
+                "estraverse": "^5.3.0",
+                "picomatch": "^4.0.2"
+            },
             "engines": {
-                "node": ">= 6"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+            },
+            "peerDependencies": {
+                "eslint": ">=9.0.0"
+            }
+        },
+        "node_modules/@stylistic/eslint-plugin-js": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/@stylistic/eslint-plugin-js/-/eslint-plugin-js-4.1.0.tgz",
+            "integrity": "sha512-YOe+dChNoR26JVVt+7BjyebsPIQF05OLNmHCXivq8lLZ4ZeVs4+wXaW+pREVboDiAaSRznauAdAU8f+iQouw6Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "eslint-visitor-keys": "^4.2.0",
+                "espree": "^10.3.0"
+            },
+            "engines": {
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+            },
+            "peerDependencies": {
+                "eslint": ">=9.0.0"
             }
         },
         "node_modules/@tsconfig/strictest": {
-            "version": "2.0.1",
-            "resolved": "https://registry.npmjs.org/@tsconfig/strictest/-/strictest-2.0.1.tgz",
-            "integrity": "sha512-7JHHCbyCsGUxLd0pDbp24yz3zjxw2t673W5oAP6HCEdr/UUhaRhYd3SSnUsGCk+VnPVJVA4mXROzbhI+nyIk+w==",
-            "dev": true
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/@tsconfig/strictest/-/strictest-2.0.5.tgz",
+            "integrity": "sha512-ec4tjL2Rr0pkZ5hww65c+EEPYwxOi4Ryv+0MtjeaSQRJyq322Q27eOQiFbuNgw2hpL4hB1/W/HBGk3VKS43osg==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/@types/estree": {
+            "version": "1.0.6",
+            "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz",
+            "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/@types/json-schema": {
-            "version": "7.0.12",
-            "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.12.tgz",
-            "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==",
-            "dev": true
+            "version": "7.0.15",
+            "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+            "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/@types/node": {
-            "version": "16.11.68",
-            "resolved": "https://registry.npmjs.org/@types/node/-/node-16.11.68.tgz",
-            "integrity": "sha512-JkRpuVz3xCNCWaeQ5EHLR/6woMbHZz/jZ7Kmc63AkU+1HxnoUugzSWMck7dsR4DvNYX8jp9wTi9K7WvnxOIQZQ==",
-            "dev": true
-        },
-        "node_modules/@types/semver": {
-            "version": "7.5.0",
-            "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz",
-            "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==",
-            "dev": true
+            "version": "22.13.5",
+            "resolved": "https://registry.npmjs.org/@types/node/-/node-22.13.5.tgz",
+            "integrity": "sha512-+lTU0PxZXn0Dr1NBtC7Y8cR21AJr87dLLU953CWA6pMxxv/UDc7jYAY90upcrie1nRcD6XNG5HOYEDtgW5TxAg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "undici-types": "~6.20.0"
+            }
         },
         "node_modules/@types/vscode": {
-            "version": "1.83.3",
-            "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.83.3.tgz",
-            "integrity": "sha512-ZPp5+OQNYrCSFoT4jWOZKdcuXijj+JdN2BJNDhWH4pPbVL6PRQycG9NT8C4a94oul1tFMbkVbXXa9HasI7cLUg==",
-            "dev": true
+            "version": "1.93.0",
+            "resolved": "https://registry.npmjs.org/@types/vscode/-/vscode-1.93.0.tgz",
+            "integrity": "sha512-kUK6jAHSR5zY8ps42xuW89NLcBpw1kOabah7yv38J8MyiYuOHxLQBi0e7zeXbQgVefDy/mZZetqEFC+Fl5eIEQ==",
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/@typescript-eslint/eslint-plugin": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.0.0.tgz",
-            "integrity": "sha512-xuv6ghKGoiq856Bww/yVYnXGsKa588kY3M0XK7uUW/3fJNNULKRfZfSBkMTSpqGG/8ZCXCadfh8G/z/B4aqS/A==",
+            "version": "8.25.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.25.0.tgz",
+            "integrity": "sha512-VM7bpzAe7JO/BFf40pIT1lJqS/z1F8OaSsUB3rpFJucQA4cOSuH2RVVVkFULN+En0Djgr29/jb4EQnedUo95KA==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "@eslint-community/regexpp": "^4.5.0",
-                "@typescript-eslint/scope-manager": "6.0.0",
-                "@typescript-eslint/type-utils": "6.0.0",
-                "@typescript-eslint/utils": "6.0.0",
-                "@typescript-eslint/visitor-keys": "6.0.0",
-                "debug": "^4.3.4",
-                "grapheme-splitter": "^1.0.4",
+                "@eslint-community/regexpp": "^4.10.0",
+                "@typescript-eslint/scope-manager": "8.25.0",
+                "@typescript-eslint/type-utils": "8.25.0",
+                "@typescript-eslint/utils": "8.25.0",
+                "@typescript-eslint/visitor-keys": "8.25.0",
                 "graphemer": "^1.4.0",
-                "ignore": "^5.2.4",
+                "ignore": "^5.3.1",
                 "natural-compare": "^1.4.0",
-                "natural-compare-lite": "^1.4.0",
-                "semver": "^7.5.0",
-                "ts-api-utils": "^1.0.1"
+                "ts-api-utils": "^2.0.1"
             },
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/typescript-eslint"
             },
             "peerDependencies": {
-                "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
-                "eslint": "^7.0.0 || ^8.0.0"
-            },
-            "peerDependenciesMeta": {
-                "typescript": {
-                    "optional": true
-                }
+                "@typescript-eslint/parser": "^8.0.0 || ^8.0.0-alpha.0",
+                "eslint": "^8.57.0 || ^9.0.0",
+                "typescript": ">=4.8.4 <5.8.0"
             }
         },
         "node_modules/@typescript-eslint/parser": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.0.0.tgz",
-            "integrity": "sha512-TNaufYSPrr1U8n+3xN+Yp9g31vQDJqhXzzPSHfQDLcaO4tU+mCfODPxCwf4H530zo7aUBE3QIdxCXamEnG04Tg==",
+            "version": "8.25.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.25.0.tgz",
+            "integrity": "sha512-4gbs64bnbSzu4FpgMiQ1A+D+urxkoJk/kqlDJ2W//5SygaEiAP2B4GoS7TEdxgwol2el03gckFV9lJ4QOMiiHg==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "@typescript-eslint/scope-manager": "6.0.0",
-                "@typescript-eslint/types": "6.0.0",
-                "@typescript-eslint/typescript-estree": "6.0.0",
-                "@typescript-eslint/visitor-keys": "6.0.0",
+                "@typescript-eslint/scope-manager": "8.25.0",
+                "@typescript-eslint/types": "8.25.0",
+                "@typescript-eslint/typescript-estree": "8.25.0",
+                "@typescript-eslint/visitor-keys": "8.25.0",
                 "debug": "^4.3.4"
             },
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/typescript-eslint"
             },
             "peerDependencies": {
-                "eslint": "^7.0.0 || ^8.0.0"
-            },
-            "peerDependenciesMeta": {
-                "typescript": {
-                    "optional": true
-                }
+                "eslint": "^8.57.0 || ^9.0.0",
+                "typescript": ">=4.8.4 <5.8.0"
             }
         },
         "node_modules/@typescript-eslint/scope-manager": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.0.0.tgz",
-            "integrity": "sha512-o4q0KHlgCZTqjuaZ25nw5W57NeykZT9LiMEG4do/ovwvOcPnDO1BI5BQdCsUkjxFyrCL0cSzLjvIMfR9uo7cWg==",
+            "version": "8.25.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.25.0.tgz",
+            "integrity": "sha512-6PPeiKIGbgStEyt4NNXa2ru5pMzQ8OYKO1hX1z53HMomrmiSB+R5FmChgQAP1ro8jMtNawz+TRQo/cSXrauTpg==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "@typescript-eslint/types": "6.0.0",
-                "@typescript-eslint/visitor-keys": "6.0.0"
+                "@typescript-eslint/types": "8.25.0",
+                "@typescript-eslint/visitor-keys": "8.25.0"
             },
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
@@ -1041,39 +1096,37 @@
             }
         },
         "node_modules/@typescript-eslint/type-utils": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.0.0.tgz",
-            "integrity": "sha512-ah6LJvLgkoZ/pyJ9GAdFkzeuMZ8goV6BH7eC9FPmojrnX9yNCIsfjB+zYcnex28YO3RFvBkV6rMV6WpIqkPvoQ==",
+            "version": "8.25.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.25.0.tgz",
+            "integrity": "sha512-d77dHgHWnxmXOPJuDWO4FDWADmGQkN5+tt6SFRZz/RtCWl4pHgFl3+WdYCn16+3teG09DY6XtEpf3gGD0a186g==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "@typescript-eslint/typescript-estree": "6.0.0",
-                "@typescript-eslint/utils": "6.0.0",
+                "@typescript-eslint/typescript-estree": "8.25.0",
+                "@typescript-eslint/utils": "8.25.0",
                 "debug": "^4.3.4",
-                "ts-api-utils": "^1.0.1"
+                "ts-api-utils": "^2.0.1"
             },
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/typescript-eslint"
             },
             "peerDependencies": {
-                "eslint": "^7.0.0 || ^8.0.0"
-            },
-            "peerDependenciesMeta": {
-                "typescript": {
-                    "optional": true
-                }
+                "eslint": "^8.57.0 || ^9.0.0",
+                "typescript": ">=4.8.4 <5.8.0"
             }
         },
         "node_modules/@typescript-eslint/types": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.0.0.tgz",
-            "integrity": "sha512-Zk9KDggyZM6tj0AJWYYKgF0yQyrcnievdhG0g5FqyU3Y2DRxJn4yWY21sJC0QKBckbsdKKjYDV2yVrrEvuTgxg==",
+            "version": "8.25.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.25.0.tgz",
+            "integrity": "sha512-+vUe0Zb4tkNgznQwicsvLUJgZIRs6ITeWSCclX1q85pR1iOiaj+4uZJIUp//Z27QWu5Cseiw3O3AR8hVpax7Aw==",
             "dev": true,
+            "license": "MIT",
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
@@ -1081,69 +1134,68 @@
             }
         },
         "node_modules/@typescript-eslint/typescript-estree": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.0.0.tgz",
-            "integrity": "sha512-2zq4O7P6YCQADfmJ5OTDQTP3ktajnXIRrYAtHM9ofto/CJZV3QfJ89GEaM2BNGeSr1KgmBuLhEkz5FBkS2RQhQ==",
+            "version": "8.25.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.25.0.tgz",
+            "integrity": "sha512-ZPaiAKEZ6Blt/TPAx5Ot0EIB/yGtLI2EsGoY6F7XKklfMxYQyvtL+gT/UCqkMzO0BVFHLDlzvFqQzurYahxv9Q==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "@typescript-eslint/types": "6.0.0",
-                "@typescript-eslint/visitor-keys": "6.0.0",
+                "@typescript-eslint/types": "8.25.0",
+                "@typescript-eslint/visitor-keys": "8.25.0",
                 "debug": "^4.3.4",
-                "globby": "^11.1.0",
+                "fast-glob": "^3.3.2",
                 "is-glob": "^4.0.3",
-                "semver": "^7.5.0",
-                "ts-api-utils": "^1.0.1"
+                "minimatch": "^9.0.4",
+                "semver": "^7.6.0",
+                "ts-api-utils": "^2.0.1"
             },
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/typescript-eslint"
             },
-            "peerDependenciesMeta": {
-                "typescript": {
-                    "optional": true
-                }
+            "peerDependencies": {
+                "typescript": ">=4.8.4 <5.8.0"
             }
         },
         "node_modules/@typescript-eslint/utils": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.0.0.tgz",
-            "integrity": "sha512-SOr6l4NB6HE4H/ktz0JVVWNXqCJTOo/mHnvIte1ZhBQ0Cvd04x5uKZa3zT6tiodL06zf5xxdK8COiDvPnQ27JQ==",
+            "version": "8.25.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.25.0.tgz",
+            "integrity": "sha512-syqRbrEv0J1wywiLsK60XzHnQe/kRViI3zwFALrNEgnntn1l24Ra2KvOAWwWbWZ1lBZxZljPDGOq967dsl6fkA==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "@eslint-community/eslint-utils": "^4.3.0",
-                "@types/json-schema": "^7.0.11",
-                "@types/semver": "^7.3.12",
-                "@typescript-eslint/scope-manager": "6.0.0",
-                "@typescript-eslint/types": "6.0.0",
-                "@typescript-eslint/typescript-estree": "6.0.0",
-                "eslint-scope": "^5.1.1",
-                "semver": "^7.5.0"
+                "@eslint-community/eslint-utils": "^4.4.0",
+                "@typescript-eslint/scope-manager": "8.25.0",
+                "@typescript-eslint/types": "8.25.0",
+                "@typescript-eslint/typescript-estree": "8.25.0"
             },
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
                 "url": "https://opencollective.com/typescript-eslint"
             },
             "peerDependencies": {
-                "eslint": "^7.0.0 || ^8.0.0"
+                "eslint": "^8.57.0 || ^9.0.0",
+                "typescript": ">=4.8.4 <5.8.0"
             }
         },
         "node_modules/@typescript-eslint/visitor-keys": {
-            "version": "6.0.0",
-            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.0.0.tgz",
-            "integrity": "sha512-cvJ63l8c0yXdeT5POHpL0Q1cZoRcmRKFCtSjNGJxPkcP571EfZMcNbzWAc7oK3D1dRzm/V5EwtkANTZxqvuuUA==",
+            "version": "8.25.0",
+            "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.25.0.tgz",
+            "integrity": "sha512-kCYXKAum9CecGVHGij7muybDfTS2sD3t0L4bJsEZLkyrXUImiCTq1M3LG2SRtOhiHFwMR9wAFplpT6XHYjTkwQ==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "@typescript-eslint/types": "6.0.0",
-                "eslint-visitor-keys": "^3.4.1"
+                "@typescript-eslint/types": "8.25.0",
+                "eslint-visitor-keys": "^4.2.0"
             },
             "engines": {
-                "node": "^16.0.0 || >=18.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "type": "opencollective",
@@ -1151,24 +1203,26 @@
             }
         },
         "node_modules/@vscode/test-electron": {
-            "version": "2.3.8",
-            "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.3.8.tgz",
-            "integrity": "sha512-b4aZZsBKtMGdDljAsOPObnAi7+VWIaYl3ylCz1jTs+oV6BZ4TNHcVNC3xUn0azPeszBmwSBDQYfFESIaUQnrOg==",
+            "version": "2.4.1",
+            "resolved": "https://registry.npmjs.org/@vscode/test-electron/-/test-electron-2.4.1.tgz",
+            "integrity": "sha512-Gc6EdaLANdktQ1t+zozoBVRynfIsMKMc94Svu1QreOBC8y76x4tvaK32TljrLi1LI2+PK58sDVbL7ALdqf3VRQ==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "http-proxy-agent": "^4.0.1",
-                "https-proxy-agent": "^5.0.0",
+                "http-proxy-agent": "^7.0.2",
+                "https-proxy-agent": "^7.0.5",
                 "jszip": "^3.10.1",
-                "semver": "^7.5.2"
+                "ora": "^7.0.1",
+                "semver": "^7.6.2"
             },
             "engines": {
                 "node": ">=16"
             }
         },
         "node_modules/@vscode/vsce": {
-            "version": "3.1.1",
-            "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.1.1.tgz",
-            "integrity": "sha512-N62Ca9ElRPLUUzf7l9CeEBlLrYzFPRQq7huKk4pVW+LjIOSXfFIPudixn5QvZcz+yXDOh15IopI3K2o3y9666Q==",
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/@vscode/vsce/-/vsce-3.2.2.tgz",
+            "integrity": "sha512-4TqdUq/yKlQTHcQMk/DamR632bq/+IJDomSbexOMee/UAYWqYm0XHWA6scGslsCpzY+sCWEhhl0nqdOB0XW1kw==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
@@ -1178,7 +1232,7 @@
                 "chalk": "^2.4.2",
                 "cheerio": "^1.0.0-rc.9",
                 "cockatiel": "^3.1.2",
-                "commander": "^6.2.1",
+                "commander": "^12.1.0",
                 "form-data": "^4.0.0",
                 "glob": "^11.0.0",
                 "hosted-git-info": "^4.0.2",
@@ -1208,9 +1262,9 @@
             }
         },
         "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==",
+            "version": "2.0.5",
+            "resolved": "https://registry.npmjs.org/@vscode/vsce-sign/-/vsce-sign-2.0.5.tgz",
+            "integrity": "sha512-GfYWrsT/vypTMDMgWDm75iDmAOMe7F71sZECJ+Ws6/xyIfmB3ELVnVN+LwMFAvmXY+e6eWhR2EzNGF/zAhWY3Q==",
             "dev": true,
             "hasInstallScript": true,
             "license": "SEE LICENSE IN LICENSE.txt",
@@ -1352,141 +1406,36 @@
                 "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",
-            "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
-            "dev": true,
-            "dependencies": {
-                "color-convert": "^1.9.0"
-            },
-            "engines": {
-                "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==",
+            "version": "1.1.11",
+            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+            "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
             "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",
-            "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
-            "dev": true,
-            "dependencies": {
-                "ansi-styles": "^3.2.1",
-                "escape-string-regexp": "^1.0.5",
-                "supports-color": "^5.3.0"
-            },
-            "engines": {
-                "node": ">=4"
-            }
-        },
-        "node_modules/@vscode/vsce/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,
-            "dependencies": {
-                "color-name": "1.1.3"
-            }
-        },
-        "node_modules/@vscode/vsce/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
-        },
-        "node_modules/@vscode/vsce/node_modules/commander": {
-            "version": "6.2.1",
-            "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz",
-            "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
-            "dev": true,
-            "engines": {
-                "node": ">= 6"
-            }
-        },
-        "node_modules/@vscode/vsce/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,
-            "engines": {
-                "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"
+                "balanced-match": "^1.0.0",
+                "concat-map": "0.0.1"
             }
         },
-        "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==",
+        "node_modules/@vscode/vsce/node_modules/minimatch": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+            "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
             "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",
-            "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
-            "dev": true,
-            "engines": {
-                "node": ">=4"
-            }
-        },
-        "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",
-            "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
-            "dev": true,
-            "dependencies": {
-                "has-flag": "^3.0.0"
+                "brace-expansion": "^1.1.7"
             },
             "engines": {
-                "node": ">=4"
+                "node": "*"
             }
         },
         "node_modules/acorn": {
-            "version": "8.10.0",
-            "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
-            "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
+            "version": "8.14.0",
+            "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.14.0.tgz",
+            "integrity": "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA==",
             "dev": true,
+            "license": "MIT",
             "bin": {
                 "acorn": "bin/acorn"
             },
@@ -1499,20 +1448,19 @@
             "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
             "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
             "dev": true,
+            "license": "MIT",
             "peerDependencies": {
                 "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
             }
         },
         "node_modules/agent-base": {
-            "version": "6.0.2",
-            "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz",
-            "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==",
+            "version": "7.1.3",
+            "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.3.tgz",
+            "integrity": "sha512-jRR5wdylq8CkOe6hei19GGZnxM6rBGwFl3Bg0YItGDimvjGtAvdZk4Pu6Cl4u4Igsws4a1fd1Vq3ezrhn4KmFw==",
             "dev": true,
-            "dependencies": {
-                "debug": "4"
-            },
+            "license": "MIT",
             "engines": {
-                "node": ">= 6.0.0"
+                "node": ">= 14"
             }
         },
         "node_modules/ajv": {
@@ -1520,6 +1468,7 @@
             "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz",
             "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "fast-deep-equal": "^3.1.1",
                 "fast-json-stable-stringify": "^2.0.0",
@@ -1532,46 +1481,43 @@
             }
         },
         "node_modules/anser": {
-            "version": "2.1.1",
-            "resolved": "https://registry.npmjs.org/anser/-/anser-2.1.1.tgz",
-            "integrity": "sha512-nqLm4HxOTpeLOxcmB3QWmV5TcDFhW9y/fyQ+hivtDFcK4OQ+pQ5fzPnXHM1Mfcm0VkLtvVi1TCPr++Qy0Q/3EQ=="
+            "version": "2.3.2",
+            "resolved": "https://registry.npmjs.org/anser/-/anser-2.3.2.tgz",
+            "integrity": "sha512-PMqBCBvrOVDRqLGooQb+z+t1Q0PiPyurUQeZRR5uHBOVZcW8B04KMmnT12USnhpNX2wCPagWzLVppQMUG3u0Dw==",
+            "license": "MIT"
         },
         "node_modules/ansi-regex": {
-            "version": "5.0.1",
-            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
-            "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+            "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": ">=8"
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/ansi-regex?sponsor=1"
             }
         },
         "node_modules/ansi-styles": {
-            "version": "4.3.0",
-            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
-            "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+            "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": "^2.0.1"
+                "color-convert": "^1.9.0"
             },
             "engines": {
-                "node": ">=8"
-            },
-            "funding": {
-                "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+                "node": ">=4"
             }
         },
         "node_modules/argparse": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
             "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
-            "dev": true
-        },
-        "node_modules/array-union": {
-            "version": "2.1.0",
-            "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
-            "integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
             "dev": true,
-            "engines": {
-                "node": ">=8"
-            }
+            "license": "Python-2.0"
         },
         "node_modules/asynckit": {
             "version": "0.4.0",
@@ -1594,7 +1540,8 @@
         "node_modules/balanced-match": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
-            "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+            "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+            "license": "MIT"
         },
         "node_modules/base64-js": {
             "version": "1.5.1",
@@ -1615,26 +1562,26 @@
                     "url": "https://feross.org/support"
                 }
             ],
-            "optional": true
+            "license": "MIT"
         },
         "node_modules/bl": {
-            "version": "4.1.0",
-            "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
-            "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/bl/-/bl-5.1.0.tgz",
+            "integrity": "sha512-tv1ZJHLfTDnXE6tMHv73YgSJaWR2AFuPwMntBe7XL/GBFHnT0CLnsHMogfk5+GzCDC5ZWarSCYaIGATZt9dNsQ==",
             "dev": true,
-            "optional": true,
+            "license": "MIT",
             "dependencies": {
-                "buffer": "^5.5.0",
+                "buffer": "^6.0.3",
                 "inherits": "^2.0.4",
                 "readable-stream": "^3.4.0"
             }
         },
         "node_modules/bl/node_modules/readable-stream": {
-            "version": "3.6.0",
-            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-            "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+            "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
             "dev": true,
-            "optional": true,
+            "license": "MIT",
             "dependencies": {
                 "inherits": "^2.0.3",
                 "string_decoder": "^1.1.1",
@@ -1648,16 +1595,16 @@
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
             "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
-            "dev": true
+            "dev": true,
+            "license": "ISC"
         },
         "node_modules/brace-expansion": {
-            "version": "1.1.11",
-            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
-            "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-            "dev": true,
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
+            "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
+            "license": "MIT",
             "dependencies": {
-                "balanced-match": "^1.0.0",
-                "concat-map": "0.0.1"
+                "balanced-match": "^1.0.0"
             }
         },
         "node_modules/braces": {
@@ -1665,6 +1612,7 @@
             "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.3.tgz",
             "integrity": "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "fill-range": "^7.1.1"
             },
@@ -1673,9 +1621,9 @@
             }
         },
         "node_modules/buffer": {
-            "version": "5.7.1",
-            "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
-            "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+            "version": "6.0.3",
+            "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz",
+            "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==",
             "dev": true,
             "funding": [
                 {
@@ -1691,10 +1639,10 @@
                     "url": "https://feross.org/support"
                 }
             ],
-            "optional": true,
+            "license": "MIT",
             "dependencies": {
                 "base64-js": "^1.3.1",
-                "ieee754": "^1.1.13"
+                "ieee754": "^1.2.1"
             }
         },
         "node_modules/buffer-crc32": {
@@ -1702,6 +1650,7 @@
             "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz",
             "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": "*"
             }
@@ -1713,18 +1662,45 @@
             "dev": true,
             "license": "BSD-3-Clause"
         },
-        "node_modules/call-bind": {
-            "version": "1.0.7",
-            "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz",
-            "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==",
+        "node_modules/bundle-name": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-4.1.0.tgz",
+            "integrity": "sha512-tjwM5exMg6BGRI+kNmTntNsvdZS1X8BFYS6tnJ2hdH0kVxM6/eVZ2xy+FqStSWvYmtfFMDLIxurorHwDKfDz5Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "run-applescript": "^7.0.0"
+            },
+            "engines": {
+                "node": ">=18"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/call-bind-apply-helpers": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+            "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "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"
+                "function-bind": "^1.1.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/call-bound": {
+            "version": "1.0.3",
+            "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.3.tgz",
+            "integrity": "sha512-YTd+6wGlNlPxSuri7Y6X8tY2dmm12UMH66RpKMhiX6rsk5wXXnYgbUcOt8kiS31/AjfoTOvCsE+w8nZQLQnzHA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "call-bind-apply-helpers": "^1.0.1",
+                "get-intrinsic": "^1.2.6"
             },
             "engines": {
                 "node": ">= 0.4"
@@ -1738,42 +1714,47 @@
             "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
             "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">=6"
             }
         },
         "node_modules/chalk": {
-            "version": "4.1.2",
-            "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
-            "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+            "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": "^4.1.0",
-                "supports-color": "^7.1.0"
+                "ansi-styles": "^3.2.1",
+                "escape-string-regexp": "^1.0.5",
+                "supports-color": "^5.3.0"
             },
             "engines": {
-                "node": ">=10"
-            },
-            "funding": {
-                "url": "https://github.com/chalk/chalk?sponsor=1"
+                "node": ">=4"
             }
         },
         "node_modules/cheerio": {
-            "version": "1.0.0-rc.12",
-            "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0-rc.12.tgz",
-            "integrity": "sha512-VqR8m68vM46BNnuZ5NtnGBKIE/DfN0cRIzg9n40EIq9NOv90ayxLBXA8fXC5gquFRGJSTRqBq25Jt2ECLR431Q==",
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz",
+            "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "cheerio-select": "^2.1.0",
                 "dom-serializer": "^2.0.0",
                 "domhandler": "^5.0.3",
-                "domutils": "^3.0.1",
-                "htmlparser2": "^8.0.1",
-                "parse5": "^7.0.0",
-                "parse5-htmlparser2-tree-adapter": "^7.0.0"
+                "domutils": "^3.1.0",
+                "encoding-sniffer": "^0.2.0",
+                "htmlparser2": "^9.1.0",
+                "parse5": "^7.1.2",
+                "parse5-htmlparser2-tree-adapter": "^7.0.0",
+                "parse5-parser-stream": "^7.1.2",
+                "undici": "^6.19.5",
+                "whatwg-mimetype": "^4.0.0"
             },
             "engines": {
-                "node": ">= 6"
+                "node": ">=18.17"
             },
             "funding": {
                 "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
@@ -1784,6 +1765,7 @@
             "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
             "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
             "dev": true,
+            "license": "BSD-2-Clause",
             "dependencies": {
                 "boolbase": "^1.0.0",
                 "css-select": "^5.1.0",
@@ -1801,18 +1783,50 @@
             "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz",
             "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==",
             "dev": true,
+            "license": "ISC",
             "optional": true
         },
         "node_modules/ci-info": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-2.0.0.tgz",
             "integrity": "sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/cli-cursor": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
+            "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "restore-cursor": "^4.0.0"
+            },
+            "engines": {
+                "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/cli-spinners": {
+            "version": "2.9.2",
+            "resolved": "https://registry.npmjs.org/cli-spinners/-/cli-spinners-2.9.2.tgz",
+            "integrity": "sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
         },
         "node_modules/cliui": {
             "version": "8.0.1",
             "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
             "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+            "license": "ISC",
             "dependencies": {
                 "string-width": "^4.2.0",
                 "strip-ansi": "^6.0.1",
@@ -1822,20 +1836,35 @@
                 "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,
+        "node_modules/cliui/node_modules/ansi-regex": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+            "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
             "license": "MIT",
             "engines": {
-                "node": ">=16"
+                "node": ">=8"
             }
         },
-        "node_modules/color-convert": {
+        "node_modules/cliui/node_modules/ansi-styles": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+            "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+            "license": "MIT",
+            "dependencies": {
+                "color-convert": "^2.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+            }
+        },
+        "node_modules/cliui/node_modules/color-convert": {
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
             "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+            "license": "MIT",
             "dependencies": {
                 "color-name": "~1.1.4"
             },
@@ -1843,10 +1872,87 @@
                 "node": ">=7.0.0"
             }
         },
-        "node_modules/color-name": {
+        "node_modules/cliui/node_modules/color-name": {
             "version": "1.1.4",
             "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
-            "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="
+            "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+            "license": "MIT"
+        },
+        "node_modules/cliui/node_modules/emoji-regex": {
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+            "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+            "license": "MIT"
+        },
+        "node_modules/cliui/node_modules/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==",
+            "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/cliui/node_modules/strip-ansi": {
+            "version": "6.0.1",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+            "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+            "license": "MIT",
+            "dependencies": {
+                "ansi-regex": "^5.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/cliui/node_modules/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==",
+            "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/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": "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/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/combined-stream": {
             "version": "1.0.8",
@@ -1862,30 +1968,35 @@
             }
         },
         "node_modules/commander": {
-            "version": "7.2.0",
-            "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
-            "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+            "version": "12.1.0",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-12.1.0.tgz",
+            "integrity": "sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==",
+            "dev": true,
+            "license": "MIT",
             "engines": {
-                "node": ">= 10"
+                "node": ">=18"
             }
         },
         "node_modules/concat-map": {
             "version": "0.0.1",
             "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
             "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/core-util-is": {
             "version": "1.0.3",
             "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz",
             "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/cross-spawn": {
-            "version": "7.0.3",
-            "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz",
-            "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+            "version": "7.0.6",
+            "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+            "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "path-key": "^3.1.0",
                 "shebang-command": "^2.0.0",
@@ -1900,6 +2011,7 @@
             "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
             "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==",
             "dev": true,
+            "license": "BSD-2-Clause",
             "dependencies": {
                 "boolbase": "^1.0.0",
                 "css-what": "^6.1.0",
@@ -1916,6 +2028,7 @@
             "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.1.0.tgz",
             "integrity": "sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==",
             "dev": true,
+            "license": "BSD-2-Clause",
             "engines": {
                 "node": ">= 6"
             },
@@ -1924,9 +2037,10 @@
             }
         },
         "node_modules/d3": {
-            "version": "7.8.5",
-            "resolved": "https://registry.npmjs.org/d3/-/d3-7.8.5.tgz",
-            "integrity": "sha512-JgoahDG51ncUfJu6wX/1vWQEqOflgXyl4MaHqlcSruTez7yhaRKR9i8VjjcQGeS2en/jnFivXuaIMnseMMt0XA==",
+            "version": "7.9.0",
+            "resolved": "https://registry.npmjs.org/d3/-/d3-7.9.0.tgz",
+            "integrity": "sha512-e1U46jVP+w7Iut8Jt8ri1YsPOvFpg46k+K8TpCb0P+zjCkjkPnV7WzfDJzMHy1LnA+wj5pLT1wjO901gLXeEhA==",
+            "license": "ISC",
             "dependencies": {
                 "d3-array": "3",
                 "d3-axis": "3",
@@ -1964,9 +2078,10 @@
             }
         },
         "node_modules/d3-array": {
-            "version": "3.2.2",
-            "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.2.tgz",
-            "integrity": "sha512-yEEyEAbDrF8C6Ob2myOBLjwBLck1Z89jMGFee0oPsn95GqjerpaOA4ch+vc2l0FNFFwMD5N7OCSEN5eAlsUbgQ==",
+            "version": "3.2.4",
+            "resolved": "https://registry.npmjs.org/d3-array/-/d3-array-3.2.4.tgz",
+            "integrity": "sha512-tdQAmyA18i4J7wprpYq8ClcxZy3SC31QMeByyCFyRt7BVHdREQZ5lpzoe5mFEYZUWe+oq8HBvk9JjpibyEV4Jg==",
+            "license": "ISC",
             "dependencies": {
                 "internmap": "1 - 2"
             },
@@ -1978,6 +2093,7 @@
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/d3-axis/-/d3-axis-3.0.0.tgz",
             "integrity": "sha512-IH5tgjV4jE/GhHkRV0HiVYPDtvfjHQlQfJHs0usq7M30XcSBvOotpmH1IgkcXsO/5gEQZD43B//fc7SRT5S+xw==",
+            "license": "ISC",
             "engines": {
                 "node": ">=12"
             }
@@ -1986,6 +2102,7 @@
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/d3-brush/-/d3-brush-3.0.0.tgz",
             "integrity": "sha512-ALnjWlVYkXsVIGlOsuWH1+3udkYFI48Ljihfnh8FZPF2QS9o+PzGLBslO0PjzVoHLZ2KCVgAM8NVkXPJB2aNnQ==",
+            "license": "ISC",
             "dependencies": {
                 "d3-dispatch": "1 - 3",
                 "d3-drag": "2 - 3",
@@ -2001,6 +2118,7 @@
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/d3-chord/-/d3-chord-3.0.1.tgz",
             "integrity": "sha512-VE5S6TNa+j8msksl7HwjxMHDM2yNK3XCkusIlpX5kwauBfXuyLAtNg9jCp/iHH61tgI4sb6R/EIMWCqEIdjT/g==",
+            "license": "ISC",
             "dependencies": {
                 "d3-path": "1 - 3"
             },
@@ -2012,6 +2130,7 @@
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/d3-color/-/d3-color-3.1.0.tgz",
             "integrity": "sha512-zg/chbXyeBtMQ1LbD/WSoW2DpC3I0mpmPdW+ynRTj/x2DAWYrIY7qeZIHidozwV24m4iavr15lNwIwLxRmOxhA==",
+            "license": "ISC",
             "engines": {
                 "node": ">=12"
             }
@@ -2020,6 +2139,7 @@
             "version": "4.0.2",
             "resolved": "https://registry.npmjs.org/d3-contour/-/d3-contour-4.0.2.tgz",
             "integrity": "sha512-4EzFTRIikzs47RGmdxbeUvLWtGedDUNkTcmzoeyg4sP/dvCexO47AaQL7VKy/gul85TOxw+IBgA8US2xwbToNA==",
+            "license": "ISC",
             "dependencies": {
                 "d3-array": "^3.2.0"
             },
@@ -2028,9 +2148,10 @@
             }
         },
         "node_modules/d3-delaunay": {
-            "version": "6.0.2",
-            "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.2.tgz",
-            "integrity": "sha512-IMLNldruDQScrcfT+MWnazhHbDJhcRJyOEBAJfwQnHle1RPh6WDuLvxNArUju2VSMSUuKlY5BGHRJ2cYyoFLQQ==",
+            "version": "6.0.4",
+            "resolved": "https://registry.npmjs.org/d3-delaunay/-/d3-delaunay-6.0.4.tgz",
+            "integrity": "sha512-mdjtIZ1XLAM8bm/hx3WwjfHt6Sggek7qH043O8KEjDXN40xi3vx/6pYSVTwLjEgiXQTbvaouWKynLBiUZ6SK6A==",
+            "license": "ISC",
             "dependencies": {
                 "delaunator": "5"
             },
@@ -2042,6 +2163,7 @@
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/d3-dispatch/-/d3-dispatch-3.0.1.tgz",
             "integrity": "sha512-rzUyPU/S7rwUflMyLc1ETDeBj0NRuHKKAcvukozwhshr6g6c5d8zh4c2gQjY2bZ0dXeGLWc1PF174P2tVvKhfg==",
+            "license": "ISC",
             "engines": {
                 "node": ">=12"
             }
@@ -2050,6 +2172,7 @@
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/d3-drag/-/d3-drag-3.0.0.tgz",
             "integrity": "sha512-pWbUJLdETVA8lQNJecMxoXfH6x+mO2UQo8rSmZ+QqxcbyA3hfeprFgIT//HW2nlHChWeIIMwS2Fq+gEARkhTkg==",
+            "license": "ISC",
             "dependencies": {
                 "d3-dispatch": "1 - 3",
                 "d3-selection": "3"
@@ -2062,6 +2185,7 @@
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/d3-dsv/-/d3-dsv-3.0.1.tgz",
             "integrity": "sha512-UG6OvdI5afDIFP9w4G0mNq50dSOsXHJaRE8arAS5o9ApWnIElp8GZw1Dun8vP8OyHOZ/QJUKUJwxiiCCnUwm+Q==",
+            "license": "ISC",
             "dependencies": {
                 "commander": "7",
                 "iconv-lite": "0.6",
@@ -2082,10 +2206,20 @@
                 "node": ">=12"
             }
         },
+        "node_modules/d3-dsv/node_modules/commander": {
+            "version": "7.2.0",
+            "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz",
+            "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==",
+            "license": "MIT",
+            "engines": {
+                "node": ">= 10"
+            }
+        },
         "node_modules/d3-ease": {
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/d3-ease/-/d3-ease-3.0.1.tgz",
             "integrity": "sha512-wR/XK3D3XcLIZwpbvQwQ5fK+8Ykds1ip7A2Txe0yxncXSdq1L9skcG7blcedkOX+ZcgxGAmLX1FrRGbADwzi0w==",
+            "license": "BSD-3-Clause",
             "engines": {
                 "node": ">=12"
             }
@@ -2094,6 +2228,7 @@
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/d3-fetch/-/d3-fetch-3.0.1.tgz",
             "integrity": "sha512-kpkQIM20n3oLVBKGg6oHrUchHM3xODkTzjMoj7aWQFq5QEM+R6E4WkzT5+tojDY7yjez8KgCBRoj4aEr99Fdqw==",
+            "license": "ISC",
             "dependencies": {
                 "d3-dsv": "1 - 3"
             },
@@ -2105,6 +2240,7 @@
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/d3-force/-/d3-force-3.0.0.tgz",
             "integrity": "sha512-zxV/SsA+U4yte8051P4ECydjD/S+qeYtnaIyAs9tgHCqfguma/aAQDjo85A9Z6EKhBirHRJHXIgJUlffT4wdLg==",
+            "license": "ISC",
             "dependencies": {
                 "d3-dispatch": "1 - 3",
                 "d3-quadtree": "1 - 3",
@@ -2118,14 +2254,16 @@
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-3.1.0.tgz",
             "integrity": "sha512-YyUI6AEuY/Wpt8KWLgZHsIU86atmikuoOmCfommt0LYHiQSPjvX2AcFc38PX0CBpr2RCyZhjex+NS/LPOv6YqA==",
+            "license": "ISC",
             "engines": {
                 "node": ">=12"
             }
         },
         "node_modules/d3-geo": {
-            "version": "3.1.0",
-            "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.0.tgz",
-            "integrity": "sha512-JEo5HxXDdDYXCaWdwLRt79y7giK8SbhZJbFWXqbRTolCHFI5jRqteLzCsq51NKbUoX0PjBVSohxrx+NoOUujYA==",
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/d3-geo/-/d3-geo-3.1.1.tgz",
+            "integrity": "sha512-637ln3gXKXOwhalDzinUgY83KzNWZRKbYubaG+fGVuc/dxO64RRljtCTnf5ecMyE1RIdtqpkVcq0IbtU2S8j2Q==",
+            "license": "ISC",
             "dependencies": {
                 "d3-array": "2.5.0 - 3"
             },
@@ -2134,11 +2272,12 @@
             }
         },
         "node_modules/d3-graphviz": {
-            "version": "5.0.2",
-            "resolved": "https://registry.npmjs.org/d3-graphviz/-/d3-graphviz-5.0.2.tgz",
-            "integrity": "sha512-EVRow9rnFgm/L1trbbnu2PGOND11IcSEdWXbrDbz9hH0/Kj3YM2AqMkkTN/EAWgawD5/zryyCy+3Vm05oSJ1Kg==",
+            "version": "5.6.0",
+            "resolved": "https://registry.npmjs.org/d3-graphviz/-/d3-graphviz-5.6.0.tgz",
+            "integrity": "sha512-46OOyRv5Ioo9kZBc919FVIYPD/ObtdSZxOK1hv+qwmD7TunpPvvmsI1dSdxhVgH4GragJxFZ31+TQC5aOuXzzw==",
+            "license": "BSD-3-Clause",
             "dependencies": {
-                "@hpcc-js/wasm": "2.5.0",
+                "@hpcc-js/wasm": "^2.20.0",
                 "d3-dispatch": "^3.0.1",
                 "d3-format": "^3.1.0",
                 "d3-interpolate": "^3.0.1",
@@ -2154,38 +2293,11 @@
                 "d3-selection": "^3.0.0"
             }
         },
-        "node_modules/d3-graphviz/node_modules/@hpcc-js/wasm": {
-            "version": "2.5.0",
-            "resolved": "https://registry.npmjs.org/@hpcc-js/wasm/-/wasm-2.5.0.tgz",
-            "integrity": "sha512-G26BamgaHW46f6P8bmkygapgNcy+tTDMwIvCzmMzdp39sxUS1u4gaT/vR2SSDc4x3SfL5RE4B2B8ef/wd429Hg==",
-            "dependencies": {
-                "yargs": "17.6.2"
-            },
-            "bin": {
-                "dot-wasm": "bin/dot-wasm.js"
-            }
-        },
-        "node_modules/d3-graphviz/node_modules/yargs": {
-            "version": "17.6.2",
-            "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.6.2.tgz",
-            "integrity": "sha512-1/9UrdHjDZc0eOU0HxOHoS78C69UD3JRMvzlJ7S79S2nTaWRA/whGCTV8o9e/N/1Va9YIV7Q4sOxD8VV4pCWOw==",
-            "dependencies": {
-                "cliui": "^8.0.1",
-                "escalade": "^3.1.1",
-                "get-caller-file": "^2.0.5",
-                "require-directory": "^2.1.1",
-                "string-width": "^4.2.3",
-                "y18n": "^5.0.5",
-                "yargs-parser": "^21.1.1"
-            },
-            "engines": {
-                "node": ">=12"
-            }
-        },
         "node_modules/d3-hierarchy": {
             "version": "3.1.2",
             "resolved": "https://registry.npmjs.org/d3-hierarchy/-/d3-hierarchy-3.1.2.tgz",
             "integrity": "sha512-FX/9frcub54beBdugHjDCdikxThEqjnR93Qt7PvQTOHxyiNCAlvMrHhclk3cD5VeAaq9fxmfRp+CnWw9rEMBuA==",
+            "license": "ISC",
             "engines": {
                 "node": ">=12"
             }
@@ -2194,6 +2306,7 @@
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-3.0.1.tgz",
             "integrity": "sha512-3bYs1rOD33uo8aqJfKP3JWPAibgw8Zm2+L9vBKEHJ2Rg+viTR7o5Mmv5mZcieN+FRYaAOWX5SJATX6k1PWz72g==",
+            "license": "ISC",
             "dependencies": {
                 "d3-color": "1 - 3"
             },
@@ -2205,6 +2318,7 @@
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/d3-path/-/d3-path-3.1.0.tgz",
             "integrity": "sha512-p3KP5HCf/bvjBSSKuXid6Zqijx7wIfNW+J/maPs+iwR35at5JCbLUT0LzF1cnjbCHWhqzQTIN2Jpe8pRebIEFQ==",
+            "license": "ISC",
             "engines": {
                 "node": ">=12"
             }
@@ -2213,6 +2327,7 @@
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/d3-polygon/-/d3-polygon-3.0.1.tgz",
             "integrity": "sha512-3vbA7vXYwfe1SYhED++fPUQlWSYTTGmFmQiany/gdbiWgU/iEyQzyymwL9SkJjFFuCS4902BSzewVGsHHmHtXg==",
+            "license": "ISC",
             "engines": {
                 "node": ">=12"
             }
@@ -2221,6 +2336,7 @@
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/d3-quadtree/-/d3-quadtree-3.0.1.tgz",
             "integrity": "sha512-04xDrxQTDTCFwP5H6hRhsRcb9xxv2RzkcsygFzmkSIOJy3PeRJP7sNk3VRIbKXcog561P9oU0/rVH6vDROAgUw==",
+            "license": "ISC",
             "engines": {
                 "node": ">=12"
             }
@@ -2229,6 +2345,7 @@
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/d3-random/-/d3-random-3.0.1.tgz",
             "integrity": "sha512-FXMe9GfxTxqd5D6jFsQ+DJ8BJS4E/fT5mqqdjovykEB2oFbTMDVdg1MGFxfQW+FBOGoB++k8swBrgwSHT1cUXQ==",
+            "license": "ISC",
             "engines": {
                 "node": ">=12"
             }
@@ -2237,6 +2354,7 @@
             "version": "4.0.2",
             "resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-4.0.2.tgz",
             "integrity": "sha512-GZW464g1SH7ag3Y7hXjf8RoUuAFIqklOAq3MRl4OaWabTFJY9PN/E1YklhXLh+OQ3fM9yS2nOkCoS+WLZ6kvxQ==",
+            "license": "ISC",
             "dependencies": {
                 "d3-array": "2.10.0 - 3",
                 "d3-format": "1 - 3",
@@ -2249,9 +2367,10 @@
             }
         },
         "node_modules/d3-scale-chromatic": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.0.0.tgz",
-            "integrity": "sha512-Lx9thtxAKrO2Pq6OO2Ua474opeziKr279P/TKZsMAhYyNDD3EnCffdbgeSYN5O7m2ByQsxtuP2CSDczNUIZ22g==",
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/d3-scale-chromatic/-/d3-scale-chromatic-3.1.0.tgz",
+            "integrity": "sha512-A3s5PWiZ9YCXFye1o246KoscMWqf8BsD9eRiJ3He7C9OBaxKhAd5TFCdEx/7VbKtxxTsu//1mMJFrEt572cEyQ==",
+            "license": "ISC",
             "dependencies": {
                 "d3-color": "1 - 3",
                 "d3-interpolate": "1 - 3"
@@ -2264,6 +2383,7 @@
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
             "integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
+            "license": "ISC",
             "engines": {
                 "node": ">=12"
             }
@@ -2272,6 +2392,7 @@
             "version": "3.2.0",
             "resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-3.2.0.tgz",
             "integrity": "sha512-SaLBuwGm3MOViRq2ABk3eLoxwZELpH6zhl3FbAoJ7Vm1gofKx6El1Ib5z23NUEhF9AsGl7y+dzLe5Cw2AArGTA==",
+            "license": "ISC",
             "dependencies": {
                 "d3-path": "^3.1.0"
             },
@@ -2283,6 +2404,7 @@
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/d3-time/-/d3-time-3.1.0.tgz",
             "integrity": "sha512-VqKjzBLejbSMT4IgbmVgDjpkYrNWUYJnbCGo874u7MMKIWsILRX+OpX/gTk8MqjpT1A/c6HY2dCA77ZN0lkQ2Q==",
+            "license": "ISC",
             "dependencies": {
                 "d3-array": "2 - 3"
             },
@@ -2294,6 +2416,7 @@
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-4.1.0.tgz",
             "integrity": "sha512-dJxPBlzC7NugB2PDLwo9Q8JiTR3M3e4/XANkreKSUxF8vvXKqm1Yfq4Q5dl8budlunRVlUUaDUgFt7eA8D6NLg==",
+            "license": "ISC",
             "dependencies": {
                 "d3-time": "1 - 3"
             },
@@ -2305,6 +2428,7 @@
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/d3-timer/-/d3-timer-3.0.1.tgz",
             "integrity": "sha512-ndfJ/JxxMd3nw31uyKoY2naivF+r29V+Lc0svZxe1JvvIRmi8hUsrMvdOwgS1o6uBHmiz91geQ0ylPP0aj1VUA==",
+            "license": "ISC",
             "engines": {
                 "node": ">=12"
             }
@@ -2313,6 +2437,7 @@
             "version": "3.0.1",
             "resolved": "https://registry.npmjs.org/d3-transition/-/d3-transition-3.0.1.tgz",
             "integrity": "sha512-ApKvfjsSR6tg06xrL434C0WydLr7JewBB3V+/39RMHsaXTOG0zmt/OAXeng5M5LBm0ojmxJrpomQVZ1aPvBL4w==",
+            "license": "ISC",
             "dependencies": {
                 "d3-color": "1 - 3",
                 "d3-dispatch": "1 - 3",
@@ -2331,6 +2456,7 @@
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/d3-zoom/-/d3-zoom-3.0.0.tgz",
             "integrity": "sha512-b8AmV3kfQaqWAuacbPuNbL6vahnOJflOhexLzMMNLga62+/nh0JzvJ0aO/5a5MVgUFGS7Hu1P9P03o3fJkDCyw==",
+            "license": "ISC",
             "dependencies": {
                 "d3-dispatch": "1 - 3",
                 "d3-drag": "2 - 3",
@@ -2343,12 +2469,13 @@
             }
         },
         "node_modules/debug": {
-            "version": "4.3.4",
-            "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz",
-            "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+            "version": "4.4.0",
+            "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
+            "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "ms": "2.1.2"
+                "ms": "^2.1.3"
             },
             "engines": {
                 "node": ">=6.0"
@@ -2364,6 +2491,7 @@
             "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz",
             "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==",
             "dev": true,
+            "license": "MIT",
             "optional": true,
             "dependencies": {
                 "mimic-response": "^3.1.0"
@@ -2380,6 +2508,7 @@
             "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz",
             "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==",
             "dev": true,
+            "license": "MIT",
             "optional": true,
             "engines": {
                 "node": ">=4.0.0"
@@ -2389,42 +2518,59 @@
             "version": "0.1.4",
             "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
             "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
-        "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==",
+        "node_modules/default-browser": {
+            "version": "5.2.1",
+            "resolved": "https://registry.npmjs.org/default-browser/-/default-browser-5.2.1.tgz",
+            "integrity": "sha512-WY/3TUME0x3KPYdRRxEJJvXRHV4PyPoUsxtZa78lwItwRQRHhd2U9xOscaT/YTf8uCXIAjeJOFBVEh/7FtD8Xg==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "es-define-property": "^1.0.0",
-                "es-errors": "^1.3.0",
-                "gopd": "^1.0.1"
+                "bundle-name": "^4.1.0",
+                "default-browser-id": "^5.0.0"
             },
             "engines": {
-                "node": ">= 0.4"
+                "node": ">=18"
             },
             "funding": {
-                "url": "https://github.com/sponsors/ljharb"
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/default-browser-id": {
+            "version": "5.0.0",
+            "resolved": "https://registry.npmjs.org/default-browser-id/-/default-browser-id-5.0.0.tgz",
+            "integrity": "sha512-A6p/pu/6fyBcA1TRz/GqWYPViplrftcW2gZC9q79ngNCKAeR/X3gcEdXQHl4KNXV+3wgIJ1CPkJQ3IHM6lcsyA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=18"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "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==",
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-3.0.0.tgz",
+            "integrity": "sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==",
             "dev": true,
             "license": "MIT",
             "engines": {
-                "node": ">=8"
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/delaunator": {
-            "version": "5.0.0",
-            "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.0.tgz",
-            "integrity": "sha512-AyLvtyJdbv/U1GkiS6gUUzclRoAY4Gs75qkMygJJhU75LW4DNuSF2RMzpxs9jw9Oz1BobHjTdkG3zdP55VxAqw==",
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/delaunator/-/delaunator-5.0.1.tgz",
+            "integrity": "sha512-8nvh+XBe96aCESrGOqMp/84b13H9cdKbG5P2ejQCh4d4sK9RL4371qou9drQjMhvnPmhWl5hnmqbEE0fXr9Xnw==",
+            "license": "ISC",
             "dependencies": {
-                "robust-predicates": "^3.0.0"
+                "robust-predicates": "^3.0.2"
             }
         },
         "node_modules/delayed-stream": {
@@ -2438,44 +2584,22 @@
             }
         },
         "node_modules/detect-libc": {
-            "version": "2.0.1",
-            "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.1.tgz",
-            "integrity": "sha512-463v3ZeIrcWtdgIg6vI6XUncguvr2TnGl4SzDXinkt9mSLpBJKXT3mW6xT3VQdDN11+WVs29pgvivTc4Lp8v+w==",
+            "version": "2.0.3",
+            "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz",
+            "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==",
             "dev": true,
+            "license": "Apache-2.0",
             "optional": true,
             "engines": {
                 "node": ">=8"
             }
         },
-        "node_modules/dir-glob": {
-            "version": "3.0.1",
-            "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
-            "integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
-            "dev": true,
-            "dependencies": {
-                "path-type": "^4.0.0"
-            },
-            "engines": {
-                "node": ">=8"
-            }
-        },
-        "node_modules/doctrine": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz",
-            "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==",
-            "dev": true,
-            "dependencies": {
-                "esutils": "^2.0.2"
-            },
-            "engines": {
-                "node": ">=6.0.0"
-            }
-        },
         "node_modules/dom-serializer": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
             "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "domelementtype": "^2.3.0",
                 "domhandler": "^5.0.2",
@@ -2495,13 +2619,15 @@
                     "type": "github",
                     "url": "https://github.com/sponsors/fb55"
                 }
-            ]
+            ],
+            "license": "BSD-2-Clause"
         },
         "node_modules/domhandler": {
             "version": "5.0.3",
             "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
             "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
             "dev": true,
+            "license": "BSD-2-Clause",
             "dependencies": {
                 "domelementtype": "^2.3.0"
             },
@@ -2513,19 +2639,35 @@
             }
         },
         "node_modules/domutils": {
-            "version": "3.0.1",
-            "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.0.1.tgz",
-            "integrity": "sha512-z08c1l761iKhDFtfXO04C7kTdPBLi41zwOZl00WS8b5eiaebNpY00HKbztwBq+e3vyqWNwWF3mP9YLUeqIrF+Q==",
+            "version": "3.2.2",
+            "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+            "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
             "dev": true,
+            "license": "BSD-2-Clause",
             "dependencies": {
                 "dom-serializer": "^2.0.0",
                 "domelementtype": "^2.3.0",
-                "domhandler": "^5.0.1"
+                "domhandler": "^5.0.3"
             },
             "funding": {
                 "url": "https://github.com/fb55/domutils?sponsor=1"
             }
         },
+        "node_modules/dunder-proto": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+            "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "call-bind-apply-helpers": "^1.0.1",
+                "es-errors": "^1.3.0",
+                "gopd": "^1.2.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
         "node_modules/eastasianwidth": {
             "version": "0.2.0",
             "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
@@ -2544,25 +2686,43 @@
             }
         },
         "node_modules/emoji-regex": {
-            "version": "8.0.0",
-            "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
-            "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="
+            "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/encoding-sniffer": {
+            "version": "0.2.0",
+            "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz",
+            "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "iconv-lite": "^0.6.3",
+                "whatwg-encoding": "^3.1.1"
+            },
+            "funding": {
+                "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
+            }
         },
         "node_modules/end-of-stream": {
             "version": "1.4.4",
             "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz",
             "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==",
             "dev": true,
+            "license": "MIT",
             "optional": true,
             "dependencies": {
                 "once": "^1.4.0"
             }
         },
         "node_modules/entities": {
-            "version": "4.4.0",
-            "resolved": "https://registry.npmjs.org/entities/-/entities-4.4.0.tgz",
-            "integrity": "sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==",
+            "version": "4.5.0",
+            "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+            "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
             "dev": true,
+            "license": "BSD-2-Clause",
             "engines": {
                 "node": ">=0.12"
             },
@@ -2571,14 +2731,11 @@
             }
         },
         "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==",
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+            "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
             "dev": true,
             "license": "MIT",
-            "dependencies": {
-                "get-intrinsic": "^1.2.4"
-            },
             "engines": {
                 "node": ">= 0.4"
             }
@@ -2593,6 +2750,35 @@
                 "node": ">= 0.4"
             }
         },
+        "node_modules/es-object-atoms": {
+            "version": "1.1.1",
+            "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+            "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "es-errors": "^1.3.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
+        "node_modules/es-set-tostringtag": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+            "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "es-errors": "^1.3.0",
+                "get-intrinsic": "^1.2.6",
+                "has-tostringtag": "^1.0.2",
+                "hasown": "^2.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
         "node_modules/esbuild": {
             "version": "0.25.0",
             "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.0.tgz",
@@ -2635,165 +2821,286 @@
             }
         },
         "node_modules/escalade": {
-            "version": "3.1.1",
-            "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz",
-            "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==",
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+            "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+            "license": "MIT",
             "engines": {
                 "node": ">=6"
             }
         },
         "node_modules/escape-string-regexp": {
-            "version": "4.0.0",
-            "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
-            "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+            "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": ">=10"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
+                "node": ">=0.8.0"
             }
         },
         "node_modules/eslint": {
-            "version": "8.44.0",
-            "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz",
-            "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==",
+            "version": "9.21.0",
+            "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.21.0.tgz",
+            "integrity": "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "@eslint-community/eslint-utils": "^4.2.0",
-                "@eslint-community/regexpp": "^4.4.0",
-                "@eslint/eslintrc": "^2.1.0",
-                "@eslint/js": "8.44.0",
-                "@humanwhocodes/config-array": "^0.11.10",
+                "@eslint-community/regexpp": "^4.12.1",
+                "@eslint/config-array": "^0.19.2",
+                "@eslint/core": "^0.12.0",
+                "@eslint/eslintrc": "^3.3.0",
+                "@eslint/js": "9.21.0",
+                "@eslint/plugin-kit": "^0.2.7",
+                "@humanfs/node": "^0.16.6",
                 "@humanwhocodes/module-importer": "^1.0.1",
-                "@nodelib/fs.walk": "^1.2.8",
-                "ajv": "^6.10.0",
+                "@humanwhocodes/retry": "^0.4.2",
+                "@types/estree": "^1.0.6",
+                "@types/json-schema": "^7.0.15",
+                "ajv": "^6.12.4",
                 "chalk": "^4.0.0",
-                "cross-spawn": "^7.0.2",
+                "cross-spawn": "^7.0.6",
                 "debug": "^4.3.2",
-                "doctrine": "^3.0.0",
                 "escape-string-regexp": "^4.0.0",
-                "eslint-scope": "^7.2.0",
-                "eslint-visitor-keys": "^3.4.1",
-                "espree": "^9.6.0",
-                "esquery": "^1.4.2",
+                "eslint-scope": "^8.2.0",
+                "eslint-visitor-keys": "^4.2.0",
+                "espree": "^10.3.0",
+                "esquery": "^1.5.0",
                 "esutils": "^2.0.2",
                 "fast-deep-equal": "^3.1.3",
-                "file-entry-cache": "^6.0.1",
+                "file-entry-cache": "^8.0.0",
                 "find-up": "^5.0.0",
                 "glob-parent": "^6.0.2",
-                "globals": "^13.19.0",
-                "graphemer": "^1.4.0",
                 "ignore": "^5.2.0",
-                "import-fresh": "^3.0.0",
                 "imurmurhash": "^0.1.4",
                 "is-glob": "^4.0.0",
-                "is-path-inside": "^3.0.3",
-                "js-yaml": "^4.1.0",
                 "json-stable-stringify-without-jsonify": "^1.0.1",
-                "levn": "^0.4.1",
                 "lodash.merge": "^4.6.2",
                 "minimatch": "^3.1.2",
                 "natural-compare": "^1.4.0",
-                "optionator": "^0.9.3",
-                "strip-ansi": "^6.0.1",
-                "strip-json-comments": "^3.1.0",
-                "text-table": "^0.2.0"
+                "optionator": "^0.9.3"
             },
             "bin": {
                 "eslint": "bin/eslint.js"
             },
             "engines": {
-                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
-                "url": "https://opencollective.com/eslint"
+                "url": "https://eslint.org/donate"
+            },
+            "peerDependencies": {
+                "jiti": "*"
+            },
+            "peerDependenciesMeta": {
+                "jiti": {
+                    "optional": true
+                }
             }
         },
         "node_modules/eslint-config-prettier": {
-            "version": "8.8.0",
-            "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.8.0.tgz",
-            "integrity": "sha512-wLbQiFre3tdGgpDv67NQKnJuTlcUVYHas3k+DZCc2U2BadthoEY4B7hLPvAxaqdyOGCzuLfii2fqGph10va7oA==",
+            "version": "10.0.2",
+            "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.0.2.tgz",
+            "integrity": "sha512-1105/17ZIMjmCOJOPNfVdbXafLCLj3hPmkmB7dLgt7XsQ/zkxSuDerE/xgO3RxoHysR1N1whmquY0lSn2O0VLg==",
             "dev": true,
+            "license": "MIT",
             "bin": {
-                "eslint-config-prettier": "bin/cli.js"
+                "eslint-config-prettier": "build/bin/cli.js"
             },
             "peerDependencies": {
                 "eslint": ">=7.0.0"
             }
         },
+        "node_modules/eslint-define-config": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/eslint-define-config/-/eslint-define-config-2.1.0.tgz",
+            "integrity": "sha512-QUp6pM9pjKEVannNAbSJNeRuYwW3LshejfyBBpjeMGaJjaDUpVps4C6KVR8R7dWZnD3i0synmrE36znjTkJvdQ==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/Shinigami92"
+                },
+                {
+                    "type": "paypal",
+                    "url": "https://www.paypal.com/donate/?hosted_button_id=L7GY729FBKTZY"
+                }
+            ],
+            "license": "MIT",
+            "engines": {
+                "node": ">=18.0.0",
+                "npm": ">=9.0.0",
+                "pnpm": ">=8.6.0"
+            }
+        },
         "node_modules/eslint-scope": {
-            "version": "5.1.1",
-            "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
-            "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
+            "version": "8.2.0",
+            "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.2.0.tgz",
+            "integrity": "sha512-PHlWUfG6lvPc3yvP5A4PNyBL1W8fkDUccmI21JUu/+GKZBoH/W5u6usENXUrWFRsyoW5ACUjFGgAFQp5gUlb/A==",
             "dev": true,
+            "license": "BSD-2-Clause",
             "dependencies": {
                 "esrecurse": "^4.3.0",
-                "estraverse": "^4.1.1"
+                "estraverse": "^5.2.0"
             },
             "engines": {
-                "node": ">=8.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+            },
+            "funding": {
+                "url": "https://opencollective.com/eslint"
             }
         },
         "node_modules/eslint-visitor-keys": {
-            "version": "3.4.1",
-            "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
-            "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
+            "version": "4.2.0",
+            "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.0.tgz",
+            "integrity": "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==",
             "dev": true,
+            "license": "Apache-2.0",
             "engines": {
-                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "url": "https://opencollective.com/eslint"
             }
         },
-        "node_modules/eslint/node_modules/eslint-scope": {
-            "version": "7.2.0",
-            "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
-            "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
+        "node_modules/eslint/node_modules/ansi-styles": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+            "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "esrecurse": "^4.3.0",
-                "estraverse": "^5.2.0"
+                "color-convert": "^2.0.1"
             },
             "engines": {
-                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+                "node": ">=8"
             },
             "funding": {
-                "url": "https://opencollective.com/eslint"
+                "url": "https://github.com/chalk/ansi-styles?sponsor=1"
             }
         },
-        "node_modules/eslint/node_modules/estraverse": {
-            "version": "5.3.0",
-            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-            "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+        "node_modules/eslint/node_modules/brace-expansion": {
+            "version": "1.1.11",
+            "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
+            "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "balanced-match": "^1.0.0",
+                "concat-map": "0.0.1"
+            }
+        },
+        "node_modules/eslint/node_modules/chalk": {
+            "version": "4.1.2",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+            "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
             "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "ansi-styles": "^4.1.0",
+                "supports-color": "^7.1.0"
+            },
             "engines": {
-                "node": ">=4.0"
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/chalk?sponsor=1"
+            }
+        },
+        "node_modules/eslint/node_modules/color-convert": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+            "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "color-name": "~1.1.4"
+            },
+            "engines": {
+                "node": ">=7.0.0"
+            }
+        },
+        "node_modules/eslint/node_modules/color-name": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+            "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/eslint/node_modules/escape-string-regexp": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+            "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=10"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/eslint/node_modules/has-flag": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+            "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/eslint/node_modules/minimatch": {
+            "version": "3.1.2",
+            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
+            "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+            "dev": true,
+            "license": "ISC",
+            "dependencies": {
+                "brace-expansion": "^1.1.7"
+            },
+            "engines": {
+                "node": "*"
+            }
+        },
+        "node_modules/eslint/node_modules/supports-color": {
+            "version": "7.2.0",
+            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+            "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "has-flag": "^4.0.0"
+            },
+            "engines": {
+                "node": ">=8"
             }
         },
         "node_modules/espree": {
-            "version": "9.6.0",
-            "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz",
-            "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==",
+            "version": "10.3.0",
+            "resolved": "https://registry.npmjs.org/espree/-/espree-10.3.0.tgz",
+            "integrity": "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg==",
             "dev": true,
+            "license": "BSD-2-Clause",
             "dependencies": {
-                "acorn": "^8.9.0",
+                "acorn": "^8.14.0",
                 "acorn-jsx": "^5.3.2",
-                "eslint-visitor-keys": "^3.4.1"
+                "eslint-visitor-keys": "^4.2.0"
             },
             "engines": {
-                "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
             },
             "funding": {
                 "url": "https://opencollective.com/eslint"
             }
         },
         "node_modules/esquery": {
-            "version": "1.5.0",
-            "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.5.0.tgz",
-            "integrity": "sha512-YQLXUplAwJgCydQ78IMJywZCceoqk1oH01OERdSAJc/7U2AylwjhSCLDEtqwg811idIS/9fIU5GjG73IgjKMVg==",
+            "version": "1.6.0",
+            "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.6.0.tgz",
+            "integrity": "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg==",
             "dev": true,
+            "license": "BSD-3-Clause",
             "dependencies": {
                 "estraverse": "^5.1.0"
             },
@@ -2801,20 +3108,12 @@
                 "node": ">=0.10"
             }
         },
-        "node_modules/esquery/node_modules/estraverse": {
-            "version": "5.3.0",
-            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
-            "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
-            "dev": true,
-            "engines": {
-                "node": ">=4.0"
-            }
-        },
         "node_modules/esrecurse": {
             "version": "4.3.0",
             "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
             "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
             "dev": true,
+            "license": "BSD-2-Clause",
             "dependencies": {
                 "estraverse": "^5.2.0"
             },
@@ -2822,20 +3121,12 @@
                 "node": ">=4.0"
             }
         },
-        "node_modules/esrecurse/node_modules/estraverse": {
+        "node_modules/estraverse": {
             "version": "5.3.0",
             "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
             "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
             "dev": true,
-            "engines": {
-                "node": ">=4.0"
-            }
-        },
-        "node_modules/estraverse": {
-            "version": "4.3.0",
-            "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
-            "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
-            "dev": true,
+            "license": "BSD-2-Clause",
             "engines": {
                 "node": ">=4.0"
             }
@@ -2845,6 +3136,7 @@
             "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
             "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
             "dev": true,
+            "license": "BSD-2-Clause",
             "engines": {
                 "node": ">=0.10.0"
             }
@@ -2864,6 +3156,7 @@
             "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz",
             "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==",
             "dev": true,
+            "license": "(MIT OR WTFPL)",
             "optional": true,
             "engines": {
                 "node": ">=6"
@@ -2873,19 +3166,21 @@
             "version": "3.1.3",
             "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
             "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/fast-glob": {
-            "version": "3.3.0",
-            "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.0.tgz",
-            "integrity": "sha512-ChDuvbOypPuNjO8yIDf36x7BlZX1smcUMTTcyoIjycexOxd6DFsKsg21qVBzEmr3G7fUKIRy2/psii+CIUt7FA==",
+            "version": "3.3.3",
+            "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz",
+            "integrity": "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "@nodelib/fs.stat": "^2.0.2",
                 "@nodelib/fs.walk": "^1.2.3",
                 "glob-parent": "^5.1.2",
                 "merge2": "^1.3.0",
-                "micromatch": "^4.0.4"
+                "micromatch": "^4.0.8"
             },
             "engines": {
                 "node": ">=8.6.0"
@@ -2896,6 +3191,7 @@
             "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
             "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
             "dev": true,
+            "license": "ISC",
             "dependencies": {
                 "is-glob": "^4.0.1"
             },
@@ -2907,19 +3203,22 @@
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
             "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/fast-levenshtein": {
             "version": "2.0.6",
             "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
             "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/fastq": {
-            "version": "1.15.0",
-            "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz",
-            "integrity": "sha512-wBrocU2LCXXa+lWBt8RoIRD89Fi8OdABODa/kEnyeyjS5aZO5/GNvI5sEINADqP/h8M29UHTHUb53sUu5Ihqdw==",
+            "version": "1.19.0",
+            "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.0.tgz",
+            "integrity": "sha512-7SFSRCNjBQIZH/xZR3iy5iQYR8aGBE0h3VG6/cwlbrpdciNYBMotQav8c1XI3HjHH+NikUpP53nPdlZSdWmFzA==",
             "dev": true,
+            "license": "ISC",
             "dependencies": {
                 "reusify": "^1.0.4"
             }
@@ -2929,20 +3228,22 @@
             "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz",
             "integrity": "sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "pend": "~1.2.0"
             }
         },
         "node_modules/file-entry-cache": {
-            "version": "6.0.1",
-            "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-6.0.1.tgz",
-            "integrity": "sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==",
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+            "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "flat-cache": "^3.0.4"
+                "flat-cache": "^4.0.0"
             },
             "engines": {
-                "node": "^10.12.0 || >=12.0.0"
+                "node": ">=16.0.0"
             }
         },
         "node_modules/fill-range": {
@@ -2950,6 +3251,7 @@
             "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz",
             "integrity": "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "to-regex-range": "^5.0.1"
             },
@@ -2962,6 +3264,7 @@
             "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
             "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "locate-path": "^6.0.0",
                 "path-exists": "^4.0.0"
@@ -2974,28 +3277,30 @@
             }
         },
         "node_modules/flat-cache": {
-            "version": "3.0.4",
-            "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz",
-            "integrity": "sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==",
+            "version": "4.0.1",
+            "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+            "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "flatted": "^3.1.0",
-                "rimraf": "^3.0.2"
+                "flatted": "^3.2.9",
+                "keyv": "^4.5.4"
             },
             "engines": {
-                "node": "^10.12.0 || >=12.0.0"
+                "node": ">=16"
             }
         },
         "node_modules/flatted": {
-            "version": "3.2.7",
-            "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.2.7.tgz",
-            "integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
-            "dev": true
+            "version": "3.3.3",
+            "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.3.tgz",
+            "integrity": "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg==",
+            "dev": true,
+            "license": "ISC"
         },
         "node_modules/follow-redirects": {
-            "version": "1.15.6",
-            "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz",
-            "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==",
+            "version": "1.15.9",
+            "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz",
+            "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==",
             "dev": true,
             "funding": [
                 {
@@ -3003,6 +3308,7 @@
                     "url": "https://github.com/sponsors/RubenVerborgh"
                 }
             ],
+            "license": "MIT",
             "engines": {
                 "node": ">=4.0"
             },
@@ -3030,14 +3336,15 @@
             }
         },
         "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==",
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
+            "integrity": "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
                 "asynckit": "^0.4.0",
                 "combined-stream": "^1.0.8",
+                "es-set-tostringtag": "^2.1.0",
                 "mime-types": "^2.1.12"
             },
             "engines": {
@@ -3049,14 +3356,9 @@
             "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz",
             "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==",
             "dev": true,
+            "license": "MIT",
             "optional": true
         },
-        "node_modules/fs.realpath": {
-            "version": "1.0.0",
-            "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
-            "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
-            "dev": true
-        },
         "node_modules/function-bind": {
             "version": "1.1.2",
             "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
@@ -3071,22 +3373,28 @@
             "version": "2.0.5",
             "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
             "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+            "license": "ISC",
             "engines": {
                 "node": "6.* || 8.* || >= 10.*"
             }
         },
         "node_modules/get-intrinsic": {
-            "version": "1.2.4",
-            "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz",
-            "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==",
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+            "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
+                "call-bind-apply-helpers": "^1.0.2",
+                "es-define-property": "^1.0.1",
                 "es-errors": "^1.3.0",
+                "es-object-atoms": "^1.1.1",
                 "function-bind": "^1.1.2",
-                "has-proto": "^1.0.1",
-                "has-symbols": "^1.0.3",
-                "hasown": "^2.0.0"
+                "get-proto": "^1.0.1",
+                "gopd": "^1.2.0",
+                "has-symbols": "^1.1.0",
+                "hasown": "^2.0.2",
+                "math-intrinsics": "^1.1.0"
             },
             "engines": {
                 "node": ">= 0.4"
@@ -3095,28 +3403,47 @@
                 "url": "https://github.com/sponsors/ljharb"
             }
         },
+        "node_modules/get-proto": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+            "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "dunder-proto": "^1.0.1",
+                "es-object-atoms": "^1.0.0"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
         "node_modules/github-from-package": {
             "version": "0.0.0",
             "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz",
             "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==",
             "dev": true,
+            "license": "MIT",
             "optional": true
         },
         "node_modules/glob": {
-            "version": "7.2.3",
-            "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
-            "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
+            "version": "11.0.1",
+            "resolved": "https://registry.npmjs.org/glob/-/glob-11.0.1.tgz",
+            "integrity": "sha512-zrQDm8XPnYEKawJScsnM0QzobJxlT/kHOOlRTio8IH/GrmxRE5fjllkzdaHclIuNjUQTJYH2xHNIGfdpJkDJUw==",
             "dev": true,
+            "license": "ISC",
             "dependencies": {
-                "fs.realpath": "^1.0.0",
-                "inflight": "^1.0.4",
-                "inherits": "2",
-                "minimatch": "^3.1.1",
-                "once": "^1.3.0",
-                "path-is-absolute": "^1.0.0"
+                "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": "*"
+                "node": "20 || >=22"
             },
             "funding": {
                 "url": "https://github.com/sponsors/isaacs"
@@ -3127,6 +3454,7 @@
             "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
             "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
             "dev": true,
+            "license": "ISC",
             "dependencies": {
                 "is-glob": "^4.0.3"
             },
@@ -3134,92 +3462,69 @@
                 "node": ">=10.13.0"
             }
         },
-        "node_modules/globals": {
-            "version": "13.20.0",
-            "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
-            "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
+        "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": {
-                "type-fest": "^0.20.2"
+                "brace-expansion": "^2.0.1"
             },
             "engines": {
-                "node": ">=8"
+                "node": "20 || >=22"
             },
             "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
+                "url": "https://github.com/sponsors/isaacs"
             }
         },
-        "node_modules/globby": {
-            "version": "11.1.0",
-            "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
-            "integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
+        "node_modules/globals": {
+            "version": "14.0.0",
+            "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+            "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
             "dev": true,
-            "dependencies": {
-                "array-union": "^2.1.0",
-                "dir-glob": "^3.0.1",
-                "fast-glob": "^3.2.9",
-                "ignore": "^5.2.0",
-                "merge2": "^1.4.1",
-                "slash": "^3.0.0"
-            },
+            "license": "MIT",
             "engines": {
-                "node": ">=10"
+                "node": ">=18"
             },
             "funding": {
                 "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==",
+            "version": "1.2.0",
+            "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+            "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
             "dev": true,
             "license": "MIT",
-            "dependencies": {
-                "get-intrinsic": "^1.1.3"
+            "engines": {
+                "node": ">= 0.4"
             },
             "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",
-            "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
-            "dev": true
-        },
         "node_modules/graphemer": {
             "version": "1.4.0",
             "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz",
             "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==",
-            "dev": true
-        },
-        "node_modules/has-flag": {
-            "version": "4.0.0",
-            "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
-            "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
             "dev": true,
-            "engines": {
-                "node": ">=8"
-            }
+            "license": "MIT"
         },
-        "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==",
+        "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",
-            "dependencies": {
-                "es-define-property": "^1.0.0"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/ljharb"
+            "engines": {
+                "node": ">=4"
             }
         },
-        "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==",
+        "node_modules/has-symbols": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+            "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
             "dev": true,
             "license": "MIT",
             "engines": {
@@ -3229,12 +3534,15 @@
                 "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==",
+        "node_modules/has-tostringtag": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+            "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
             "dev": true,
             "license": "MIT",
+            "dependencies": {
+                "has-symbols": "^1.0.3"
+            },
             "engines": {
                 "node": ">= 0.4"
             },
@@ -3260,6 +3568,7 @@
             "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-4.1.0.tgz",
             "integrity": "sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==",
             "dev": true,
+            "license": "ISC",
             "dependencies": {
                 "lru-cache": "^6.0.0"
             },
@@ -3268,9 +3577,9 @@
             }
         },
         "node_modules/htmlparser2": {
-            "version": "8.0.1",
-            "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-8.0.1.tgz",
-            "integrity": "sha512-4lVbmc1diZC7GUJQtRQ5yBAeUCL1exyMwmForWkRLnwyzWBFxN633SALPMGYaWZvKe9j1pRZJpauvmxENSp/EA==",
+            "version": "9.1.0",
+            "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz",
+            "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==",
             "dev": true,
             "funding": [
                 "https://github.com/fb55/htmlparser2?sponsor=1",
@@ -3279,44 +3588,47 @@
                     "url": "https://github.com/sponsors/fb55"
                 }
             ],
+            "license": "MIT",
             "dependencies": {
                 "domelementtype": "^2.3.0",
-                "domhandler": "^5.0.2",
-                "domutils": "^3.0.1",
-                "entities": "^4.3.0"
+                "domhandler": "^5.0.3",
+                "domutils": "^3.1.0",
+                "entities": "^4.5.0"
             }
         },
         "node_modules/http-proxy-agent": {
-            "version": "4.0.1",
-            "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz",
-            "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==",
+            "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": {
-                "@tootallnate/once": "1",
-                "agent-base": "6",
-                "debug": "4"
+                "agent-base": "^7.1.0",
+                "debug": "^4.3.4"
             },
             "engines": {
-                "node": ">= 6"
+                "node": ">= 14"
             }
         },
         "node_modules/https-proxy-agent": {
-            "version": "5.0.1",
-            "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz",
-            "integrity": "sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==",
+            "version": "7.0.6",
+            "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+            "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "agent-base": "6",
+                "agent-base": "^7.1.2",
                 "debug": "4"
             },
             "engines": {
-                "node": ">= 6"
+                "node": ">= 14"
             }
         },
         "node_modules/iconv-lite": {
             "version": "0.6.3",
             "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
             "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+            "license": "MIT",
             "dependencies": {
                 "safer-buffer": ">= 2.1.2 < 3.0.0"
             },
@@ -3343,13 +3655,14 @@
                     "url": "https://feross.org/support"
                 }
             ],
-            "optional": true
+            "license": "BSD-3-Clause"
         },
         "node_modules/ignore": {
-            "version": "5.2.4",
-            "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
-            "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
+            "version": "5.3.2",
+            "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+            "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">= 4"
             }
@@ -3358,13 +3671,15 @@
             "version": "3.0.6",
             "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz",
             "integrity": "sha512-XXOFtyqDjNDAQxVfYxuF7g9Il/IbWmmlQg2MYKOH8ExIT1qg6xc4zyS3HaEEATgs1btfzxq15ciUiY7gjSXRGQ==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/import-fresh": {
-            "version": "3.3.0",
-            "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.0.tgz",
-            "integrity": "sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==",
+            "version": "3.3.1",
+            "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+            "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "parent-module": "^1.0.0",
                 "resolve-from": "^4.0.0"
@@ -3381,37 +3696,31 @@
             "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
             "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">=0.8.19"
             }
         },
-        "node_modules/inflight": {
-            "version": "1.0.6",
-            "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
-            "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
-            "dev": true,
-            "dependencies": {
-                "once": "^1.3.0",
-                "wrappy": "1"
-            }
-        },
         "node_modules/inherits": {
             "version": "2.0.4",
             "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
             "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
-            "dev": true
+            "dev": true,
+            "license": "ISC"
         },
         "node_modules/ini": {
             "version": "1.3.8",
             "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
             "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
             "dev": true,
+            "license": "ISC",
             "optional": true
         },
         "node_modules/internmap": {
             "version": "2.0.3",
             "resolved": "https://registry.npmjs.org/internmap/-/internmap-2.0.3.tgz",
             "integrity": "sha512-5Hh7Y1wQbvY5ooGgPbDaL5iYLAPzMTUrjMulskHLH6wnv/A+1q5rgEaiuqEjB+oxGXIVZs1FF+R/KPN3ZSQYYg==",
+            "license": "ISC",
             "engines": {
                 "node": ">=12"
             }
@@ -3421,6 +3730,7 @@
             "resolved": "https://registry.npmjs.org/is-ci/-/is-ci-2.0.0.tgz",
             "integrity": "sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "ci-info": "^2.0.0"
             },
@@ -3429,16 +3739,16 @@
             }
         },
         "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==",
+            "version": "3.0.0",
+            "resolved": "https://registry.npmjs.org/is-docker/-/is-docker-3.0.0.tgz",
+            "integrity": "sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==",
             "dev": true,
             "license": "MIT",
             "bin": {
                 "is-docker": "cli.js"
             },
             "engines": {
-                "node": ">=8"
+                "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
             },
             "funding": {
                 "url": "https://github.com/sponsors/sindresorhus"
@@ -3449,6 +3759,7 @@
             "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
             "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">=0.10.0"
             }
@@ -3457,6 +3768,7 @@
             "version": "3.0.0",
             "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
             "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+            "license": "MIT",
             "engines": {
                 "node": ">=8"
             }
@@ -3466,6 +3778,7 @@
             "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
             "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "is-extglob": "^2.1.1"
             },
@@ -3473,53 +3786,95 @@
                 "node": ">=0.10.0"
             }
         },
+        "node_modules/is-inside-container": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/is-inside-container/-/is-inside-container-1.0.0.tgz",
+            "integrity": "sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "is-docker": "^3.0.0"
+            },
+            "bin": {
+                "is-inside-container": "cli.js"
+            },
+            "engines": {
+                "node": ">=14.16"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/is-interactive": {
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/is-interactive/-/is-interactive-2.0.0.tgz",
+            "integrity": "sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
         "node_modules/is-number": {
             "version": "7.0.0",
             "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
             "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">=0.12.0"
             }
         },
-        "node_modules/is-path-inside": {
-            "version": "3.0.3",
-            "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
-            "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
+        "node_modules/is-unicode-supported": {
+            "version": "1.3.0",
+            "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-1.3.0.tgz",
+            "integrity": "sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==",
             "dev": true,
+            "license": "MIT",
             "engines": {
-                "node": ">=8"
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "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==",
+            "version": "3.1.0",
+            "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz",
+            "integrity": "sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "is-docker": "^2.0.0"
+                "is-inside-container": "^1.0.0"
             },
             "engines": {
-                "node": ">=8"
+                "node": ">=16"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/isarray": {
             "version": "1.0.0",
             "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz",
             "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/isexe": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
             "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
-            "dev": true
+            "dev": true,
+            "license": "ISC"
         },
         "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==",
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-4.1.0.tgz",
+            "integrity": "sha512-9DDdhb5j6cpeitCbvLO7n7J4IxnbM6hoF6O1g4HQ5TfhvvKN8ywDM7668ZhMHRqVmxqhps/F6syWK2KcPxYlkw==",
             "dev": true,
             "license": "BlueOak-1.0.0",
             "dependencies": {
@@ -3532,11 +3887,21 @@
                 "url": "https://github.com/sponsors/isaacs"
             }
         },
+        "node_modules/jiti": {
+            "version": "2.4.2",
+            "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.4.2.tgz",
+            "integrity": "sha512-rg9zJN+G4n2nfJl5MW3BMygZX56zKPNVEYYqq7adpmMh4Jn2QNEwhvQlFy6jPVdcod7txZtKHWnyZiA3a0zP7A==",
+            "license": "MIT",
+            "bin": {
+                "jiti": "lib/jiti-cli.mjs"
+            }
+        },
         "node_modules/js-yaml": {
             "version": "4.1.0",
             "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
             "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "argparse": "^2.0.1"
             },
@@ -3544,23 +3909,33 @@
                 "js-yaml": "bin/js-yaml.js"
             }
         },
+        "node_modules/json-buffer": {
+            "version": "3.0.1",
+            "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+            "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+            "dev": true,
+            "license": "MIT"
+        },
         "node_modules/json-schema-traverse": {
             "version": "0.4.1",
             "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
             "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/json-stable-stringify-without-jsonify": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz",
             "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/jsonc-parser": {
-            "version": "3.2.0",
-            "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz",
-            "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==",
-            "dev": true
+            "version": "3.3.1",
+            "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.3.1.tgz",
+            "integrity": "sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==",
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/jsonwebtoken": {
             "version": "9.0.2",
@@ -3613,6 +3988,7 @@
             "resolved": "https://registry.npmjs.org/jszip/-/jszip-3.10.1.tgz",
             "integrity": "sha512-xXDvecyTpGLrqFrvkrUSoxxfJI5AH7U8zxxtVclpsUtMCq4JQ290LY8AW5c7Ggnr/Y/oK+bQMbqK2qmtk3pN4g==",
             "dev": true,
+            "license": "(MIT OR GPL-3.0-or-later)",
             "dependencies": {
                 "lie": "~3.3.0",
                 "pako": "~1.0.2",
@@ -3649,17 +4025,29 @@
             "integrity": "sha512-VPD8mtVtm5JNtA2AErl6Chp06JBfy7diFQ7TQQhdpWOl6MrCRB+eRbvAZUsbGQS9kiMq0coJsy0W0vHpDCkWsQ==",
             "dev": true,
             "hasInstallScript": true,
+            "license": "MIT",
             "optional": true,
             "dependencies": {
                 "node-addon-api": "^4.3.0",
                 "prebuild-install": "^7.0.1"
             }
         },
+        "node_modules/keyv": {
+            "version": "4.5.4",
+            "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+            "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "json-buffer": "3.0.1"
+            }
+        },
         "node_modules/leven": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/leven/-/leven-3.1.0.tgz",
             "integrity": "sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">=6"
             }
@@ -3669,6 +4057,7 @@
             "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
             "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "prelude-ls": "^1.2.1",
                 "type-check": "~0.4.0"
@@ -3682,6 +4071,7 @@
             "resolved": "https://registry.npmjs.org/lie/-/lie-3.3.0.tgz",
             "integrity": "sha512-UaiMJzeWRlEujzAuw5LokY1L5ecNQYZKfmyZ9L7wDHb/p5etKaxXhohBcrw0EYby+G/NA52vRSN4N39dxHAIwQ==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "immediate": "~3.0.5"
             }
@@ -3701,6 +4091,7 @@
             "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
             "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "p-locate": "^5.0.0"
             },
@@ -3757,7 +4148,8 @@
             "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
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/lodash.once": {
             "version": "4.1.1",
@@ -3766,10 +4158,42 @@
             "dev": true,
             "license": "MIT"
         },
+        "node_modules/log-symbols": {
+            "version": "5.1.0",
+            "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-5.1.0.tgz",
+            "integrity": "sha512-l0x2DvrW294C9uDCoQe1VSU4gf529FkSZ6leBl4TiqZH/e+0R7hSfHQBNut2mNygDgHwvYHfFLn6Oxb3VWj2rA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "chalk": "^5.0.0",
+                "is-unicode-supported": "^1.1.0"
+            },
+            "engines": {
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/log-symbols/node_modules/chalk": {
+            "version": "5.4.1",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
+            "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": "^12.17.0 || ^14.13 || >=16.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/chalk?sponsor=1"
+            }
+        },
         "node_modules/lru-cache": {
             "version": "6.0.0",
             "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz",
             "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==",
+            "dev": true,
+            "license": "ISC",
             "dependencies": {
                 "yallist": "^4.0.0"
             },
@@ -3795,6 +4219,16 @@
                 "markdown-it": "bin/markdown-it.mjs"
             }
         },
+        "node_modules/math-intrinsics": {
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+            "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">= 0.4"
+            }
+        },
         "node_modules/mdurl": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
@@ -3807,6 +4241,7 @@
             "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
             "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">= 8"
             }
@@ -3825,11 +4260,25 @@
                 "node": ">=8.6"
             }
         },
+        "node_modules/micromatch/node_modules/picomatch": {
+            "version": "2.3.1",
+            "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
+            "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=8.6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/jonschlinkert"
+            }
+        },
         "node_modules/mime": {
             "version": "1.6.0",
             "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz",
             "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==",
             "dev": true,
+            "license": "MIT",
             "bin": {
                 "mime": "cli.js"
             },
@@ -3860,11 +4309,22 @@
                 "node": ">= 0.6"
             }
         },
+        "node_modules/mimic-fn": {
+            "version": "2.1.0",
+            "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+            "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=6"
+            }
+        },
         "node_modules/mimic-response": {
             "version": "3.1.0",
             "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz",
             "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==",
             "dev": true,
+            "license": "MIT",
             "optional": true,
             "engines": {
                 "node": ">=10"
@@ -3874,22 +4334,27 @@
             }
         },
         "node_modules/minimatch": {
-            "version": "3.1.2",
-            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
-            "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+            "version": "9.0.5",
+            "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
+            "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
             "dev": true,
+            "license": "ISC",
             "dependencies": {
-                "brace-expansion": "^1.1.7"
+                "brace-expansion": "^2.0.1"
             },
             "engines": {
-                "node": "*"
+                "node": ">=16 || 14 >=14.17"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/isaacs"
             }
         },
         "node_modules/minimist": {
-            "version": "1.2.7",
-            "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
-            "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
+            "version": "1.2.8",
+            "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+            "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
             "dev": true,
+            "license": "MIT",
             "optional": true,
             "funding": {
                 "url": "https://github.com/sponsors/ljharb"
@@ -3910,44 +4375,44 @@
             "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz",
             "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==",
             "dev": true,
+            "license": "MIT",
             "optional": true
         },
         "node_modules/ms": {
-            "version": "2.1.2",
-            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
-            "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
-            "dev": true
+            "version": "2.1.3",
+            "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+            "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/mute-stream": {
             "version": "0.0.8",
             "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz",
             "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==",
-            "dev": true
+            "dev": true,
+            "license": "ISC"
         },
         "node_modules/napi-build-utils": {
-            "version": "1.0.2",
-            "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-1.0.2.tgz",
-            "integrity": "sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==",
+            "version": "2.0.0",
+            "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz",
+            "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==",
             "dev": true,
+            "license": "MIT",
             "optional": true
         },
         "node_modules/natural-compare": {
             "version": "1.4.0",
             "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
             "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
-            "dev": true
-        },
-        "node_modules/natural-compare-lite": {
-            "version": "1.4.0",
-            "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
-            "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/node-abi": {
-            "version": "3.31.0",
-            "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.31.0.tgz",
-            "integrity": "sha512-eSKV6s+APenqVh8ubJyiu/YhZgxQpGP66ntzUb3lY1xB9ukSRaGnx0AIxI+IM+1+IVYC1oWobgG5L3Lt9ARykQ==",
+            "version": "3.74.0",
+            "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.74.0.tgz",
+            "integrity": "sha512-c5XK0MjkGBrQPGYG24GBADZud0NCbznxNx0ZkS+ebUTrmV1qTDxPxSL8zEAPURXSbLRWVexxmP4986BziahL5w==",
             "dev": true,
+            "license": "MIT",
             "optional": true,
             "dependencies": {
                 "semver": "^7.3.5"
@@ -3961,6 +4426,7 @@
             "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz",
             "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==",
             "dev": true,
+            "license": "MIT",
             "optional": true
         },
         "node_modules/nth-check": {
@@ -3968,6 +4434,7 @@
             "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
             "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
             "dev": true,
+            "license": "BSD-2-Clause",
             "dependencies": {
                 "boolbase": "^1.0.0"
             },
@@ -3976,9 +4443,9 @@
             }
         },
         "node_modules/object-inspect": {
-            "version": "1.13.2",
-            "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz",
-            "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==",
+            "version": "1.13.4",
+            "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+            "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
             "dev": true,
             "license": "MIT",
             "engines": {
@@ -3993,251 +4460,180 @@
             "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
             "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
             "dev": true,
+            "license": "ISC",
+            "optional": true,
             "dependencies": {
                 "wrappy": "1"
             }
         },
+        "node_modules/onetime": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+            "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "mimic-fn": "^2.1.0"
+            },
+            "engines": {
+                "node": ">=6"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
         "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==",
+            "version": "10.1.0",
+            "resolved": "https://registry.npmjs.org/open/-/open-10.1.0.tgz",
+            "integrity": "sha512-mnkeQ1qP5Ue2wd+aivTD3NHd/lZ96Lu0jgf0pwktLPtx6cTZiH7tyeGRRHs0zX0rbrahXPnXlUnbeXyaBBuIaw==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "define-lazy-prop": "^2.0.0",
-                "is-docker": "^2.1.1",
-                "is-wsl": "^2.2.0"
+                "default-browser": "^5.2.1",
+                "define-lazy-prop": "^3.0.0",
+                "is-inside-container": "^1.0.0",
+                "is-wsl": "^3.1.0"
             },
             "engines": {
-                "node": ">=12"
+                "node": ">=18"
             },
             "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",
-            "integrity": "sha512-JjCoypp+jKn1ttEFExxhetCKeJt9zhAgAve5FXHixTvFDW/5aEktX9bufBKLRRMdU7bNtpLfcGu94B3cdEJgjg==",
+            "version": "0.9.4",
+            "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+            "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "@aashutoshrathi/word-wrap": "^1.2.3",
                 "deep-is": "^0.1.3",
                 "fast-levenshtein": "^2.0.6",
                 "levn": "^0.4.1",
                 "prelude-ls": "^1.2.1",
-                "type-check": "^0.4.0"
+                "type-check": "^0.4.0",
+                "word-wrap": "^1.2.5"
             },
             "engines": {
                 "node": ">= 0.8.0"
             }
         },
-        "node_modules/ovsx": {
-            "version": "0.8.2",
-            "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.8.2.tgz",
-            "integrity": "sha512-btDXZorXlmwN9+9Un3khrVygCXmhwbrtg8gifNXw92rZPXcRBAiLG/L09Kb6srhGEratsFt42AktfD8t9XhzoA==",
+        "node_modules/ora": {
+            "version": "7.0.1",
+            "resolved": "https://registry.npmjs.org/ora/-/ora-7.0.1.tgz",
+            "integrity": "sha512-0TUxTiFJWv+JnjWm4o9yvuskpEJLXTcng8MJuKd+SzAzp2o+OP3HWqNhB4OdJRt1Vsd9/mR0oyaEYlOnL7XIRw==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "@vscode/vsce": "^2.19.0",
-                "commander": "^6.1.0",
-                "follow-redirects": "^1.14.6",
-                "is-ci": "^2.0.0",
-                "leven": "^3.1.0",
-                "semver": "^7.5.2",
-                "tmp": "^0.2.1"
-            },
-            "bin": {
-                "ovsx": "lib/ovsx"
+                "chalk": "^5.3.0",
+                "cli-cursor": "^4.0.0",
+                "cli-spinners": "^2.9.0",
+                "is-interactive": "^2.0.0",
+                "is-unicode-supported": "^1.3.0",
+                "log-symbols": "^5.1.0",
+                "stdin-discarder": "^0.1.0",
+                "string-width": "^6.1.0",
+                "strip-ansi": "^7.1.0"
             },
             "engines": {
-                "node": ">= 14"
+                "node": ">=16"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
             }
         },
-        "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==",
+        "node_modules/ora/node_modules/chalk": {
+            "version": "5.4.1",
+            "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.4.1.tgz",
+            "integrity": "sha512-zgVZuo2WcZgfUEmsn6eO3kINexW8RAE4maiQ8QNs8CtpPCSyMiYsULR3HQYkm3w8FIA3SberyMJMSldGsW+U3w==",
             "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"
+                "node": "^12.17.0 || ^14.13 || >=16.0.0"
             },
-            "optionalDependencies": {
-                "keytar": "^7.7.0"
+            "funding": {
+                "url": "https://github.com/chalk/chalk?sponsor=1"
             }
         },
-        "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==",
+        "node_modules/ora/node_modules/emoji-regex": {
+            "version": "10.4.0",
+            "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
+            "integrity": "sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==",
             "dev": true,
-            "license": "MIT",
-            "dependencies": {
-                "color-convert": "^1.9.0"
-            },
-            "engines": {
-                "node": ">=4"
-            }
+            "license": "MIT"
         },
-        "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==",
+        "node_modules/ora/node_modules/string-width": {
+            "version": "6.1.0",
+            "resolved": "https://registry.npmjs.org/string-width/-/string-width-6.1.0.tgz",
+            "integrity": "sha512-k01swCJAgQmuADB0YIc+7TuatfNvTBVOoaUWJjTB9R4VJzR5vNWzf5t42ESVZFPS8xTySF7CAdV4t/aaIm3UnQ==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "ansi-styles": "^3.2.1",
-                "escape-string-regexp": "^1.0.5",
-                "supports-color": "^5.3.0"
+                "eastasianwidth": "^0.2.0",
+                "emoji-regex": "^10.2.1",
+                "strip-ansi": "^7.0.1"
             },
             "engines": {
-                "node": ">=4"
+                "node": ">=16"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
             }
         },
-        "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==",
+        "node_modules/ovsx": {
+            "version": "0.10.1",
+            "resolved": "https://registry.npmjs.org/ovsx/-/ovsx-0.10.1.tgz",
+            "integrity": "sha512-8i7+MJMMeq73m1zPEIClSFe17SNuuzU5br7G77ZIfOC24elB4pGQs0N1qRd+gnnbyhL5Qu96G21nFOVOBa2OBg==",
             "dev": true,
-            "license": "MIT",
+            "license": "EPL-2.0",
             "dependencies": {
-                "color-name": "1.1.3"
+                "@vscode/vsce": "^3.2.1",
+                "commander": "^6.2.1",
+                "follow-redirects": "^1.14.6",
+                "is-ci": "^2.0.0",
+                "leven": "^3.1.0",
+                "semver": "^7.6.0",
+                "tmp": "^0.2.3",
+                "yauzl": "^3.1.3"
+            },
+            "bin": {
+                "ovsx": "lib/ovsx"
+            },
+            "engines": {
+                "node": ">= 20"
             }
         },
-        "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",
             "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==",
             "dev": true,
-            "engines": {
-                "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": ">= 6"
             }
         },
-        "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==",
+        "node_modules/ovsx/node_modules/yauzl": {
+            "version": "3.2.0",
+            "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-3.2.0.tgz",
+            "integrity": "sha512-Ow9nuGZE+qp1u4JIPvg+uCiUr7xGQWdff7JQSk5VGYTAZMDe2q8lxJ10ygv10qmSj031Ty/6FNJpLO4o1Sgc+w==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "has-flag": "^3.0.0"
+                "buffer-crc32": "~0.2.3",
+                "pend": "~1.2.0"
             },
             "engines": {
-                "node": ">=4"
+                "node": ">=12"
             }
         },
-        "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",
             "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "yocto-queue": "^0.1.0"
             },
@@ -4253,6 +4649,7 @@
             "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
             "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "p-limit": "^3.0.2"
             },
@@ -4274,13 +4671,15 @@
             "version": "1.0.11",
             "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.11.tgz",
             "integrity": "sha512-4hLB8Py4zZce5s4yd9XzopqwVv/yGNhV1Bl8NTmCq1763HeK2+EwVTv+leGeL13Dnh2wfbqowVPXCIO0z4taYw==",
-            "dev": true
+            "dev": true,
+            "license": "(MIT AND Zlib)"
         },
         "node_modules/parent-module": {
             "version": "1.0.1",
             "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
             "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "callsites": "^3.0.0"
             },
@@ -4293,6 +4692,7 @@
             "resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz",
             "integrity": "sha512-Eg1OuNntBMH0ojvEKSrvDSnwLmvVuUOSdylH/pSCPNMIspLlweJyIWXCE+k/5hm3cj/EBUYwmWkjhBALNP4LXQ==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "semver": "^5.1.0"
             }
@@ -4302,29 +4702,45 @@
             "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz",
             "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==",
             "dev": true,
+            "license": "ISC",
             "bin": {
                 "semver": "bin/semver"
             }
         },
         "node_modules/parse5": {
-            "version": "7.1.2",
-            "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.1.2.tgz",
-            "integrity": "sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==",
+            "version": "7.2.1",
+            "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
+            "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "entities": "^4.4.0"
+                "entities": "^4.5.0"
             },
             "funding": {
                 "url": "https://github.com/inikulin/parse5?sponsor=1"
             }
         },
         "node_modules/parse5-htmlparser2-tree-adapter": {
-            "version": "7.0.0",
-            "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.0.0.tgz",
-            "integrity": "sha512-B77tOZrqqfUfnVcOrUvfdLbz4pu4RopLD/4vmu3HUPswwTA8OH0EMW9BlWR2B0RCoiZRAHEUu7IxeP1Pd1UU+g==",
+            "version": "7.1.0",
+            "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
+            "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
             "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "domhandler": "^5.0.3",
+                "parse5": "^7.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/inikulin/parse5?sponsor=1"
+            }
+        },
+        "node_modules/parse5-parser-stream": {
+            "version": "7.1.2",
+            "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
+            "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
+            "dev": true,
+            "license": "MIT",
             "dependencies": {
-                "domhandler": "^5.0.2",
                 "parse5": "^7.0.0"
             },
             "funding": {
@@ -4336,24 +4752,17 @@
             "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
             "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">=8"
             }
         },
-        "node_modules/path-is-absolute": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
-            "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
-            "dev": true,
-            "engines": {
-                "node": ">=0.10.0"
-            }
-        },
         "node_modules/path-key": {
             "version": "3.1.1",
             "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
             "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">=8"
             }
@@ -4376,47 +4785,41 @@
             }
         },
         "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==",
+            "version": "11.0.2",
+            "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.0.2.tgz",
+            "integrity": "sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==",
             "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",
-            "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
-            "dev": true,
-            "engines": {
-                "node": ">=8"
-            }
-        },
         "node_modules/pend": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz",
             "integrity": "sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/picomatch": {
-            "version": "2.3.1",
-            "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
-            "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
+            "version": "4.0.2",
+            "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
+            "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
             "dev": true,
+            "license": "MIT",
             "engines": {
-                "node": ">=8.6"
+                "node": ">=12"
             },
             "funding": {
                 "url": "https://github.com/sponsors/jonschlinkert"
             }
         },
         "node_modules/prebuild-install": {
-            "version": "7.1.1",
-            "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.1.tgz",
-            "integrity": "sha512-jAXscXWMcCK8GgCoHOfIr0ODh5ai8mj63L2nWrjuAgXE6tDyYGnx4/8o/rCgU+B4JSyZBKbeZqzhtwtC3ovxjw==",
+            "version": "7.1.3",
+            "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz",
+            "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==",
             "dev": true,
+            "license": "MIT",
             "optional": true,
             "dependencies": {
                 "detect-libc": "^2.0.0",
@@ -4424,7 +4827,7 @@
                 "github-from-package": "0.0.0",
                 "minimist": "^1.2.3",
                 "mkdirp-classic": "^0.5.3",
-                "napi-build-utils": "^1.0.1",
+                "napi-build-utils": "^2.0.0",
                 "node-abi": "^3.3.0",
                 "pump": "^3.0.0",
                 "rc": "^1.2.7",
@@ -4444,15 +4847,17 @@
             "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
             "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">= 0.8.0"
             }
         },
         "node_modules/prettier": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.0.tgz",
-            "integrity": "sha512-zBf5eHpwHOGPC47h0zrPyNn+eAEIdEzfywMoYn2XPi0P44Zp0tSq64rq0xAREh4auw2cJZHo9QUob+NqCQky4g==",
+            "version": "3.5.2",
+            "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.5.2.tgz",
+            "integrity": "sha512-lc6npv5PH7hVqozBR7lkBNOGXV9vMwROAPlumdBkX0wTbbzPu/U1hk5yL8p2pt4Xoc+2mkT8t/sow2YrV/M5qg==",
             "dev": true,
+            "license": "MIT",
             "bin": {
                 "prettier": "bin/prettier.cjs"
             },
@@ -4467,13 +4872,15 @@
             "version": "2.0.1",
             "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz",
             "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/pump": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz",
-            "integrity": "sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==",
+            "version": "3.0.2",
+            "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz",
+            "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==",
             "dev": true,
+            "license": "MIT",
             "optional": true,
             "dependencies": {
                 "end-of-stream": "^1.1.0",
@@ -4481,10 +4888,11 @@
             }
         },
         "node_modules/punycode": {
-            "version": "2.3.0",
-            "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.0.tgz",
-            "integrity": "sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==",
+            "version": "2.3.1",
+            "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+            "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">=6"
             }
@@ -4500,13 +4908,13 @@
             }
         },
         "node_modules/qs": {
-            "version": "6.13.0",
-            "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz",
-            "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==",
+            "version": "6.14.0",
+            "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz",
+            "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==",
             "dev": true,
             "license": "BSD-3-Clause",
             "dependencies": {
-                "side-channel": "^1.0.6"
+                "side-channel": "^1.1.0"
             },
             "engines": {
                 "node": ">=0.6"
@@ -4533,13 +4941,15 @@
                     "type": "consulting",
                     "url": "https://feross.org/support"
                 }
-            ]
+            ],
+            "license": "MIT"
         },
         "node_modules/rc": {
             "version": "1.2.8",
             "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz",
             "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==",
             "dev": true,
+            "license": "(BSD-2-Clause OR MIT OR Apache-2.0)",
             "optional": true,
             "dependencies": {
                 "deep-extend": "^0.6.0",
@@ -4556,6 +4966,7 @@
             "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz",
             "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==",
             "dev": true,
+            "license": "MIT",
             "optional": true,
             "engines": {
                 "node": ">=0.10.0"
@@ -4566,6 +4977,7 @@
             "resolved": "https://registry.npmjs.org/read/-/read-1.0.7.tgz",
             "integrity": "sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==",
             "dev": true,
+            "license": "ISC",
             "dependencies": {
                 "mute-stream": "~0.0.4"
             },
@@ -4578,6 +4990,7 @@
             "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz",
             "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "core-util-is": "~1.0.0",
                 "inherits": "~2.0.3",
@@ -4588,10 +5001,18 @@
                 "util-deprecate": "~1.0.1"
             }
         },
+        "node_modules/readable-stream/node_modules/safe-buffer": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+            "dev": true,
+            "license": "MIT"
+        },
         "node_modules/require-directory": {
             "version": "2.1.1",
             "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
             "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+            "license": "MIT",
             "engines": {
                 "node": ">=0.10.0"
             }
@@ -4601,40 +5022,65 @@
             "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
             "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">=4"
             }
         },
+        "node_modules/restore-cursor": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz",
+            "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "onetime": "^5.1.0",
+                "signal-exit": "^3.0.2"
+            },
+            "engines": {
+                "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
+            }
+        },
+        "node_modules/restore-cursor/node_modules/signal-exit": {
+            "version": "3.0.7",
+            "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+            "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+            "dev": true,
+            "license": "ISC"
+        },
         "node_modules/reusify": {
             "version": "1.0.4",
             "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
             "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "iojs": ">=1.0.0",
                 "node": ">=0.10.0"
             }
         },
-        "node_modules/rimraf": {
+        "node_modules/robust-predicates": {
             "version": "3.0.2",
-            "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
-            "integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
+            "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.2.tgz",
+            "integrity": "sha512-IXgzBWvWQwE6PrDI05OvmXUIruQTcoMDzRsOd5CDvHCVLcLHMTSYvOK5Cm46kWqlV3yAbuSpBZdJ5oP5OUoStg==",
+            "license": "Unlicense"
+        },
+        "node_modules/run-applescript": {
+            "version": "7.0.0",
+            "resolved": "https://registry.npmjs.org/run-applescript/-/run-applescript-7.0.0.tgz",
+            "integrity": "sha512-9by4Ij99JUr/MCFBUkDKLWK3G9HVXmabKz9U5MlIAIuvuzkiOicRYs8XJLxX+xahD+mLiiCYDqF9dKAgtzKP1A==",
             "dev": true,
-            "dependencies": {
-                "glob": "^7.1.3"
-            },
-            "bin": {
-                "rimraf": "bin.js"
+            "license": "MIT",
+            "engines": {
+                "node": ">=18"
             },
             "funding": {
-                "url": "https://github.com/sponsors/isaacs"
+                "url": "https://github.com/sponsors/sindresorhus"
             }
         },
-        "node_modules/robust-predicates": {
-            "version": "3.0.1",
-            "resolved": "https://registry.npmjs.org/robust-predicates/-/robust-predicates-3.0.1.tgz",
-            "integrity": "sha512-ndEIpszUHiG4HtDsQLeIuMvRsDnn8c8rYStabochtUeCvfuvNptb5TUbVD68LRAILPX7p9nqQGh4xJgn3EHS/g=="
-        },
         "node_modules/run-parallel": {
             "version": "1.2.0",
             "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
@@ -4654,6 +5100,7 @@
                     "url": "https://feross.org/support"
                 }
             ],
+            "license": "MIT",
             "dependencies": {
                 "queue-microtask": "^1.2.2"
             }
@@ -4661,32 +5108,48 @@
         "node_modules/rw": {
             "version": "1.3.3",
             "resolved": "https://registry.npmjs.org/rw/-/rw-1.3.3.tgz",
-            "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ=="
+            "integrity": "sha512-PdhdWy89SiZogBLaw42zdeqtRJ//zFd2PgQavcICDUgJT5oW10QCRKbJ6bg4r0/UY2M6BWd5tkxuGFRvCkgfHQ==",
+            "license": "BSD-3-Clause"
         },
         "node_modules/safe-buffer": {
-            "version": "5.1.2",
-            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
-            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
-            "dev": true
+            "version": "5.2.1",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
+            "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "license": "MIT"
         },
         "node_modules/safer-buffer": {
             "version": "2.1.2",
             "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
-            "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+            "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+            "license": "MIT"
         },
         "node_modules/sax": {
-            "version": "1.2.4",
-            "resolved": "https://registry.npmjs.org/sax/-/sax-1.2.4.tgz",
-            "integrity": "sha512-NqVDv9TpANUjFm0N8uM5GxL36UgKi9/atZw+x7YFnQ8ckwFGKrl4xX4yWtrey3UJm5nP1kUbnYgLopqWNSRhWw==",
-            "dev": true
+            "version": "1.4.1",
+            "resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
+            "integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
+            "dev": true,
+            "license": "ISC"
         },
         "node_modules/semver": {
-            "version": "7.5.4",
-            "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
-            "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
-            "dependencies": {
-                "lru-cache": "^6.0.0"
-            },
+            "version": "7.7.1",
+            "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
+            "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
+            "license": "ISC",
             "bin": {
                 "semver": "bin/semver.js"
             },
@@ -4694,35 +5157,19 @@
                 "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",
             "integrity": "sha512-MATJdZp8sLqDl/68LfQmbP8zKPLQNV6BIZoIgrscFDQ+RsvK/BxeDQOgyxKKoh0y/8h3BqVFnCqQ/gd+reiIXA==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/shebang-command": {
             "version": "2.0.0",
             "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
             "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "shebang-regex": "^3.0.0"
             },
@@ -4735,21 +5182,79 @@
             "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
             "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">=8"
             }
         },
         "node_modules/side-channel": {
-            "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==",
+            "version": "1.1.0",
+            "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+            "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "es-errors": "^1.3.0",
+                "object-inspect": "^1.13.3",
+                "side-channel-list": "^1.0.0",
+                "side-channel-map": "^1.0.1",
+                "side-channel-weakmap": "^1.0.2"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/side-channel-list": {
+            "version": "1.0.0",
+            "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+            "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
             "dev": true,
             "license": "MIT",
             "dependencies": {
-                "call-bind": "^1.0.7",
                 "es-errors": "^1.3.0",
-                "get-intrinsic": "^1.2.4",
-                "object-inspect": "^1.13.1"
+                "object-inspect": "^1.13.3"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/side-channel-map": {
+            "version": "1.0.1",
+            "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+            "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "call-bound": "^1.0.2",
+                "es-errors": "^1.3.0",
+                "get-intrinsic": "^1.2.5",
+                "object-inspect": "^1.13.3"
+            },
+            "engines": {
+                "node": ">= 0.4"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/ljharb"
+            }
+        },
+        "node_modules/side-channel-weakmap": {
+            "version": "1.0.2",
+            "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+            "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "call-bound": "^1.0.2",
+                "es-errors": "^1.3.0",
+                "get-intrinsic": "^1.2.5",
+                "object-inspect": "^1.13.3",
+                "side-channel-map": "^1.0.1"
             },
             "engines": {
                 "node": ">= 0.4"
@@ -4790,6 +5295,7 @@
                     "url": "https://feross.org/support"
                 }
             ],
+            "license": "MIT",
             "optional": true
         },
         "node_modules/simple-get": {
@@ -4811,6 +5317,7 @@
                     "url": "https://feross.org/support"
                 }
             ],
+            "license": "MIT",
             "optional": true,
             "dependencies": {
                 "decompress-response": "^6.0.0",
@@ -4818,13 +5325,20 @@
                 "simple-concat": "^1.0.0"
             }
         },
-        "node_modules/slash": {
-            "version": "3.0.0",
-            "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
-            "integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
+        "node_modules/stdin-discarder": {
+            "version": "0.1.0",
+            "resolved": "https://registry.npmjs.org/stdin-discarder/-/stdin-discarder-0.1.0.tgz",
+            "integrity": "sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==",
             "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "bl": "^5.0.0"
+            },
             "engines": {
-                "node": ">=8"
+                "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/stoppable": {
@@ -4843,21 +5357,34 @@
             "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz",
             "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "safe-buffer": "~5.1.0"
             }
         },
+        "node_modules/string_decoder/node_modules/safe-buffer": {
+            "version": "5.1.2",
+            "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
+            "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
+            "dev": true,
+            "license": "MIT"
+        },
         "node_modules/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==",
+            "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": {
-                "emoji-regex": "^8.0.0",
-                "is-fullwidth-code-point": "^3.0.0",
-                "strip-ansi": "^6.0.1"
+                "eastasianwidth": "^0.2.0",
+                "emoji-regex": "^9.2.2",
+                "strip-ansi": "^7.0.1"
             },
             "engines": {
-                "node": ">=8"
+                "node": ">=12"
+            },
+            "funding": {
+                "url": "https://github.com/sponsors/sindresorhus"
             }
         },
         "node_modules/string-width-cjs": {
@@ -4876,10 +5403,29 @@
                 "node": ">=8"
             }
         },
-        "node_modules/strip-ansi": {
+        "node_modules/string-width-cjs/node_modules/ansi-regex": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+            "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/string-width-cjs/node_modules/emoji-regex": {
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+            "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/string-width-cjs/node_modules/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"
             },
@@ -4887,6 +5433,22 @@
                 "node": ">=8"
             }
         },
+        "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/strip-ansi-cjs": {
             "name": "strip-ansi",
             "version": "6.0.1",
@@ -4901,11 +5463,22 @@
                 "node": ">=8"
             }
         },
+        "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+            "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+            "dev": true,
+            "license": "MIT",
+            "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",
             "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">=8"
             },
@@ -4914,22 +5487,24 @@
             }
         },
         "node_modules/supports-color": {
-            "version": "7.2.0",
-            "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
-            "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+            "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": "^4.0.0"
+                "has-flag": "^3.0.0"
             },
             "engines": {
-                "node": ">=8"
+                "node": ">=4"
             }
         },
         "node_modules/tar-fs": {
-            "version": "2.1.1",
-            "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz",
-            "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==",
+            "version": "2.1.2",
+            "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz",
+            "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==",
             "dev": true,
+            "license": "MIT",
             "optional": true,
             "dependencies": {
                 "chownr": "^1.1.1",
@@ -4943,6 +5518,7 @@
             "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz",
             "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==",
             "dev": true,
+            "license": "MIT",
             "optional": true,
             "dependencies": {
                 "bl": "^4.0.3",
@@ -4955,11 +5531,51 @@
                 "node": ">=6"
             }
         },
+        "node_modules/tar-stream/node_modules/bl": {
+            "version": "4.1.0",
+            "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz",
+            "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==",
+            "dev": true,
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "buffer": "^5.5.0",
+                "inherits": "^2.0.4",
+                "readable-stream": "^3.4.0"
+            }
+        },
+        "node_modules/tar-stream/node_modules/buffer": {
+            "version": "5.7.1",
+            "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz",
+            "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==",
+            "dev": true,
+            "funding": [
+                {
+                    "type": "github",
+                    "url": "https://github.com/sponsors/feross"
+                },
+                {
+                    "type": "patreon",
+                    "url": "https://www.patreon.com/feross"
+                },
+                {
+                    "type": "consulting",
+                    "url": "https://feross.org/support"
+                }
+            ],
+            "license": "MIT",
+            "optional": true,
+            "dependencies": {
+                "base64-js": "^1.3.1",
+                "ieee754": "^1.1.13"
+            }
+        },
         "node_modules/tar-stream/node_modules/readable-stream": {
-            "version": "3.6.0",
-            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.0.tgz",
-            "integrity": "sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==",
+            "version": "3.6.2",
+            "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz",
+            "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==",
             "dev": true,
+            "license": "MIT",
             "optional": true,
             "dependencies": {
                 "inherits": "^2.0.3",
@@ -4970,12 +5586,6 @@
                 "node": ">= 6"
             }
         },
-        "node_modules/text-table": {
-            "version": "0.2.0",
-            "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz",
-            "integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
-            "dev": true
-        },
         "node_modules/tmp": {
             "version": "0.2.3",
             "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.3.tgz",
@@ -4991,6 +5601,7 @@
             "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
             "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "is-number": "^7.0.0"
             },
@@ -4999,21 +5610,22 @@
             }
         },
         "node_modules/ts-api-utils": {
-            "version": "1.0.1",
-            "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz",
-            "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==",
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.0.1.tgz",
+            "integrity": "sha512-dnlgjFSVetynI8nzgJ+qF62efpglpWRk8isUEWZGWlJYySCTD6aKvbUDu+zbPeDakk3bg5H4XpitHukgfL1m9w==",
             "dev": true,
+            "license": "MIT",
             "engines": {
-                "node": ">=16.13.0"
+                "node": ">=18.12"
             },
             "peerDependencies": {
-                "typescript": ">=4.2.0"
+                "typescript": ">=4.8.4"
             }
         },
         "node_modules/tslib": {
-            "version": "2.8.0",
-            "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.0.tgz",
-            "integrity": "sha512-jWVzBLplnCmoaTr13V9dYbiQ99wvZRd0vNWaDRg+aVYRcjDF3nDksxFDE/+fkXnKhpnUUkmx5pK/v8mCtLVqZA==",
+            "version": "2.8.1",
+            "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+            "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
             "dev": true,
             "license": "0BSD"
         },
@@ -5032,6 +5644,7 @@
             "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
             "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==",
             "dev": true,
+            "license": "Apache-2.0",
             "optional": true,
             "dependencies": {
                 "safe-buffer": "^5.0.1"
@@ -5045,6 +5658,7 @@
             "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
             "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "prelude-ls": "^1.2.1"
             },
@@ -5052,18 +5666,6 @@
                 "node": ">= 0.8.0"
             }
         },
-        "node_modules/type-fest": {
-            "version": "0.20.2",
-            "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz",
-            "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==",
-            "dev": true,
-            "engines": {
-                "node": ">=10"
-            },
-            "funding": {
-                "url": "https://github.com/sponsors/sindresorhus"
-            }
-        },
         "node_modules/typed-rest-client": {
             "version": "1.8.11",
             "resolved": "https://registry.npmjs.org/typed-rest-client/-/typed-rest-client-1.8.11.tgz",
@@ -5077,9 +5679,9 @@
             }
         },
         "node_modules/typescript": {
-            "version": "5.6.3",
-            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.3.tgz",
-            "integrity": "sha512-hjcS1mhfuyi4WW8IWtjP7brDrG2cuDZukyrYrSauoXGNgx0S7zceP07adYkJycEr56BOUTNPzbInooiN3fn1qw==",
+            "version": "5.7.3",
+            "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.3.tgz",
+            "integrity": "sha512-84MVSjMEHP+FQRPy3pX9sTVV/INIex71s9TL2Gm5FG/WG1SqXeKyZ0k7/blY/4FdOzI12CBy1vGc4og/eus0fw==",
             "dev": true,
             "license": "Apache-2.0",
             "bin": {
@@ -5090,6 +5692,29 @@
                 "node": ">=14.17"
             }
         },
+        "node_modules/typescript-eslint": {
+            "version": "8.25.0",
+            "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.25.0.tgz",
+            "integrity": "sha512-TxRdQQLH4g7JkoFlYG3caW5v1S6kEkz8rqt80iQJZUYPq1zD1Ra7HfQBJJ88ABRaMvHAXnwRvRB4V+6sQ9xN5Q==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "@typescript-eslint/eslint-plugin": "8.25.0",
+                "@typescript-eslint/parser": "8.25.0",
+                "@typescript-eslint/utils": "8.25.0"
+            },
+            "engines": {
+                "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+            },
+            "funding": {
+                "type": "opencollective",
+                "url": "https://opencollective.com/typescript-eslint"
+            },
+            "peerDependencies": {
+                "eslint": "^8.57.0 || ^9.0.0",
+                "typescript": ">=4.8.4 <5.8.0"
+            }
+        },
         "node_modules/uc.micro": {
             "version": "2.1.0",
             "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
@@ -5104,11 +5729,29 @@
             "dev": true,
             "license": "MIT"
         },
+        "node_modules/undici": {
+            "version": "6.21.1",
+            "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.1.tgz",
+            "integrity": "sha512-q/1rj5D0/zayJB2FraXdaWxbhWiNKDvu8naDT2dl1yTlvJp4BLtOcp2a5BvgGNQpYYJzau7tf1WgKv3b+7mqpQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=18.17"
+            }
+        },
+        "node_modules/undici-types": {
+            "version": "6.20.0",
+            "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.20.0.tgz",
+            "integrity": "sha512-Ny6QZ2Nju20vw1SRHe3d9jVu6gJ+4e3+MMpqu7pqE5HT6WsTSlce++GQmK5UXS8mzV8DSYHrQH+Xrf2jVcuKNg==",
+            "dev": true,
+            "license": "MIT"
+        },
         "node_modules/uri-js": {
             "version": "4.4.1",
             "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
             "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
             "dev": true,
+            "license": "BSD-2-Clause",
             "dependencies": {
                 "punycode": "^2.1.0"
             }
@@ -5117,13 +5760,15 @@
             "version": "4.0.1",
             "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz",
             "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/util-deprecate": {
             "version": "1.0.2",
             "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
             "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==",
-            "dev": true
+            "dev": true,
+            "license": "MIT"
         },
         "node_modules/uuid": {
             "version": "8.3.2",
@@ -5139,6 +5784,7 @@
             "version": "8.2.0",
             "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-8.2.0.tgz",
             "integrity": "sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==",
+            "license": "MIT",
             "engines": {
                 "node": ">=14.0.0"
             }
@@ -5147,6 +5793,7 @@
             "version": "9.0.1",
             "resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-9.0.1.tgz",
             "integrity": "sha512-JZiimVdvimEuHh5olxhxkht09m3JzUGwggb5eRUkzzJhZ2KjCN0nh55VfiED9oez9DyF8/fz1g1iBV3h+0Z2EA==",
+            "license": "MIT",
             "dependencies": {
                 "minimatch": "^5.1.0",
                 "semver": "^7.3.7",
@@ -5156,18 +5803,11 @@
                 "vscode": "^1.82.0"
             }
         },
-        "node_modules/vscode-languageclient/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==",
-            "dependencies": {
-                "balanced-match": "^1.0.0"
-            }
-        },
         "node_modules/vscode-languageclient/node_modules/minimatch": {
             "version": "5.1.6",
             "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz",
             "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==",
+            "license": "ISC",
             "dependencies": {
                 "brace-expansion": "^2.0.1"
             },
@@ -5179,6 +5819,7 @@
             "version": "3.17.5",
             "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.17.5.tgz",
             "integrity": "sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==",
+            "license": "MIT",
             "dependencies": {
                 "vscode-jsonrpc": "8.2.0",
                 "vscode-languageserver-types": "3.17.5"
@@ -5187,13 +5828,38 @@
         "node_modules/vscode-languageserver-types": {
             "version": "3.17.5",
             "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.17.5.tgz",
-            "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg=="
+            "integrity": "sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==",
+            "license": "MIT"
+        },
+        "node_modules/whatwg-encoding": {
+            "version": "3.1.1",
+            "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+            "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "iconv-lite": "0.6.3"
+            },
+            "engines": {
+                "node": ">=18"
+            }
+        },
+        "node_modules/whatwg-mimetype": {
+            "version": "4.0.0",
+            "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+            "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=18"
+            }
         },
         "node_modules/which": {
             "version": "2.0.2",
             "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
             "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
             "dev": true,
+            "license": "ISC",
             "dependencies": {
                 "isexe": "^2.0.0"
             },
@@ -5204,17 +5870,29 @@
                 "node": ">= 8"
             }
         },
+        "node_modules/word-wrap": {
+            "version": "1.2.5",
+            "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+            "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=0.10.0"
+            }
+        },
         "node_modules/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==",
+            "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": "^4.0.0",
-                "string-width": "^4.1.0",
-                "strip-ansi": "^6.0.0"
+                "ansi-styles": "^6.1.0",
+                "string-width": "^5.0.1",
+                "strip-ansi": "^7.0.1"
             },
             "engines": {
-                "node": ">=10"
+                "node": ">=12"
             },
             "funding": {
                 "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
@@ -5239,11 +5917,107 @@
                 "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
             }
         },
+        "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+            "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+            "dev": true,
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
+            "version": "4.3.0",
+            "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+            "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "color-convert": "^2.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            },
+            "funding": {
+                "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+            }
+        },
+        "node_modules/wrap-ansi-cjs/node_modules/color-convert": {
+            "version": "2.0.1",
+            "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+            "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+            "dev": true,
+            "license": "MIT",
+            "dependencies": {
+                "color-name": "~1.1.4"
+            },
+            "engines": {
+                "node": ">=7.0.0"
+            }
+        },
+        "node_modules/wrap-ansi-cjs/node_modules/color-name": {
+            "version": "1.1.4",
+            "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+            "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": {
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+            "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+            "dev": true,
+            "license": "MIT"
+        },
+        "node_modules/wrap-ansi-cjs/node_modules/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/wrap-ansi-cjs/node_modules/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/wrap-ansi/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/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
+            "dev": true,
+            "license": "ISC",
+            "optional": true
         },
         "node_modules/xml2js": {
             "version": "0.5.0",
@@ -5264,6 +6038,7 @@
             "resolved": "https://registry.npmjs.org/xmlbuilder/-/xmlbuilder-11.0.1.tgz",
             "integrity": "sha512-fDlsI/kFEx7gLvbecc0/ohLG50fugQp8ryHzMTuW9vSa1GJ0XYWKnhsUx7oie3G98+r56aTQIUB4kht42R3JvA==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">=4.0"
             }
@@ -5272,6 +6047,7 @@
             "version": "5.0.8",
             "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
             "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+            "license": "ISC",
             "engines": {
                 "node": ">=10"
             }
@@ -5279,12 +6055,15 @@
         "node_modules/yallist": {
             "version": "4.0.0",
             "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
-            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
+            "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
+            "dev": true,
+            "license": "ISC"
         },
         "node_modules/yargs": {
             "version": "17.7.2",
             "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
             "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+            "license": "MIT",
             "dependencies": {
                 "cliui": "^8.0.1",
                 "escalade": "^3.1.1",
@@ -5302,15 +6081,58 @@
             "version": "21.1.1",
             "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
             "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+            "license": "ISC",
             "engines": {
                 "node": ">=12"
             }
         },
+        "node_modules/yargs/node_modules/ansi-regex": {
+            "version": "5.0.1",
+            "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+            "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+            "license": "MIT",
+            "engines": {
+                "node": ">=8"
+            }
+        },
+        "node_modules/yargs/node_modules/emoji-regex": {
+            "version": "8.0.0",
+            "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+            "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+            "license": "MIT"
+        },
+        "node_modules/yargs/node_modules/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==",
+            "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/yargs/node_modules/strip-ansi": {
+            "version": "6.0.1",
+            "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+            "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+            "license": "MIT",
+            "dependencies": {
+                "ansi-regex": "^5.0.1"
+            },
+            "engines": {
+                "node": ">=8"
+            }
+        },
         "node_modules/yauzl": {
             "version": "2.10.0",
             "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
             "integrity": "sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "buffer-crc32": "~0.2.3",
                 "fd-slicer": "~1.1.0"
@@ -5321,6 +6143,7 @@
             "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz",
             "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==",
             "dev": true,
+            "license": "MIT",
             "dependencies": {
                 "buffer-crc32": "~0.2.3"
             }
@@ -5330,6 +6153,7 @@
             "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
             "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
             "dev": true,
+            "license": "MIT",
             "engines": {
                 "node": ">=10"
             },
diff --git a/src/tools/rust-analyzer/editors/code/package.json b/src/tools/rust-analyzer/editors/code/package.json
index 3f09033051b..587ae92520b 100644
--- a/src/tools/rust-analyzer/editors/code/package.json
+++ b/src/tools/rust-analyzer/editors/code/package.json
@@ -7,6 +7,7 @@
     "version": "0.5.0-dev",
     "releaseTag": null,
     "publisher": "rust-lang",
+    "type": "commonjs",
     "repository": {
         "url": "https://github.com/rust-lang/rust-analyzer.git",
         "type": "git"
@@ -27,45 +28,51 @@
         }
     },
     "engines": {
-        "vscode": "^1.83.0"
+        "vscode": "^1.93.0"
     },
     "enabledApiProposals": [],
     "scripts": {
         "vscode:prepublish": "npm run build-base -- --minify",
         "package": "vsce package -o rust-analyzer.vsix",
-        "build-base": "esbuild ./src/main.ts --bundle --outfile=out/main.js --external:vscode --format=cjs --platform=node --target=node16",
+        "build-base": "esbuild ./src/main.ts --bundle --outfile=out/main.js --external:vscode --format=cjs --platform=node --target=node20",
         "build": "npm run build-base -- --sourcemap",
         "watch": "npm run build-base -- --sourcemap --watch",
-        "format": "prettier --write .",
-        "format:check": "prettier --check .",
-        "lint": "eslint -c .eslintrc.js --ext ts ./src ./tests",
+        "format": "node --experimental-strip-types node_modules/prettier/bin/prettier.cjs . --write",
+        "format:check": "node --experimental-strip-types node_modules/prettier/bin/prettier.cjs . --check",
+        "lint": "eslint .",
         "lint:fix": "npm run lint -- --fix",
         "typecheck": "tsc",
         "pretest": "npm run typecheck && npm run build",
         "test": "node ./out/tests/runTests.js"
     },
     "dependencies": {
-        "@hpcc-js/wasm": "^2.13.0",
-        "anser": "^2.1.1",
-        "d3": "^7.8.5",
-        "d3-graphviz": "^5.0.2",
+        "@hpcc-js/wasm": "^2.22.4",
+        "anser": "^2.3.2",
+        "d3": "^7.9.0",
+        "d3-graphviz": "^5.6.0",
+        "jiti": "^2.4.2",
         "vscode-languageclient": "^9.0.1"
     },
     "devDependencies": {
-        "@tsconfig/strictest": "^2.0.1",
-        "@types/node": "~16.11.7",
-        "@types/vscode": "~1.83",
-        "@typescript-eslint/eslint-plugin": "^6.0.0",
-        "@typescript-eslint/parser": "^6.0.0",
-        "@vscode/test-electron": "^2.3.8",
-        "@vscode/vsce": "^3.0.0",
+        "@eslint/js": "^9.21.0",
+        "@stylistic/eslint-plugin": "^4.1.0",
+        "@stylistic/eslint-plugin-js": "^4.1.0",
+        "@tsconfig/strictest": "^2.0.5",
+        "@types/node": "~22.13.4",
+        "@types/vscode": "~1.93.0",
+        "@typescript-eslint/eslint-plugin": "^8.25.0",
+        "@typescript-eslint/parser": "^8.25.0",
+        "@vscode/test-electron": "^2.4.1",
+        "@vscode/vsce": "^3.2.2",
         "esbuild": "^0.25.0",
-        "eslint": "^8.44.0",
-        "eslint-config-prettier": "^8.8.0",
-        "ovsx": "^0.8.2",
-        "prettier": "^3.0.0",
-        "tslib": "^2.6.0",
-        "typescript": "^5.6.0"
+        "eslint": "^9.21.0",
+        "eslint-config-prettier": "^10.0.2",
+        "eslint-define-config": "^2.1.0",
+        "ovsx": "0.10.1",
+        "prettier": "^3.5.2",
+        "tslib": "^2.8.1",
+        "typescript": "^5.7.3",
+        "typescript-eslint": "^8.25.0"
     },
     "activationEvents": [
         "workspaceContains:Cargo.toml",
@@ -1644,6 +1651,16 @@
             {
                 "title": "hover",
                 "properties": {
+                    "rust-analyzer.hover.dropGlue.enable": {
+                        "markdownDescription": "Whether to show drop glue information on hover.",
+                        "default": true,
+                        "type": "boolean"
+                    }
+                }
+            },
+            {
+                "title": "hover",
+                "properties": {
                     "rust-analyzer.hover.links.enable": {
                         "markdownDescription": "Use markdown syntax for links on hover.",
                         "default": true,
diff --git a/src/tools/rust-analyzer/editors/code/prettier.config.mts b/src/tools/rust-analyzer/editors/code/prettier.config.mts
new file mode 100644
index 00000000000..45cb3874eea
--- /dev/null
+++ b/src/tools/rust-analyzer/editors/code/prettier.config.mts
@@ -0,0 +1,12 @@
+import { type Config } from "prettier";
+
+const config: Config = {
+    // use 4 because it's Rustfmt's default
+    // https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#%5C34%20%5C%20%5C(default%5C)%5C%3A
+    tabWidth: 4,
+    // use 100 because it's Rustfmt's default
+    // https://rust-lang.github.io/rustfmt/?version=v1.4.38&search=#max_width
+    printWidth: 100,
+};
+
+export default config;
diff --git a/src/tools/rust-analyzer/editors/code/src/bootstrap.ts b/src/tools/rust-analyzer/editors/code/src/bootstrap.ts
index 8fc9f09324a..bccae73c9a7 100644
--- a/src/tools/rust-analyzer/editors/code/src/bootstrap.ts
+++ b/src/tools/rust-analyzer/editors/code/src/bootstrap.ts
@@ -177,9 +177,9 @@ async function hasToolchainFileWithRaDeclared(uri: vscode.Uri): Promise<boolean>
             await vscode.workspace.fs.readFile(uri),
         );
         return (
-            toolchainFileContents.match(/components\s*=\s*\[.*\"rust-analyzer\".*\]/g)?.length === 1
+            toolchainFileContents.match(/components\s*=\s*\[.*"rust-analyzer".*\]/g)?.length === 1
         );
-    } catch (e) {
+    } catch (_) {
         return false;
     }
 }
diff --git a/src/tools/rust-analyzer/editors/code/src/client.ts b/src/tools/rust-analyzer/editors/code/src/client.ts
index eac7b849fdb..cdeea7333a6 100644
--- a/src/tools/rust-analyzer/editors/code/src/client.ts
+++ b/src/tools/rust-analyzer/editors/code/src/client.ts
@@ -18,282 +18,263 @@ export async function createClient(
     config: Config,
     unlinkedFiles: vscode.Uri[],
 ): Promise<lc.LanguageClient> {
-    const clientOptions: lc.LanguageClientOptions = {
-        documentSelector: [{ scheme: "file", language: "rust" }],
-        initializationOptions,
-        diagnosticCollectionName: "rustc",
-        traceOutputChannel,
-        outputChannel,
-        middleware: {
-            workspace: {
-                // HACK: This is a workaround, when the client has been disposed, VSCode
-                // continues to emit events to the client and the default one for this event
-                // attempt to restart the client for no reason
-                async didChangeWatchedFile(event, next) {
-                    if (client.isRunning()) {
-                        await next(event);
-                    }
-                },
-                async configuration(
-                    params: lc.ConfigurationParams,
-                    token: vscode.CancellationToken,
-                    next: lc.ConfigurationRequest.HandlerSignature,
-                ) {
-                    const resp = await next(params, token);
-                    if (resp && Array.isArray(resp)) {
-                        return resp.map((val) => {
-                            return prepareVSCodeConfig(val);
-                        });
-                    } else {
-                        return resp;
-                    }
-                },
+    const raMiddleware: lc.Middleware = {
+        workspace: {
+            // HACK: This is a workaround, when the client has been disposed, VSCode
+            // continues to emit events to the client and the default one for this event
+            // attempt to restart the client for no reason
+            async didChangeWatchedFile(event, next) {
+                if (client.isRunning()) {
+                    await next(event);
+                }
             },
-            async handleDiagnostics(
-                uri: vscode.Uri,
-                diagnosticList: vscode.Diagnostic[],
-                next: lc.HandleDiagnosticsSignature,
+            async configuration(
+                params: lc.ConfigurationParams,
+                token: vscode.CancellationToken,
+                next: lc.ConfigurationRequest.HandlerSignature,
             ) {
-                const preview = config.previewRustcOutput;
-                const errorCode = config.useRustcErrorCode;
-                diagnosticList.forEach((diag, idx) => {
-                    const value =
-                        typeof diag.code === "string" || typeof diag.code === "number"
-                            ? diag.code
-                            : diag.code?.value;
-                    if (
-                        // FIXME: We currently emit this diagnostic way too early, before we have
-                        // loaded the project fully
-                        // value === "unlinked-file" &&
-                        value === "temporary-disabled" &&
-                        !unlinkedFiles.includes(uri) &&
-                        (diag.message === "file not included in crate hierarchy" ||
-                            diag.message.startsWith("This file is not included in any crates"))
-                    ) {
-                        const config = vscode.workspace.getConfiguration("rust-analyzer");
-                        if (config.get("showUnlinkedFileNotification")) {
-                            unlinkedFiles.push(uri);
-                            const folder = vscode.workspace.getWorkspaceFolder(uri)?.uri.fsPath;
-                            if (folder) {
-                                const parentBackslash = uri.fsPath.lastIndexOf(
-                                    pathSeparator + "src",
-                                );
-                                const parent = uri.fsPath.substring(0, parentBackslash);
+                const resp = await next(params, token);
+                if (resp && Array.isArray(resp)) {
+                    return resp.map((val) => {
+                        return prepareVSCodeConfig(val);
+                    });
+                } else {
+                    return resp;
+                }
+            },
+        },
+        async handleDiagnostics(
+            uri: vscode.Uri,
+            diagnosticList: vscode.Diagnostic[],
+            next: lc.HandleDiagnosticsSignature,
+        ) {
+            const preview = config.previewRustcOutput;
+            const errorCode = config.useRustcErrorCode;
+            diagnosticList.forEach((diag, idx) => {
+                const value =
+                    typeof diag.code === "string" || typeof diag.code === "number"
+                        ? diag.code
+                        : diag.code?.value;
+                if (
+                    // FIXME: We currently emit this diagnostic way too early, before we have
+                    // loaded the project fully
+                    // value === "unlinked-file" &&
+                    value === "temporary-disabled" &&
+                    !unlinkedFiles.includes(uri) &&
+                    (diag.message === "file not included in crate hierarchy" ||
+                        diag.message.startsWith("This file is not included in any crates"))
+                ) {
+                    const config = vscode.workspace.getConfiguration("rust-analyzer");
+                    if (config.get("showUnlinkedFileNotification")) {
+                        unlinkedFiles.push(uri);
+                        const folder = vscode.workspace.getWorkspaceFolder(uri)?.uri.fsPath;
+                        if (folder) {
+                            const parentBackslash = uri.fsPath.lastIndexOf(pathSeparator + "src");
+                            const parent = uri.fsPath.substring(0, parentBackslash);
 
-                                if (parent.startsWith(folder)) {
-                                    const path = vscode.Uri.file(
-                                        parent + pathSeparator + "Cargo.toml",
+                            if (parent.startsWith(folder)) {
+                                const path = vscode.Uri.file(parent + pathSeparator + "Cargo.toml");
+                                void vscode.workspace.fs.stat(path).then(async () => {
+                                    const choice = await vscode.window.showInformationMessage(
+                                        `This rust file does not belong to a loaded cargo project. It looks like it might belong to the workspace at ${path.path}, do you want to add it to the linked Projects?`,
+                                        "Yes",
+                                        "No",
+                                        "Don't show this again",
                                     );
-                                    void vscode.workspace.fs.stat(path).then(async () => {
-                                        const choice = await vscode.window.showInformationMessage(
-                                            `This rust file does not belong to a loaded cargo project. It looks like it might belong to the workspace at ${path.path}, do you want to add it to the linked Projects?`,
-                                            "Yes",
-                                            "No",
-                                            "Don't show this again",
-                                        );
-                                        switch (choice) {
-                                            case undefined:
-                                                break;
-                                            case "No":
-                                                break;
-                                            case "Yes":
-                                                const pathToInsert =
-                                                    "." +
-                                                    parent.substring(folder.length) +
-                                                    pathSeparator +
-                                                    "Cargo.toml";
-                                                await config.update(
-                                                    "linkedProjects",
-                                                    config
-                                                        .get<any[]>("linkedProjects")
-                                                        ?.concat(pathToInsert),
-                                                    false,
-                                                );
-                                                break;
-                                            case "Don't show this again":
-                                                await config.update(
-                                                    "showUnlinkedFileNotification",
-                                                    false,
-                                                    false,
-                                                );
-                                                break;
+                                    switch (choice) {
+                                        case undefined:
+                                            break;
+                                        case "No":
+                                            break;
+                                        case "Yes": {
+                                            const pathToInsert =
+                                                "." +
+                                                parent.substring(folder.length) +
+                                                pathSeparator +
+                                                "Cargo.toml";
+                                            const value = config
+                                                // eslint-disable-next-line @typescript-eslint/no-explicit-any
+                                                .get<any[]>("linkedProjects")
+                                                ?.concat(pathToInsert);
+                                            await config.update("linkedProjects", value, false);
+                                            break;
                                         }
-                                    });
-                                }
+                                        case "Don't show this again":
+                                            await config.update(
+                                                "showUnlinkedFileNotification",
+                                                false,
+                                                false,
+                                            );
+                                            break;
+                                    }
+                                });
                             }
                         }
                     }
+                }
 
-                    // Abuse the fact that VSCode leaks the LSP diagnostics data field through the
-                    // Diagnostic class, if they ever break this we are out of luck and have to go
-                    // back to the worst diagnostics experience ever:)
+                // Abuse the fact that VSCode leaks the LSP diagnostics data field through the
+                // Diagnostic class, if they ever break this we are out of luck and have to go
+                // back to the worst diagnostics experience ever:)
 
-                    // We encode the rendered output of a rustc diagnostic in the rendered field of
-                    // the data payload of the lsp diagnostic. If that field exists, overwrite the
-                    // diagnostic code such that clicking it opens the diagnostic in a readonly
-                    // text editor for easy inspection
-                    const rendered = (diag as unknown as { data?: { rendered?: string } }).data
-                        ?.rendered;
-                    if (rendered) {
-                        if (preview) {
-                            const decolorized = anser.ansiToText(rendered);
-                            const index =
-                                decolorized.match(/^(note|help):/m)?.index || rendered.length;
-                            diag.message = decolorized
-                                .substring(0, index)
-                                .replace(/^ -->[^\n]+\n/m, "");
-                        }
-                        diag.code = {
-                            target: vscode.Uri.from({
-                                scheme: diagnostics.URI_SCHEME,
-                                path: `/diagnostic message [${idx.toString()}]`,
-                                fragment: uri.toString(),
-                                query: idx.toString(),
-                            }),
-                            value:
-                                errorCode && value ? value : "Click for full compiler diagnostic",
-                        };
+                // We encode the rendered output of a rustc diagnostic in the rendered field of
+                // the data payload of the lsp diagnostic. If that field exists, overwrite the
+                // diagnostic code such that clicking it opens the diagnostic in a readonly
+                // text editor for easy inspection
+                const rendered = (diag as unknown as { data?: { rendered?: string } }).data
+                    ?.rendered;
+                if (rendered) {
+                    if (preview) {
+                        const decolorized = anser.ansiToText(rendered);
+                        const index = decolorized.match(/^(note|help):/m)?.index || rendered.length;
+                        diag.message = decolorized
+                            .substring(0, index)
+                            .replace(/^ -->[^\n]+\n/m, "");
                     }
-                });
-                return next(uri, diagnosticList);
-            },
-            async provideHover(
-                document: vscode.TextDocument,
-                position: vscode.Position,
-                token: vscode.CancellationToken,
-                _next: lc.ProvideHoverSignature,
-            ) {
-                const editor = vscode.window.activeTextEditor;
-                const positionOrRange = editor?.selection?.contains(position)
-                    ? client.code2ProtocolConverter.asRange(editor.selection)
-                    : client.code2ProtocolConverter.asPosition(position);
-                return client
-                    .sendRequest(
-                        ra.hover,
-                        {
-                            textDocument:
-                                client.code2ProtocolConverter.asTextDocumentIdentifier(document),
-                            position: positionOrRange,
-                        },
-                        token,
-                    )
-                    .then(
-                        (result) => {
-                            if (!result) return null;
-                            const hover = client.protocol2CodeConverter.asHover(result);
-                            if (!!result.actions) {
-                                hover.contents.push(renderHoverActions(result.actions));
-                            }
-                            return hover;
-                        },
-                        (error) => {
-                            client.handleFailedRequest(lc.HoverRequest.type, token, error, null);
-                            return Promise.resolve(null);
-                        },
+                    diag.code = {
+                        target: vscode.Uri.from({
+                            scheme: diagnostics.URI_SCHEME,
+                            path: `/diagnostic message [${idx.toString()}]`,
+                            fragment: uri.toString(),
+                            query: idx.toString(),
+                        }),
+                        value: errorCode && value ? value : "Click for full compiler diagnostic",
+                    };
+                }
+            });
+            return next(uri, diagnosticList);
+        },
+        async provideHover(
+            document: vscode.TextDocument,
+            position: vscode.Position,
+            token: vscode.CancellationToken,
+            _next: lc.ProvideHoverSignature,
+        ) {
+            const editor = vscode.window.activeTextEditor;
+            const positionOrRange = editor?.selection?.contains(position)
+                ? client.code2ProtocolConverter.asRange(editor.selection)
+                : client.code2ProtocolConverter.asPosition(position);
+            const params = {
+                textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
+                position: positionOrRange,
+            };
+            return client.sendRequest(ra.hover, params, token).then(
+                (result) => {
+                    if (!result) return null;
+                    const hover = client.protocol2CodeConverter.asHover(result);
+                    if (result.actions) {
+                        hover.contents.push(renderHoverActions(result.actions));
+                    }
+                    return hover;
+                },
+                (error) => {
+                    client.handleFailedRequest(lc.HoverRequest.type, token, error, null);
+                    return Promise.resolve(null);
+                },
+            );
+        },
+        // Using custom handling of CodeActions to support action groups and snippet edits.
+        // Note that this means we have to re-implement lazy edit resolving ourselves as well.
+        async provideCodeActions(
+            document: vscode.TextDocument,
+            range: vscode.Range,
+            context: vscode.CodeActionContext,
+            token: vscode.CancellationToken,
+            _next: lc.ProvideCodeActionsSignature,
+        ) {
+            const params: lc.CodeActionParams = {
+                textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
+                range: client.code2ProtocolConverter.asRange(range),
+                context: await client.code2ProtocolConverter.asCodeActionContext(context, token),
+            };
+            const callback = async (
+                values: (lc.Command | lc.CodeAction)[] | null,
+            ): Promise<(vscode.Command | vscode.CodeAction)[] | undefined> => {
+                if (values === null) return undefined;
+                const result: (vscode.CodeAction | vscode.Command)[] = [];
+                const groups = new Map<string, { index: number; items: vscode.CodeAction[] }>();
+                for (const item of values) {
+                    // In our case we expect to get code edits only from diagnostics
+                    if (lc.CodeAction.is(item)) {
+                        assert(!item.command, "We don't expect to receive commands in CodeActions");
+                        const action = await client.protocol2CodeConverter.asCodeAction(
+                            item,
+                            token,
+                        );
+                        result.push(action);
+                        continue;
+                    }
+                    assert(
+                        isCodeActionWithoutEditsAndCommands(item),
+                        "We don't expect edits or commands here",
                     );
-            },
-            // Using custom handling of CodeActions to support action groups and snippet edits.
-            // Note that this means we have to re-implement lazy edit resolving ourselves as well.
-            async provideCodeActions(
-                document: vscode.TextDocument,
-                range: vscode.Range,
-                context: vscode.CodeActionContext,
-                token: vscode.CancellationToken,
-                _next: lc.ProvideCodeActionsSignature,
-            ) {
-                const params: lc.CodeActionParams = {
-                    textDocument: client.code2ProtocolConverter.asTextDocumentIdentifier(document),
-                    range: client.code2ProtocolConverter.asRange(range),
-                    context: await client.code2ProtocolConverter.asCodeActionContext(
-                        context,
-                        token,
-                    ),
-                };
-                return client.sendRequest(lc.CodeActionRequest.type, params, token).then(
-                    async (values) => {
-                        if (values === null) return undefined;
-                        const result: (vscode.CodeAction | vscode.Command)[] = [];
-                        const groups = new Map<
-                            string,
-                            { index: number; items: vscode.CodeAction[] }
-                        >();
-                        for (const item of values) {
-                            // In our case we expect to get code edits only from diagnostics
-                            if (lc.CodeAction.is(item)) {
-                                assert(
-                                    !item.command,
-                                    "We don't expect to receive commands in CodeActions",
-                                );
-                                const action = await client.protocol2CodeConverter.asCodeAction(
-                                    item,
-                                    token,
-                                );
-                                result.push(action);
-                                continue;
-                            }
-                            assert(
-                                isCodeActionWithoutEditsAndCommands(item),
-                                "We don't expect edits or commands here",
-                            );
-                            const kind = client.protocol2CodeConverter.asCodeActionKind(
-                                (item as any).kind,
-                            );
-                            const action = new vscode.CodeAction(item.title, kind);
-                            const group = (item as any).group;
-                            action.command = {
-                                command: "rust-analyzer.resolveCodeAction",
-                                title: item.title,
-                                arguments: [item],
-                            };
+                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+                    const kind = client.protocol2CodeConverter.asCodeActionKind((item as any).kind);
+                    const action = new vscode.CodeAction(item.title, kind);
+                    // eslint-disable-next-line @typescript-eslint/no-explicit-any
+                    const group = (item as any).group;
+                    action.command = {
+                        command: "rust-analyzer.resolveCodeAction",
+                        title: item.title,
+                        arguments: [item],
+                    };
 
-                            // Set a dummy edit, so that VS Code doesn't try to resolve this.
-                            action.edit = new WorkspaceEdit();
+                    // Set a dummy edit, so that VS Code doesn't try to resolve this.
+                    action.edit = new WorkspaceEdit();
 
-                            if (group) {
-                                let entry = groups.get(group);
-                                if (!entry) {
-                                    entry = { index: result.length, items: [] };
-                                    groups.set(group, entry);
-                                    result.push(action);
-                                }
-                                entry.items.push(action);
-                            } else {
-                                result.push(action);
-                            }
+                    if (group) {
+                        let entry = groups.get(group);
+                        if (!entry) {
+                            entry = { index: result.length, items: [] };
+                            groups.set(group, entry);
+                            result.push(action);
                         }
-                        for (const [group, { index, items }] of groups) {
-                            if (items.length === 1) {
-                                const item = unwrapUndefinable(items[0]);
-                                result[index] = item;
-                            } else {
-                                const action = new vscode.CodeAction(group);
-                                const item = unwrapUndefinable(items[0]);
-                                action.kind = item.kind;
-                                action.command = {
-                                    command: "rust-analyzer.applyActionGroup",
-                                    title: "",
-                                    arguments: [
-                                        items.map((item) => {
-                                            return {
-                                                label: item.title,
-                                                arguments: item.command!.arguments![0],
-                                            };
-                                        }),
-                                    ],
-                                };
+                        entry.items.push(action);
+                    } else {
+                        result.push(action);
+                    }
+                }
+                for (const [group, { index, items }] of groups) {
+                    if (items.length === 1) {
+                        const item = unwrapUndefinable(items[0]);
+                        result[index] = item;
+                    } else {
+                        const action = new vscode.CodeAction(group);
+                        const item = unwrapUndefinable(items[0]);
+                        action.kind = item.kind;
+                        action.command = {
+                            command: "rust-analyzer.applyActionGroup",
+                            title: "",
+                            arguments: [
+                                items.map((item) => {
+                                    return {
+                                        label: item.title,
+                                        arguments: item.command!.arguments![0],
+                                    };
+                                }),
+                            ],
+                        };
 
-                                // Set a dummy edit, so that VS Code doesn't try to resolve this.
-                                action.edit = new WorkspaceEdit();
+                        // Set a dummy edit, so that VS Code doesn't try to resolve this.
+                        action.edit = new WorkspaceEdit();
 
-                                result[index] = action;
-                            }
-                        }
-                        return result;
-                    },
-                    (_error) => undefined,
-                );
-            },
+                        result[index] = action;
+                    }
+                }
+                return result;
+            };
+            return client
+                .sendRequest(lc.CodeActionRequest.type, params, token)
+                .then(callback, (_error) => undefined);
         },
+    };
+    const clientOptions: lc.LanguageClientOptions = {
+        documentSelector: [{ scheme: "file", language: "rust" }],
+        initializationOptions,
+        diagnosticCollectionName: "rustc",
+        traceOutputChannel,
+        outputChannel,
+        middleware: raMiddleware,
         markdown: {
             supportHtml: true,
         },
@@ -319,9 +300,11 @@ class ExperimentalFeatures implements lc.StaticFeature {
     constructor(config: Config) {
         this.testExplorer = config.testExplorer || false;
     }
+
     getState(): lc.FeatureState {
         return { kind: "static" };
     }
+
     fillClientCapabilities(capabilities: lc.ClientCapabilities): void {
         capabilities.experimental = {
             snippetTextEdit: true,
@@ -345,11 +328,14 @@ class ExperimentalFeatures implements lc.StaticFeature {
             ...capabilities.experimental,
         };
     }
+
     initialize(
         _capabilities: lc.ServerCapabilities,
         _documentSelector: lc.DocumentSelector | undefined,
     ): void {}
+
     dispose(): void {}
+
     clear(): void {}
 }
 
@@ -357,6 +343,7 @@ class OverrideFeatures implements lc.StaticFeature {
     getState(): lc.FeatureState {
         return { kind: "static" };
     }
+
     fillClientCapabilities(capabilities: lc.ClientCapabilities): void {
         // Force disable `augmentsSyntaxTokens`, VSCode's textmate grammar is somewhat incomplete
         // making the experience generally worse
@@ -365,14 +352,18 @@ class OverrideFeatures implements lc.StaticFeature {
             caps.augmentsSyntaxTokens = false;
         }
     }
+
     initialize(
         _capabilities: lc.ServerCapabilities,
         _documentSelector: lc.DocumentSelector | undefined,
     ): void {}
+
     dispose(): void {}
+
     clear(): void {}
 }
 
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
 function isCodeActionWithoutEditsAndCommands(value: any): boolean {
     const candidate: lc.CodeAction = value;
     return (
diff --git a/src/tools/rust-analyzer/editors/code/src/commands.ts b/src/tools/rust-analyzer/editors/code/src/commands.ts
index eee623ecae9..4e614d32057 100644
--- a/src/tools/rust-analyzer/editors/code/src/commands.ts
+++ b/src/tools/rust-analyzer/editors/code/src/commands.ts
@@ -78,6 +78,7 @@ export function memoryUsage(ctx: CtxInit): Cmd {
         provideTextDocumentContent(_uri: vscode.Uri): vscode.ProviderResult<string> {
             if (!vscode.window.activeTextEditor) return "";
 
+            // eslint-disable-next-line @typescript-eslint/no-explicit-any
             return ctx.client.sendRequest(ra.memoryUsage).then((mem: any) => {
                 return "Per-query memory usage:\n" + mem + "\n(note: database has been cleared)";
             });
@@ -161,7 +162,7 @@ export function joinLines(ctx: CtxInit): Cmd {
         });
         const textEdits = await client.protocol2CodeConverter.asTextEdits(items);
         await editor.edit((builder) => {
-            textEdits.forEach((edit: any) => {
+            textEdits.forEach((edit: vscode.TextEdit) => {
                 builder.replace(edit.range, edit.newText);
             });
         });
@@ -209,6 +210,7 @@ export function onEnter(ctx: CtxInit): Cmd {
                 ),
                 position: client.code2ProtocolConverter.asPosition(editor.selection.active),
             })
+            // eslint-disable-next-line @typescript-eslint/no-explicit-any
             .catch((_error: any) => {
                 // client.handleFailedRequest(OnEnterRequest.type, error, null);
                 return null;
@@ -528,6 +530,7 @@ function viewFileUsingTextDocumentContentProvider(
                 void sleep(10).then(() => this.eventEmitter.fire(this.uri));
             }
         }
+
         private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) {
             if (editor && isRustEditor(editor) && shouldUpdate) {
                 this.eventEmitter.fire(this.uri);
@@ -620,6 +623,7 @@ export function viewFileText(ctx: CtxInit): Cmd {
                 void sleep(10).then(() => this.eventEmitter.fire(this.uri));
             }
         }
+
         private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) {
             if (editor && isRustEditor(editor)) {
                 this.eventEmitter.fire(this.uri);
@@ -683,6 +687,7 @@ export function viewItemTree(ctx: CtxInit): Cmd {
                 void sleep(10).then(() => this.eventEmitter.fire(this.uri));
             }
         }
+
         private onDidChangeActiveTextEditor(editor: vscode.TextEditor | undefined) {
             if (editor && isRustEditor(editor)) {
                 this.eventEmitter.fire(this.uri);
@@ -1001,9 +1006,8 @@ export function resolveCodeAction(ctx: CtxInit): Cmd {
             ...itemEdit,
             documentChanges: itemEdit.documentChanges?.filter((change) => "kind" in change),
         };
-        const fileSystemEdit = await client.protocol2CodeConverter.asWorkspaceEdit(
-            lcFileSystemEdit,
-        );
+        const fileSystemEdit =
+            await client.protocol2CodeConverter.asWorkspaceEdit(lcFileSystemEdit);
         await vscode.workspace.applyEdit(fileSystemEdit);
 
         // replace all text edits so that we can convert snippet text edits into `vscode.SnippetTextEdit`s
diff --git a/src/tools/rust-analyzer/editors/code/src/config.ts b/src/tools/rust-analyzer/editors/code/src/config.ts
index d1467a4e824..2ae32913452 100644
--- a/src/tools/rust-analyzer/editors/code/src/config.ts
+++ b/src/tools/rust-analyzer/editors/code/src/config.ts
@@ -13,12 +13,7 @@ export type RunnableEnvCfgItem = {
 };
 export type RunnableEnvCfg = Record<string, string> | RunnableEnvCfgItem[];
 
-type ShowStatusBar =
-    | "always"
-    | "never"
-    | {
-          documentSelector: vscode.DocumentSelector;
-      };
+type ShowStatusBar = "always" | "never" | { documentSelector: vscode.DocumentSelector };
 
 export class Config {
     readonly extensionId = "rust-lang.rust-analyzer";
@@ -145,13 +140,13 @@ export class Config {
                 {
                     // Parent doc single-line comment
                     // e.g. //!|
-                    beforeText: /^\s*\/{2}\!.*$/,
+                    beforeText: /^\s*\/{2}!.*$/,
                     action: { indentAction, appendText: "//! " },
                 },
                 {
                     // Begins an auto-closed multi-line comment (standard or parent doc)
                     // e.g. /** | */ or /*! | */
-                    beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/,
+                    beforeText: /^\s*\/\*(\*|!)(?!\/)([^*]|\*(?!\/))*$/,
                     afterText: /^\s*\*\/$/,
                     action: {
                         indentAction: vscode.IndentAction.IndentOutdent,
@@ -161,19 +156,19 @@ export class Config {
                 {
                     // Begins a multi-line comment (standard or parent doc)
                     // e.g. /** ...| or /*! ...|
-                    beforeText: /^\s*\/\*(\*|\!)(?!\/)([^\*]|\*(?!\/))*$/,
+                    beforeText: /^\s*\/\*(\*|!)(?!\/)([^*]|\*(?!\/))*$/,
                     action: { indentAction, appendText: " * " },
                 },
                 {
                     // Continues a multi-line comment
                     // e.g.  * ...|
-                    beforeText: /^(\ \ )*\ \*(\ ([^\*]|\*(?!\/))*)?$/,
+                    beforeText: /^( {2})* \*( ([^*]|\*(?!\/))*)?$/,
                     action: { indentAction, appendText: "* " },
                 },
                 {
                     // Dedents after closing a multi-line comment
                     // e.g.  */|
-                    beforeText: /^(\ \ )*\ \*\/\s*$/,
+                    beforeText: /^( {2})* \*\/\s*$/,
                     action: { indentAction, removeText: 1 },
                 },
             ];
@@ -227,9 +222,11 @@ export class Config {
             ),
         );
     }
+
     get checkOnSave() {
         return this.get<boolean>("checkOnSave") ?? false;
     }
+
     async toggleCheckOnSave() {
         const config = this.cfg.inspect<boolean>("checkOnSave") ?? { key: "checkOnSave" };
         let overrideInLanguage;
@@ -269,8 +266,10 @@ export class Config {
     }
 
     runnablesExtraEnv(label: string): Record<string, string> | undefined {
+        // eslint-disable-next-line @typescript-eslint/no-explicit-any
         const item = this.get<any>("runnables.extraEnv") ?? this.get<any>("runnableEnv");
         if (!item) return undefined;
+        // eslint-disable-next-line @typescript-eslint/no-explicit-any
         const fixRecord = (r: Record<string, any>) => {
             for (const key in r) {
                 if (typeof r[key] !== "string") {
@@ -339,6 +338,7 @@ export class Config {
             gotoTypeDef: this.get<boolean>("hover.actions.gotoTypeDef.enable"),
         };
     }
+
     get previewRustcOutput() {
         return this.get<boolean>("diagnostics.previewRustcOutput");
     }
@@ -370,6 +370,7 @@ export class Config {
     get askBeforeUpdateTest() {
         return this.get<boolean>("runnables.askBeforeUpdateTest");
     }
+
     async setAskBeforeUpdateTest(value: boolean) {
         await this.cfg.update("runnables.askBeforeUpdateTest", value, true);
     }
@@ -378,11 +379,13 @@ export class Config {
 export function prepareVSCodeConfig<T>(resp: T): T {
     if (Is.string(resp)) {
         return substituteVSCodeVariableInString(resp) as T;
+        // eslint-disable-next-line @typescript-eslint/no-explicit-any
     } else if (resp && Is.array<any>(resp)) {
         return resp.map((val) => {
             return prepareVSCodeConfig(val);
         }) as T;
     } else if (resp && typeof resp === "object") {
+        // eslint-disable-next-line @typescript-eslint/no-explicit-any
         const res: { [key: string]: any } = {};
         for (const key in resp) {
             const val = resp[key];
@@ -489,8 +492,7 @@ function computeVscodeVar(varName: string): string | null {
         // TODO: support for remote workspaces?
         const fsPath: string =
             folder === undefined
-                ? // no workspace opened
-                  ""
+                ? "" // no workspace opened
                 : // could use currently opened document to detect the correct
                   // workspace. However, that would be determined by the document
                   // user has opened on Editor startup. Could lead to
diff --git a/src/tools/rust-analyzer/editors/code/src/ctx.ts b/src/tools/rust-analyzer/editors/code/src/ctx.ts
index 4248305d5cc..ac73f2ae6bf 100644
--- a/src/tools/rust-analyzer/editors/code/src/ctx.ts
+++ b/src/tools/rust-analyzer/editors/code/src/ctx.ts
@@ -34,13 +34,8 @@ import type { RustAnalyzerExtensionApi } from "./main";
 
 export type Workspace =
     | { kind: "Empty" }
-    | {
-          kind: "Workspace Folder";
-      }
-    | {
-          kind: "Detached Files";
-          files: vscode.TextDocument[];
-      };
+    | { kind: "Workspace Folder" }
+    | { kind: "Detached Files"; files: vscode.TextDocument[] };
 
 export function fetchWorkspace(): Workspace {
     const folders = (vscode.workspace.workspaceFolders || []).filter(
@@ -53,10 +48,7 @@ export function fetchWorkspace(): Workspace {
     return folders.length === 0
         ? rustDocuments.length === 0
             ? { kind: "Empty" }
-            : {
-                  kind: "Detached Files",
-                  files: rustDocuments,
-              }
+            : { kind: "Detached Files", files: rustDocuments }
         : { kind: "Workspace Folder" };
 }
 
@@ -89,6 +81,7 @@ export class Ctx implements RustAnalyzerExtensionApi {
     private _dependencyTreeView:
         | vscode.TreeView<Dependency | DependencyFile | DependencyId>
         | undefined;
+
     private _syntaxTreeProvider: SyntaxTreeProvider | undefined;
     private _syntaxTreeView: vscode.TreeView<SyntaxElement> | undefined;
     private lastStatus: ServerStatusParams | { health: "stopped" } = { health: "stopped" };
@@ -267,7 +260,7 @@ export class Ctx implements RustAnalyzerExtensionApi {
             let message = "bootstrap error. ";
 
             message +=
-                'See the logs in "OUTPUT > Rust Analyzer Client" (should open automatically). ';
+                'See the logs in "OUTPUT > Rust Analyzer Client" (should open automatically).';
             message +=
                 'To enable verbose logs, click the gear icon in the "OUTPUT" tab and select "Debug".';
 
@@ -476,9 +469,11 @@ export class Ctx implements RustAnalyzerExtensionApi {
         this.lastStatus = status;
         this.updateStatusBarItem();
     }
+
     refreshServerStatus() {
         this.updateStatusBarItem();
     }
+
     private updateStatusBarItem() {
         let icon = "";
         const status = this.lastStatus;
@@ -533,19 +528,14 @@ export class Ctx implements RustAnalyzerExtensionApi {
 
         const toggleCheckOnSave = this.config.checkOnSave ? "Disable" : "Enable";
         statusBar.tooltip.appendMarkdown(
-            `[Extension Info](command:rust-analyzer.serverVersion "Show version and server binary info"): Version ${this.version}, Server Version ${this._serverVersion}` +
-                "\n\n---\n\n" +
-                '[$(terminal) Open Logs](command:rust-analyzer.openLogs "Open the server logs")' +
-                "\n\n" +
-                `[$(settings) ${toggleCheckOnSave} Check on Save](command:rust-analyzer.toggleCheckOnSave "Temporarily ${toggleCheckOnSave.toLowerCase()} check on save functionality")` +
-                "\n\n" +
-                '[$(refresh) Reload Workspace](command:rust-analyzer.reloadWorkspace "Reload and rediscover workspaces")' +
-                "\n\n" +
-                '[$(symbol-property) Rebuild Build Dependencies](command:rust-analyzer.rebuildProcMacros "Rebuild build scripts and proc-macros")' +
-                "\n\n" +
-                '[$(stop-circle) Stop server](command:rust-analyzer.stopServer "Stop the server")' +
-                "\n\n" +
-                '[$(debug-restart) Restart server](command:rust-analyzer.restartServer "Restart the server")',
+            `[Extension Info](command:rust-analyzer.serverVersion "Show version and server binary info"): Version ${this.version}, Server Version ${this._serverVersion}\n\n` +
+                `---\n\n` +
+                `[$(terminal) Open Logs](command:rust-analyzer.openLogs "Open the server logs")\n\n` +
+                `[$(settings) ${toggleCheckOnSave} Check on Save](command:rust-analyzer.toggleCheckOnSave "Temporarily ${toggleCheckOnSave.toLowerCase()} check on save functionality")\n\n` +
+                `[$(refresh) Reload Workspace](command:rust-analyzer.reloadWorkspace "Reload and rediscover workspaces")\n\n` +
+                `[$(symbol-property) Rebuild Build Dependencies](command:rust-analyzer.rebuildProcMacros "Rebuild build scripts and proc-macros")\n\n` +
+                `[$(stop-circle) Stop server](command:rust-analyzer.stopServer "Stop the server")\n\n` +
+                `[$(debug-restart) Restart server](command:rust-analyzer.restartServer "Restart the server")`,
         );
         if (!status.quiescent) icon = "$(loading~spin) ";
         statusBar.text = `${icon}rust-analyzer`;
@@ -580,4 +570,5 @@ export interface Disposable {
     dispose(): void;
 }
 
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
 export type Cmd = (...args: any[]) => unknown;
diff --git a/src/tools/rust-analyzer/editors/code/src/debug.ts b/src/tools/rust-analyzer/editors/code/src/debug.ts
index f21ca2e8f96..72a9aabc043 100644
--- a/src/tools/rust-analyzer/editors/code/src/debug.ts
+++ b/src/tools/rust-analyzer/editors/code/src/debug.ts
@@ -22,6 +22,7 @@ export async function makeDebugConfig(ctx: Ctx, runnable: ra.Runnable): Promise<
     if (!debugConfig) return;
 
     const wsLaunchSection = vscode.workspace.getConfiguration("launch", scope);
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     const configurations = wsLaunchSection.get<any[]>("configurations") || [];
 
     const index = configurations.findIndex((c) => c.name === debugConfig.name);
@@ -46,6 +47,7 @@ export async function startDebugSession(ctx: Ctx, runnable: ra.Runnable): Promis
     let message = "";
 
     const wsLaunchSection = vscode.workspace.getConfiguration("launch");
+    // eslint-disable-next-line @typescript-eslint/no-explicit-any
     const configurations = wsLaunchSection.get<any[]>("configurations") || [];
 
     // The runnable label is the name of the test with the "test prefix"
@@ -121,7 +123,7 @@ async function getDebugConfiguration(
         debugOutput.show(true);
     }
     // folder exists or RA is not active.
-    // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
+
     const workspaceFolders = vscode.workspace.workspaceFolders!;
     const isMultiFolderWorkspace = workspaceFolders.length > 1;
     const firstWorkspace = workspaceFolders[0];
@@ -189,8 +191,9 @@ async function getDebugConfiguration(
         sourceFileMap,
     );
     if (debugConfig.type in debugOptions.engineSettings) {
+        // eslint-disable-next-line @typescript-eslint/no-explicit-any
         const settingsMap = (debugOptions.engineSettings as any)[debugConfig.type];
-        for (var key in settingsMap) {
+        for (const key in settingsMap) {
             debugConfig[key] = settingsMap[key];
         }
     }
@@ -409,7 +412,7 @@ function quote(xs: string[]) {
                 return "'" + s.replace(/(['\\])/g, "\\$1") + "'";
             }
             if (/["'\s]/.test(s)) {
-                return '"' + s.replace(/(["\\$`!])/g, "\\$1") + '"';
+                return `"${s.replace(/(["\\$`!])/g, "\\$1")}"`;
             }
             return s.replace(/([A-Za-z]:)?([#!"$&'()*,:;<=>?@[\\\]^`{|}])/g, "$1\\$2");
         })
diff --git a/src/tools/rust-analyzer/editors/code/src/diagnostics.ts b/src/tools/rust-analyzer/editors/code/src/diagnostics.ts
index 9fb2993d12f..cd0e43b2120 100644
--- a/src/tools/rust-analyzer/editors/code/src/diagnostics.ts
+++ b/src/tools/rust-analyzer/editors/code/src/diagnostics.ts
@@ -104,10 +104,7 @@ export class AnsiDecorationProvider implements vscode.Disposable {
 
         for (const [lineNumber, line] of lines.entries()) {
             const totalEscapeLength = 0;
-
-            // eslint-disable-next-line camelcase
             const parsed = anser.ansiToJson(line, { use_classes: true });
-
             let offset = 0;
 
             for (const span of parsed) {
@@ -162,23 +159,23 @@ export class AnsiDecorationProvider implements vscode.Disposable {
     // NOTE: This could just be a kebab-case to camelCase conversion, but I think it's
     // a short enough list to just write these by hand
     static readonly _anserToThemeColor: Record<string, ThemeColor> = {
-        "ansi-black": "ansiBlack",
-        "ansi-white": "ansiWhite",
-        "ansi-red": "ansiRed",
-        "ansi-green": "ansiGreen",
-        "ansi-yellow": "ansiYellow",
-        "ansi-blue": "ansiBlue",
-        "ansi-magenta": "ansiMagenta",
-        "ansi-cyan": "ansiCyan",
-
-        "ansi-bright-black": "ansiBrightBlack",
-        "ansi-bright-white": "ansiBrightWhite",
-        "ansi-bright-red": "ansiBrightRed",
-        "ansi-bright-green": "ansiBrightGreen",
-        "ansi-bright-yellow": "ansiBrightYellow",
-        "ansi-bright-blue": "ansiBrightBlue",
-        "ansi-bright-magenta": "ansiBrightMagenta",
-        "ansi-bright-cyan": "ansiBrightCyan",
+        "ansi-black": new ThemeColor("terminal.ansiBlack"),
+        "ansi-white": new ThemeColor("terminal.ansiWhite"),
+        "ansi-red": new ThemeColor("terminal.ansiRed"),
+        "ansi-green": new ThemeColor("terminal.ansiGreen"),
+        "ansi-yellow": new ThemeColor("terminal.ansiYellow"),
+        "ansi-blue": new ThemeColor("terminal.ansiBlue"),
+        "ansi-magenta": new ThemeColor("terminal.ansiMagenta"),
+        "ansi-cyan": new ThemeColor("terminal.ansiCyan"),
+
+        "ansi-bright-black": new ThemeColor("terminal.ansiBrightBlack"),
+        "ansi-bright-white": new ThemeColor("terminal.ansiBrightWhite"),
+        "ansi-bright-red": new ThemeColor("terminal.ansiBrightRed"),
+        "ansi-bright-green": new ThemeColor("terminal.ansiBrightGreen"),
+        "ansi-bright-yellow": new ThemeColor("terminal.ansiBrightYellow"),
+        "ansi-bright-blue": new ThemeColor("terminal.ansiBrightBlue"),
+        "ansi-bright-magenta": new ThemeColor("terminal.ansiBrightMagenta"),
+        "ansi-bright-cyan": new ThemeColor("terminal.ansiBrightCyan"),
     };
 
     private static _convertColor(
@@ -210,11 +207,6 @@ export class AnsiDecorationProvider implements vscode.Disposable {
             }
         }
 
-        const themeColor = AnsiDecorationProvider._anserToThemeColor[color];
-        if (themeColor) {
-            return new ThemeColor("terminal." + themeColor);
-        }
-
-        return undefined;
+        return AnsiDecorationProvider._anserToThemeColor[color];
     }
 }
diff --git a/src/tools/rust-analyzer/editors/code/src/lang_client.ts b/src/tools/rust-analyzer/editors/code/src/lang_client.ts
index 09d64efc048..dc448f554c5 100644
--- a/src/tools/rust-analyzer/editors/code/src/lang_client.ts
+++ b/src/tools/rust-analyzer/editors/code/src/lang_client.ts
@@ -5,6 +5,8 @@ export class RaLanguageClient extends lc.LanguageClient {
     override handleFailedRequest<T>(
         type: lc.MessageSignature,
         token: vscode.CancellationToken | undefined,
+        // declared as `any` in vscode-languageclient
+        // eslint-disable-next-line @typescript-eslint/no-explicit-any
         error: any,
         defaultValue: T,
         showNotification?: boolean | undefined,
diff --git a/src/tools/rust-analyzer/editors/code/src/lsp_ext.ts b/src/tools/rust-analyzer/editors/code/src/lsp_ext.ts
index af86d9efd14..af5129ac963 100644
--- a/src/tools/rust-analyzer/editors/code/src/lsp_ext.ts
+++ b/src/tools/rust-analyzer/editors/code/src/lsp_ext.ts
@@ -1,3 +1,4 @@
+/* eslint-disable @typescript-eslint/no-empty-object-type */
 /**
  * This file mirrors `crates/rust-analyzer/src/lsp_ext.rs` declarations.
  */
diff --git a/src/tools/rust-analyzer/editors/code/src/main.ts b/src/tools/rust-analyzer/editors/code/src/main.ts
index c84b69b66cd..451294e26f6 100644
--- a/src/tools/rust-analyzer/editors/code/src/main.ts
+++ b/src/tools/rust-analyzer/editors/code/src/main.ts
@@ -214,6 +214,7 @@ function checkConflictingExtensions() {
                     "both plugins to not work correctly. You should disable one of them.",
                 "Got it",
             )
+            // eslint-disable-next-line no-console
             .then(() => {}, console.error);
     }
 }
diff --git a/src/tools/rust-analyzer/editors/code/src/persistent_state.ts b/src/tools/rust-analyzer/editors/code/src/persistent_state.ts
index cebd16a3c90..3f90cd3bb93 100644
--- a/src/tools/rust-analyzer/editors/code/src/persistent_state.ts
+++ b/src/tools/rust-analyzer/editors/code/src/persistent_state.ts
@@ -14,6 +14,7 @@ export class PersistentState {
     get serverVersion(): string | undefined {
         return this.globalState.get("serverVersion");
     }
+
     async updateServerVersion(value: string | undefined) {
         await this.globalState.update("serverVersion", value);
     }
diff --git a/src/tools/rust-analyzer/editors/code/src/snippets.ts b/src/tools/rust-analyzer/editors/code/src/snippets.ts
index a469a9cd1f4..e3f43a80670 100644
--- a/src/tools/rust-analyzer/editors/code/src/snippets.ts
+++ b/src/tools/rust-analyzer/editors/code/src/snippets.ts
@@ -24,9 +24,7 @@ export async function applySnippetWorkspaceEdit(
                 for (const indel of edits) {
                     assert(
                         !(indel instanceof vscode.SnippetTextEdit),
-                        `bad ws edit: snippet received with multiple edits: ${JSON.stringify(
-                            edit,
-                        )}`,
+                        `bad ws edit: snippet received with multiple edits: ${JSON.stringify(edit)}`,
                     );
                     builder.replace(indel.range, indel.newText);
                 }
diff --git a/src/tools/rust-analyzer/editors/code/src/syntax_tree_provider.ts b/src/tools/rust-analyzer/editors/code/src/syntax_tree_provider.ts
index 3f7e30f13a3..b86f8cbc707 100644
--- a/src/tools/rust-analyzer/editors/code/src/syntax_tree_provider.ts
+++ b/src/tools/rust-analyzer/editors/code/src/syntax_tree_provider.ts
@@ -7,8 +7,10 @@ import * as ra from "./lsp_ext";
 export class SyntaxTreeProvider implements vscode.TreeDataProvider<SyntaxElement> {
     private _onDidChangeTreeData: vscode.EventEmitter<SyntaxElement | undefined | void> =
         new vscode.EventEmitter<SyntaxElement | undefined | void>();
+
     readonly onDidChangeTreeData: vscode.Event<SyntaxElement | undefined | void> =
         this._onDidChangeTreeData.event;
+
     ctx: CtxInit;
     root: SyntaxNode | undefined;
     hideWhitespace: boolean = false;
diff --git a/src/tools/rust-analyzer/editors/code/src/test_explorer.ts b/src/tools/rust-analyzer/editors/code/src/test_explorer.ts
index de41d2a57ec..e45f8282942 100644
--- a/src/tools/rust-analyzer/editors/code/src/test_explorer.ts
+++ b/src/tools/rust-analyzer/editors/code/src/test_explorer.ts
@@ -133,7 +133,7 @@ export const prepareTestExplorer = (
         }
         if (scope) {
             const recursivelyRemove = (tests: vscode.TestItemCollection) => {
-                for (const [_, test] of tests) {
+                for (const [, test] of tests) {
                     if (!testSet.has(test.id)) {
                         deleteTest(test, tests);
                     } else {
diff --git a/src/tools/rust-analyzer/editors/code/src/toolchain.ts b/src/tools/rust-analyzer/editors/code/src/toolchain.ts
index e8bab9c3d84..bb061442953 100644
--- a/src/tools/rust-analyzer/editors/code/src/toolchain.ts
+++ b/src/tools/rust-analyzer/editors/code/src/toolchain.ts
@@ -18,6 +18,22 @@ export interface ArtifactSpec {
     filter?: (artifacts: CompilationArtifact[]) => CompilationArtifact[];
 }
 
+interface CompilerMessage {
+    reason: string;
+    executable?: string;
+    target: {
+        crate_types: [string, ...string[]];
+        kind: [string, ...string[]];
+        name: string;
+    };
+    profile: {
+        test: boolean;
+    };
+    message: {
+        rendered: string;
+    };
+}
+
 export class Cargo {
     constructor(
         readonly rootFolder: string,
@@ -109,7 +125,7 @@ export class Cargo {
 
     private async runCargo(
         cargoArgs: string[],
-        onStdoutJson: (obj: any) => void,
+        onStdoutJson: (obj: CompilerMessage) => void,
         onStderrString: (data: string) => void,
         env?: Record<string, string>,
     ): Promise<number> {
@@ -131,7 +147,7 @@ export class Cargo {
                 onStdoutJson(message);
             });
 
-            cargo.on("exit", (exitCode, _) => {
+            cargo.on("exit", (exitCode) => {
                 if (exitCode === 0) resolve(exitCode);
                 else reject(new Error(`exit code: ${exitCode}.`));
             });
diff --git a/src/tools/rust-analyzer/editors/code/src/util.ts b/src/tools/rust-analyzer/editors/code/src/util.ts
index d7ca6b3557d..2f7702baebb 100644
--- a/src/tools/rust-analyzer/editors/code/src/util.ts
+++ b/src/tools/rust-analyzer/editors/code/src/util.ts
@@ -104,6 +104,7 @@ export function isDocumentInWorkspace(document: RustDocument): boolean {
 }
 
 /** Sets ['when'](https://code.visualstudio.com/docs/getstarted/keybindings#_when-clause-contexts) clause contexts */
+// eslint-disable-next-line @typescript-eslint/no-explicit-any
 export function setContextValue(key: string, value: any): Thenable<void> {
     return vscode.commands.executeCommand("setContext", key, value);
 }
@@ -167,27 +168,35 @@ export class LazyOutputChannel implements vscode.OutputChannel {
     append(value: string): void {
         this.channel.append(value);
     }
+
     appendLine(value: string): void {
         this.channel.appendLine(value);
     }
+
     replace(value: string): void {
         this.channel.replace(value);
     }
+
     clear(): void {
         if (this._channel) {
             this._channel.clear();
         }
     }
-    show(preserveFocus?: boolean): void;
-    show(column?: vscode.ViewColumn, preserveFocus?: boolean): void;
-    show(column?: any, preserveFocus?: any): void {
-        this.channel.show(column, preserveFocus);
+
+    show(columnOrPreserveFocus?: vscode.ViewColumn | boolean, preserveFocus?: boolean): void {
+        if (typeof columnOrPreserveFocus === "boolean") {
+            this.channel.show(columnOrPreserveFocus);
+        } else {
+            this.channel.show(columnOrPreserveFocus, preserveFocus);
+        }
     }
+
     hide(): void {
         if (this._channel) {
             this._channel.hide();
         }
     }
+
     dispose(): void {
         if (this._channel) {
             this._channel.dispose();
@@ -276,6 +285,7 @@ export async function spawnAsync(
             stderr: res.stderr,
             status: res.status,
         };
+        // eslint-disable-next-line @typescript-eslint/no-explicit-any
     } catch (e: any) {
         return {
             stdout: e.stdout,
diff --git a/src/tools/rust-analyzer/editors/code/tests/unit/index.ts b/src/tools/rust-analyzer/editors/code/tests/unit/index.ts
index 8ad46546abd..bf74060c730 100644
--- a/src/tools/rust-analyzer/editors/code/tests/unit/index.ts
+++ b/src/tools/rust-analyzer/editors/code/tests/unit/index.ts
@@ -1,6 +1,7 @@
 import * as assert from "node:assert/strict";
 import { readdir } from "fs/promises";
 import * as path from "path";
+import { pathToFileURL } from "url";
 
 class Test {
     readonly name: string;
@@ -67,7 +68,7 @@ export async function run(): Promise<void> {
     );
     for (const testFile of testFiles) {
         try {
-            const testModule = require(path.resolve(__dirname, testFile));
+            const testModule = await import(pathToFileURL(path.resolve(__dirname, testFile)).href);
             await testModule.getTests(context);
         } catch (e) {
             error(`${e}`);
diff --git a/src/tools/rust-analyzer/editors/code/tests/unit/tasks.test.ts b/src/tools/rust-analyzer/editors/code/tests/unit/tasks.test.ts
index 9bccaaf3d47..9b5d98ee7e9 100644
--- a/src/tools/rust-analyzer/editors/code/tests/unit/tasks.test.ts
+++ b/src/tools/rust-analyzer/editors/code/tests/unit/tasks.test.ts
@@ -114,6 +114,7 @@ function f(task: vscode.Task): {
         execution,
     };
 }
+
 function executionToSimple(
     taskExecution: vscode.ProcessExecution | vscode.ShellExecution | vscode.CustomExecution,
 ): {
@@ -122,8 +123,8 @@ function executionToSimple(
     const exec = taskExecution as vscode.ProcessExecution | vscode.ShellExecution;
     if (exec instanceof vscode.ShellExecution) {
         return {
-            command: typeof exec.command === "string" ? exec.command : exec.command.value,
-            args: exec.args.map((arg) => {
+            command: typeof exec.command === "string" ? exec.command : (exec.command?.value ?? ""),
+            args: (exec.args ?? []).map((arg) => {
                 if (typeof arg === "string") {
                     return arg;
                 }
diff --git a/src/tools/rust-analyzer/editors/code/tsconfig.eslint.json b/src/tools/rust-analyzer/editors/code/tsconfig.eslint.json
index 5e2b33ca39f..eceffeef598 100644
--- a/src/tools/rust-analyzer/editors/code/tsconfig.eslint.json
+++ b/src/tools/rust-analyzer/editors/code/tsconfig.eslint.json
@@ -6,6 +6,6 @@
         "src",
         "tests",
         // these are the eslint-only inclusions
-        ".eslintrc.js"
+        "eslint.config.mts"
     ]
 }
diff --git a/src/tools/rust-analyzer/editors/code/tsconfig.json b/src/tools/rust-analyzer/editors/code/tsconfig.json
index 87cfd1b2ee1..a13afab1705 100644
--- a/src/tools/rust-analyzer/editors/code/tsconfig.json
+++ b/src/tools/rust-analyzer/editors/code/tsconfig.json
@@ -2,18 +2,17 @@
     "extends": "@tsconfig/strictest/tsconfig.json",
     "compilerOptions": {
         "esModuleInterop": false,
-        "module": "Node16",
-        "moduleResolution": "Node16",
-        "target": "ES2021",
+        "module": "NodeNext",
+        "moduleResolution": "nodenext",
+        "target": "ES2024",
         "outDir": "out",
-        "lib": ["ES2021"],
+        "lib": ["ES2024"],
         "sourceMap": true,
         "rootDir": ".",
         "newLine": "lf",
-
         // FIXME: https://github.com/rust-lang/rust-analyzer/issues/15253
         "exactOptionalPropertyTypes": false
     },
-    "exclude": ["node_modules", ".vscode-test"],
+    "exclude": ["node_modules", ".vscode-test", "out"],
     "include": ["src", "tests"]
 }
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 bc87ada3eb5..905da330e64 100644
--- a/src/tools/rust-analyzer/lib/line-index/src/lib.rs
+++ b/src/tools/rust-analyzer/lib/line-index/src/lib.rs
@@ -257,6 +257,8 @@ fn analyze_source_file_dispatch(
 /// SSE2 intrinsics to quickly find all newlines.
 #[target_feature(enable = "sse2")]
 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+// This can be removed once 1.87 is stable due to some intrinsics switching to safe.
+#[allow(unsafe_op_in_unsafe_fn)]
 unsafe fn analyze_source_file_sse2(
     src: &str,
     lines: &mut Vec<TextSize>,
@@ -287,17 +289,17 @@ unsafe fn analyze_source_file_sse2(
 
         // For character in the chunk, see if its byte value is < 0, which
         // indicates that it's part of a UTF-8 char.
-        let multibyte_test = unsafe { _mm_cmplt_epi8(chunk, _mm_set1_epi8(0)) };
+        let multibyte_test = _mm_cmplt_epi8(chunk, _mm_set1_epi8(0));
         // Create a bit mask from the comparison results.
-        let multibyte_mask = unsafe { _mm_movemask_epi8(multibyte_test) };
+        let multibyte_mask = _mm_movemask_epi8(multibyte_test);
 
         // If the bit mask is all zero, we only have ASCII chars here:
         if multibyte_mask == 0 {
             assert!(intra_chunk_offset == 0);
 
             // Check for newlines in the chunk
-            let newlines_test = unsafe { _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8)) };
-            let newlines_mask = unsafe { _mm_movemask_epi8(newlines_test) };
+            let newlines_test = _mm_cmpeq_epi8(chunk, _mm_set1_epi8(b'\n' as i8));
+            let newlines_mask = _mm_movemask_epi8(newlines_test);
 
             if newlines_mask != 0 {
                 // All control characters are newlines, record them
@@ -354,15 +356,19 @@ unsafe fn analyze_source_file_sse2(
 // The mask is a 64-bit integer, where each 4-bit corresponds to a u8 in the
 // input vector. The least significant 4 bits correspond to the first byte in
 // the vector.
+// This can be removed once 1.87 is stable due to some intrinsics switching to safe.
+#[allow(unsafe_op_in_unsafe_fn)]
 unsafe fn move_mask(v: std::arch::aarch64::uint8x16_t) -> u64 {
     use std::arch::aarch64::*;
 
-    let nibble_mask = unsafe { vshrn_n_u16(vreinterpretq_u16_u8(v), 4) };
-    unsafe { vget_lane_u64(vreinterpret_u64_u8(nibble_mask), 0) }
+    let nibble_mask = vshrn_n_u16(vreinterpretq_u16_u8(v), 4);
+    vget_lane_u64(vreinterpret_u64_u8(nibble_mask), 0)
 }
 
 #[target_feature(enable = "neon")]
 #[cfg(all(target_arch = "aarch64", target_endian = "little"))]
+// This can be removed once 1.87 is stable due to some intrinsics switching to safe.
+#[allow(unsafe_op_in_unsafe_fn)]
 unsafe fn analyze_source_file_neon(
     src: &str,
     lines: &mut Vec<TextSize>,
@@ -376,7 +382,7 @@ unsafe fn analyze_source_file_neon(
 
     let chunk_count = src.len() / CHUNK_SIZE;
 
-    let newline = unsafe { vdupq_n_s8(b'\n' as i8) };
+    let newline = vdupq_n_s8(b'\n' as i8);
 
     // This variable keeps track of where we should start decoding a
     // chunk. If a multi-byte character spans across chunk boundaries,
@@ -390,7 +396,7 @@ unsafe fn analyze_source_file_neon(
 
         // For character in the chunk, see if its byte value is < 0, which
         // indicates that it's part of a UTF-8 char.
-        let multibyte_test = unsafe { vcltzq_s8(chunk) };
+        let multibyte_test = vcltzq_s8(chunk);
         // Create a bit mask from the comparison results.
         let multibyte_mask = unsafe { move_mask(multibyte_test) };
 
@@ -399,7 +405,7 @@ unsafe fn analyze_source_file_neon(
             assert!(intra_chunk_offset == 0);
 
             // Check for newlines in the chunk
-            let newlines_test = unsafe { vceqq_s8(chunk, newline) };
+            let newlines_test = vceqq_s8(chunk, newline);
             let mut newlines_mask = unsafe { move_mask(newlines_test) };
 
             // If the bit mask is not all zero, there are newlines in this chunk.
diff --git a/src/tools/rust-analyzer/rust-version b/src/tools/rust-analyzer/rust-version
index 6cd39fabeee..e24e08d0687 100644
--- a/src/tools/rust-analyzer/rust-version
+++ b/src/tools/rust-analyzer/rust-version
@@ -1 +1 @@
-e0be1a02626abef2878cb7f4aaef7ae409477112
+daf59857d6d2b87af4b846316bf1561a6083ed51
diff --git a/src/tools/rust-analyzer/xtask/src/dist.rs b/src/tools/rust-analyzer/xtask/src/dist.rs
index c6a0be8aeb9..99483f4a5dc 100644
--- a/src/tools/rust-analyzer/xtask/src/dist.rs
+++ b/src/tools/rust-analyzer/xtask/src/dist.rs
@@ -38,11 +38,11 @@ impl flags::Dist {
                 // A hack to make VS Code prefer nightly over stable.
                 format!("{VERSION_NIGHTLY}.{patch_version}")
             };
-            dist_server(sh, &format!("{version}-standalone"), &target, allocator)?;
+            dist_server(sh, &format!("{version}-standalone"), &target, allocator, self.zig)?;
             let release_tag = if stable { date_iso(sh)? } else { "nightly".to_owned() };
             dist_client(sh, &version, &release_tag, &target)?;
         } else {
-            dist_server(sh, "0.0.0-standalone", &target, allocator)?;
+            dist_server(sh, "0.0.0-standalone", &target, allocator, self.zig)?;
         }
         Ok(())
     }
@@ -83,6 +83,7 @@ fn dist_server(
     release: &str,
     target: &Target,
     allocator: Malloc,
+    zig: bool,
 ) -> anyhow::Result<()> {
     let _e = sh.push_env("CFG_RELEASE", release);
     let _e = sh.push_env("CARGO_PROFILE_RELEASE_LTO", "thin");
@@ -92,13 +93,14 @@ fn dist_server(
     //   * on Linux, this blows up the binary size from 8MB to 43MB, which is unreasonable.
     // let _e = sh.push_env("CARGO_PROFILE_RELEASE_DEBUG", "1");
 
-    if target.name.contains("-linux-") {
-        env::set_var("CC", "clang");
-    }
-
-    let target_name = &target.name;
+    let linux_target = target.is_linux();
+    let target_name = match &target.libc_suffix {
+        Some(libc_suffix) if zig => format!("{}.{libc_suffix}", target.name),
+        _ => target.name.to_owned(),
+    };
     let features = allocator.to_features();
-    cmd!(sh, "cargo build --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target_name} {features...} --release").run()?;
+    let command = if linux_target && zig { "zigbuild" } else { "build" };
+    cmd!(sh, "cargo {command} --manifest-path ./crates/rust-analyzer/Cargo.toml --bin rust-analyzer --target {target_name} {features...} --release").run()?;
 
     let dst = Path::new("dist").join(&target.artifact_name);
     if target_name.contains("-windows-") {
@@ -156,6 +158,7 @@ fn zip(src_path: &Path, symbols_path: Option<&PathBuf>, dest_path: &Path) -> any
 
 struct Target {
     name: String,
+    libc_suffix: Option<String>,
     server_path: PathBuf,
     symbols_path: Option<PathBuf>,
     artifact_name: String,
@@ -177,6 +180,10 @@ impl Target {
                 }
             }
         };
+        let (name, libc_suffix) = match name.split_once('.') {
+            Some((l, r)) => (l.to_owned(), Some(r.to_owned())),
+            None => (name, None),
+        };
         let out_path = project_root.join("target").join(&name).join("release");
         let (exe_suffix, symbols_path) = if name.contains("-windows-") {
             (".exe".into(), Some(out_path.join("rust_analyzer.pdb")))
@@ -185,7 +192,11 @@ impl Target {
         };
         let server_path = out_path.join(format!("rust-analyzer{exe_suffix}"));
         let artifact_name = format!("rust-analyzer-{name}{exe_suffix}");
-        Self { name, server_path, symbols_path, artifact_name }
+        Self { name, libc_suffix, server_path, symbols_path, artifact_name }
+    }
+
+    fn is_linux(&self) -> bool {
+        self.name.contains("-linux-")
     }
 }
 
diff --git a/src/tools/rust-analyzer/xtask/src/flags.rs b/src/tools/rust-analyzer/xtask/src/flags.rs
index ebb9e71a4f4..d03e2f8437e 100644
--- a/src/tools/rust-analyzer/xtask/src/flags.rs
+++ b/src/tools/rust-analyzer/xtask/src/flags.rs
@@ -57,6 +57,8 @@ xflags::xflags! {
             /// Use jemalloc allocator for server
             optional --jemalloc
             optional --client-patch-version version: String
+            /// Use cargo-zigbuild
+            optional --zig
         }
         /// Read a changelog AsciiDoc file and update the GitHub Releases entry in Markdown.
         cmd publish-release-notes {
@@ -144,6 +146,7 @@ pub struct Dist {
     pub mimalloc: bool,
     pub jemalloc: bool,
     pub client_patch_version: Option<String>,
+    pub zig: bool,
 }
 
 #[derive(Debug)]
diff --git a/src/tools/rust-analyzer/xtask/src/release.rs b/src/tools/rust-analyzer/xtask/src/release.rs
index 8e56ce439c5..9f65c402953 100644
--- a/src/tools/rust-analyzer/xtask/src/release.rs
+++ b/src/tools/rust-analyzer/xtask/src/release.rs
@@ -50,7 +50,7 @@ impl flags::Release {
             .unwrap_or_default();
 
         let tags = cmd!(sh, "git tag --list").read()?;
-        let prev_tag = tags.lines().filter(|line| is_release_tag(line)).last().unwrap();
+        let prev_tag = tags.lines().filter(|line| is_release_tag(line)).next_back().unwrap();
 
         let contents = changelog::get_changelog(sh, changelog_n, &commit, prev_tag, &today)?;
         let path = changelog_dir.join(format!("{today}-changelog-{changelog_n}.adoc"));
diff --git a/src/tools/rustdoc/Cargo.toml b/src/tools/rustdoc/Cargo.toml
index c4101f72cc2..d1682758d36 100644
--- a/src/tools/rustdoc/Cargo.toml
+++ b/src/tools/rustdoc/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "rustdoc-tool"
 version = "0.0.0"
-edition = "2021"
+edition = "2024"
 
 # Cargo adds a number of paths to the dylib search path on windows, which results in
 # the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs
index 457d0afe3b5..3fb3284e3d7 100644
--- a/src/tools/rustfmt/src/items.rs
+++ b/src/tools/rustfmt/src/items.rs
@@ -2359,6 +2359,21 @@ impl Rewrite for ast::Param {
     }
 }
 
+fn rewrite_opt_lifetime(
+    context: &RewriteContext<'_>,
+    lifetime: Option<ast::Lifetime>,
+) -> RewriteResult {
+    let Some(l) = lifetime else {
+        return Ok(String::new());
+    };
+    let mut result = l.rewrite_result(
+        context,
+        Shape::legacy(context.config.max_width(), Indent::empty()),
+    )?;
+    result.push(' ');
+    Ok(result)
+}
+
 fn rewrite_explicit_self(
     context: &RewriteContext<'_>,
     explicit_self: &ast::ExplicitSelf,
@@ -2367,58 +2382,34 @@ fn rewrite_explicit_self(
     shape: Shape,
     has_multiple_attr_lines: bool,
 ) -> RewriteResult {
-    match explicit_self.node {
+    let self_str = match explicit_self.node {
         ast::SelfKind::Region(lt, m) => {
             let mut_str = format_mutability(m);
-            match lt {
-                Some(ref l) => {
-                    let lifetime_str = l.rewrite_result(
-                        context,
-                        Shape::legacy(context.config.max_width(), Indent::empty()),
-                    )?;
-                    Ok(combine_strs_with_missing_comments(
-                        context,
-                        param_attrs,
-                        &format!("&{lifetime_str} {mut_str}self"),
-                        span,
-                        shape,
-                        !has_multiple_attr_lines,
-                    )?)
-                }
-                None => Ok(combine_strs_with_missing_comments(
-                    context,
-                    param_attrs,
-                    &format!("&{mut_str}self"),
-                    span,
-                    shape,
-                    !has_multiple_attr_lines,
-                )?),
-            }
+            let lifetime_str = rewrite_opt_lifetime(context, lt)?;
+            format!("&{lifetime_str}{mut_str}self")
+        }
+        ast::SelfKind::Pinned(lt, m) => {
+            let mut_str = m.ptr_str();
+            let lifetime_str = rewrite_opt_lifetime(context, lt)?;
+            format!("&{lifetime_str}pin {mut_str} self")
         }
         ast::SelfKind::Explicit(ref ty, mutability) => {
             let type_str = ty.rewrite_result(
                 context,
                 Shape::legacy(context.config.max_width(), Indent::empty()),
             )?;
-
-            Ok(combine_strs_with_missing_comments(
-                context,
-                param_attrs,
-                &format!("{}self: {}", format_mutability(mutability), type_str),
-                span,
-                shape,
-                !has_multiple_attr_lines,
-            )?)
+            format!("{}self: {}", format_mutability(mutability), type_str)
         }
-        ast::SelfKind::Value(mutability) => Ok(combine_strs_with_missing_comments(
-            context,
-            param_attrs,
-            &format!("{}self", format_mutability(mutability)),
-            span,
-            shape,
-            !has_multiple_attr_lines,
-        )?),
-    }
+        ast::SelfKind::Value(mutability) => format!("{}self", format_mutability(mutability)),
+    };
+    Ok(combine_strs_with_missing_comments(
+        context,
+        param_attrs,
+        &self_str,
+        span,
+        shape,
+        !has_multiple_attr_lines,
+    )?)
 }
 
 pub(crate) fn span_lo_for_param(param: &ast::Param) -> BytePos {
diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs
index ea8ca38cb77..664c90b991a 100644
--- a/src/tools/rustfmt/src/macros.rs
+++ b/src/tools/rustfmt/src/macros.rs
@@ -12,7 +12,7 @@
 use std::collections::HashMap;
 use std::panic::{AssertUnwindSafe, catch_unwind};
 
-use rustc_ast::token::{BinOpToken, Delimiter, Token, TokenKind};
+use rustc_ast::token::{Delimiter, Token, TokenKind};
 use rustc_ast::tokenstream::{TokenStream, TokenStreamIter, TokenTree};
 use rustc_ast::{ast, ptr};
 use rustc_ast_pretty::pprust;
@@ -841,7 +841,7 @@ impl MacroArgParser {
             match tok {
                 TokenTree::Token(
                     Token {
-                        kind: TokenKind::BinOp(BinOpToken::Plus),
+                        kind: TokenKind::Plus,
                         ..
                     },
                     _,
@@ -855,7 +855,7 @@ impl MacroArgParser {
                 )
                 | TokenTree::Token(
                     Token {
-                        kind: TokenKind::BinOp(BinOpToken::Star),
+                        kind: TokenKind::Star,
                         ..
                     },
                     _,
@@ -1088,14 +1088,32 @@ fn force_space_before(tok: &TokenKind) -> bool {
         | TokenKind::Gt
         | TokenKind::AndAnd
         | TokenKind::OrOr
-        | TokenKind::Not
+        | TokenKind::Bang
         | TokenKind::Tilde
-        | TokenKind::BinOpEq(_)
+        | TokenKind::PlusEq
+        | TokenKind::MinusEq
+        | TokenKind::StarEq
+        | TokenKind::SlashEq
+        | TokenKind::PercentEq
+        | TokenKind::CaretEq
+        | TokenKind::AndEq
+        | TokenKind::OrEq
+        | TokenKind::ShlEq
+        | TokenKind::ShrEq
         | TokenKind::At
         | TokenKind::RArrow
         | TokenKind::LArrow
         | TokenKind::FatArrow
-        | TokenKind::BinOp(_)
+        | TokenKind::Plus
+        | TokenKind::Minus
+        | TokenKind::Star
+        | TokenKind::Slash
+        | TokenKind::Percent
+        | TokenKind::Caret
+        | TokenKind::And
+        | TokenKind::Or
+        | TokenKind::Shl
+        | TokenKind::Shr
         | TokenKind::Pound
         | TokenKind::Dollar => true,
         _ => false,
@@ -1113,8 +1131,8 @@ fn next_space(tok: &TokenKind) -> SpaceState {
     debug!("next_space: {:?}", tok);
 
     match tok {
-        TokenKind::Not
-        | TokenKind::BinOp(BinOpToken::And)
+        TokenKind::Bang
+        | TokenKind::And
         | TokenKind::Tilde
         | TokenKind::At
         | TokenKind::Comma
diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs
index e93eb53cd87..507647566d4 100644
--- a/src/tools/rustfmt/src/spanned.rs
+++ b/src/tools/rustfmt/src/spanned.rs
@@ -58,6 +58,7 @@ implement_spanned!(ast::ExprField);
 implement_spanned!(ast::ForeignItem);
 implement_spanned!(ast::Item);
 implement_spanned!(ast::Local);
+implement_spanned!(ast::WherePredicate);
 
 impl Spanned for ast::Stmt {
     fn span(&self) -> Span {
@@ -149,12 +150,6 @@ impl Spanned for ast::FieldDef {
     }
 }
 
-impl Spanned for ast::WherePredicate {
-    fn span(&self) -> Span {
-        self.span
-    }
-}
-
 impl Spanned for ast::FnRetTy {
     fn span(&self) -> Span {
         match *self {
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 7b44b47c719..06a67334086 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -463,8 +463,9 @@ impl Rewrite for ast::WherePredicate {
     }
 
     fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
+        let attrs_str = self.attrs.rewrite_result(context, shape)?;
         // FIXME: dead spans?
-        let result = match self.kind {
+        let pred_str = &match self.kind {
             ast::WherePredicateKind::BoundPredicate(ast::WhereBoundPredicate {
                 ref bound_generic_params,
                 ref bounded_ty,
@@ -499,6 +500,38 @@ impl Rewrite for ast::WherePredicate {
             }
         };
 
+        let mut result = String::with_capacity(attrs_str.len() + pred_str.len() + 1);
+        result.push_str(&attrs_str);
+        let pred_start = self.span.lo();
+        let line_len = last_line_width(&attrs_str) + 1 + first_line_width(&pred_str);
+        if let Some(last_attr) = self.attrs.last().filter(|last_attr| {
+            contains_comment(context.snippet(mk_sp(last_attr.span.hi(), pred_start)))
+        }) {
+            result = combine_strs_with_missing_comments(
+                context,
+                &result,
+                &pred_str,
+                mk_sp(last_attr.span.hi(), pred_start),
+                Shape {
+                    width: shape.width.min(context.config.inline_attribute_width()),
+                    ..shape
+                },
+                !last_attr.is_doc_comment(),
+            )?;
+        } else {
+            if !self.attrs.is_empty() {
+                if context.config.inline_attribute_width() < line_len
+                    || self.attrs.len() > 1
+                    || self.attrs.last().is_some_and(|a| a.is_doc_comment())
+                {
+                    result.push_str(&shape.indent.to_string_with_newline(context.config));
+                } else {
+                    result.push(' ');
+                }
+            }
+            result.push_str(&pred_str);
+        }
+
         Ok(result)
     }
 }
diff --git a/src/tools/rustfmt/tests/source/pin_sugar.rs b/src/tools/rustfmt/tests/source/pin_sugar.rs
index 0eb3c0770c4..370dfbc196a 100644
--- a/src/tools/rustfmt/tests/source/pin_sugar.rs
+++ b/src/tools/rustfmt/tests/source/pin_sugar.rs
@@ -8,3 +8,13 @@ fn g<'a>(x: &  'a pin const  i32) {}
 fn h<'a>(x: &  'a pin  
 mut i32) {}
 fn i(x: &pin      mut  i32) {}
+
+struct Foo;
+
+impl Foo {
+    fn f(&pin   const self) {}
+    fn g<'a>(&   'a pin const    self) {}
+    fn h<'a>(&    'a pin
+mut self) {}
+    fn i(&pin      mut   self) {}
+}
diff --git a/src/tools/rustfmt/tests/target/cfg_attribute_in_where.rs b/src/tools/rustfmt/tests/target/cfg_attribute_in_where.rs
new file mode 100644
index 00000000000..11f495b1629
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/cfg_attribute_in_where.rs
@@ -0,0 +1,116 @@
+// rustfmt-inline_attribute_width: 40
+
+#![crate_type = "lib"]
+#![feature(cfg_attribute_in_where)]
+use std::marker::PhantomData;
+
+#[cfg(a)]
+trait TraitA {}
+
+#[cfg(b)]
+trait TraitB {}
+
+trait A<T>
+where
+    #[cfg = a_very_long_attribute_name]
+    T: TraitA,
+    #[cfg = another_very_long_attribute_name]
+    T: TraitB,
+{
+    type B<U>
+    where
+        #[cfg = a]
+        // line comment after the attribute
+        U: TraitA,
+        #[cfg = b]
+        /* block comment after the attribute */
+        U: TraitB,
+        #[cfg = a] // short
+        U: TraitA,
+        #[cfg = b] /* short */ U: TraitB;
+
+    fn foo<U>(&self)
+    where
+        /// line doc comment before the attribute
+        U: TraitA,
+        /** line doc block comment before the attribute */
+        U: TraitB;
+}
+
+impl<T> A<T> for T
+where
+    #[doc = "line doc before the attribute"]
+    T: TraitA,
+    /** short doc */
+    T: TraitB,
+{
+    type B<U>
+        = ()
+    where
+        #[doc = "short"] U: TraitA,
+        #[doc = "short"]
+        #[cfg = a]
+        U: TraitB;
+
+    fn foo<U>(&self)
+    where
+        #[cfg = a]
+        #[cfg = b]
+        U: TraitA,
+        /// line doc
+        #[cfg = c]
+        U: TraitB,
+    {
+    }
+}
+
+struct C<T>
+where
+    #[cfg = a] T: TraitA,
+    #[cfg = b] T: TraitB,
+{
+    _t: PhantomData<T>,
+}
+
+union D<T>
+where
+    #[cfg = a] T: TraitA,
+    #[cfg = b] T: TraitB,
+{
+    _t: PhantomData<T>,
+}
+
+enum E<T>
+where
+    #[cfg = a] T: TraitA,
+    #[cfg = b] T: TraitB,
+{
+    E(PhantomData<T>),
+}
+
+#[allow(type_alias_bounds)]
+type F<T>
+where
+    #[cfg = a] T: TraitA,
+    #[cfg = b] T: TraitB,
+= T;
+
+impl<T> C<T>
+where
+    #[cfg = a] T: TraitA,
+    #[cfg = b] T: TraitB,
+{
+    fn new<U>()
+    where
+        #[cfg = a] U: TraitA,
+        #[cfg = b] U: TraitB,
+    {
+    }
+}
+
+fn foo<T>()
+where
+    #[cfg = a] T: TraitA,
+    #[cfg = b] T: TraitB,
+{
+}
diff --git a/src/tools/rustfmt/tests/target/pin_sugar.rs b/src/tools/rustfmt/tests/target/pin_sugar.rs
index c9fa883e238..7d04efb1b32 100644
--- a/src/tools/rustfmt/tests/target/pin_sugar.rs
+++ b/src/tools/rustfmt/tests/target/pin_sugar.rs
@@ -7,3 +7,12 @@ fn f(x: &pin const i32) {}
 fn g<'a>(x: &'a pin const i32) {}
 fn h<'a>(x: &'a pin mut i32) {}
 fn i(x: &pin mut i32) {}
+
+struct Foo;
+
+impl Foo {
+    fn f(&pin const self) {}
+    fn g<'a>(&'a pin const self) {}
+    fn h<'a>(&'a pin mut self) {}
+    fn i(&pin mut self) {}
+}
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
deleted file mode 100644
index e69de29bb2d..00000000000
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ /dev/null
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 1e7eb82b83e..9f6d563166e 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -79,7 +79,6 @@ pub(crate) mod iter_header;
 pub mod known_bug;
 pub mod mir_opt_tests;
 pub mod pal;
-pub mod run_make_tests;
 pub mod rustdoc_css_themes;
 pub mod rustdoc_gui_tests;
 pub mod rustdoc_templates;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index 13a558fea48..1d8514ef4c9 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -103,8 +103,6 @@ fn main() {
         check!(tests_revision_unpaired_stdout_stderr, &tests_path);
         check!(debug_artifacts, &tests_path);
         check!(ui_tests, &root_path, bless);
-        // FIXME(jieyouxu): remove this check once all run-make tests are ported over to rmake.rs.
-        check!(run_make_tests, &tests_path, &src_path, bless);
         check!(mir_opt_tests, &tests_path, bless);
         check!(rustdoc_gui_tests, &tests_path);
         check!(rustdoc_css_themes, &librustdoc_path);
diff --git a/src/tools/tidy/src/run_make_tests.rs b/src/tools/tidy/src/run_make_tests.rs
deleted file mode 100644
index 8d176787837..00000000000
--- a/src/tools/tidy/src/run_make_tests.rs
+++ /dev/null
@@ -1,104 +0,0 @@
-//! Tidy check to ensure that no new Makefiles are added under `tests/run-make/`.
-
-use std::collections::BTreeSet;
-use std::fs::File;
-use std::io::Write;
-use std::path::{Path, PathBuf};
-
-pub fn check(tests_path: &Path, src_path: &Path, bless: bool, bad: &mut bool) {
-    let mut is_sorted = true;
-
-    let allowed_makefiles = {
-        let mut total_lines = 0;
-        let mut prev_line = "";
-        let allowed_makefiles: BTreeSet<&str> = include_str!("allowed_run_make_makefiles.txt")
-            .lines()
-            .map(|line| {
-                total_lines += 1;
-
-                if prev_line > line {
-                    is_sorted = false;
-                }
-
-                prev_line = line;
-
-                line
-            })
-            .collect();
-
-        if !is_sorted && !bless {
-            tidy_error!(
-                bad,
-                "`src/tools/tidy/src/allowed_run_make_makefiles.txt` is not in order, likely \
-                because you modified it manually, please only update it with command \
-                `x test tidy --bless`"
-            );
-        }
-        if allowed_makefiles.len() != total_lines {
-            tidy_error!(
-                bad,
-                "`src/tools/tidy/src/allowed_run_make_makefiles.txt` contains duplicate entries, \
-                likely because you modified it manually, please only update it with command \
-                `x test tidy --bless`"
-            );
-        }
-
-        allowed_makefiles
-    };
-
-    let mut remaining_makefiles = allowed_makefiles.clone();
-
-    crate::walk::walk_no_read(
-        &[tests_path.join("run-make").as_ref()],
-        |_, _| false,
-        &mut |entry| {
-            if entry.file_type().map_or(true, |t| t.is_dir()) {
-                return;
-            }
-
-            if entry.file_name().to_str().map_or(true, |f| f != "Makefile") {
-                return;
-            }
-
-            let makefile_path = entry.path().strip_prefix(&tests_path).unwrap();
-            let makefile_path = makefile_path.to_str().unwrap().replace('\\', "/");
-
-            if !remaining_makefiles.remove(makefile_path.as_str()) {
-                tidy_error!(
-                    bad,
-                    "found run-make Makefile not permitted in \
-                `src/tools/tidy/src/allowed_run_make_makefiles.txt`, please write new run-make \
-                tests with `rmake.rs` instead: {}",
-                    entry.path().display()
-                );
-            }
-        },
-    );
-
-    // If there are any expected Makefiles remaining, they were moved or deleted.
-    // Our data must remain up to date, so they must be removed from
-    // `src/tools/tidy/src/allowed_run_make_makefiles.txt`.
-    // This can be done automatically on --bless, or else a tidy error will be issued.
-    if bless && (!remaining_makefiles.is_empty() || !is_sorted) {
-        let tidy_src = src_path.join("tools").join("tidy").join("src");
-        let org_file_path = tidy_src.join("allowed_run_make_makefiles.txt");
-        let temp_file_path = tidy_src.join("blessed_allowed_run_make_makefiles.txt");
-        let mut temp_file = t!(File::create_new(&temp_file_path));
-        for file in allowed_makefiles.difference(&remaining_makefiles) {
-            t!(writeln!(temp_file, "{file}"));
-        }
-        t!(std::fs::rename(&temp_file_path, &org_file_path));
-    } else {
-        for file in remaining_makefiles {
-            let mut p = PathBuf::from(tests_path);
-            p.push(file);
-            tidy_error!(
-                bad,
-                "Makefile `{}` no longer exists and should be removed from the exclusions in \
-                `src/tools/tidy/src/allowed_run_make_makefiles.txt`, you can run `x test tidy --bless` to update \
-                the allow list",
-                p.display()
-            );
-        }
-    }
-}
diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs
index 21b513629ed..205d6720718 100644
--- a/src/tools/tidy/src/style.rs
+++ b/src/tools/tidy/src/style.rs
@@ -72,12 +72,14 @@ const ANNOTATIONS_TO_IGNORE: &[&str] = &[
     "//@ normalize-stderr",
 ];
 
+const LINELENGTH_CHECK: &str = "linelength";
+
 // If you edit this, also edit where it gets used in `check` (calling `contains_ignore_directives`)
 const CONFIGURABLE_CHECKS: [&str; 11] = [
     "cr",
     "undocumented-unsafe",
     "tab",
-    "linelength",
+    LINELENGTH_CHECK,
     "filelength",
     "end-whitespace",
     "trailing-newlines",
@@ -250,14 +252,24 @@ enum Directive {
 // Use a fixed size array in the return type to catch mistakes with changing `CONFIGURABLE_CHECKS`
 // without changing the code in `check` easier.
 fn contains_ignore_directives<const N: usize>(
+    path_str: &str,
     can_contain: bool,
     contents: &str,
     checks: [&str; N],
 ) -> [Directive; N] {
-    if !can_contain {
+    // The rustdoc-json test syntax often requires very long lines, so the checks
+    // for long lines aren't really useful.
+    let always_ignore_linelength = path_str.contains("rustdoc-json");
+
+    if !can_contain && !always_ignore_linelength {
         return [Directive::Deny; N];
     }
+
     checks.map(|check| {
+        if check == LINELENGTH_CHECK && always_ignore_linelength {
+            return Directive::Ignore(false);
+        }
+
         // Update `can_contain` when changing this
         if contents.contains(&format!("// ignore-tidy-{check}"))
             || contents.contains(&format!("# ignore-tidy-{check}"))
@@ -367,6 +379,7 @@ pub fn check(path: &Path, bad: &mut bool) {
 
     walk(path, skip, &mut |entry, contents| {
         let file = entry.path();
+        let path_str = file.to_string_lossy();
         let filename = file.file_name().unwrap().to_string_lossy();
 
         let is_css_file = filename.ends_with(".css");
@@ -422,7 +435,7 @@ pub fn check(path: &Path, bad: &mut bool) {
             mut skip_copyright,
             mut skip_dbg,
             mut skip_odd_backticks,
-        ] = contains_ignore_directives(can_contain, &contents, CONFIGURABLE_CHECKS);
+        ] = contains_ignore_directives(&path_str, can_contain, &contents, CONFIGURABLE_CHECKS);
         let mut leading_new_lines = false;
         let mut trailing_new_lines = 0;
         let mut lines = 0;
@@ -502,7 +515,7 @@ pub fn check(path: &Path, bad: &mut bool) {
                 let contains_potential_directive =
                     possible_line_start && (line.contains("-tidy") || line.contains("tidy-"));
                 let has_recognized_ignore_directive =
-                    contains_ignore_directives(can_contain, line, CONFIGURABLE_CHECKS)
+                    contains_ignore_directives(&path_str, can_contain, line, CONFIGURABLE_CHECKS)
                         .into_iter()
                         .any(|directive| matches!(directive, Directive::Ignore(_)));
                 let has_alphabetical_directive = line.contains("tidy-alphabetical-start")
diff --git a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
index 57fc601a2e0..91c83fa2f5b 100644
--- a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
+++ b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
@@ -19,7 +19,7 @@
 #![allow(incomplete_features)]
 #![feature(unsized_locals, unsized_fn_params)]
 
-// CHECK-LABEL: emptyfn:
+// CHECK-LABEL: emptyfn{{:|\[}}
 #[no_mangle]
 pub fn emptyfn() {
     // all: __stack_chk_fail
@@ -29,7 +29,7 @@ pub fn emptyfn() {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: array_char
+// CHECK-LABEL: array_char{{:|\[}}
 #[no_mangle]
 pub fn array_char(f: fn(*const char)) {
     let a = ['c'; 1];
@@ -47,7 +47,7 @@ pub fn array_char(f: fn(*const char)) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: array_u8_1
+// CHECK-LABEL: array_u8_1{{:|\[}}
 #[no_mangle]
 pub fn array_u8_1(f: fn(*const u8)) {
     let a = [0u8; 1];
@@ -63,7 +63,7 @@ pub fn array_u8_1(f: fn(*const u8)) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: array_u8_small:
+// CHECK-LABEL: array_u8_small{{:|\[}}
 #[no_mangle]
 pub fn array_u8_small(f: fn(*const u8)) {
     let a = [0u8; 2];
@@ -80,7 +80,7 @@ pub fn array_u8_small(f: fn(*const u8)) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: array_u8_large:
+// CHECK-LABEL: array_u8_large{{:|\[}}
 #[no_mangle]
 pub fn array_u8_large(f: fn(*const u8)) {
     let a = [0u8; 9];
@@ -99,7 +99,7 @@ pub fn array_u8_large(f: fn(*const u8)) {
 #[derive(Copy, Clone)]
 pub struct ByteSizedNewtype(u8);
 
-// CHECK-LABEL: array_bytesizednewtype_9:
+// CHECK-LABEL: array_bytesizednewtype_9{{:|\[}}
 #[no_mangle]
 pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) {
     let a = [ByteSizedNewtype(0); 9];
@@ -115,7 +115,7 @@ pub fn array_bytesizednewtype_9(f: fn(*const ByteSizedNewtype)) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: local_var_addr_used_indirectly
+// CHECK-LABEL: local_var_addr_used_indirectly{{:|\[}}
 #[no_mangle]
 pub fn local_var_addr_used_indirectly(f: fn(bool)) {
     let a = 5;
@@ -142,7 +142,7 @@ pub fn local_var_addr_used_indirectly(f: fn(bool)) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: local_string_addr_taken
+// CHECK-LABEL: local_string_addr_taken{{:|\[}}
 #[no_mangle]
 pub fn local_string_addr_taken(f: fn(&String)) {
     let x = String::new();
@@ -168,7 +168,7 @@ impl SelfByRef for i32 {
     }
 }
 
-// CHECK-LABEL: local_var_addr_taken_used_locally_only
+// CHECK-LABEL: local_var_addr_taken_used_locally_only{{:|\[}}
 #[no_mangle]
 pub fn local_var_addr_taken_used_locally_only(factory: fn() -> i32, sink: fn(i32)) {
     let x = factory();
@@ -195,7 +195,7 @@ pub struct Gigastruct {
     members: u64,
 }
 
-// CHECK-LABEL: local_large_var_moved
+// CHECK-LABEL: local_large_var_moved{{:|\[}}
 #[no_mangle]
 pub fn local_large_var_moved(f: fn(Gigastruct)) {
     let x = Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 };
@@ -224,7 +224,7 @@ pub fn local_large_var_moved(f: fn(Gigastruct)) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: local_large_var_cloned
+// CHECK-LABEL: local_large_var_cloned{{:|\[}}
 #[no_mangle]
 pub fn local_large_var_cloned(f: fn(Gigastruct)) {
     f(Gigastruct { does: 0, not: 1, have: 2, array: 3, members: 4 });
@@ -281,7 +281,7 @@ extern "C" {
     fn alloca(size: usize) -> *mut ();
 }
 
-// CHECK-LABEL: alloca_small_compile_time_constant_arg
+// CHECK-LABEL: alloca_small_compile_time_constant_arg{{:|\[}}
 #[no_mangle]
 pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) {
     f(unsafe { alloca(8) });
@@ -293,7 +293,7 @@ pub fn alloca_small_compile_time_constant_arg(f: fn(*mut ())) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: alloca_large_compile_time_constant_arg
+// CHECK-LABEL: alloca_large_compile_time_constant_arg{{:|\[}}
 #[no_mangle]
 pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) {
     f(unsafe { alloca(9) });
@@ -305,7 +305,7 @@ pub fn alloca_large_compile_time_constant_arg(f: fn(*mut ())) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: alloca_dynamic_arg
+// CHECK-LABEL: alloca_dynamic_arg{{:|\[}}
 #[no_mangle]
 pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) {
     f(unsafe { alloca(n) });
@@ -324,7 +324,7 @@ pub fn alloca_dynamic_arg(f: fn(*mut ()), n: usize) {
 // this is support for the "unsized locals" unstable feature:
 // https://doc.rust-lang.org/unstable-book/language-features/unsized-locals.html.
 
-// CHECK-LABEL: unsized_fn_param
+// CHECK-LABEL: unsized_fn_param{{:|\[}}
 #[no_mangle]
 pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) {
     let n = if l { 1 } else { 2 };
@@ -344,7 +344,7 @@ pub fn unsized_fn_param(s: [u8], l: bool, f: fn([u8])) {
     // missing-NOT: __stack_chk_fail
 }
 
-// CHECK-LABEL: unsized_local
+// CHECK-LABEL: unsized_local{{:|\[}}
 #[no_mangle]
 pub fn unsized_local(s: &[u8], l: bool, f: fn(&mut [u8])) {
     let n = if l { 1 } else { 2 };
diff --git a/tests/codegen/asm/critical.rs b/tests/codegen/asm/critical.rs
new file mode 100644
index 00000000000..8c039900cab
--- /dev/null
+++ b/tests/codegen/asm/critical.rs
@@ -0,0 +1,37 @@
+//@ only-x86_64
+//@ compile-flags: -C no-prepopulate-passes
+#![feature(asm_goto)]
+#![feature(asm_goto_with_outputs)]
+#![crate_type = "lib"]
+use std::arch::asm;
+
+// Regression test for #137867. Check that critical edges have been split before code generation,
+// and so all stores to the asm output occur on disjoint paths without any of them jumping to
+// another callbr label.
+//
+// CHECK-LABEL: @f(
+// CHECK:        [[OUT:%.*]] = callbr i32 asm
+// CHECK-NEXT:   to label %[[BB0:.*]] [label %[[BB1:.*]], label %[[BB2:.*]]],
+// CHECK:       [[BB1]]:
+// CHECK-NEXT:    store i32 [[OUT]], ptr %a
+// CHECK-NEXT:    br label %[[BBR:.*]]
+// CHECK:       [[BB2]]:
+// CHECK-NEXT:    store i32 [[OUT]], ptr %a
+// CHECK-NEXT:    br label %[[BBR]]
+// CHECK:       [[BB0]]:
+// CHECK-NEXT:    store i32 [[OUT]], ptr %a
+// CHECK-NEXT:    br label %[[BBR]]
+// CHECK:       [[BBR]]:
+// CHECK-NEXT:    [[RET:%.*]] = load i32, ptr %a
+// CHECK-NEXT:    ret i32 [[RET]]
+#[unsafe(no_mangle)]
+pub unsafe fn f(mut a: u32) -> u32 {
+    asm!(
+        "jmp {}
+         jmp {}",
+        label {},
+        label {},
+        inout("eax") a,
+    );
+    a
+}
diff --git a/tests/codegen/issues/looping-over-ne-bytes-133528.rs b/tests/codegen/issues/looping-over-ne-bytes-133528.rs
new file mode 100644
index 00000000000..35acf765d69
--- /dev/null
+++ b/tests/codegen/issues/looping-over-ne-bytes-133528.rs
@@ -0,0 +1,17 @@
+//@ compile-flags: -Copt-level=3
+//@ min-llvm-version: 20
+#![crate_type = "lib"]
+
+/// Ensure the function is properly optimized
+/// In the issue #133528, the function was not getting optimized
+/// whereas, a version with `bytes` wrapped into a `black_box` was optimized
+/// It was probably a LLVM bug that was fixed in LLVM 20
+
+// CHECK-LABEL: @looping_over_ne_bytes
+// CHECK: icmp eq i64 %input, -1
+// CHECK-NEXT: ret i1
+#[no_mangle]
+fn looping_over_ne_bytes(input: u64) -> bool {
+    let bytes = input.to_ne_bytes();
+    bytes.iter().all(|x| *x == !0)
+}
diff --git a/tests/codegen/pattern_type_symbols.rs b/tests/codegen/pattern_type_symbols.rs
index b504a3508f9..e86a9ef27de 100644
--- a/tests/codegen/pattern_type_symbols.rs
+++ b/tests/codegen/pattern_type_symbols.rs
@@ -16,7 +16,7 @@ pub fn bar() {
     // CHECK: call pattern_type_symbols::foo::<u32>
     // CHECK: call void @_RINvC[[CRATE_IDENT:[a-zA-Z0-9]{12}]]_20pattern_type_symbols3foomEB2_
     foo::<u32>();
-    // CHECK: call pattern_type_symbols::foo::<(u32, [(); 0], [(); 999999999], [(); true])>
-    // CHECK: call void @_RINvC[[CRATE_IDENT]]_20pattern_type_symbols3fooTmAum0_Aum3b9ac9ff_Aub1_EEB2_
+    // CHECK: call pattern_type_symbols::foo::<(u32, [(); 0], [(); 999999999])>
+    // CHECK: call void @_RINvC[[CRATE_IDENT]]_20pattern_type_symbols3fooTmAum0_Aum3b9ac9ff_EEB2_
     foo::<NanoU32>();
 }
diff --git a/tests/codegen/slice-init.rs b/tests/codegen/slice-init.rs
index b36a5b5de3d..950e0b0c10d 100644
--- a/tests/codegen/slice-init.rs
+++ b/tests/codegen/slice-init.rs
@@ -2,8 +2,6 @@
 
 #![crate_type = "lib"]
 
-use std::mem::MaybeUninit;
-
 // CHECK-LABEL: @zero_sized_elem
 #[no_mangle]
 pub fn zero_sized_elem() {
@@ -78,64 +76,31 @@ pub fn u16_init_one_bytes() -> [u16; N] {
     [const { u16::from_be_bytes([1, 1]) }; N]
 }
 
+// FIXME: undef bytes can just be initialized with the same value as the
+// defined bytes, if the defines bytes are all the same.
 // CHECK-LABEL: @option_none_init
 #[no_mangle]
 pub fn option_none_init() -> [Option<u8>; N] {
     // CHECK-NOT: select
-    // CHECK-NOT: br
-    // CHECK-NOT: switch
-    // CHECK-NOT: icmp
-    // CHECK: call void @llvm.memset.p0
-    [const { None }; N]
-}
-
-// If there is partial provenance or some bytes are initialized and some are not,
-// we can't really do better than initialize bytes or groups of bytes together.
-// CHECK-LABEL: @option_maybe_uninit_init
-#[no_mangle]
-pub fn option_maybe_uninit_init() -> [MaybeUninit<u16>; N] {
-    // CHECK-NOT: select
     // CHECK: br label %repeat_loop_header{{.*}}
     // CHECK-NOT: switch
     // CHECK: icmp
     // CHECK-NOT: call void @llvm.memset.p0
-    [const {
-        let mut val: MaybeUninit<u16> = MaybeUninit::uninit();
-        let ptr = val.as_mut_ptr() as *mut u8;
-        unsafe {
-            ptr.write(0);
-        }
-        val
-    }; N]
+    [None; N]
 }
 
-#[repr(packed)]
-struct Packed {
-    start: u8,
-    ptr: &'static (),
-    rest: u16,
-    rest2: u8,
-}
+use std::mem::MaybeUninit;
 
-// If there is partial provenance or some bytes are initialized and some are not,
-// we can't really do better than initialize bytes or groups of bytes together.
-// CHECK-LABEL: @option_maybe_uninit_provenance
+// FIXME: This could be optimized into a memset.
+// Regression test for <https://github.com/rust-lang/rust/issues/137892>.
 #[no_mangle]
-pub fn option_maybe_uninit_provenance() -> [MaybeUninit<Packed>; N] {
+pub fn half_uninit() -> [(u128, MaybeUninit<u128>); N] {
     // CHECK-NOT: select
     // CHECK: br label %repeat_loop_header{{.*}}
     // CHECK-NOT: switch
     // CHECK: icmp
     // CHECK-NOT: call void @llvm.memset.p0
-    [const {
-        let mut val: MaybeUninit<Packed> = MaybeUninit::uninit();
-        unsafe {
-            let ptr = &raw mut (*val.as_mut_ptr()).ptr;
-            static HAS_ADDR: () = ();
-            ptr.write_unaligned(&HAS_ADDR);
-        }
-        val
-    }; N]
+    [const { (0, MaybeUninit::uninit()) }; N]
 }
 
 // Use an opaque function to prevent rustc from removing useless drops.
diff --git a/tests/crashes/129095.rs b/tests/crashes/129095.rs
index d82474e18e7..b1bb74708c2 100644
--- a/tests/crashes/129095.rs
+++ b/tests/crashes/129095.rs
@@ -1,10 +1,13 @@
 //@ known-bug: rust-lang/rust#129095
 //@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir
 
+#![feature(adt_const_params, unsized_const_params)]
+#![allow(incomplete_features)]
+
 pub fn function_with_bytes<const BYTES: &'static [u8; 4]>() -> &'static [u8] {
     BYTES
 }
 
 pub fn main() {
-    assert_eq!(function_with_bytes::<b"AAAAb">(), &[0x41, 0x41, 0x41, 0x41]);
+    assert_eq!(function_with_bytes::<b"AAAAA">(), &[0x41, 0x41, 0x41, 0x41]);
 }
diff --git a/tests/crashes/132960.rs b/tests/crashes/132960.rs
index 87d0ee7dede..c23a3393429 100644
--- a/tests/crashes/132960.rs
+++ b/tests/crashes/132960.rs
@@ -1,6 +1,6 @@
 //@ known-bug: #132960
 
-#![feature(adt_const_params, const_ptr_read, generic_const_exprs)]
+#![feature(adt_const_params, const_ptr_read, generic_const_exprs, unsized_const_params)]
 
 const fn concat_strs<const A: &'static str, const B: &'static str>() -> &'static str
 where
diff --git a/tests/crashes/132981.rs b/tests/crashes/132981.rs
deleted file mode 100644
index 916c1559240..00000000000
--- a/tests/crashes/132981.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//@ known-bug: #132981
-//@compile-flags: -Clink-dead-code=true --crate-type lib
-//@ only-x86_64
-//@ ignore-windows
-// The set of targets this crashes on is really fiddly, because it is deep in our ABI logic. It
-// crashes on x86_64-unknown-linux-gnu, and i686-pc-windows-msvc, but not on
-// x86_64-pc-windows-msvc. If you are trying to fix this crash, don't pay too much attention to the
-// directives.
-
-#![feature(rust_cold_cc)]
-pub extern "rust-cold" fn foo(_: [usize; 3]) {}
diff --git a/tests/crashes/134654.rs b/tests/crashes/134654.rs
index 8a8d18359e9..f2323fe4ecd 100644
--- a/tests/crashes/134654.rs
+++ b/tests/crashes/134654.rs
@@ -2,6 +2,9 @@
 //@ compile-flags: -Zmir-enable-passes=+GVN -Zmir-enable-passes=+Inline -Zvalidate-mir
 //@ only-x86_64
 
+#![feature(adt_const_params, unsized_const_params)]
+#![allow(incomplete_features)]
+
 fn function_with_bytes<const BYTES:
     &'static [u8; 0xa9008fb6c9d81e42_0e25730562a601c8_u128]>() -> &'static [u8] {
     BYTES
diff --git a/tests/crashes/135128.rs b/tests/crashes/135128.rs
index 2ce17df824a..a8fd1ae1ff5 100644
--- a/tests/crashes/135128.rs
+++ b/tests/crashes/135128.rs
@@ -1,6 +1,8 @@
 //@ known-bug: #135128
 //@ compile-flags: -Copt-level=1 --edition=2021
 
+#![feature(trivial_bounds)]
+
 async fn return_str() -> str
 where
     str: Sized,
diff --git a/tests/crashes/135570.rs b/tests/crashes/135570.rs
index a9eda97ef9d..7919ceb26d5 100644
--- a/tests/crashes/135570.rs
+++ b/tests/crashes/135570.rs
@@ -2,6 +2,9 @@
 //@compile-flags: -Zvalidate-mir -Zmir-enable-passes=+Inline -Copt-level=0 -Zmir-enable-passes=+GVN
 //@ only-x86_64
 
+#![feature(adt_const_params, unsized_const_params)]
+#![allow(incomplete_features)]
+
 fn function_with_bytes<const BYTES: &'static [u8; 0xc7b889180b67b07d_bc1a3c88783d35b5_u128]>(
 ) -> &'static [u8] {
     BYTES
diff --git a/tests/debuginfo/unsized.rs b/tests/debuginfo/unsized.rs
index acfe511be7c..17c5e463fba 100644
--- a/tests/debuginfo/unsized.rs
+++ b/tests/debuginfo/unsized.rs
@@ -18,12 +18,6 @@
 // gdb-command:print _box
 // gdb-check:$4 = alloc::boxed::Box<unsized::Foo<dyn core::fmt::Debug>, alloc::alloc::Global> {pointer: [...], vtable: [...]}
 
-// gdb-command:print tuple_slice
-// gdb-check:$5 = &(i32, i32, [i32]) {data_ptr: [...], length: 2}
-
-// gdb-command:print tuple_dyn
-// gdb-check:$6 = &(i32, i32, dyn core::fmt::Debug) {pointer: [...], vtable: [...]}
-
 // === CDB TESTS ===================================================================================
 
 // cdb-command: g
@@ -48,17 +42,6 @@
 // cdb-check:[+0x000] pointer          : 0x[...] [Type: unsized::Foo<dyn$<core::fmt::Debug> > *]
 // cdb-check:[...] vtable           : 0x[...] [Type: unsigned [...]int[...] (*)[4]]
 
-// cdb-command:dx tuple_slice
-// cdb-check:tuple_slice      [Type: ref$<tuple$<i32,i32,slice2$<i32> > >]
-// cdb-check:    [+0x000] data_ptr         : 0x[...] [Type: tuple$<i32,i32,slice2$<i32> > *]
-// cdb-check:    [...] length           : 0x2 [Type: unsigned [...]int[...]
-
-// cdb-command:dx tuple_dyn
-// cdb-check:tuple_dyn        [Type: ref$<tuple$<i32,i32,dyn$<core::fmt::Debug> > >]
-// cdb-check:    [+0x000] pointer          : 0x[...] [Type: tuple$<i32,i32,dyn$<core::fmt::Debug> > *]
-// cdb-check:    [...] vtable           : 0x[...] [Type: unsigned [...]int[...] (*)[4]]
-
-#![feature(unsized_tuple_coercion)]
 #![feature(omit_gdb_pretty_printer_section)]
 #![omit_gdb_pretty_printer_section]
 
@@ -77,10 +60,6 @@ fn main() {
     let c: &Foo<dyn std::fmt::Debug> = &Foo { value: 7i32 };
     let _box: Box<Foo<dyn std::fmt::Debug>> = Box::new(Foo { value: 8i32 });
 
-    // Also check unsized tuples
-    let tuple_slice: &(i32, i32, [i32]) = &(0, 1, [2, 3]);
-    let tuple_dyn: &(i32, i32, dyn std::fmt::Debug) = &(0, 1, &3u64);
-
     zzz(); // #break
 }
 
diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff
index 757617e5940..0615f8132af 100644
--- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-abort.diff
@@ -7,23 +7,42 @@
       let mut _0: ();
       let mut _3: &mut std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>;
       let mut _4: I;
++     scope 1 (inlined <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut) {
++         let mut _5: &mut dyn std::ops::FnMut<I, Output = ()>;
++         let mut _6: std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>;
++         let mut _7: *const dyn std::ops::FnMut<I, Output = ()>;
++     }
   
       bb0: {
           StorageLive(_3);
           _3 = &mut _1;
           StorageLive(_4);
           _4 = move _2;
-          _0 = <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut(move _3, move _4) -> [return: bb1, unwind unreachable];
+-         _0 = <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut(move _3, move _4) -> [return: bb1, unwind unreachable];
++         StorageLive(_6);
++         StorageLive(_7);
++         StorageLive(_5);
++         _6 = copy (*_3);
++         _7 = copy ((_6.0: std::ptr::Unique<dyn std::ops::FnMut<I, Output = ()>>).0: std::ptr::NonNull<dyn std::ops::FnMut<I, Output = ()>>) as *const dyn std::ops::FnMut<I, Output = ()> (Transmute);
++         _5 = &mut (*_7);
++         _0 = <dyn FnMut<I, Output = ()> as FnMut<I>>::call_mut(move _5, move _4) -> [return: bb2, unwind unreachable];
       }
   
       bb1: {
-          StorageDead(_4);
-          StorageDead(_3);
-          drop(_1) -> [return: bb2, unwind unreachable];
+-         StorageDead(_4);
+-         StorageDead(_3);
+-         drop(_1) -> [return: bb2, unwind unreachable];
++         return;
       }
   
       bb2: {
-          return;
+-         return;
++         StorageDead(_5);
++         StorageDead(_7);
++         StorageDead(_6);
++         StorageDead(_4);
++         StorageDead(_3);
++         drop(_1) -> [return: bb1, unwind unreachable];
       }
   }
   
diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff
index b82961c2815..21b20329d4f 100644
--- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.call.Inline.panic-unwind.diff
@@ -7,31 +7,54 @@
       let mut _0: ();
       let mut _3: &mut std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>;
       let mut _4: I;
++     scope 1 (inlined <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut) {
++         let mut _5: &mut dyn std::ops::FnMut<I, Output = ()>;
++         let mut _6: std::boxed::Box<dyn std::ops::FnMut<I, Output = ()>>;
++         let mut _7: *const dyn std::ops::FnMut<I, Output = ()>;
++     }
   
       bb0: {
           StorageLive(_3);
           _3 = &mut _1;
           StorageLive(_4);
           _4 = move _2;
-          _0 = <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut(move _3, move _4) -> [return: bb1, unwind: bb3];
+-         _0 = <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut(move _3, move _4) -> [return: bb1, unwind: bb3];
++         StorageLive(_6);
++         StorageLive(_7);
++         StorageLive(_5);
++         _6 = copy (*_3);
++         _7 = copy ((_6.0: std::ptr::Unique<dyn std::ops::FnMut<I, Output = ()>>).0: std::ptr::NonNull<dyn std::ops::FnMut<I, Output = ()>>) as *const dyn std::ops::FnMut<I, Output = ()> (Transmute);
++         _5 = &mut (*_7);
++         _0 = <dyn FnMut<I, Output = ()> as FnMut<I>>::call_mut(move _5, move _4) -> [return: bb4, unwind: bb2];
       }
   
       bb1: {
-          StorageDead(_4);
-          StorageDead(_3);
-          drop(_1) -> [return: bb2, unwind: bb4];
+-         StorageDead(_4);
+-         StorageDead(_3);
+-         drop(_1) -> [return: bb2, unwind: bb4];
++         return;
       }
   
-      bb2: {
-          return;
+-     bb2: {
+-         return;
++     bb2 (cleanup): {
++         drop(_1) -> [return: bb3, unwind terminate(cleanup)];
       }
   
       bb3 (cleanup): {
-          drop(_1) -> [return: bb4, unwind terminate(cleanup)];
+-         drop(_1) -> [return: bb4, unwind terminate(cleanup)];
++         resume;
       }
   
-      bb4 (cleanup): {
-          resume;
+-     bb4 (cleanup): {
+-         resume;
++     bb4: {
++         StorageDead(_5);
++         StorageDead(_7);
++         StorageDead(_6);
++         StorageDead(_4);
++         StorageDead(_3);
++         drop(_1) -> [return: bb1, unwind: bb3];
       }
   }
   
diff --git a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs
index abc0ef5c61d..ac0c3ddac76 100644
--- a/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs
+++ b/tests/mir-opt/inline/dont_ice_on_generic_rust_call.rs
@@ -8,6 +8,6 @@ use std::marker::Tuple;
 // EMIT_MIR dont_ice_on_generic_rust_call.call.Inline.diff
 pub fn call<I: Tuple>(mut mock: Box<dyn FnMut<I, Output = ()>>, input: I) {
     // CHECK-LABEL: fn call(
-    // CHECK-NOT: inlined
+    // CHECK: (inlined <Box<dyn FnMut<I, Output = ()>> as FnMut<I>>::call_mut)
     mock.call_mut(input)
 }
diff --git a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff
index 4fa04b05e89..ecea7a97513 100644
--- a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-abort.diff
@@ -7,6 +7,11 @@
       let _2: ();
       let mut _3: &std::boxed::Box<dyn std::ops::Fn(i32)>;
       let mut _4: (i32,);
++     scope 1 (inlined <Box<dyn Fn(i32)> as Fn<(i32,)>>::call) {
++         let mut _5: &dyn std::ops::Fn(i32);
++         let mut _6: std::boxed::Box<dyn std::ops::Fn(i32)>;
++         let mut _7: *const dyn std::ops::Fn(i32);
++     }
   
       bb0: {
           StorageLive(_2);
@@ -14,19 +19,34 @@
           _3 = &_1;
           StorageLive(_4);
           _4 = (const 1_i32,);
-          _2 = <Box<dyn Fn(i32)> as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind unreachable];
+-         _2 = <Box<dyn Fn(i32)> as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind unreachable];
++         StorageLive(_6);
++         StorageLive(_7);
++         StorageLive(_5);
++         _6 = copy (*_3);
++         _7 = copy ((_6.0: std::ptr::Unique<dyn std::ops::Fn(i32)>).0: std::ptr::NonNull<dyn std::ops::Fn(i32)>) as *const dyn std::ops::Fn(i32) (Transmute);
++         _5 = &(*_7);
++         _2 = <dyn Fn(i32) as Fn<(i32,)>>::call(move _5, move _4) -> [return: bb2, unwind unreachable];
       }
   
       bb1: {
++         return;
++     }
++ 
++     bb2: {
++         StorageDead(_5);
++         StorageDead(_7);
++         StorageDead(_6);
           StorageDead(_4);
           StorageDead(_3);
           StorageDead(_2);
           _0 = const ();
-          drop(_1) -> [return: bb2, unwind unreachable];
-      }
-  
-      bb2: {
-          return;
+-         drop(_1) -> [return: bb2, unwind unreachable];
+-     }
+- 
+-     bb2: {
+-         return;
++         drop(_1) -> [return: bb1, unwind unreachable];
       }
   }
   
diff --git a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff
index 47fd0ed0799..3a4a528e879 100644
--- a/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_box_fn.call.Inline.panic-unwind.diff
@@ -7,6 +7,11 @@
       let _2: ();
       let mut _3: &std::boxed::Box<dyn std::ops::Fn(i32)>;
       let mut _4: (i32,);
++     scope 1 (inlined <Box<dyn Fn(i32)> as Fn<(i32,)>>::call) {
++         let mut _5: &dyn std::ops::Fn(i32);
++         let mut _6: std::boxed::Box<dyn std::ops::Fn(i32)>;
++         let mut _7: *const dyn std::ops::Fn(i32);
++     }
   
       bb0: {
           StorageLive(_2);
@@ -14,27 +19,47 @@
           _3 = &_1;
           StorageLive(_4);
           _4 = (const 1_i32,);
-          _2 = <Box<dyn Fn(i32)> as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind: bb3];
+-         _2 = <Box<dyn Fn(i32)> as Fn<(i32,)>>::call(move _3, move _4) -> [return: bb1, unwind: bb3];
++         StorageLive(_6);
++         StorageLive(_7);
++         StorageLive(_5);
++         _6 = copy (*_3);
++         _7 = copy ((_6.0: std::ptr::Unique<dyn std::ops::Fn(i32)>).0: std::ptr::NonNull<dyn std::ops::Fn(i32)>) as *const dyn std::ops::Fn(i32) (Transmute);
++         _5 = &(*_7);
++         _2 = <dyn Fn(i32) as Fn<(i32,)>>::call(move _5, move _4) -> [return: bb4, unwind: bb2];
       }
   
       bb1: {
-          StorageDead(_4);
-          StorageDead(_3);
-          StorageDead(_2);
-          _0 = const ();
-          drop(_1) -> [return: bb2, unwind: bb4];
+-         StorageDead(_4);
+-         StorageDead(_3);
+-         StorageDead(_2);
+-         _0 = const ();
+-         drop(_1) -> [return: bb2, unwind: bb4];
++         return;
       }
   
-      bb2: {
-          return;
+-     bb2: {
+-         return;
++     bb2 (cleanup): {
++         drop(_1) -> [return: bb3, unwind terminate(cleanup)];
       }
   
       bb3 (cleanup): {
-          drop(_1) -> [return: bb4, unwind terminate(cleanup)];
+-         drop(_1) -> [return: bb4, unwind terminate(cleanup)];
++         resume;
       }
   
-      bb4 (cleanup): {
-          resume;
+-     bb4 (cleanup): {
+-         resume;
++     bb4: {
++         StorageDead(_5);
++         StorageDead(_7);
++         StorageDead(_6);
++         StorageDead(_4);
++         StorageDead(_3);
++         StorageDead(_2);
++         _0 = const ();
++         drop(_1) -> [return: bb1, unwind: bb3];
       }
   }
   
diff --git a/tests/mir-opt/inline/inline_box_fn.rs b/tests/mir-opt/inline/inline_box_fn.rs
index bb2da3ac515..e9ab3bef01f 100644
--- a/tests/mir-opt/inline/inline_box_fn.rs
+++ b/tests/mir-opt/inline/inline_box_fn.rs
@@ -5,6 +5,6 @@
 // EMIT_MIR inline_box_fn.call.Inline.diff
 fn call(x: Box<dyn Fn(i32)>) {
     // CHECK-LABEL: fn call(
-    // CHECK-NOT: inlined
+    // CHECK: (inlined <Box<dyn Fn(i32)> as Fn<(i32,)>>::call)
     x(1);
 }
diff --git a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff
index 8a6eec3352a..c878b8b6324 100644
--- a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-abort.diff
@@ -5,9 +5,15 @@
       let mut _0: ();
       let _1: ();
 +     let mut _2: fn() {f};
++     let mut _4: ();
 +     scope 1 (inlined call::<fn() {f}>) {
 +         debug f => _2;
 +         let _3: ();
++         scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) {
++             scope 3 (inlined f) {
++                 let _5: ();
++             }
++         }
 +     }
   
       bb0: {
@@ -16,10 +22,15 @@
 +         StorageLive(_2);
 +         _2 = f;
 +         StorageLive(_3);
-+         _3 = <fn() {f} as FnOnce<()>>::call_once(move _2, const ()) -> [return: bb1, unwind unreachable];
++         StorageLive(_4);
++         _4 = const ();
++         StorageLive(_5);
++         _5 = call::<fn() {f}>(f) -> [return: bb1, unwind unreachable];
       }
   
       bb1: {
++         StorageDead(_5);
++         StorageDead(_4);
 +         StorageDead(_3);
 +         StorageDead(_2);
           StorageDead(_1);
diff --git a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff
index a24649c1ebd..072b7ab3fa4 100644
--- a/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_cycle.two.Inline.panic-unwind.diff
@@ -5,9 +5,15 @@
       let mut _0: ();
       let _1: ();
 +     let mut _2: fn() {f};
++     let mut _4: ();
 +     scope 1 (inlined call::<fn() {f}>) {
 +         debug f => _2;
 +         let _3: ();
++         scope 2 (inlined <fn() {f} as FnOnce<()>>::call_once - shim(fn() {f})) {
++             scope 3 (inlined f) {
++                 let _5: ();
++             }
++         }
 +     }
   
       bb0: {
@@ -16,10 +22,15 @@
 +         StorageLive(_2);
 +         _2 = f;
 +         StorageLive(_3);
-+         _3 = <fn() {f} as FnOnce<()>>::call_once(move _2, const ()) -> [return: bb1, unwind continue];
++         StorageLive(_4);
++         _4 = const ();
++         StorageLive(_5);
++         _5 = call::<fn() {f}>(f) -> [return: bb1, unwind continue];
       }
   
       bb1: {
++         StorageDead(_5);
++         StorageDead(_4);
 +         StorageDead(_3);
 +         StorageDead(_2);
           StorageDead(_1);
diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff
index 338dca85e5c..75fc2ea16e3 100644
--- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff
@@ -5,6 +5,7 @@
       let mut _0: ();
       let _1: (!, !);
 +     let mut _2: fn() -> ! {sleep};
++     let mut _7: ();
 +     scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) {
 +         debug f => _2;
 +         let mut _3: &fn() -> ! {sleep};
@@ -17,6 +18,10 @@
 +                 debug b => _6;
 +             }
 +         }
++         scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) {
++             scope 5 (inlined sleep) {
++             }
++         }
 +     }
   
       bb0: {
@@ -28,24 +33,13 @@
 +         StorageLive(_6);
 +         StorageLive(_3);
 +         _3 = &_2;
-+         _4 = <fn() -> ! {sleep} as Fn<()>>::call(move _3, const ()) -> [return: bb1, unwind unreachable];
++         StorageLive(_7);
++         _7 = const ();
++         goto -> bb1;
 +     }
 + 
 +     bb1: {
-+         StorageDead(_3);
-+         StorageLive(_5);
-+         _5 = &_2;
-+         _6 = <fn() -> ! {sleep} as Fn<()>>::call(move _5, const ()) -> [return: bb2, unwind unreachable];
-+     }
-+ 
-+     bb2: {
-+         StorageDead(_5);
-+         _1 = (copy _4, copy _6);
-+         drop(_2) -> [return: bb3, unwind unreachable];
-+     }
-+ 
-+     bb3: {
-+         unreachable;
++         goto -> bb1;
       }
   }
   
diff --git a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
index a77cb913bfd..407cb24df67 100644
--- a/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff
@@ -5,6 +5,7 @@
       let mut _0: ();
       let _1: (!, !);
 +     let mut _2: fn() -> ! {sleep};
++     let mut _8: ();
 +     scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) {
 +         debug f => _2;
 +         let mut _3: &fn() -> ! {sleep};
@@ -18,6 +19,10 @@
 +                 debug b => _6;
 +             }
 +         }
++         scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) {
++             scope 5 (inlined sleep) {
++             }
++         }
 +     }
   
       bb0: {
@@ -29,40 +34,13 @@
 +         StorageLive(_4);
 +         StorageLive(_3);
 +         _3 = &_2;
-+         _4 = <fn() -> ! {sleep} as Fn<()>>::call(move _3, const ()) -> [return: bb1, unwind: bb5];
++         StorageLive(_8);
++         _8 = const ();
++         goto -> bb1;
 +     }
 + 
 +     bb1: {
-+         StorageDead(_3);
-+         StorageLive(_5);
-+         _5 = &_2;
-+         _6 = <fn() -> ! {sleep} as Fn<()>>::call(move _5, const ()) -> [return: bb2, unwind: bb4];
-+     }
-+ 
-+     bb2: {
-+         StorageDead(_5);
-+         StorageLive(_7);
-+         _7 = move _4;
-+         _1 = (move _7, copy _6);
-+         StorageDead(_7);
-+         StorageDead(_4);
-+         drop(_2) -> [return: bb3, unwind continue];
-+     }
-+ 
-+     bb3: {
-+         unreachable;
-+     }
-+ 
-+     bb4 (cleanup): {
-+         drop(_4) -> [return: bb5, unwind terminate(cleanup)];
-+     }
-+ 
-+     bb5 (cleanup): {
-+         drop(_2) -> [return: bb6, unwind terminate(cleanup)];
-+     }
-+ 
-+     bb6 (cleanup): {
-+         resume;
++         goto -> bb1;
       }
   }
   
diff --git a/tests/mir-opt/inline/inline_diverging.rs b/tests/mir-opt/inline/inline_diverging.rs
index e1cea3618f1..04ff943e746 100644
--- a/tests/mir-opt/inline/inline_diverging.rs
+++ b/tests/mir-opt/inline/inline_diverging.rs
@@ -26,7 +26,8 @@ pub fn g(i: i32) -> u32 {
 pub fn h() {
     // CHECK-LABEL: fn h(
     // CHECK: (inlined call_twice::<!, fn() -> ! {sleep}>)
-    // CHECK-NOT: inlined
+    // CHECK: (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep}))
+    // CHECK: (inlined sleep)
     call_twice(sleep);
 }
 
diff --git a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff
index b9f268df351..14a0c639c3a 100644
--- a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-abort.diff
@@ -10,6 +10,10 @@
       let mut _5: ();
 +     scope 1 (inlined hide_foo) {
 +     }
++     scope 2 (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo})) {
++         scope 3 (inlined foo) {
++         }
++     }
   
       bb0: {
           StorageLive(_2);
@@ -23,22 +27,20 @@
           StorageLive(_5);
           _5 = ();
 -         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind unreachable];
-+         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb1, unwind unreachable];
-      }
-  
+-     }
+- 
 -     bb2: {
-+     bb1: {
           StorageDead(_5);
           StorageDead(_3);
           StorageDead(_4);
           StorageDead(_2);
           _0 = const ();
 -         drop(_1) -> [return: bb3, unwind unreachable];
-+         drop(_1) -> [return: bb2, unwind unreachable];
++         drop(_1) -> [return: bb1, unwind unreachable];
       }
   
 -     bb3: {
-+     bb2: {
++     bb1: {
           return;
       }
   }
diff --git a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff
index 8495164df9c..e0a273eb13f 100644
--- a/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/issue_78442.bar.Inline.panic-unwind.diff
@@ -10,6 +10,10 @@
       let mut _5: ();
 +     scope 1 (inlined hide_foo) {
 +     }
++     scope 2 (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo})) {
++         scope 3 (inlined foo) {
++         }
++     }
   
       bb0: {
           StorageLive(_2);
@@ -23,33 +27,29 @@
           StorageLive(_5);
           _5 = ();
 -         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4];
-+         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb1, unwind: bb3];
-      }
-  
+-     }
+- 
 -     bb2: {
-+     bb1: {
           StorageDead(_5);
           StorageDead(_3);
           StorageDead(_4);
           StorageDead(_2);
           _0 = const ();
 -         drop(_1) -> [return: bb3, unwind: bb5];
-+         drop(_1) -> [return: bb2, unwind: bb4];
++         drop(_1) -> [return: bb1, unwind: bb2];
       }
   
 -     bb3: {
-+     bb2: {
++     bb1: {
           return;
       }
   
 -     bb4 (cleanup): {
 -         drop(_1) -> [return: bb5, unwind terminate(cleanup)];
-+     bb3 (cleanup): {
-+         drop(_1) -> [return: bb4, unwind terminate(cleanup)];
-      }
-  
+-     }
+- 
 -     bb5 (cleanup): {
-+     bb4 (cleanup): {
++     bb2 (cleanup): {
           resume;
       }
   }
diff --git a/tests/mir-opt/inline/issue_78442.rs b/tests/mir-opt/inline/issue_78442.rs
index 4eb5c142034..a142d457377 100644
--- a/tests/mir-opt/inline/issue_78442.rs
+++ b/tests/mir-opt/inline/issue_78442.rs
@@ -9,10 +9,9 @@ pub fn bar<P>(
     _baz: P,
 ) {
     // CHECK-LABEL: fn bar(
-    // CHECK: let mut {{.*}}: &fn() {foo};
-    // CHECK: let {{.*}}: fn() {foo};
     // CHECK: (inlined hide_foo)
-    // CHECK-NOT: inlined
+    // CHECK: (inlined <fn() {foo} as Fn<()>>::call - shim(fn() {foo}))
+    // CHECK: (inlined foo)
     hide_foo()();
 }
 
diff --git a/tests/mir-opt/inline_fn_call_for_fn_def.rs b/tests/mir-opt/inline_fn_call_for_fn_def.rs
new file mode 100644
index 00000000000..7601feda573
--- /dev/null
+++ b/tests/mir-opt/inline_fn_call_for_fn_def.rs
@@ -0,0 +1,19 @@
+//@ test-mir-pass: Inline
+//@ compile-flags: --crate-type=lib -C panic=abort
+
+// EMIT_MIR inline_fn_call_for_fn_def.test.Inline.diff
+
+fn inline_fn(x: impl FnOnce() -> i32) -> i32 {
+    x()
+}
+
+fn yield_number() -> i32 {
+    64
+}
+
+fn test() -> i32 {
+    // CHECK: (inlined inline_fn::<fn() -> i32 {yield_number}>)
+    // CHECK: (inlined <fn() -> i32 {yield_number} as FnOnce<()>>::call_once - shim(fn() -> i32 {yield_number}))
+    // CHECK: (inlined yield_number)
+    inline_fn(yield_number)
+}
diff --git a/tests/mir-opt/inline_fn_call_for_fn_def.test.Inline.diff b/tests/mir-opt/inline_fn_call_for_fn_def.test.Inline.diff
new file mode 100644
index 00000000000..aef7aa23970
--- /dev/null
+++ b/tests/mir-opt/inline_fn_call_for_fn_def.test.Inline.diff
@@ -0,0 +1,34 @@
+- // MIR for `test` before Inline
++ // MIR for `test` after Inline
+  
+  fn test() -> i32 {
+      let mut _0: i32;
+- 
+-     bb0: {
+-         _0 = inline_fn::<fn() -> i32 {yield_number}>(yield_number) -> [return: bb1, unwind unreachable];
++     let mut _1: fn() -> i32 {yield_number};
++     scope 1 (inlined inline_fn::<fn() -> i32 {yield_number}>) {
++         let mut _2: fn() -> i32 {yield_number};
++         let mut _3: ();
++         scope 2 (inlined <fn() -> i32 {yield_number} as FnOnce<()>>::call_once - shim(fn() -> i32 {yield_number})) {
++             scope 3 (inlined yield_number) {
++             }
++         }
+      }
+  
+-     bb1: {
++     bb0: {
++         StorageLive(_1);
++         _1 = yield_number;
++         StorageLive(_2);
++         _2 = move _1;
++         StorageLive(_3);
++         _3 = ();
++         _0 = const 64_i32;
++         StorageDead(_3);
++         StorageDead(_2);
++         StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir
index 5876c55c52b..5876c55c52b 100644
--- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-abort.mir
diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir
index f1185353a43..f1185353a43 100644
--- a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.32bit.panic-unwind.mir
diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir
new file mode 100644
index 00000000000..5876c55c52b
--- /dev/null
+++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-abort.mir
@@ -0,0 +1,68 @@
+// MIR for `num_to_digit` after PreCodegen
+
+fn num_to_digit(_1: char) -> u32 {
+    debug num => _1;
+    let mut _0: u32;
+    let mut _4: std::option::Option<u32>;
+    scope 1 (inlined char::methods::<impl char>::is_digit) {
+        let _2: std::option::Option<u32>;
+        scope 2 (inlined Option::<u32>::is_some) {
+            let mut _3: isize;
+        }
+    }
+    scope 3 (inlined #[track_caller] Option::<u32>::unwrap) {
+        let mut _5: isize;
+        let mut _6: !;
+        scope 4 {
+        }
+    }
+
+    bb0: {
+        StorageLive(_2);
+        _2 = char::methods::<impl char>::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind unreachable];
+    }
+
+    bb1: {
+        StorageLive(_3);
+        _3 = discriminant(_2);
+        StorageDead(_2);
+        switchInt(move _3) -> [1: bb2, otherwise: bb7];
+    }
+
+    bb2: {
+        StorageDead(_3);
+        StorageLive(_4);
+        _4 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb3, unwind unreachable];
+    }
+
+    bb3: {
+        StorageLive(_5);
+        _5 = discriminant(_4);
+        switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb6];
+    }
+
+    bb4: {
+        _6 = option::unwrap_failed() -> unwind unreachable;
+    }
+
+    bb5: {
+        _0 = move ((_4 as Some).0: u32);
+        StorageDead(_5);
+        StorageDead(_4);
+        goto -> bb8;
+    }
+
+    bb6: {
+        unreachable;
+    }
+
+    bb7: {
+        StorageDead(_3);
+        _0 = const 0_u32;
+        goto -> bb8;
+    }
+
+    bb8: {
+        return;
+    }
+}
diff --git a/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir
new file mode 100644
index 00000000000..f1185353a43
--- /dev/null
+++ b/tests/mir-opt/issues/issue_59352.num_to_digit.PreCodegen.after.64bit.panic-unwind.mir
@@ -0,0 +1,68 @@
+// MIR for `num_to_digit` after PreCodegen
+
+fn num_to_digit(_1: char) -> u32 {
+    debug num => _1;
+    let mut _0: u32;
+    let mut _4: std::option::Option<u32>;
+    scope 1 (inlined char::methods::<impl char>::is_digit) {
+        let _2: std::option::Option<u32>;
+        scope 2 (inlined Option::<u32>::is_some) {
+            let mut _3: isize;
+        }
+    }
+    scope 3 (inlined #[track_caller] Option::<u32>::unwrap) {
+        let mut _5: isize;
+        let mut _6: !;
+        scope 4 {
+        }
+    }
+
+    bb0: {
+        StorageLive(_2);
+        _2 = char::methods::<impl char>::to_digit(copy _1, const 8_u32) -> [return: bb1, unwind continue];
+    }
+
+    bb1: {
+        StorageLive(_3);
+        _3 = discriminant(_2);
+        StorageDead(_2);
+        switchInt(move _3) -> [1: bb2, otherwise: bb7];
+    }
+
+    bb2: {
+        StorageDead(_3);
+        StorageLive(_4);
+        _4 = char::methods::<impl char>::to_digit(move _1, const 8_u32) -> [return: bb3, unwind continue];
+    }
+
+    bb3: {
+        StorageLive(_5);
+        _5 = discriminant(_4);
+        switchInt(move _5) -> [0: bb4, 1: bb5, otherwise: bb6];
+    }
+
+    bb4: {
+        _6 = option::unwrap_failed() -> unwind continue;
+    }
+
+    bb5: {
+        _0 = move ((_4 as Some).0: u32);
+        StorageDead(_5);
+        StorageDead(_4);
+        goto -> bb8;
+    }
+
+    bb6: {
+        unreachable;
+    }
+
+    bb7: {
+        StorageDead(_3);
+        _0 = const 0_u32;
+        goto -> bb8;
+    }
+
+    bb8: {
+        return;
+    }
+}
diff --git a/tests/mir-opt/issues/issue_59352.rs b/tests/mir-opt/issues/issue_59352.rs
index 9024dc976e4..516a712f1db 100644
--- a/tests/mir-opt/issues/issue_59352.rs
+++ b/tests/mir-opt/issues/issue_59352.rs
@@ -1,4 +1,6 @@
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+
 // 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
 // as effectively `if x.is_some() { x.unwrap() } else { 0 }`.
diff --git a/tests/mir-opt/pattern_types.main.PreCodegen.after.mir b/tests/mir-opt/pattern_types.main.PreCodegen.after.mir
index 5ff90de9615..cc01f51973c 100644
--- a/tests/mir-opt/pattern_types.main.PreCodegen.after.mir
+++ b/tests/mir-opt/pattern_types.main.PreCodegen.after.mir
@@ -3,9 +3,9 @@
 fn main() -> () {
     let mut _0: ();
     scope 1 {
-        debug x => const 2_u32 is 1..=;
+        debug x => const 2_u32 is 1..;
         scope 2 {
-            debug y => const {transmute(0x00000000): (u32) is 1..=};
+            debug y => const {transmute(0x00000000): (u32) is 1..};
         }
     }
 
diff --git a/tests/mir-opt/pattern_types.rs b/tests/mir-opt/pattern_types.rs
index 0369ccf9a9d..d5847b95f73 100644
--- a/tests/mir-opt/pattern_types.rs
+++ b/tests/mir-opt/pattern_types.rs
@@ -5,8 +5,8 @@ use std::pat::pattern_type;
 
 // EMIT_MIR pattern_types.main.PreCodegen.after.mir
 fn main() {
-    // CHECK: debug x => const 2_u32 is 1..=
+    // CHECK: debug x => const 2_u32 is 1..
     let x: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(2) };
-    // CHECK: debug y => const {transmute(0x00000000): (u32) is 1..=}
+    // CHECK: debug y => const {transmute(0x00000000): (u32) is 1..}
     let y: pattern_type!(u32 is 1..) = unsafe { std::mem::transmute(0) };
 }
diff --git a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
index 4977f39ccef..d22ea54004c 100644
--- a/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.mapped.PreCodegen.after.mir
@@ -29,6 +29,10 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
                 let mut _12: U;
                 scope 6 {
                     debug x => _10;
+                    scope 7 (inlined ops::function::impls::<impl FnOnce<(T,)> for &mut impl Fn(T) -> U>::call_once) {
+                        debug self => _8;
+                        debug args => _11;
+                    }
                 }
             }
         }
@@ -85,7 +89,7 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
         StorageLive(_12);
         StorageLive(_11);
         _11 = (copy _10,);
-        _12 = <&mut impl Fn(T) -> U as FnOnce<(T,)>>::call_once(move _8, move _11) -> [return: bb7, unwind: bb10];
+        _12 = <impl Fn(T) -> U as FnMut<(T,)>>::call_mut(move _8, move _11) -> [return: bb7, unwind: bb10];
     }
 
     bb7: {
diff --git a/tests/pretty/pin-ergonomics.rs b/tests/pretty/pin-ergonomics.rs
new file mode 100644
index 00000000000..47ffc97b118
--- /dev/null
+++ b/tests/pretty/pin-ergonomics.rs
@@ -0,0 +1,24 @@
+//@ pp-exact
+
+#![feature(pin_ergonomics)]
+#![allow(dead_code, incomplete_features)]
+
+struct Foo;
+
+impl Foo {
+    fn baz(&pin mut self) {}
+
+    fn baz_const(&pin const self) {}
+
+    fn baz_lt<'a>(&'a pin mut self) {}
+
+    fn baz_const_lt(&'_ pin const self) {}
+}
+
+fn foo(_: &pin mut Foo) {}
+fn foo_lt<'a>(_: &'a pin mut Foo) {}
+
+fn foo_const(_: &pin const Foo) {}
+fn foo_const_lt(_: &'_ pin const Foo) {}
+
+fn main() {}
diff --git a/tests/run-make/README.md b/tests/run-make/README.md
index 40359903473..5cdd2fdc523 100644
--- a/tests/run-make/README.md
+++ b/tests/run-make/README.md
@@ -1,32 +1,17 @@
 # The `run-make` test suite
 
-The `run-make` test suite contains tests which are the most flexible out of all
-the [rust-lang/rust](https://github.com/rust-lang/rust) test suites. `run-make`
-tests can basically contain arbitrary code, and are supported by the
-[`run_make_support`] library.
+The `run-make` test suite contains tests which are the most flexible out of all the [rust-lang/rust](https://github.com/rust-lang/rust) test suites. `run-make` tests can basically contain arbitrary code, and are supported by the [`run_make_support`] library.
 
 ## Infrastructure
 
-There are two kinds of run-make tests:
+A `run-make` test is a test recipe source file `rmake.rs` accompanied by its parent directory (e.g. `tests/run-make/foo/rmake.rs` is the `foo` `run-make` test).
 
-1. The new `rmake.rs` version: this allows run-make tests to be written in Rust
-   (with `rmake.rs` as the main test file).
-2. The legacy `Makefile` version: this is what run-make tests were written with
-   before support for `rmake.rs` was introduced.
+The implementation for collecting and building the `rmake.rs` recipes are in [`src/tools/compiletest/src/runtest.rs`](../../src/tools/compiletest/src/runtest.rs), in `run_rmake_test`.
 
-The implementation for collecting and building the `rmake.rs` recipes (or
-`Makefile`s) are in
-[`src/tools/compiletest/src/runtest.rs`](../../src/tools/compiletest/src/runtest.rs),
-in `run_rmake_v2_test` and `run_rmake_legacy_test`.
-
-### Rust-based `run-make` tests: `rmake.rs`
-
-The setup for the `rmake.rs` version is a 3-stage process:
+The setup for the `rmake.rs` can be summarized as a 3-stage process:
 
 1. First, we build the [`run_make_support`] library in bootstrap as a tool lib.
-2. Then, we compile the `rmake.rs` "recipe" linking the support library and its
-   dependencies in, and provide a bunch of env vars. We setup a directory
-   structure within `build/<target>/test/run-make/`
+2. Then, we compile the `rmake.rs` "recipe" linking the support library and its dependencies in, and provide a bunch of env vars. We setup a directory structure within `build/<target>/test/run-make/`
 
    ```
    <test-name>/
@@ -34,15 +19,8 @@ The setup for the `rmake.rs` version is a 3-stage process:
        rmake_out/             # sources from test sources copied over
    ```
 
-   and copy non-`rmake.rs` input support files over to `rmake_out/`. The
-   support library is made available as an [*extern prelude*][extern_prelude].
-3. Finally, we run the recipe binary and set `rmake_out/` as the working
-   directory.
+   and copy non-`rmake.rs` input support files over to `rmake_out/`. The support library is made available as an [*extern prelude*][extern_prelude].
+3. Finally, we run the recipe binary and set `rmake_out/` as the working directory.
 
 [`run_make_support`]: ../../src/tools/run-make-support
 [extern_prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude
-
-### Formatting
-
-Note that files under `tests/` are not formatted by `./x fmt`,
-use `rustfmt tests/path/to/file.rs` to format a specific file if desired.
diff --git a/tests/run-make/a-b-a-linker-guard/rmake.rs b/tests/run-make/a-b-a-linker-guard/rmake.rs
index ee6d655bc76..4428685a6cf 100644
--- a/tests/run-make/a-b-a-linker-guard/rmake.rs
+++ b/tests/run-make/a-b-a-linker-guard/rmake.rs
@@ -1,7 +1,8 @@
-// ignore-tidy-linelength
+// Test that if we build `b` against a version of `a` that has
+// one set of types, it will not run with a dylib that has a different set of types.
 
-// Test that if we build `b` against a version of `a` that has one set of types, it will not run
-// with a dylib that has a different set of types.
+//@ ignore-cross-compile
+// Reason: the compiled binary is executed
 
 use run_make_support::{run, run_fail, rustc};
 
diff --git a/tests/run-make/linker-warning/rmake.rs b/tests/run-make/linker-warning/rmake.rs
index 30387af428c..73ad248b6f3 100644
--- a/tests/run-make/linker-warning/rmake.rs
+++ b/tests/run-make/linker-warning/rmake.rs
@@ -60,6 +60,8 @@ fn main() {
                 regex::escape(run_make_support::build_root().to_str().unwrap()),
                 "/build-root",
             )
+            .normalize(r#""[^"]*\/symbols.o""#, "\"/symbols.o\"")
+            .normalize(r#""[^"]*\/raw-dylibs""#, "\"/raw-dylibs\"")
             .run();
     }
 
diff --git a/tests/run-make/linker-warning/short-error.txt b/tests/run-make/linker-warning/short-error.txt
index dd3b742bbfd..a7f48af885a 100644
--- a/tests/run-make/linker-warning/short-error.txt
+++ b/tests/run-make/linker-warning/short-error.txt
@@ -1,6 +1,6 @@
 error: linking with `./fake-linker` failed: exit status: 1
   |
-  = note:  "./fake-linker" "-m64" "/tmp/rustc/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*,liballoc-*,librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/build-root/test/run-make/linker-warning/rmake_out" "-L" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error"
+  = note:  "./fake-linker" "-m64" "/symbols.o" "<2 object files omitted>" "-Wl,--as-needed" "-Wl,-Bstatic" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib/{libstd-*,libpanic_unwind-*,libobject-*,libmemchr-*,libaddr2line-*,libgimli-*,librustc_demangle-*,libstd_detect-*,libhashbrown-*,librustc_std_workspace_alloc-*,libminiz_oxide-*,libadler2-*,libunwind-*,libcfg_if-*,liblibc-*,liballoc-*,librustc_std_workspace_core-*,libcore-*,libcompiler_builtins-*}.rlib" "-Wl,-Bdynamic" "-lgcc_s" "-lutil" "-lrt" "-lpthread" "-lm" "-ldl" "-lc" "-L" "/raw-dylibs" "-Wl,--eh-frame-hdr" "-Wl,-z,noexecstack" "-L" "/build-root/test/run-make/linker-warning/rmake_out" "-L" "<sysroot>/lib/rustlib/x86_64-unknown-linux-gnu/lib" "-o" "main" "-Wl,--gc-sections" "-pie" "-Wl,-z,relro,-z,now" "-nodefaultlibs" "run_make_error"
   = note: some arguments are omitted. use `--verbose` to show all linker arguments
   = note: error: baz
           
diff --git a/tests/run-make/raw-dylib-elf-verbatim-absolute/main.rs b/tests/run-make/raw-dylib-elf-verbatim-absolute/main.rs
new file mode 100644
index 00000000000..75bd7747f4f
--- /dev/null
+++ b/tests/run-make/raw-dylib-elf-verbatim-absolute/main.rs
@@ -0,0 +1,11 @@
+#![feature(raw_dylib_elf)]
+#![allow(incomplete_features)]
+
+#[link(name = "/absolute-path/liblibrary.so.1", kind = "raw-dylib", modifiers = "+verbatim")]
+unsafe extern "C" {
+    safe fn this_is_a_library_function() -> core::ffi::c_int;
+}
+
+fn main() {
+    println!("{}", this_is_a_library_function())
+}
diff --git a/tests/run-make/raw-dylib-elf-verbatim-absolute/output.txt b/tests/run-make/raw-dylib-elf-verbatim-absolute/output.txt
new file mode 100644
index 00000000000..d81cc0710eb
--- /dev/null
+++ b/tests/run-make/raw-dylib-elf-verbatim-absolute/output.txt
@@ -0,0 +1 @@
+42
diff --git a/tests/run-make/raw-dylib-elf-verbatim-absolute/rmake.rs b/tests/run-make/raw-dylib-elf-verbatim-absolute/rmake.rs
new file mode 100644
index 00000000000..d2a9b0477e5
--- /dev/null
+++ b/tests/run-make/raw-dylib-elf-verbatim-absolute/rmake.rs
@@ -0,0 +1,20 @@
+//@ only-elf
+//@ ignore-cross-compile: Runs a binary.
+//@ needs-dynamic-linking
+// FIXME(raw_dylib_elf): Debug the failures on other targets.
+//@ only-gnu
+//@ only-x86_64
+
+//! Ensure ELF raw-dylib is able to link against a non-existent verbatim absolute path
+//! by embedding the absolute path in the DT_SONAME and passing a different path for
+//! the linker for the stub.
+
+use run_make_support::{build_native_dynamic_lib, cwd, diff, rfs, run, rustc};
+
+fn main() {
+    // We compile the binary without having the library present.
+    // The verbatim library name is an absolute path.
+    rustc().crate_type("bin").input("main.rs").run();
+
+    // FIXME(raw_dylib_elf): Read the NEEDED of the library to ensure it's the absolute path.
+}
diff --git a/tests/run-make/raw-dylib-elf-verbatim/library.c b/tests/run-make/raw-dylib-elf-verbatim/library.c
new file mode 100644
index 00000000000..2e3a95b7ede
--- /dev/null
+++ b/tests/run-make/raw-dylib-elf-verbatim/library.c
@@ -0,0 +1,3 @@
+int this_is_a_library_function() {
+    return 42;
+}
diff --git a/tests/run-make/raw-dylib-elf-verbatim/main.rs b/tests/run-make/raw-dylib-elf-verbatim/main.rs
new file mode 100644
index 00000000000..044b7400a84
--- /dev/null
+++ b/tests/run-make/raw-dylib-elf-verbatim/main.rs
@@ -0,0 +1,11 @@
+#![feature(raw_dylib_elf)]
+#![allow(incomplete_features)]
+
+#[link(name = "liblibrary.so.1", kind = "raw-dylib", modifiers = "+verbatim")]
+unsafe extern "C" {
+    safe fn this_is_a_library_function() -> core::ffi::c_int;
+}
+
+fn main() {
+    println!("{}", this_is_a_library_function())
+}
diff --git a/tests/run-make/raw-dylib-elf-verbatim/output.txt b/tests/run-make/raw-dylib-elf-verbatim/output.txt
new file mode 100644
index 00000000000..d81cc0710eb
--- /dev/null
+++ b/tests/run-make/raw-dylib-elf-verbatim/output.txt
@@ -0,0 +1 @@
+42
diff --git a/tests/run-make/raw-dylib-elf-verbatim/rmake.rs b/tests/run-make/raw-dylib-elf-verbatim/rmake.rs
new file mode 100644
index 00000000000..319534b24c8
--- /dev/null
+++ b/tests/run-make/raw-dylib-elf-verbatim/rmake.rs
@@ -0,0 +1,31 @@
+//@ only-elf
+//@ ignore-cross-compile: Runs a binary.
+//@ needs-dynamic-linking
+// FIXME(raw_dylib_elf): Debug the failures on other targets.
+//@ only-gnu
+//@ only-x86_64
+
+//! Ensure ELF raw-dylib is able to link against the verbatim versioned library
+//! without it being present, and then be executed against this library.
+
+use run_make_support::{build_native_dynamic_lib, cwd, diff, rfs, run, rustc};
+
+fn main() {
+    // We compile the binary without having the library present.
+    // We also set the rpath to the current directory so we can pick up the library at runtime.
+    rustc()
+        .crate_type("bin")
+        .input("main.rs")
+        .arg(&format!("-Wl,-rpath={}", cwd().display()))
+        .run();
+
+    // Now, *after* building the binary, we build the library...
+    build_native_dynamic_lib("library");
+    // ... rename it to have the versioned library name...
+    rfs::rename("liblibrary.so", "liblibrary.so.1");
+
+    // ... and run with this library, ensuring it was linked correctly at runtime.
+    let output = run("main").stdout_utf8();
+
+    diff().expected_file("output.txt").actual_text("actual", output).run();
+}
diff --git a/tests/run-make/raw-dylib-elf/library.c b/tests/run-make/raw-dylib-elf/library.c
new file mode 100644
index 00000000000..2e3a95b7ede
--- /dev/null
+++ b/tests/run-make/raw-dylib-elf/library.c
@@ -0,0 +1,3 @@
+int this_is_a_library_function() {
+    return 42;
+}
diff --git a/tests/run-make/raw-dylib-elf/main.rs b/tests/run-make/raw-dylib-elf/main.rs
new file mode 100644
index 00000000000..3be944d2951
--- /dev/null
+++ b/tests/run-make/raw-dylib-elf/main.rs
@@ -0,0 +1,11 @@
+#![feature(raw_dylib_elf)]
+#![allow(incomplete_features)]
+
+#[link(name = "library", kind = "raw-dylib")]
+unsafe extern "C" {
+    safe fn this_is_a_library_function() -> core::ffi::c_int;
+}
+
+fn main() {
+    println!("{}", this_is_a_library_function())
+}
diff --git a/tests/run-make/raw-dylib-elf/output.txt b/tests/run-make/raw-dylib-elf/output.txt
new file mode 100644
index 00000000000..d81cc0710eb
--- /dev/null
+++ b/tests/run-make/raw-dylib-elf/output.txt
@@ -0,0 +1 @@
+42
diff --git a/tests/run-make/raw-dylib-elf/rmake.rs b/tests/run-make/raw-dylib-elf/rmake.rs
new file mode 100644
index 00000000000..59f901ac1ed
--- /dev/null
+++ b/tests/run-make/raw-dylib-elf/rmake.rs
@@ -0,0 +1,29 @@
+//@ only-elf
+//@ ignore-cross-compile: Runs a binary.
+//@ needs-dynamic-linking
+// FIXME(raw_dylib_elf): Debug the failures on other targets.
+//@ only-gnu
+//@ only-x86_64
+
+//! Ensure ELF raw-dylib is able to link the binary without having the library present,
+//! and then successfully run against the real library.
+
+use run_make_support::{build_native_dynamic_lib, cwd, diff, run, rustc};
+
+fn main() {
+    // We compile the binary without having the library present.
+    // We also set the rpath to the current directory so we can pick up the library at runtime.
+    rustc()
+        .crate_type("bin")
+        .input("main.rs")
+        .arg(&format!("-Wl,-rpath={}", cwd().display()))
+        .run();
+
+    // Now, *after* building the binary, we build the library...
+    build_native_dynamic_lib("library");
+
+    // ... and run with this library, ensuring it was linked correctly at runtime.
+    let output = run("main").stdout_utf8();
+
+    diff().expected_file("output.txt").actual_text("actual", output).run();
+}
diff --git a/tests/run-make/repr128-dwarf/main.rs b/tests/run-make/repr128-dwarf/main.rs
index 57923a8386d..9842ab4a342 100644
--- a/tests/run-make/repr128-dwarf/main.rs
+++ b/tests/run-make/repr128-dwarf/main.rs
@@ -19,8 +19,33 @@ pub enum I128Enum {
     I128D = i128::MAX.to_le(),
 }
 
+#[cfg(not(old_llvm))]
+#[repr(u128)]
+pub enum U128VariantEnum {
+    VariantU128A(u8) = 0_u128.to_le(),
+    VariantU128B = 1_u128.to_le(),
+    VariantU128C = (u64::MAX as u128 + 1).to_le(),
+    VariantU128D = u128::MAX.to_le(),
+}
+
+#[cfg(not(old_llvm))]
+#[repr(i128)]
+pub enum I128VariantEnum {
+    VariantI128A(u8) = 0_i128.to_le(),
+    VariantI128B = (-1_i128).to_le(),
+    VariantI128C = i128::MIN.to_le(),
+    VariantI128D = i128::MAX.to_le(),
+}
+
 pub fn f(_: U128Enum, _: I128Enum) {}
 
+#[cfg(not(old_llvm))]
+pub fn g(_: U128VariantEnum, _: I128VariantEnum) {}
+
 fn main() {
     f(U128Enum::U128A, I128Enum::I128A);
+    #[cfg(not(old_llvm))]
+    {
+        g(U128VariantEnum::VariantU128A(1), I128VariantEnum::VariantI128A(2));
+    }
 }
diff --git a/tests/run-make/repr128-dwarf/rmake.rs b/tests/run-make/repr128-dwarf/rmake.rs
index 2fd54c186b9..15eb186717f 100644
--- a/tests/run-make/repr128-dwarf/rmake.rs
+++ b/tests/run-make/repr128-dwarf/rmake.rs
@@ -5,13 +5,32 @@ use std::collections::HashMap;
 use std::path::PathBuf;
 use std::rc::Rc;
 
+use gimli::read::DebuggingInformationEntry;
 use gimli::{AttributeValue, EndianRcSlice, Reader, RunTimeEndian};
 use object::{Object, ObjectSection};
 use run_make_support::{gimli, object, rfs, rustc};
 
 fn main() {
+    // Before LLVM 20, 128-bit enums with variants didn't emit debuginfo correctly.
+    // This check can be removed once Rust no longer supports LLVM 18 and 19.
+    let llvm_version = rustc()
+        .verbose()
+        .arg("--version")
+        .run()
+        .stdout_utf8()
+        .lines()
+        .filter_map(|line| line.strip_prefix("LLVM version: "))
+        .map(|version| version.split(".").next().unwrap().parse::<u32>().unwrap())
+        .next()
+        .unwrap();
+    let is_old_llvm = llvm_version < 20;
+
     let output = PathBuf::from("repr128");
-    rustc().input("main.rs").output(&output).arg("-Cdebuginfo=2").run();
+    let mut rustc = rustc();
+    if is_old_llvm {
+        rustc.cfg("old_llvm");
+    }
+    rustc.input("main.rs").output(&output).arg("-Cdebuginfo=2").run();
     // Mach-O uses packed debug info
     let dsym_location = output
         .with_extension("dSYM")
@@ -29,7 +48,8 @@ fn main() {
     })
     .unwrap();
     let mut iter = dwarf.units();
-    let mut still_to_find = HashMap::from([
+
+    let mut enumerators_to_find = HashMap::from([
         ("U128A", 0_u128),
         ("U128B", 1_u128),
         ("U128C", u64::MAX as u128 + 1),
@@ -39,35 +59,88 @@ fn main() {
         ("I128C", i128::MIN as u128),
         ("I128D", i128::MAX as u128),
     ]);
+    let mut variants_to_find = HashMap::from([
+        ("VariantU128A", 0_u128),
+        ("VariantU128B", 1_u128),
+        ("VariantU128C", u64::MAX as u128 + 1),
+        ("VariantU128D", u128::MAX),
+        ("VariantI128A", 0_i128 as u128),
+        ("VariantI128B", (-1_i128) as u128),
+        ("VariantI128C", i128::MIN as u128),
+        ("VariantI128D", i128::MAX as u128),
+    ]);
+
     while let Some(header) = iter.next().unwrap() {
         let unit = dwarf.unit(header).unwrap();
         let mut cursor = unit.entries();
+
+        let get_name = |entry: &DebuggingInformationEntry<'_, '_, _>| {
+            let name = dwarf
+                .attr_string(
+                    &unit,
+                    entry.attr(gimli::constants::DW_AT_name).unwrap().unwrap().value(),
+                )
+                .unwrap();
+            name.to_string().unwrap().to_string()
+        };
+
         while let Some((_, entry)) = cursor.next_dfs().unwrap() {
-            if entry.tag() == gimli::constants::DW_TAG_enumerator {
-                let name = dwarf
-                    .attr_string(
-                        &unit,
-                        entry.attr(gimli::constants::DW_AT_name).unwrap().unwrap().value(),
-                    )
-                    .unwrap();
-                let name = name.to_string().unwrap();
-                if let Some(expected) = still_to_find.remove(name.as_ref()) {
-                    match entry.attr(gimli::constants::DW_AT_const_value).unwrap().unwrap().value()
+            match entry.tag() {
+                gimli::constants::DW_TAG_variant if !is_old_llvm => {
+                    let value = match entry
+                        .attr(gimli::constants::DW_AT_discr_value)
+                        .unwrap()
+                        .unwrap()
+                        .value()
                     {
-                        AttributeValue::Block(value) => {
-                            assert_eq!(
-                                value.to_slice().unwrap(),
-                                expected.to_le_bytes().as_slice(),
-                                "{name}"
-                            );
+                        AttributeValue::Block(value) => value.to_slice().unwrap().to_vec(),
+                        value => panic!("unexpected DW_AT_discr_value of {value:?}"),
+                    };
+                    // The `DW_TAG_member` that is a child of `DW_TAG_variant` will contain the
+                    // variant's name.
+                    let Some((1, child_entry)) = cursor.next_dfs().unwrap() else {
+                        panic!("Missing child of DW_TAG_variant");
+                    };
+                    assert_eq!(child_entry.tag(), gimli::constants::DW_TAG_member);
+                    let name = get_name(child_entry);
+                    if let Some(expected) = variants_to_find.remove(name.as_str()) {
+                        // This test uses LE byte order is used for consistent values across
+                        // architectures.
+                        assert_eq!(value.as_slice(), expected.to_le_bytes().as_slice(), "{name}");
+                    }
+                }
+
+                gimli::constants::DW_TAG_enumerator => {
+                    let name = get_name(entry);
+                    if let Some(expected) = enumerators_to_find.remove(name.as_str()) {
+                        match entry
+                            .attr(gimli::constants::DW_AT_const_value)
+                            .unwrap()
+                            .unwrap()
+                            .value()
+                        {
+                            AttributeValue::Block(value) => {
+                                // This test uses LE byte order is used for consistent values across
+                                // architectures.
+                                assert_eq!(
+                                    value.to_slice().unwrap(),
+                                    expected.to_le_bytes().as_slice(),
+                                    "{name}"
+                                );
+                            }
+                            value => panic!("{name}: unexpected DW_AT_const_value of {value:?}"),
                         }
-                        value => panic!("{name}: unexpected DW_AT_const_value of {value:?}"),
                     }
                 }
+
+                _ => {}
             }
         }
     }
-    if !still_to_find.is_empty() {
-        panic!("Didn't find debug entries for {still_to_find:?}");
+    if !enumerators_to_find.is_empty() {
+        panic!("Didn't find debug enumerator entries for {enumerators_to_find:?}");
+    }
+    if !is_old_llvm && !variants_to_find.is_empty() {
+        panic!("Didn't find debug variant entries for {variants_to_find:?}");
     }
 }
diff --git a/tests/run-make/reproducible-build/linker.rs b/tests/run-make/reproducible-build/linker.rs
index ab3b4049cc3..2f57d9f9be9 100644
--- a/tests/run-make/reproducible-build/linker.rs
+++ b/tests/run-make/reproducible-build/linker.rs
@@ -17,6 +17,8 @@ fn main() {
     for arg in env::args().skip(1) {
         let path = Path::new(&arg);
         if !path.is_file() {
+            // This directory is produced during linking in a temporary directory (ELF only).
+            let arg = if arg.ends_with("/raw-dylibs") { "/raw-dylibs" } else { &*arg };
             out.push_str(&arg);
             out.push_str("\n");
             continue;
diff --git a/tests/run-make/rustc-help/help-v.stdout b/tests/run-make/rustc-help/help-v.stdout
index 382b1c96682..c8ea09ee2c8 100644
--- a/tests/run-make/rustc-help/help-v.stdout
+++ b/tests/run-make/rustc-help/help-v.stdout
@@ -29,7 +29,7 @@ Options:
         --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
                         Comma separated list of types of output for the
                         compiler to emit
-        --print [crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|target-list|target-cpus|target-features|relocation-models|code-models|tls-models|target-spec-json|all-target-specs-json|native-static-libs|stack-protector-strategies|link-args|deployment-target]
+        --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
                         Compiler information to print on stdout
     -g                  Equivalent to -C debuginfo=2
     -O                  Equivalent to -C opt-level=3
diff --git a/tests/run-make/rustc-help/help.stdout b/tests/run-make/rustc-help/help.stdout
index 08bb7f85098..434e71e901e 100644
--- a/tests/run-make/rustc-help/help.stdout
+++ b/tests/run-make/rustc-help/help.stdout
@@ -29,7 +29,7 @@ Options:
         --emit [asm|llvm-bc|llvm-ir|obj|metadata|link|dep-info|mir]
                         Comma separated list of types of output for the
                         compiler to emit
-        --print [crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|target-list|target-cpus|target-features|relocation-models|code-models|tls-models|target-spec-json|all-target-specs-json|native-static-libs|stack-protector-strategies|link-args|deployment-target]
+        --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
                         Compiler information to print on stdout
     -g                  Equivalent to -C debuginfo=2
     -O                  Equivalent to -C opt-level=3
diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout
index c1b246e849c..01f470f6e16 100644
--- a/tests/run-make/rustdoc-default-output/output-default.stdout
+++ b/tests/run-make/rustdoc-default-output/output-default.stdout
@@ -153,7 +153,7 @@ Options:
         --generate-redirect-map 
                         Generate JSON file at the top level instead of
                         generating HTML redirection files
-        --emit [unversioned-shared-resources,toolchain-shared-resources,invocation-specific]
+        --emit [unversioned-shared-resources,toolchain-shared-resources,invocation-specific,dep-info]
                         Comma separated list of types of output for rustdoc to
                         emit
         --no-run        Compile doctests without running them
diff --git a/tests/run-make/rustdoc-default-output/rmake.rs b/tests/run-make/rustdoc-default-output/rmake.rs
index 06720445a35..5f9c501e528 100644
--- a/tests/run-make/rustdoc-default-output/rmake.rs
+++ b/tests/run-make/rustdoc-default-output/rmake.rs
@@ -3,10 +3,10 @@
 // ensures the output of rustdoc's help menu is as expected.
 // See https://github.com/rust-lang/rust/issues/88756
 
-use run_make_support::{bare_rustdoc, diff};
+use run_make_support::{diff, rustdoc};
 
 fn main() {
-    let out = bare_rustdoc().run().stdout_utf8();
+    let out = rustdoc().run().stdout_utf8();
     diff()
         .expected_file("output-default.stdout")
         .actual_text("actual", out)
diff --git a/tests/run-make/rustdoc-dep-info/bar.rs b/tests/run-make/rustdoc-dep-info/bar.rs
new file mode 100644
index 00000000000..76b8dcd05c8
--- /dev/null
+++ b/tests/run-make/rustdoc-dep-info/bar.rs
@@ -0,0 +1 @@
+include!("foo.rs");
diff --git a/tests/run-make/rustdoc-dep-info/doc.md b/tests/run-make/rustdoc-dep-info/doc.md
new file mode 100644
index 00000000000..6a4238fc8b6
--- /dev/null
+++ b/tests/run-make/rustdoc-dep-info/doc.md
@@ -0,0 +1 @@
+blablabla
diff --git a/tests/run-make/rustdoc-dep-info/foo.rs b/tests/run-make/rustdoc-dep-info/foo.rs
new file mode 100644
index 00000000000..b76b4321d62
--- /dev/null
+++ b/tests/run-make/rustdoc-dep-info/foo.rs
@@ -0,0 +1 @@
+pub fn foo() {}
diff --git a/tests/run-make/rustdoc-dep-info/lib.rs b/tests/run-make/rustdoc-dep-info/lib.rs
new file mode 100644
index 00000000000..1f003f79b1f
--- /dev/null
+++ b/tests/run-make/rustdoc-dep-info/lib.rs
@@ -0,0 +1,6 @@
+#![crate_name = "foo"]
+
+#[cfg_attr(doc, doc = include_str!("doc.md"))]
+pub struct Bar;
+
+mod bar;
diff --git a/tests/run-make/rustdoc-dep-info/rmake.rs b/tests/run-make/rustdoc-dep-info/rmake.rs
new file mode 100644
index 00000000000..6902bfc21ca
--- /dev/null
+++ b/tests/run-make/rustdoc-dep-info/rmake.rs
@@ -0,0 +1,21 @@
+// This is a simple smoke test for rustdoc's `--emit dep-info` feature. It prints out
+// information about dependencies in a Makefile-compatible format, as a `.d` file.
+
+use run_make_support::assertion_helpers::assert_contains;
+use run_make_support::{path, rfs, rustdoc};
+
+fn main() {
+    // We're only emitting dep info, so we shouldn't be running static analysis to
+    // figure out that this program is erroneous.
+    rustdoc().input("lib.rs").arg("-Zunstable-options").emit("dep-info").run();
+
+    let content = rfs::read_to_string("foo.d");
+    assert_contains(&content, "lib.rs:");
+    assert_contains(&content, "foo.rs:");
+    assert_contains(&content, "bar.rs:");
+    assert_contains(&content, "doc.md:");
+
+    // Now we check that we can provide a file name to the `dep-info` argument.
+    rustdoc().input("lib.rs").arg("-Zunstable-options").emit("dep-info=bla.d").run();
+    assert!(path("bla.d").exists());
+}
diff --git a/tests/run-make/tools.mk b/tests/run-make/tools.mk
deleted file mode 100644
index b1e872a202a..00000000000
--- a/tests/run-make/tools.mk
+++ /dev/null
@@ -1,209 +0,0 @@
-# These deliberately use `=` and not `:=` so that client makefiles can
-# augment HOST_RPATH_DIR / TARGET_RPATH_DIR.
-HOST_RPATH_ENV = \
-    $(LD_LIB_PATH_ENVVAR)="$(TMPDIR):$(HOST_RPATH_DIR):$($(LD_LIB_PATH_ENVVAR))"
-TARGET_RPATH_ENV = \
-    $(LD_LIB_PATH_ENVVAR)="$(TMPDIR):$(TARGET_RPATH_DIR):$($(LD_LIB_PATH_ENVVAR))"
-
-RUSTC_ORIGINAL := $(RUSTC)
-BARE_RUSTC := $(HOST_RPATH_ENV) '$(RUSTC)'
-BARE_RUSTDOC := $(HOST_RPATH_ENV) '$(RUSTDOC)'
-RUSTC := $(BARE_RUSTC) --out-dir $(TMPDIR) -L $(TMPDIR) $(RUSTFLAGS) -Ainternal_features
-RUSTDOC := $(BARE_RUSTDOC) -L $(TARGET_RPATH_DIR)
-ifdef RUSTC_LINKER
-RUSTC := $(RUSTC) -Clinker='$(RUSTC_LINKER)'
-RUSTDOC := $(RUSTDOC) -Clinker='$(RUSTC_LINKER)'
-endif
-#CC := $(CC) -L $(TMPDIR)
-HTMLDOCCK := '$(PYTHON)' '$(S)/src/etc/htmldocck.py'
-CGREP := "$(S)/src/etc/cat-and-grep.sh"
-
-# diff with common flags for multi-platform diffs against text output
-DIFF := diff -u --strip-trailing-cr
-
-# With RUSTC_TEST_OP you can elegantly support blessing of run-make tests. Do
-# like this in a Makefile recipe:
-#
-#   "$(TMPDIR)"/your-test > "$(TMPDIR)"/your-test.run.stdout
-#   $(RUSTC_TEST_OP) "$(TMPDIR)"/your-test.run.stdout your-test.run.stdout
-#
-# When running the test normally with
-#
-#   ./x test tests/run-make/your-test
-#
-# the actual output will be diffed against the expected output. When running in
-# bless-mode with
-#
-#   ./x test --bless tests/run-make/your-test
-#
-# the actual output will be blessed as the expected output.
-ifdef RUSTC_BLESS_TEST
-    RUSTC_TEST_OP = cp
-else
-    RUSTC_TEST_OP = $(DIFF)
-endif
-
-# Some of the Rust CI platforms use `/bin/dash` to run `shell` script in
-# Makefiles. Other platforms, including many developer platforms, default to
-# `/bin/bash`. (In many cases, `make` is actually using `/bin/sh`, but `sh`
-# is configured to execute one or the other shell binary). `dash` features
-# support only a small subset of `bash` features, so `dash` can be thought of as
-# the lowest common denominator, and tests should be validated against `dash`
-# whenever possible. Most developer platforms include `/bin/dash`, but to ensure
-# tests still work when `/bin/dash`, if not available, this `SHELL` override is
-# conditional:
-ifndef IS_WINDOWS # dash interprets backslashes in executable paths incorrectly
-ifneq (,$(wildcard /bin/dash))
-SHELL := /bin/dash
-endif
-endif
-
-# This is the name of the binary we will generate and run; use this
-# e.g. for `$(CC) -o $(RUN_BINFILE)`.
-RUN_BINFILE = $(TMPDIR)/$(1)
-
-# Invoke the generated binary on the remote machine if compiletest was
-# configured to use a remote test device, otherwise run it on the current host.
-ifdef REMOTE_TEST_CLIENT
-# FIXME: if a test requires additional files, this will need to be changed to
-# also push them (by changing the 0 to the number of additional files, and
-# providing the path of the additional files as the last arguments).
-EXECUTE = $(REMOTE_TEST_CLIENT) run 0 $(RUN_BINFILE)
-else
-EXECUTE = $(RUN_BINFILE)
-endif
-
-# RUN and FAIL are basic way we will invoke the generated binary.  On
-# non-windows platforms, they set the LD_LIBRARY_PATH environment
-# variable before running the binary.
-
-RLIB_GLOB = lib$(1)*.rlib
-BIN = $(1)
-
-UNAME = $(shell uname)
-
-ifeq ($(UNAME),Darwin)
-RUN = $(TARGET_RPATH_ENV) $(EXECUTE)
-FAIL = $(TARGET_RPATH_ENV) $(EXECUTE) && exit 1 || exit 0
-DYLIB_GLOB = lib$(1)*.dylib
-DYLIB = $(TMPDIR)/lib$(1).dylib
-STATICLIB = $(TMPDIR)/lib$(1).a
-STATICLIB_GLOB = lib$(1)*.a
-else
-ifdef IS_WINDOWS
-RUN = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE)
-FAIL = PATH="$(PATH):$(TARGET_RPATH_DIR)" $(EXECUTE) && exit 1 || exit 0
-DYLIB_GLOB = $(1)*.dll
-DYLIB = $(TMPDIR)/$(1).dll
-ifdef IS_MSVC
-STATICLIB = $(TMPDIR)/$(1).lib
-STATICLIB_GLOB = $(1)*.lib
-else
-IMPLIB = $(TMPDIR)/lib$(1).dll.a
-STATICLIB = $(TMPDIR)/lib$(1).a
-STATICLIB_GLOB = lib$(1)*.a
-endif
-BIN = $(1).exe
-LLVM_FILECHECK := $(shell cygpath -u "$(LLVM_FILECHECK)")
-else
-RUN = $(TARGET_RPATH_ENV) $(EXECUTE)
-FAIL = $(TARGET_RPATH_ENV) $(EXECUTE) && exit 1 || exit 0
-DYLIB_GLOB = lib$(1)*.so
-DYLIB = $(TMPDIR)/lib$(1).so
-STATICLIB = $(TMPDIR)/lib$(1).a
-STATICLIB_GLOB = lib$(1)*.a
-endif
-endif
-
-ifdef IS_MSVC
-COMPILE_OBJ = $(CC) -c -Fo:`cygpath -w $(1)` $(2)
-COMPILE_OBJ_CXX = $(CXX) -EHs -c -Fo:`cygpath -w $(1)` $(2)
-NATIVE_STATICLIB_FILE = $(1).lib
-NATIVE_STATICLIB = $(TMPDIR)/$(call NATIVE_STATICLIB_FILE,$(1))
-OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \
-	-Fo:`cygpath -w $(TMPDIR)/$(1).obj`
-else
-COMPILE_OBJ = $(CC) -v -c -o $(1) $(2)
-COMPILE_OBJ_CXX = $(CXX) -c -o $(1) $(2)
-NATIVE_STATICLIB_FILE = lib$(1).a
-NATIVE_STATICLIB = $(call STATICLIB,$(1))
-OUT_EXE=-o $(TMPDIR)/$(1)
-endif
-
-
-# Extra flags needed to compile a working executable with the standard library
-ifdef IS_WINDOWS
-ifdef IS_MSVC
-	EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib bcrypt.lib ntdll.lib synchronization.lib
-else
-	EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt -lntdll -lsynchronization
-	EXTRACXXFLAGS := -lstdc++
-	# So this is a bit hacky: we can't use the DLL version of libstdc++ because
-	# it pulls in the DLL version of libgcc, which means that we end up with 2
-	# instances of the DW2 unwinding implementation. This is a problem on
-	# i686-pc-windows-gnu because each module (DLL/EXE) needs to register its
-	# unwind information with the unwinding implementation, and libstdc++'s
-	# __cxa_throw won't see the unwinding info we registered with our statically
-	# linked libgcc.
-	#
-	# Now, simply statically linking libstdc++ would fix this problem, except
-	# that it is compiled with the expectation that pthreads is dynamically
-	# linked as a DLL and will fail to link with a statically linked libpthread.
-	#
-	# So we end up with the following hack: we link use static:-bundle to only
-	# link the parts of libstdc++ that we actually use, which doesn't include
-	# the dependency on the pthreads DLL.
-	EXTRARSCXXFLAGS := -l static:-bundle=stdc++
-endif
-else
-ifeq ($(UNAME),Darwin)
-	EXTRACFLAGS := -lresolv
-	EXTRACXXFLAGS := -lc++
-	EXTRARSCXXFLAGS := -lc++
-else
-ifeq ($(UNAME),FreeBSD)
-	EXTRACFLAGS := -lm -lpthread -lgcc_s
-else
-ifeq ($(UNAME),SunOS)
-	EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket -lresolv
-else
-ifeq ($(UNAME),OpenBSD)
-	EXTRACFLAGS := -lm -lpthread -lc++abi
-	RUSTC := $(RUSTC) -C linker="$(word 1,$(CC:ccache=))"
-else
-	EXTRACFLAGS := -lm -lrt -ldl -lpthread
-	EXTRACXXFLAGS := -lstdc++
-	EXTRARSCXXFLAGS := -lstdc++
-endif
-endif
-endif
-endif
-endif
-
-REMOVE_DYLIBS     = rm $(TMPDIR)/$(call DYLIB_GLOB,$(1))
-REMOVE_RLIBS      = rm $(TMPDIR)/$(call RLIB_GLOB,$(1))
-
-%.a: %.o
-	$(AR) crus $@ $<
-ifdef IS_MSVC
-%.lib: lib%.o
-	$(MSVC_LIB) -out:`cygpath -w $@` $<
-else
-%.lib: lib%.o
-	$(AR) crus $@ $<
-endif
-%.dylib: %.o
-	$(CC) -dynamiclib -Wl,-dylib -o $@ $<
-%.so: %.o
-	$(CC) -o $@ $< -shared
-
-ifdef IS_MSVC
-%.dll: lib%.o
-	$(CC) $< -link -dll -out:`cygpath -w $@`
-else
-%.dll: lib%.o
-	$(CC) -o $@ $< -shared -Wl,--out-implib=$@.a
-endif
-
-$(TMPDIR)/lib%.o: %.c
-	$(call COMPILE_OBJ,$@,$<)
diff --git a/tests/run-make/unstable-feature-usage-metrics/rmake.rs b/tests/run-make/unstable-feature-usage-metrics/rmake.rs
index 1397548a6fc..2183e28e89a 100644
--- a/tests/run-make/unstable-feature-usage-metrics/rmake.rs
+++ b/tests/run-make/unstable-feature-usage-metrics/rmake.rs
@@ -58,12 +58,17 @@ fn test_metrics_dump() {
         );
 
         let message = rfs::read_to_string(json_path);
-        let parsed: serde_json::Value =
+        let mut parsed: serde_json::Value =
             serde_json::from_str(&message).expect("metrics should be dumped as json");
+        // remove timestamps
+        assert!(parsed["lib_features"][0]["timestamp"].is_number());
+        assert!(parsed["lang_features"][0]["timestamp"].is_number());
+        parsed["lib_features"][0]["timestamp"] = serde_json::json!(null);
+        parsed["lang_features"][0]["timestamp"] = serde_json::json!(null);
         let expected = serde_json::json!(
             {
-                "lib_features":[{"symbol":"ascii_char"}],
-                "lang_features":[{"symbol":"box_patterns","since":null}]
+                "lib_features":[{"symbol":"ascii_char", "timestamp":null}],
+                "lang_features":[{"symbol":"box_patterns","since":null, "timestamp":null}]
             }
         );
 
diff --git a/tests/run-make/version-verbose-commit-hash/rmake.rs b/tests/run-make/version-verbose-commit-hash/rmake.rs
index 733c0e2cdb1..ae8dda38ab4 100644
--- a/tests/run-make/version-verbose-commit-hash/rmake.rs
+++ b/tests/run-make/version-verbose-commit-hash/rmake.rs
@@ -5,13 +5,13 @@
 
 //@ needs-git-hash
 
-use run_make_support::{bare_rustc, bare_rustdoc, regex};
+use run_make_support::{bare_rustc, regex, rustdoc};
 
 fn main() {
     let out_rustc =
         bare_rustc().arg("--version").arg("--verbose").run().stdout_utf8().to_lowercase();
     let out_rustdoc =
-        bare_rustdoc().arg("--version").arg("--verbose").run().stdout_utf8().to_lowercase();
+        rustdoc().arg("--version").arg("--verbose").run().stdout_utf8().to_lowercase();
     let re =
         regex::Regex::new(r#"commit-hash: [0-9a-f]{40}\ncommit-date: [0-9]{4}-[0-9]{2}-[0-9]{2}"#)
             .unwrap();
diff --git a/tests/rustdoc-json/enums/discriminant/limits.rs b/tests/rustdoc-json/enums/discriminant/limits.rs
index a023c9fbf6e..7508490d666 100644
--- a/tests/rustdoc-json/enums/discriminant/limits.rs
+++ b/tests/rustdoc-json/enums/discriminant/limits.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-linelength
 #![feature(repr128)]
 #![allow(incomplete_features)]
 
diff --git a/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs b/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs
index f16a74d638b..6f66495bed2 100644
--- a/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs
+++ b/tests/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 #[repr(u32)]
 pub enum Foo {
     //@ is "$.index[*][?(@.name=='Basic')].inner.variant.discriminant.value" '"0"'
diff --git a/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs b/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs
index 522545d34d0..8e7985f07f4 100644
--- a/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs
+++ b/tests/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 pub enum Foo {
     //@ is "$.index[*][?(@.name=='Has')].inner.variant.discriminant" '{"expr":"0", "value":"0"}'
     Has = 0,
diff --git a/tests/rustdoc-json/enums/discriminant/struct.rs b/tests/rustdoc-json/enums/discriminant/struct.rs
index 24d5f5b08c2..82437f5ef03 100644
--- a/tests/rustdoc-json/enums/discriminant/struct.rs
+++ b/tests/rustdoc-json/enums/discriminant/struct.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 #[repr(i32)]
 //@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr=\"Repr([ReprInt(SignedInt(I32))])\")]\n"]'
 pub enum Foo {
diff --git a/tests/rustdoc-json/enums/discriminant/tuple.rs b/tests/rustdoc-json/enums/discriminant/tuple.rs
index a50ae8b9189..25bba07e8f7 100644
--- a/tests/rustdoc-json/enums/discriminant/tuple.rs
+++ b/tests/rustdoc-json/enums/discriminant/tuple.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 #[repr(u32)]
 //@ is "$.index[*][?(@.name=='Foo')].attrs" '["#[attr=\"Repr([ReprInt(UnsignedInt(U32))])\")]\n"]'
 pub enum Foo {
diff --git a/tests/rustdoc-json/enums/kind.rs b/tests/rustdoc-json/enums/kind.rs
index 2e0fb3101a3..517a53828b7 100644
--- a/tests/rustdoc-json/enums/kind.rs
+++ b/tests/rustdoc-json/enums/kind.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 pub enum Foo {
     //@ set Unit = "$.index[*][?(@.name=='Unit')].id"
     //@ is "$.index[*][?(@.name=='Unit')].inner.variant.kind" '"plain"'
diff --git a/tests/rustdoc-json/fn_pointer/abi.rs b/tests/rustdoc-json/fn_pointer/abi.rs
index 03fbb3b795d..13a967bd35e 100644
--- a/tests/rustdoc-json/fn_pointer/abi.rs
+++ b/tests/rustdoc-json/fn_pointer/abi.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 #![feature(abi_vectorcall)]
 
 //@ is "$.index[*][?(@.name=='AbiRust')].inner.type_alias.type.function_pointer.header.abi" \"Rust\"
diff --git a/tests/rustdoc-json/fn_pointer/generics.rs b/tests/rustdoc-json/fn_pointer/generics.rs
index 7d64e490a22..c974b472297 100644
--- a/tests/rustdoc-json/fn_pointer/generics.rs
+++ b/tests/rustdoc-json/fn_pointer/generics.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ count "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.sig.inputs[*]" 1
 //@ is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.sig.inputs[0][0]" '"val"'
 //@ is "$.index[*][?(@.name=='WithHigherRankTraitBounds')].inner.type_alias.type.function_pointer.sig.inputs[0][1].borrowed_ref.lifetime" \"\'c\"
diff --git a/tests/rustdoc-json/fn_pointer/qualifiers.rs b/tests/rustdoc-json/fn_pointer/qualifiers.rs
index 6f03cf58522..398e31f72db 100644
--- a/tests/rustdoc-json/fn_pointer/qualifiers.rs
+++ b/tests/rustdoc-json/fn_pointer/qualifiers.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ is "$.index[*][?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.is_unsafe" false
 //@ is "$.index[*][?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.is_const" false
 //@ is "$.index[*][?(@.name=='FnPointer')].inner.type_alias.type.function_pointer.header.is_async" false
diff --git a/tests/rustdoc-json/fns/abi.rs b/tests/rustdoc-json/fns/abi.rs
index 2f6413cee6f..68957f79952 100644
--- a/tests/rustdoc-json/fns/abi.rs
+++ b/tests/rustdoc-json/fns/abi.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 #![feature(abi_vectorcall)]
 
 //@ is "$.index[*][?(@.name=='abi_rust')].inner.function.header.abi" \"Rust\"
diff --git a/tests/rustdoc-json/fns/async_return.rs b/tests/rustdoc-json/fns/async_return.rs
index ff88fa99c61..ddfd4ccf90d 100644
--- a/tests/rustdoc-json/fns/async_return.rs
+++ b/tests/rustdoc-json/fns/async_return.rs
@@ -1,5 +1,4 @@
 //@ edition:2021
-// ignore-tidy-linelength
 
 // Regression test for <https://github.com/rust-lang/rust/issues/101199>
 
diff --git a/tests/rustdoc-json/fns/generic_args.rs b/tests/rustdoc-json/fns/generic_args.rs
index b5412446ab4..6a7124976f8 100644
--- a/tests/rustdoc-json/fns/generic_args.rs
+++ b/tests/rustdoc-json/fns/generic_args.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ set foo = "$.index[*][?(@.name=='Foo')].id"
 pub trait Foo {}
 
diff --git a/tests/rustdoc-json/fns/generic_returns.rs b/tests/rustdoc-json/fns/generic_returns.rs
index 2f23801fc3f..90e17525c44 100644
--- a/tests/rustdoc-json/fns/generic_returns.rs
+++ b/tests/rustdoc-json/fns/generic_returns.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ count "$.index[*][?(@.name=='generic_returns')].inner.module.items[*]" 2
 
 //@ set foo = "$.index[*][?(@.name=='Foo')].id"
diff --git a/tests/rustdoc-json/fns/generics.rs b/tests/rustdoc-json/fns/generics.rs
index f2064fd1e93..b953094b5de 100644
--- a/tests/rustdoc-json/fns/generics.rs
+++ b/tests/rustdoc-json/fns/generics.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ set wham_id = "$.index[*][?(@.name=='Wham')].id"
 pub trait Wham {}
 
diff --git a/tests/rustdoc-json/generic-associated-types/gats.rs b/tests/rustdoc-json/generic-associated-types/gats.rs
index fdf605e9287..d1172b35fda 100644
--- a/tests/rustdoc-json/generic-associated-types/gats.rs
+++ b/tests/rustdoc-json/generic-associated-types/gats.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 pub trait Display {}
 
 pub trait LendingIterator {
diff --git a/tests/rustdoc-json/impl-trait-in-assoc-type.rs b/tests/rustdoc-json/impl-trait-in-assoc-type.rs
index 14ea2950769..fc12fc87e8d 100644
--- a/tests/rustdoc-json/impl-trait-in-assoc-type.rs
+++ b/tests/rustdoc-json/impl-trait-in-assoc-type.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-linelength
 #![feature(impl_trait_in_assoc_type)]
 
 pub struct AlwaysTrue;
diff --git a/tests/rustdoc-json/lifetime/longest.rs b/tests/rustdoc-json/lifetime/longest.rs
index 8ac60be0fef..2d4e098d696 100644
--- a/tests/rustdoc-json/lifetime/longest.rs
+++ b/tests/rustdoc-json/lifetime/longest.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ is "$.index[*][?(@.name=='longest')].inner.function.generics.params[0].name"  \"\'a\"
 //@ is "$.index[*][?(@.name=='longest')].inner.function.generics.params[0].kind"  '{"lifetime": {"outlives": []}}'
 //@ is "$.index[*][?(@.name=='longest')].inner.function.generics.params[0].kind"  '{"lifetime": {"outlives": []}}'
diff --git a/tests/rustdoc-json/lifetime/outlives.rs b/tests/rustdoc-json/lifetime/outlives.rs
index 99d14296f99..257e43985ac 100644
--- a/tests/rustdoc-json/lifetime/outlives.rs
+++ b/tests/rustdoc-json/lifetime/outlives.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ count "$.index[*][?(@.name=='foo')].inner.function.generics.params[*]" 3
 //@ is "$.index[*][?(@.name=='foo')].inner.function.generics.where_predicates" []
 //@ is "$.index[*][?(@.name=='foo')].inner.function.generics.params[0].name" \"\'a\"
diff --git a/tests/rustdoc-json/lifetime/outlives_in_param.rs b/tests/rustdoc-json/lifetime/outlives_in_param.rs
index 3eee6d9ea46..55ff5250541 100644
--- a/tests/rustdoc-json/lifetime/outlives_in_param.rs
+++ b/tests/rustdoc-json/lifetime/outlives_in_param.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ count '$.index[*][?(@.name=="outlives")].inner.function.generics.params[*]' 2
 //@ is    '$.index[*][?(@.name=="outlives")].inner.function.generics.params[0].name' \"\'a\"
 //@ is    '$.index[*][?(@.name=="outlives")].inner.function.generics.params[0].kind.lifetime.outlives' []
diff --git a/tests/rustdoc-json/lifetime/outlives_in_where.rs b/tests/rustdoc-json/lifetime/outlives_in_where.rs
index a8f88be01da..5158ff118a0 100644
--- a/tests/rustdoc-json/lifetime/outlives_in_where.rs
+++ b/tests/rustdoc-json/lifetime/outlives_in_where.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ is '$.index[*][?(@.name=="on_lifetimes")].inner.function.generics.where_predicates' '[{"lifetime_predicate": {"lifetime": "'\''all", "outlives": ["'\''a", "'\''b", "'\''c"]}}]'
 pub fn on_lifetimes<'a, 'b, 'c, 'all>()
 where
diff --git a/tests/rustdoc-json/methods/abi.rs b/tests/rustdoc-json/methods/abi.rs
index 6d33dfca373..dac02a6ce3c 100644
--- a/tests/rustdoc-json/methods/abi.rs
+++ b/tests/rustdoc-json/methods/abi.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 #![feature(abi_vectorcall)]
 
 //@ has "$.index[*][?(@.name=='Foo')]"
diff --git a/tests/rustdoc-json/non_lifetime_binders.rs b/tests/rustdoc-json/non_lifetime_binders.rs
index 8443141fecd..7c518a8f5a7 100644
--- a/tests/rustdoc-json/non_lifetime_binders.rs
+++ b/tests/rustdoc-json/non_lifetime_binders.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 #![feature(non_lifetime_binders)]
 #![allow(incomplete_features)]
 
diff --git a/tests/rustdoc-json/path_name.rs b/tests/rustdoc-json/path_name.rs
index 67843dfc8ff..a1b3ae294fa 100644
--- a/tests/rustdoc-json/path_name.rs
+++ b/tests/rustdoc-json/path_name.rs
@@ -3,7 +3,6 @@
 // See https://github.com/rust-lang/rust/issues/135600
 // and https://github.com/rust-lang/rust/pull/134880#issuecomment-2596386111
 //
-// ignore-tidy-linelength
 //@ aux-build: defines_and_reexports.rs
 extern crate defines_and_reexports;
 
diff --git a/tests/rustdoc-json/reexport/doc_inline_external_crate.rs b/tests/rustdoc-json/reexport/doc_inline_external_crate.rs
index 512c741798b..4debd395496 100644
--- a/tests/rustdoc-json/reexport/doc_inline_external_crate.rs
+++ b/tests/rustdoc-json/reexport/doc_inline_external_crate.rs
@@ -1,6 +1,5 @@
 // Regression Test for https://github.com/rust-lang/rust/issues/110138
 //@ aux-build: enum_with_discriminant.rs
-// ignore-tidy-linelength
 
 #[doc(inline)]
 pub extern crate enum_with_discriminant;
diff --git a/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs b/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs
index 6e9b5044816..4efacd283ef 100644
--- a/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs
+++ b/tests/rustdoc-json/reexport/export_extern_crate_as_self.rs
@@ -2,7 +2,5 @@
 
 #![crate_name = "export_extern_crate_as_self"]
 
-// ignore-tidy-linelength
-
 //@ is "$.index[*][?(@.inner.module)].name" \"export_extern_crate_as_self\"
 pub extern crate self as export_extern_crate_as_self; // Must be the same name as the crate already has
diff --git a/tests/rustdoc-json/reexport/private_twice_one_inline.rs b/tests/rustdoc-json/reexport/private_twice_one_inline.rs
index 87b97e65c0a..fdf8cda103b 100644
--- a/tests/rustdoc-json/reexport/private_twice_one_inline.rs
+++ b/tests/rustdoc-json/reexport/private_twice_one_inline.rs
@@ -1,5 +1,4 @@
 //@ aux-build:pub-struct.rs
-// ignore-tidy-linelength
 
 // Test for the ICE in https://github.com/rust-lang/rust/issues/83057
 // An external type re-exported with different attributes shouldn't cause an error
diff --git a/tests/rustdoc-json/reexport/private_two_names.rs b/tests/rustdoc-json/reexport/private_two_names.rs
index 1ed54f15fdc..049100d7f49 100644
--- a/tests/rustdoc-json/reexport/private_two_names.rs
+++ b/tests/rustdoc-json/reexport/private_two_names.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 // Test for the ICE in https://github.com/rust-lang/rust/issues/83720
 // A pub-in-private type re-exported under two different names shouldn't cause an error
 
diff --git a/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs b/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs
index 27e2827d08d..f313171afa5 100644
--- a/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs
+++ b/tests/rustdoc-json/reexport/same_type_reexported_more_than_once.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 // Regression test for <https://github.com/rust-lang/rust/issues/97432>.
 
 #![no_std]
diff --git a/tests/rustdoc-json/return_private.rs b/tests/rustdoc-json/return_private.rs
index bfcbed89040..214fda14aca 100644
--- a/tests/rustdoc-json/return_private.rs
+++ b/tests/rustdoc-json/return_private.rs
@@ -1,5 +1,4 @@
 // Regression test for <https://github.com/rust-lang/rust/issues/96161>.
-// ignore-tidy-linelength
 
 mod secret {
     //@ set struct_secret = "$.index[*][?(@.name == 'Secret' && @.inner.struct)].id"
diff --git a/tests/rustdoc-json/statics/extern.rs b/tests/rustdoc-json/statics/extern.rs
index d38fdf1cd1c..9e0265da8e2 100644
--- a/tests/rustdoc-json/statics/extern.rs
+++ b/tests/rustdoc-json/statics/extern.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-linelength
 //@ edition: 2021
 
 extern "C" {
diff --git a/tests/rustdoc-json/structs/with_primitives.rs b/tests/rustdoc-json/structs/with_primitives.rs
index 7202ab9af9c..fe99292456d 100644
--- a/tests/rustdoc-json/structs/with_primitives.rs
+++ b/tests/rustdoc-json/structs/with_primitives.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ is "$.index[*][?(@.name=='WithPrimitives')].visibility" \"public\"
 //@ has "$.index[*][?(@.name=='WithPrimitives')].inner.struct"
 //@ is "$.index[*][?(@.name=='WithPrimitives')].inner.struct.generics.params[0].name" \"\'a\"
diff --git a/tests/rustdoc-json/trait_alias.rs b/tests/rustdoc-json/trait_alias.rs
index 3ae5fad8acc..d9ef256b106 100644
--- a/tests/rustdoc-json/trait_alias.rs
+++ b/tests/rustdoc-json/trait_alias.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-linelength
 #![feature(trait_alias)]
 
 //@ set StrLike = "$.index[*][?(@.name=='StrLike')].id"
diff --git a/tests/rustdoc-json/traits/private_supertrait.rs b/tests/rustdoc-json/traits/private_supertrait.rs
index d31b6ca4ad8..ce0642278e0 100644
--- a/tests/rustdoc-json/traits/private_supertrait.rs
+++ b/tests/rustdoc-json/traits/private_supertrait.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ !has "$.index[*][?(@.name == 'sealed')]"
 mod sealed {
     //@ set sealed_id = "$.index[*][?(@.name=='Sealed')].id"
diff --git a/tests/rustdoc-json/traits/self.rs b/tests/rustdoc-json/traits/self.rs
index 060bc37f2d5..efd9efd556f 100644
--- a/tests/rustdoc-json/traits/self.rs
+++ b/tests/rustdoc-json/traits/self.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 pub struct Foo;
 
 // Check that Self is represented uniformly between inherent impls, trait impls,
diff --git a/tests/rustdoc-json/traits/supertrait.rs b/tests/rustdoc-json/traits/supertrait.rs
index e8fe82ab9cd..4b6199d4b26 100644
--- a/tests/rustdoc-json/traits/supertrait.rs
+++ b/tests/rustdoc-json/traits/supertrait.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ set loud_id = "$.index[*][?(@.name=='Loud')].id"
 pub trait Loud {}
 
diff --git a/tests/rustdoc-json/traits/trait_alias.rs b/tests/rustdoc-json/traits/trait_alias.rs
index 17c83ddc353..137b8947e23 100644
--- a/tests/rustdoc-json/traits/trait_alias.rs
+++ b/tests/rustdoc-json/traits/trait_alias.rs
@@ -1,5 +1,4 @@
 // Regression test for <https://github.com/rust-lang/rust/issues/104923>
-// ignore-tidy-linelength
 
 #![feature(trait_alias)]
 
diff --git a/tests/rustdoc-json/type/dyn.rs b/tests/rustdoc-json/type/dyn.rs
index f990a2cb53a..d8686d4e2fb 100644
--- a/tests/rustdoc-json/type/dyn.rs
+++ b/tests/rustdoc-json/type/dyn.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-linelength
 use std::fmt::Debug;
 
 //@ count "$.index[*][?(@.name=='dyn')].inner.module.items[*]" 3
diff --git a/tests/rustdoc-json/type/fn_lifetime.rs b/tests/rustdoc-json/type/fn_lifetime.rs
index 7fa12dad54e..aaa716bf11f 100644
--- a/tests/rustdoc-json/type/fn_lifetime.rs
+++ b/tests/rustdoc-json/type/fn_lifetime.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ has "$.index[*][?(@.name=='GenericFn')].inner.type_alias"
 
 //@ ismany "$.index[*][?(@.name=='GenericFn')].inner.type_alias.generics.params[*].name" \"\'a\"
diff --git a/tests/rustdoc-json/type/generic_default.rs b/tests/rustdoc-json/type/generic_default.rs
index 7eaa299af5c..2d2ce9cd103 100644
--- a/tests/rustdoc-json/type/generic_default.rs
+++ b/tests/rustdoc-json/type/generic_default.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ set result = "$.index[*][?(@.name=='Result')].id"
 pub enum Result<T, E> {
     Ok(T),
diff --git a/tests/rustdoc-json/type/hrtb.rs b/tests/rustdoc-json/type/hrtb.rs
index e71d9fc1e1e..08b35b90a2b 100644
--- a/tests/rustdoc-json/type/hrtb.rs
+++ b/tests/rustdoc-json/type/hrtb.rs
@@ -1,5 +1,3 @@
-// ignore-tidy-linelength
-
 //@ is "$.index[*][?(@.name=='genfn')].inner.function.generics.where_predicates[0].bound_predicate.type" '{"generic": "F"}'
 //@ is "$.index[*][?(@.name=='genfn')].inner.function.generics.where_predicates[0].bound_predicate.generic_params" '[{"kind": {"lifetime": {"outlives": []}},"name": "'\''a"},{"kind": {"lifetime": {"outlives": []}},"name": "'\''b"}]'
 pub fn genfn<F>(f: F)
diff --git a/tests/rustdoc-json/type/inherent_associated_type.rs b/tests/rustdoc-json/type/inherent_associated_type.rs
index b8ce11fc6e1..e26f8f7c651 100644
--- a/tests/rustdoc-json/type/inherent_associated_type.rs
+++ b/tests/rustdoc-json/type/inherent_associated_type.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-linelength
 #![feature(inherent_associated_types)]
 #![allow(incomplete_features)]
 
diff --git a/tests/rustdoc-json/type/inherent_associated_type_bound.rs b/tests/rustdoc-json/type/inherent_associated_type_bound.rs
index cb008291b72..22c9c9c1149 100644
--- a/tests/rustdoc-json/type/inherent_associated_type_bound.rs
+++ b/tests/rustdoc-json/type/inherent_associated_type_bound.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-linelength
 #![feature(inherent_associated_types)]
 #![allow(incomplete_features)]
 
diff --git a/tests/rustdoc-json/type/inherent_associated_type_projections.rs b/tests/rustdoc-json/type/inherent_associated_type_projections.rs
index e73e86d5817..501694dce8b 100644
--- a/tests/rustdoc-json/type/inherent_associated_type_projections.rs
+++ b/tests/rustdoc-json/type/inherent_associated_type_projections.rs
@@ -1,4 +1,3 @@
-// ignore-tidy-linelength
 #![feature(inherent_associated_types)]
 #![allow(incomplete_features)]
 
diff --git a/tests/rustdoc-ui/issues/issue-79494.rs b/tests/rustdoc-ui/issues/issue-79494.rs
index 7a1890c4429..28ef82dac0f 100644
--- a/tests/rustdoc-ui/issues/issue-79494.rs
+++ b/tests/rustdoc-ui/issues/issue-79494.rs
@@ -2,4 +2,4 @@
 
 #![feature(const_transmute)]
 
-const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; //~ ERROR cannot transmute between types of different sizes, or dependently-sized types
+pub const ZST: &[u8] = unsafe { std::mem::transmute(1usize) }; //~ ERROR cannot transmute between types of different sizes, or dependently-sized types
diff --git a/tests/rustdoc-ui/issues/issue-79494.stderr b/tests/rustdoc-ui/issues/issue-79494.stderr
index abcd69d3aae..20e568d8eab 100644
--- a/tests/rustdoc-ui/issues/issue-79494.stderr
+++ b/tests/rustdoc-ui/issues/issue-79494.stderr
@@ -1,8 +1,8 @@
 error[E0512]: cannot transmute between types of different sizes, or dependently-sized types
-  --> $DIR/issue-79494.rs:5:29
+  --> $DIR/issue-79494.rs:5:33
    |
-LL | const ZST: &[u8] = unsafe { std::mem::transmute(1usize) };
-   |                             ^^^^^^^^^^^^^^^^^^^
+LL | pub const ZST: &[u8] = unsafe { std::mem::transmute(1usize) };
+   |                                 ^^^^^^^^^^^^^^^^^^^
    |
    = note: source type: `usize` (64 bits)
    = note: target type: `&[u8]` (128 bits)
diff --git a/tests/rustdoc-ui/target-feature-stability.rs b/tests/rustdoc-ui/target-feature-stability.rs
new file mode 100644
index 00000000000..17fa3ccfe3e
--- /dev/null
+++ b/tests/rustdoc-ui/target-feature-stability.rs
@@ -0,0 +1,28 @@
+//! This is a regression test for <https://github.com/rust-lang/rust/issues/137366>, ensuring
+//! that we can use the `neon` target feature on ARM32 targets in rustdoc despite there
+//! being a "forbidden" feature of the same name for aarch64, and rustdoc merging the
+//! target features of all targets.
+//@ check-pass
+//@ revisions: arm aarch64
+//@[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
+//@[arm] needs-llvm-components: arm
+//@[aarch64] compile-flags: --target aarch64-unknown-none-softfloat
+//@[aarch64] needs-llvm-components: aarch64
+
+#![crate_type = "lib"]
+#![feature(no_core, lang_items)]
+#![feature(arm_target_feature)]
+#![no_core]
+
+#[lang = "sized"]
+pub trait Sized {}
+
+// `fp-armv8` is "forbidden" on aarch64 as we tie it to `neon`.
+#[target_feature(enable = "fp-armv8")]
+pub fn fun1() {}
+
+// This would usually be rejected as it changes the ABI.
+// But we disable that check in rustdoc since we are building "for all targets" and the
+// check can't really handle that.
+#[target_feature(enable = "soft-float")]
+pub fn fun2() {}
diff --git a/tests/rustdoc-ui/track-diagnostics.rs b/tests/rustdoc-ui/track-diagnostics.rs
index 5c950a11082..27781f47e0d 100644
--- a/tests/rustdoc-ui/track-diagnostics.rs
+++ b/tests/rustdoc-ui/track-diagnostics.rs
@@ -7,4 +7,5 @@
 
 struct A;
 struct B;
-const S: A = B;
+
+pub const S: A = B;
diff --git a/tests/rustdoc-ui/track-diagnostics.stderr b/tests/rustdoc-ui/track-diagnostics.stderr
index 3d17570a7a2..fb0d7b86644 100644
--- a/tests/rustdoc-ui/track-diagnostics.stderr
+++ b/tests/rustdoc-ui/track-diagnostics.stderr
@@ -1,8 +1,8 @@
 error[E0308]: mismatched types
   --> $DIR/track-diagnostics.rs:LL:CC
    |
-LL | const S: A = B;
-   |              ^ expected `A`, found `B`
+LL | pub const S: A = B;
+   |                  ^ expected `A`, found `B`
 -Ztrack-diagnostics: created at compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs:LL:CC
 
 error: aborting due to 1 previous error
diff --git a/tests/rustdoc/doc-hidden-reexports-109449.rs b/tests/rustdoc/doc-hidden-reexports-109449.rs
index 8f195544120..78b9214300a 100644
--- a/tests/rustdoc/doc-hidden-reexports-109449.rs
+++ b/tests/rustdoc/doc-hidden-reexports-109449.rs
@@ -26,21 +26,21 @@ pub mod single_reexport {
     //@ has 'foo/single_reexport/index.html'
 
     // First we check that we have 4 type aliases.
-    //@ count - '//*[@id="main-content"]/*[@class="item-table reexports"]//code' 4
+    //@ count - '//*[@id="main-content"]/*[@class="item-table reexports"]//code' 0
 
     // Then we check that we have the correct link for each re-export.
 
     //@ !has - '//*[@href="struct.Foo.html"]' 'Foo'
-    //@ has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;'
+    //@ !has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;'
     pub use crate::private_module::Public as Foo;
     //@ !has - '//*[@href="type.Foo2.html"]' 'Foo2'
-    //@ has - '//*[@id="reexport.Foo2"]/code' 'pub use crate::private_module::Bar as Foo2;'
+    //@ !has - '//*[@id="reexport.Foo2"]/code' 'pub use crate::private_module::Bar as Foo2;'
     pub use crate::private_module::Bar as Foo2;
     //@ !has - '//*[@href="type.Yo.html"]' 'Yo'
-    //@ has - '//*[@id="reexport.Yo"]/code' 'pub use crate::Bar3 as Yo;'
+    //@ !has - '//*[@id="reexport.Yo"]/code' 'pub use crate::Bar3 as Yo;'
     pub use crate::Bar3 as Yo;
     //@ !has - '//*[@href="struct.Yo2.html"]' 'Yo2'
-    //@ has - '//*[@id="reexport.Yo2"]/code' 'pub use crate::FooFoo as Yo2;'
+    //@ !has - '//*[@id="reexport.Yo2"]/code' 'pub use crate::FooFoo as Yo2;'
     pub use crate::FooFoo as Yo2;
 
     // Checking that each file is also created as expected.
@@ -70,19 +70,19 @@ pub mod single_reexport_no_inline {
     //@ has - '//*[@id="main-content"]/*[@class="section-header"]' 'Re-exports'
 
     // Now we check that we don't have links to the items, just `pub use`.
-    //@ has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Public as XFoo;'
+    //@ !has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Public as XFoo;'
     //@ !has - '//*[@id="main-content"]//a' 'XFoo'
     #[doc(no_inline)]
     pub use crate::private_module::Public as XFoo;
-    //@ has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Bar as Foo2;'
+    //@ !has - '//*[@id="main-content"]//*' 'pub use crate::private_module::Bar as Foo2;'
     //@ !has - '//*[@id="main-content"]//a' 'Foo2'
     #[doc(no_inline)]
     pub use crate::private_module::Bar as Foo2;
-    //@ has - '//*[@id="main-content"]//*' 'pub use crate::Bar3 as Yo;'
+    //@ !has - '//*[@id="main-content"]//*' 'pub use crate::Bar3 as Yo;'
     //@ !has - '//*[@id="main-content"]//a' 'Yo'
     #[doc(no_inline)]
     pub use crate::Bar3 as Yo;
-    //@ has - '//*[@id="main-content"]//*' 'pub use crate::FooFoo as Yo2;'
+    //@ !has - '//*[@id="main-content"]//*' 'pub use crate::FooFoo as Yo2;'
     //@ !has - '//*[@id="main-content"]//a' 'Yo2'
     #[doc(no_inline)]
     pub use crate::FooFoo as Yo2;
diff --git a/tests/rustdoc/doc-hidden-source.rs b/tests/rustdoc/doc-hidden-source.rs
new file mode 100644
index 00000000000..b6bc622dd58
--- /dev/null
+++ b/tests/rustdoc/doc-hidden-source.rs
@@ -0,0 +1,16 @@
+// Test for <https://github.com/rust-lang/rust/issues/137342>.
+
+#![crate_name = "foo"]
+
+//@ has 'foo/index.html'
+//@ !has - '//*[@id="main-content"]//*[@class="struct"]' 'Bar'
+#[doc(hidden)]
+pub struct Bar;
+
+//@ !has - '//*' 'pub use crate::Bar as A;'
+pub use crate::Bar as A;
+//@ !has - '//*' 'pub use crate::A as B;'
+pub use crate::A as B;
+//@ has - '//dt/a[@class="struct"]' 'C'
+#[doc(inline)]
+pub use crate::Bar as C;
diff --git a/tests/rustdoc/impl-parts-crosscrate.rs b/tests/rustdoc/impl-parts-crosscrate.rs
index 49752ab75d5..631c8bb3eb3 100644
--- a/tests/rustdoc/impl-parts-crosscrate.rs
+++ b/tests/rustdoc/impl-parts-crosscrate.rs
@@ -5,7 +5,7 @@
 
 extern crate rustdoc_impl_parts_crosscrate;
 
-pub struct Bar<T> { t: T }
+pub struct Bar<T: Copy + Send> { t: T }
 
 // The output file is html embedded in javascript, so the html tags
 // aren't stripped by the processing script and we can't check for the
diff --git a/tests/rustdoc/impl-parts.rs b/tests/rustdoc/impl-parts.rs
index 820f51008a4..4f281bfd63c 100644
--- a/tests/rustdoc/impl-parts.rs
+++ b/tests/rustdoc/impl-parts.rs
@@ -3,7 +3,7 @@
 
 pub auto trait AnAutoTrait {}
 
-pub struct Foo<T> { field: T }
+pub struct Foo<T: Clone + Sync> { field: T }
 
 //@ has impl_parts/struct.Foo.html '//*[@class="impl"]//h3[@class="code-header"]' \
 //     "impl<T> !AnAutoTrait for Foo<T>where T: Sync + Clone,"
diff --git a/tests/rustdoc/inline_cross/inline_hidden.rs b/tests/rustdoc/inline_cross/inline_hidden.rs
index 49ca2db6a22..f6727de2cc6 100644
--- a/tests/rustdoc/inline_cross/inline_hidden.rs
+++ b/tests/rustdoc/inline_cross/inline_hidden.rs
@@ -6,7 +6,7 @@ extern crate rustdoc_hidden;
 
 //@ has inline_hidden/index.html
 // Ensures this item is not inlined.
-//@ has - '//*[@id="reexport.Foo"]/code' 'pub use rustdoc_hidden::Foo;'
+//@ !has - '//*[@id="reexport.Foo"]/code' 'pub use rustdoc_hidden::Foo;'
 #[doc(no_inline)]
 pub use rustdoc_hidden::Foo;
 
@@ -16,7 +16,7 @@ pub use rustdoc_hidden::Foo;
 pub use rustdoc_hidden::Foo as Inlined;
 
 // Even with this import, we should not see `Foo`.
-//@ count - '//dt' 4
+//@ count - '//dt' 3
 //@ has - '//dt/a[@class="struct"]' 'Bar'
 //@ has - '//dt/a[@class="fn"]' 'foo'
 pub use rustdoc_hidden::*;
diff --git a/tests/rustdoc/reexport-attr-merge.rs b/tests/rustdoc/reexport-attr-merge.rs
index e4a406c3845..aef302eb0b2 100644
--- a/tests/rustdoc/reexport-attr-merge.rs
+++ b/tests/rustdoc/reexport-attr-merge.rs
@@ -18,7 +18,7 @@ pub use Foo1 as Foo2;
 
 // First we ensure that only the reexport `Bar2` and the inlined struct `Bar`
 // are inlined.
-//@ count - '//a[@class="struct"]' 2
+//@ count - '//a[@class="struct"]' 1
 // Then we check that `cfg` is displayed for base item, but not for intermediate re-exports.
 //@ has - '//*[@class="stab portability"]' 'foo'
 //@ !has - '//*[@class="stab portability"]' 'bar'
@@ -29,5 +29,5 @@ pub use Foo2 as Bar;
 
 // This one should appear but `Bar2` won't be linked because there is no
 // `#[doc(inline)]`.
-//@ has - '//*[@id="reexport.Bar2"]' 'pub use Foo2 as Bar2;'
+//@ !has - '//*[@id="reexport.Bar2"]' 'pub use Foo2 as Bar2;'
 pub use Foo2 as Bar2;
diff --git a/tests/rustdoc/reexport-doc-hidden-inside-private.rs b/tests/rustdoc/reexport-doc-hidden-inside-private.rs
index 8e194ef74fb..bae2aa78ec7 100644
--- a/tests/rustdoc/reexport-doc-hidden-inside-private.rs
+++ b/tests/rustdoc/reexport-doc-hidden-inside-private.rs
@@ -9,8 +9,8 @@ mod private_module {
 }
 
 //@ has 'foo/index.html'
-//@ has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;'
+//@ !has - '//*[@id="reexport.Foo"]/code' 'pub use crate::private_module::Public as Foo;'
 pub use crate::private_module::Public as Foo;
 // Glob re-exports with no visible items should not be displayed.
-//@ count - '//*[@class="item-table reexports"]/dt' 1
+//@ count - '//*[@class="item-table reexports"]/dt' 0
 pub use crate::private_module::*;
diff --git a/tests/rustdoc/reexport-doc-hidden.rs b/tests/rustdoc/reexport-doc-hidden.rs
index b912362f298..1468e9ad957 100644
--- a/tests/rustdoc/reexport-doc-hidden.rs
+++ b/tests/rustdoc/reexport-doc-hidden.rs
@@ -8,7 +8,7 @@
 pub type Type = u32;
 
 //@ has 'foo/index.html'
-//@ has - '//*[@id="reexport.Type2"]/code' 'pub use crate::Type as Type2;'
+//@ !has - '//*[@id="reexport.Type2"]/code' 'pub use crate::Type as Type2;'
 pub use crate::Type as Type2;
 
 //@ count - '//*[@id="reexport.Type3"]' 0
@@ -21,5 +21,5 @@ macro_rules! foo {
     () => {};
 }
 
-//@ has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;'
+//@ !has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;'
 pub use crate::foo as Macro;
diff --git a/tests/rustdoc/reexport-hidden-macro.rs b/tests/rustdoc/reexport-hidden-macro.rs
index 9b83bca3906..7345149c645 100644
--- a/tests/rustdoc/reexport-hidden-macro.rs
+++ b/tests/rustdoc/reexport-hidden-macro.rs
@@ -5,7 +5,7 @@
 
 //@ has 'foo/index.html'
 //@ has - '//*[@id="main-content"]//a[@href="macro.Macro2.html"]' 'Macro2'
-//@ has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;'
+//@ !has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;'
 
 //@ has 'foo/macro.Macro2.html'
 //@ has - '//*[@class="docblock"]' 'Displayed'
diff --git a/tests/rustdoc/reexport-of-doc-hidden.rs b/tests/rustdoc/reexport-of-doc-hidden.rs
index 21511bc2aea..e901d0ff8a2 100644
--- a/tests/rustdoc/reexport-of-doc-hidden.rs
+++ b/tests/rustdoc/reexport-of-doc-hidden.rs
@@ -12,13 +12,13 @@ macro_rules! foo {
 }
 
 //@ has 'foo/index.html'
-//@ has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;'
+//@ !has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;'
 pub use crate::foo as Macro;
-//@ has - '//*[@id="reexport.Macro2"]/code' 'pub use crate::foo as Macro2;'
+//@ !has - '//*[@id="reexport.Macro2"]/code' 'pub use crate::foo as Macro2;'
 pub use crate::foo as Macro2;
-//@ has - '//*[@id="reexport.Boo"]/code' 'pub use crate::Bar as Boo;'
+//@ !has - '//*[@id="reexport.Boo"]/code' 'pub use crate::Bar as Boo;'
 pub use crate::Bar as Boo;
-//@ has - '//*[@id="reexport.Boo2"]/code' 'pub use crate::Bar as Boo2;'
+//@ !has - '//*[@id="reexport.Boo2"]/code' 'pub use crate::Bar as Boo2;'
 pub use crate::Bar as Boo2;
 
 pub fn fofo() {}
@@ -30,9 +30,9 @@ pub use crate::fofo as f2;
 
 pub mod sub {
     //@ has 'foo/sub/index.html'
-    //@ has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;'
+    //@ !has - '//*[@id="reexport.Macro"]/code' 'pub use crate::foo as Macro;'
     pub use crate::foo as Macro;
-    //@ has - '//*[@id="reexport.Macro2"]/code' 'pub use crate::foo as Macro2;'
+    //@ !has - '//*[@id="reexport.Macro2"]/code' 'pub use crate::foo as Macro2;'
     pub use crate::foo as Macro2;
 
     //@ has - '//*[@id="reexport.f1"]/code' 'pub use crate::fofo as f1;'
diff --git a/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout b/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout
index 4d58fd503d0..5cf39ca3165 100644
--- a/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout
+++ b/tests/ui-fulldeps/codegen-backend/hotplug.bindep.stdout
@@ -1,4 +1,4 @@
-$TEST_BUILD_DIR/codegen-backend/hotplug.bindep/libhotplug.rlib: $DIR/hotplug.rs $TEST_BUILD_DIR/codegen-backend/hotplug.bindep/auxiliary/libthe_backend.so
+$TEST_BUILD_DIR/libhotplug.rlib: $DIR/hotplug.rs $TEST_BUILD_DIR/auxiliary/libthe_backend.so
 
 $DIR/hotplug.rs:
-$TEST_BUILD_DIR/codegen-backend/hotplug.bindep/auxiliary/libthe_backend.so:
+$TEST_BUILD_DIR/auxiliary/libthe_backend.so:
diff --git a/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout b/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout
index 48b7534d8fa..717439f14e1 100644
--- a/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout
+++ b/tests/ui-fulldeps/codegen-backend/hotplug.dep.stdout
@@ -1,3 +1,3 @@
-$TEST_BUILD_DIR/codegen-backend/hotplug.dep/libhotplug.rlib: $DIR/hotplug.rs
+$TEST_BUILD_DIR/libhotplug.rlib: $DIR/hotplug.rs
 
 $DIR/hotplug.rs:
diff --git a/tests/ui-fulldeps/stable-mir/check_ty_fold.rs b/tests/ui-fulldeps/stable-mir/check_ty_fold.rs
index 9fa4929d68e..9d71697178e 100644
--- a/tests/ui-fulldeps/stable-mir/check_ty_fold.rs
+++ b/tests/ui-fulldeps/stable-mir/check_ty_fold.rs
@@ -18,9 +18,11 @@ extern crate rustc_interface;
 extern crate stable_mir;
 
 use rustc_smir::rustc_internal;
-use stable_mir::ty::{RigidTy, TyKind, Ty, };
-use stable_mir::mir::{Body, MirVisitor, FieldIdx, Place, ProjectionElem, visit::{Location,
-                                                                            PlaceContext}};
+use stable_mir::mir::{
+    Body, FieldIdx, MirVisitor, Place, ProjectionElem,
+    visit::{Location, PlaceContext},
+};
+use stable_mir::ty::{RigidTy, Ty, TyKind};
 use std::io::Write;
 use std::ops::ControlFlow;
 
@@ -29,8 +31,8 @@ const CRATE_NAME: &str = "input";
 /// This function uses the Stable MIR APIs to get information about the test crate.
 fn test_stable_mir() -> ControlFlow<()> {
     let main_fn = stable_mir::entry_fn();
-    let body = main_fn.unwrap().body();
-    let mut visitor = PlaceVisitor{ body: &body, tested: false};
+    let body = main_fn.unwrap().expect_body();
+    let mut visitor = PlaceVisitor { body: &body, tested: false };
     visitor.visit_body(&body);
     assert!(visitor.tested);
     ControlFlow::Continue(())
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index 7f0e9b50335..4d2d7e26276 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -45,7 +45,7 @@ fn test_stable_mir() -> ControlFlow<()> {
     assert!(stable_mir::find_crates("std").len() == 1);
 
     let bar = get_item(&items, (DefKind::Fn, "bar")).unwrap();
-    let body = bar.body();
+    let body = bar.expect_body();
     assert_eq!(body.locals().len(), 2);
     assert_eq!(body.blocks.len(), 1);
     let block = &body.blocks[0];
@@ -60,7 +60,7 @@ fn test_stable_mir() -> ControlFlow<()> {
     }
 
     let foo_bar = get_item(&items, (DefKind::Fn, "foo_bar")).unwrap();
-    let body = foo_bar.body();
+    let body = foo_bar.expect_body();
     assert_eq!(body.locals().len(), 5);
     assert_eq!(body.blocks.len(), 4);
     let block = &body.blocks[0];
@@ -70,7 +70,7 @@ fn test_stable_mir() -> ControlFlow<()> {
     }
 
     let types = get_item(&items, (DefKind::Fn, "types")).unwrap();
-    let body = types.body();
+    let body = types.expect_body();
     assert_eq!(body.locals().len(), 6);
     assert_matches!(
         body.locals()[0].ty.kind(),
@@ -100,7 +100,7 @@ fn test_stable_mir() -> ControlFlow<()> {
     );
 
     let drop = get_item(&items, (DefKind::Fn, "drop")).unwrap();
-    let body = drop.body();
+    let body = drop.expect_body();
     assert_eq!(body.blocks.len(), 2);
     let block = &body.blocks[0];
     match &block.terminator.kind {
@@ -109,7 +109,7 @@ fn test_stable_mir() -> ControlFlow<()> {
     }
 
     let assert = get_item(&items, (DefKind::Fn, "assert")).unwrap();
-    let body = assert.body();
+    let body = assert.expect_body();
     assert_eq!(body.blocks.len(), 2);
     let block = &body.blocks[0];
     match &block.terminator.kind {
@@ -123,7 +123,8 @@ fn test_stable_mir() -> ControlFlow<()> {
         match &block.terminator.kind {
             stable_mir::mir::TerminatorKind::Call { func, .. } => {
                 let TyKind::RigidTy(ty) = func.ty(&body.locals()).unwrap().kind() else {
-                    unreachable!() };
+                    unreachable!()
+                };
                 let RigidTy::FnDef(def, args) = ty else { unreachable!() };
                 let next_func = Instance::resolve(def, &args).unwrap();
                 match next_func.body().unwrap().locals()[1].ty.kind() {
@@ -138,10 +139,10 @@ fn test_stable_mir() -> ControlFlow<()> {
 
     let foo_const = get_item(&items, (DefKind::Const, "FOO")).unwrap();
     // Ensure we don't panic trying to get the body of a constant.
-    foo_const.body();
+    foo_const.expect_body();
 
     let locals_fn = get_item(&items, (DefKind::Fn, "locals")).unwrap();
-    let body = locals_fn.body();
+    let body = locals_fn.expect_body();
     assert_eq!(body.locals().len(), 4);
     assert_matches!(
         body.ret_local().ty.kind(),
@@ -172,8 +173,10 @@ fn get_item<'a>(
     item: (DefKind, &str),
 ) -> Option<&'a stable_mir::CrateItem> {
     items.iter().find(|crate_item| {
-        matches!((item.0, crate_item.kind()), (DefKind::Fn, ItemKind::Fn) | (DefKind::Const,
-            ItemKind::Const)) && crate_item.name() == item.1
+        matches!(
+            (item.0, crate_item.kind()),
+            (DefKind::Fn, ItemKind::Fn) | (DefKind::Const, ItemKind::Const)
+        ) && crate_item.name() == item.1
     })
 }
 
diff --git a/tests/ui-fulldeps/stable-mir/projections.rs b/tests/ui-fulldeps/stable-mir/projections.rs
index 3cc71247e67..6f82eba61fc 100644
--- a/tests/ui-fulldeps/stable-mir/projections.rs
+++ b/tests/ui-fulldeps/stable-mir/projections.rs
@@ -18,10 +18,10 @@ extern crate rustc_interface;
 extern crate stable_mir;
 
 use rustc_smir::rustc_internal;
+use stable_mir::ItemKind;
 use stable_mir::crate_def::CrateDef;
 use stable_mir::mir::{ProjectionElem, Rvalue, StatementKind};
 use stable_mir::ty::{RigidTy, TyKind, UintTy};
-use stable_mir::ItemKind;
 use std::assert_matches::assert_matches;
 use std::io::Write;
 use std::ops::ControlFlow;
@@ -31,7 +31,7 @@ const CRATE_NAME: &str = "input";
 /// Tests projections within Place objects
 fn test_place_projections() -> ControlFlow<()> {
     let items = stable_mir::all_local_items();
-    let body = get_item(&items, (ItemKind::Fn, "projections")).unwrap().body();
+    let body = get_item(&items, (ItemKind::Fn, "projections")).unwrap().expect_body();
     assert_eq!(body.blocks.len(), 4);
     // The first statement assigns `&s.c` to a local. The projections include a deref for `s`, since
     // `s` is passed as a reference argument, and a field access for field `c`.
@@ -53,7 +53,7 @@ fn test_place_projections() -> ControlFlow<()> {
                     );
                     let ty = place.ty(body.locals()).unwrap();
                     assert_matches!(ty.kind().rigid(), Some(RigidTy::Ref(..)));
-                },
+                }
                 other => panic!(
                     "Unable to match against expected rvalue projection. Expected the projection \
                      for `s.c`, which is a Deref and u8 Field. Got: {:?}",
@@ -137,9 +137,7 @@ fn get_item<'a>(
     items: &'a stable_mir::CrateItems,
     item: (ItemKind, &str),
 ) -> Option<&'a stable_mir::CrateItem> {
-    items.iter().find(|crate_item| {
-        crate_item.kind() == item.0 && crate_item.name() == item.1
-    })
+    items.iter().find(|crate_item| crate_item.kind() == item.0 && crate_item.name() == item.1)
 }
 
 /// This test will generate and analyze a dummy crate using the stable mir.
diff --git a/tests/ui-fulldeps/stable-mir/smir_internal.rs b/tests/ui-fulldeps/stable-mir/smir_internal.rs
index 453e5372de4..f9972dc27e3 100644
--- a/tests/ui-fulldeps/stable-mir/smir_internal.rs
+++ b/tests/ui-fulldeps/stable-mir/smir_internal.rs
@@ -26,7 +26,7 @@ const CRATE_NAME: &str = "input";
 
 fn test_translation(tcx: TyCtxt<'_>) -> ControlFlow<()> {
     let main_fn = stable_mir::entry_fn().unwrap();
-    let body = main_fn.body();
+    let body = main_fn.expect_body();
     let orig_ty = body.locals()[0].ty;
     let rustc_ty = rustc_internal::internal(tcx, &orig_ty);
     assert!(rustc_ty.is_unit());
diff --git a/tests/ui-fulldeps/stable-mir/smir_serde.rs b/tests/ui-fulldeps/stable-mir/smir_serde.rs
index 2c74276d550..9b3638a9f2f 100644
--- a/tests/ui-fulldeps/stable-mir/smir_serde.rs
+++ b/tests/ui-fulldeps/stable-mir/smir_serde.rs
@@ -14,33 +14,29 @@ extern crate rustc_smir;
 extern crate rustc_driver;
 extern crate rustc_interface;
 extern crate rustc_middle;
-extern crate stable_mir;
 extern crate serde;
 extern crate serde_json;
+extern crate stable_mir;
 
 use rustc_middle::ty::TyCtxt;
 use rustc_smir::rustc_internal;
+use serde_json::to_string;
 use stable_mir::mir::Body;
-use std::io::{Write, BufWriter};
+use std::io::{BufWriter, Write};
 use std::ops::ControlFlow;
-use serde_json::to_string;
-
 
 const CRATE_NAME: &str = "input";
 
 fn serialize_to_json(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
     let path = "output.json";
-    let mut writer = BufWriter::new(std::fs::File::create(path)
-        .expect("Failed to create path"));
+    let mut writer = BufWriter::new(std::fs::File::create(path).expect("Failed to create path"));
     let local_crate = stable_mir::local_crate();
-    let items: Vec<Body> = stable_mir::all_local_items()
-        .iter()
-        .map(|item| { item.body() })
-        .collect();
-    let crate_data = ( local_crate.name, items );
-    writer.write_all(to_string(&crate_data)
-        .expect("serde_json failed")
-        .as_bytes()).expect("JSON serialization failed");
+    let items: Vec<Body> =
+        stable_mir::all_local_items().iter().map(|item| item.expect_body()).collect();
+    let crate_data = (local_crate.name, items);
+    writer
+        .write_all(to_string(&crate_data).expect("serde_json failed").as_bytes())
+        .expect("JSON serialization failed");
     ControlFlow::Continue(())
 }
 
diff --git a/tests/ui-fulldeps/stable-mir/smir_visitor.rs b/tests/ui-fulldeps/stable-mir/smir_visitor.rs
index 0a6415d490e..cffb41742b4 100644
--- a/tests/ui-fulldeps/stable-mir/smir_visitor.rs
+++ b/tests/ui-fulldeps/stable-mir/smir_visitor.rs
@@ -16,10 +16,10 @@ extern crate rustc_driver;
 extern crate rustc_interface;
 extern crate stable_mir;
 
-use std::collections::HashSet;
 use rustc_smir::rustc_internal;
-use stable_mir::*;
 use stable_mir::mir::MirVisitor;
+use stable_mir::*;
+use std::collections::HashSet;
 use std::io::Write;
 use std::ops::ControlFlow;
 
@@ -27,7 +27,7 @@ const CRATE_NAME: &str = "input";
 
 fn test_visitor() -> ControlFlow<()> {
     let main_fn = stable_mir::entry_fn();
-    let main_body = main_fn.unwrap().body();
+    let main_body = main_fn.unwrap().expect_body();
     let main_visitor = TestVisitor::collect(&main_body);
     assert!(main_visitor.ret_val.is_some());
     assert!(main_visitor.args.is_empty());
@@ -51,7 +51,7 @@ struct TestVisitor<'a> {
     pub tys: HashSet<ty::Ty>,
     pub ret_val: Option<mir::LocalDecl>,
     pub args: Vec<mir::LocalDecl>,
-    pub calls: Vec<mir::mono::Instance>
+    pub calls: Vec<mir::mono::Instance>,
 }
 
 impl<'a> TestVisitor<'a> {
@@ -90,8 +90,8 @@ impl<'a> mir::MirVisitor for TestVisitor<'a> {
     fn visit_terminator(&mut self, term: &mir::Terminator, location: mir::visit::Location) {
         if let mir::TerminatorKind::Call { func, .. } = &term.kind {
             let ty::TyKind::RigidTy(ty) = func.ty(self.body.locals()).unwrap().kind() else {
-                unreachable!
-            () };
+                unreachable!()
+            };
             let ty::RigidTy::FnDef(def, args) = ty else { unreachable!() };
             self.calls.push(mir::mono::Instance::resolve(def, &args).unwrap());
         }
diff --git a/tests/ui/abi/c-zst.aarch64-darwin.stderr b/tests/ui/abi/c-zst.aarch64-darwin.stderr
index 57cc48aa9cf..48fa2bf29bc 100644
--- a/tests/ui/abi/c-zst.aarch64-darwin.stderr
+++ b/tests/ui/abi/c-zst.aarch64-darwin.stderr
@@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Memory {
+                           backend_repr: Memory {
                                sized: true,
                            },
                            fields: Arbitrary {
@@ -38,7 +38,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/abi/c-zst.powerpc-linux.stderr b/tests/ui/abi/c-zst.powerpc-linux.stderr
index 67380176730..bfdf94c9900 100644
--- a/tests/ui/abi/c-zst.powerpc-linux.stderr
+++ b/tests/ui/abi/c-zst.powerpc-linux.stderr
@@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Memory {
+                           backend_repr: Memory {
                                sized: true,
                            },
                            fields: Arbitrary {
@@ -49,7 +49,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/abi/c-zst.s390x-linux.stderr b/tests/ui/abi/c-zst.s390x-linux.stderr
index 67380176730..bfdf94c9900 100644
--- a/tests/ui/abi/c-zst.s390x-linux.stderr
+++ b/tests/ui/abi/c-zst.s390x-linux.stderr
@@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Memory {
+                           backend_repr: Memory {
                                sized: true,
                            },
                            fields: Arbitrary {
@@ -49,7 +49,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/abi/c-zst.sparc64-linux.stderr b/tests/ui/abi/c-zst.sparc64-linux.stderr
index 67380176730..bfdf94c9900 100644
--- a/tests/ui/abi/c-zst.sparc64-linux.stderr
+++ b/tests/ui/abi/c-zst.sparc64-linux.stderr
@@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Memory {
+                           backend_repr: Memory {
                                sized: true,
                            },
                            fields: Arbitrary {
@@ -49,7 +49,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/abi/c-zst.x86_64-linux.stderr b/tests/ui/abi/c-zst.x86_64-linux.stderr
index 57cc48aa9cf..48fa2bf29bc 100644
--- a/tests/ui/abi/c-zst.x86_64-linux.stderr
+++ b/tests/ui/abi/c-zst.x86_64-linux.stderr
@@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Memory {
+                           backend_repr: Memory {
                                sized: true,
                            },
                            fields: Arbitrary {
@@ -38,7 +38,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
index 67380176730..bfdf94c9900 100644
--- a/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
+++ b/tests/ui/abi/c-zst.x86_64-pc-windows-gnu.stderr
@@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Memory {
+                           backend_repr: Memory {
                                sized: true,
                            },
                            fields: Arbitrary {
@@ -49,7 +49,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/abi/debug.stderr b/tests/ui/abi/debug.stderr
index 5f73ff7d6bd..2239ba0e588 100644
--- a/tests/ui/abi/debug.stderr
+++ b/tests/ui/abi/debug.stderr
@@ -9,7 +9,7 @@ error: fn_abi_of(test) = FnAbi {
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Scalar(
+                           backend_repr: Scalar(
                                Initialized {
                                    value: Int(
                                        I8,
@@ -48,7 +48,7 @@ error: fn_abi_of(test) = FnAbi {
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Scalar(
+                       backend_repr: Scalar(
                            Initialized {
                                value: Int(
                                    I8,
@@ -107,7 +107,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi {
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Scalar(
+                           backend_repr: Scalar(
                                Initialized {
                                    value: Int(
                                        I8,
@@ -155,7 +155,7 @@ error: fn_abi_of(TestFnPtr) = FnAbi {
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Scalar(
+                       backend_repr: Scalar(
                            Initialized {
                                value: Int(
                                    I8,
@@ -205,7 +205,7 @@ error: fn_abi_of(test_generic) = FnAbi {
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Scalar(
+                           backend_repr: Scalar(
                                Initialized {
                                    value: Pointer(
                                        AddressSpace(
@@ -245,7 +245,7 @@ error: fn_abi_of(test_generic) = FnAbi {
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -292,7 +292,7 @@ error: ABIs are not compatible
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Scalar(
+                           backend_repr: Scalar(
                                Initialized {
                                    value: Int(
                                        I8,
@@ -331,7 +331,7 @@ error: ABIs are not compatible
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -366,7 +366,7 @@ error: ABIs are not compatible
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Scalar(
+                           backend_repr: Scalar(
                                Initialized {
                                    value: Int(
                                        I32,
@@ -405,7 +405,7 @@ error: ABIs are not compatible
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -446,7 +446,7 @@ error: ABIs are not compatible
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Memory {
+                           backend_repr: Memory {
                                sized: true,
                            },
                            fields: Array {
@@ -486,7 +486,7 @@ error: ABIs are not compatible
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -521,7 +521,7 @@ error: ABIs are not compatible
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Memory {
+                           backend_repr: Memory {
                                sized: true,
                            },
                            fields: Array {
@@ -561,7 +561,7 @@ error: ABIs are not compatible
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -602,7 +602,7 @@ error: ABIs are not compatible
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Scalar(
+                           backend_repr: Scalar(
                                Initialized {
                                    value: Float(
                                        F32,
@@ -640,7 +640,7 @@ error: ABIs are not compatible
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -675,7 +675,7 @@ error: ABIs are not compatible
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Scalar(
+                           backend_repr: Scalar(
                                Initialized {
                                    value: Int(
                                        I32,
@@ -714,7 +714,7 @@ error: ABIs are not compatible
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -755,7 +755,7 @@ error: ABIs are not compatible
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Scalar(
+                           backend_repr: Scalar(
                                Initialized {
                                    value: Int(
                                        I32,
@@ -794,7 +794,7 @@ error: ABIs are not compatible
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -829,7 +829,7 @@ error: ABIs are not compatible
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Scalar(
+                           backend_repr: Scalar(
                                Initialized {
                                    value: Int(
                                        I32,
@@ -868,7 +868,7 @@ error: ABIs are not compatible
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -923,7 +923,7 @@ error: fn_abi_of(assoc_test) = FnAbi {
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Scalar(
+                           backend_repr: Scalar(
                                Initialized {
                                    value: Pointer(
                                        AddressSpace(
@@ -975,7 +975,7 @@ error: fn_abi_of(assoc_test) = FnAbi {
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/abi/rust-cold-works-with-rustic-args.rs b/tests/ui/abi/rust-cold-works-with-rustic-args.rs
new file mode 100644
index 00000000000..57027364699
--- /dev/null
+++ b/tests/ui/abi/rust-cold-works-with-rustic-args.rs
@@ -0,0 +1,6 @@
+//@build-pass
+//@compile-flags: -Clink-dead-code=true --crate-type lib
+// We used to not handle all "rustic" ABIs in a (relatively) uniform way,
+// so we failed to fix up arguments for actually passing through the ABI...
+#![feature(rust_cold_cc)]
+pub extern "rust-cold" fn foo(_: [usize; 3]) {}
diff --git a/tests/ui/abi/sysv64-zst.stderr b/tests/ui/abi/sysv64-zst.stderr
index ec85030c106..59d7b004417 100644
--- a/tests/ui/abi/sysv64-zst.stderr
+++ b/tests/ui/abi/sysv64-zst.stderr
@@ -9,7 +9,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                                abi: $SOME_ALIGN,
                                pref: $SOME_ALIGN,
                            },
-                           abi: Memory {
+                           backend_repr: Memory {
                                sized: true,
                            },
                            fields: Arbitrary {
@@ -38,7 +38,7 @@ error: fn_abi_of(pass_zst) = FnAbi {
                            abi: $SOME_ALIGN,
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/abi/unsized-args-in-c-abi-issues-94223-115845.rs b/tests/ui/abi/unsized-args-in-c-abi-issues-94223-115845.rs
index 376630b8d33..7d21307e1b2 100644
--- a/tests/ui/abi/unsized-args-in-c-abi-issues-94223-115845.rs
+++ b/tests/ui/abi/unsized-args-in-c-abi-issues-94223-115845.rs
@@ -1,9 +1,10 @@
 //@ check-pass
 #![allow(improper_ctypes_definitions)]
-#![feature(unsized_tuple_coercion)]
 #![feature(unsized_fn_params)]
 #![crate_type = "lib"]
 
+struct Fat<T: ?Sized>(T);
+
 // Check that computing the fn abi for `bad`, with a external ABI fn ptr that is not FFI-safe, does
 // not ICE.
 
@@ -19,12 +20,12 @@ pub extern "C" fn declare_bad(_x: str) {}
 pub extern "system" fn declare_more_bad(f: dyn FnOnce()) {
 }
 
-fn make_bad() -> extern "C" fn(([u8],)) {
+fn make_bad() -> extern "C" fn(Fat<[u8]>) {
     todo!()
 }
 
 pub fn call_bad() {
     let f = make_bad();
-    let slice: Box<([u8],)> = Box::new(([1; 8],));
+    let slice: Box<Fat<[u8]>> = Box::new(Fat([1; 8]));
     f(*slice);
 }
diff --git a/tests/ui/abi/unsupported.aarch64.stderr b/tests/ui/abi/unsupported.aarch64.stderr
index 01f071f1f31..c11cc4e2d52 100644
--- a/tests/ui/abi/unsupported.aarch64.stderr
+++ b/tests/ui/abi/unsupported.aarch64.stderr
@@ -206,3 +206,113 @@ LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
 error: aborting due to 19 previous errors; 10 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
+Future incompatibility report: Future breakage diagnostic:
+warning: the calling convention "ptx-kernel" is not supported on this target
+  --> $DIR/unsupported.rs:35:15
+   |
+LL | fn ptx_ptr(f: extern "ptx-kernel" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "aapcs" is not supported on this target
+  --> $DIR/unsupported.rs:51:17
+   |
+LL | fn aapcs_ptr(f: extern "aapcs" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "msp430-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:73:18
+   |
+LL | fn msp430_ptr(f: extern "msp430-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "avr-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:83:15
+   |
+LL | fn avr_ptr(f: extern "avr-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "riscv-interrupt-m" is not supported on this target
+  --> $DIR/unsupported.rs:96:17
+   |
+LL | fn riscv_ptr(f: extern "riscv-interrupt-m" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "x86-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:118:15
+   |
+LL | fn x86_ptr(f: extern "x86-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "thiscall" is not supported on this target
+  --> $DIR/unsupported.rs:141:20
+   |
+LL | fn thiscall_ptr(f: extern "thiscall" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "stdcall" is not supported on this target
+  --> $DIR/unsupported.rs:167:19
+   |
+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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
+  --> $DIR/unsupported.rs:187:21
+   |
+LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
+  --> $DIR/unsupported.rs:195:22
+   |
+LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
diff --git a/tests/ui/abi/unsupported.arm.stderr b/tests/ui/abi/unsupported.arm.stderr
index dfb4b573349..b2f24381336 100644
--- a/tests/ui/abi/unsupported.arm.stderr
+++ b/tests/ui/abi/unsupported.arm.stderr
@@ -185,3 +185,102 @@ LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
 error: aborting due to 17 previous errors; 9 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
+Future incompatibility report: Future breakage diagnostic:
+warning: the calling convention "ptx-kernel" is not supported on this target
+  --> $DIR/unsupported.rs:35:15
+   |
+LL | fn ptx_ptr(f: extern "ptx-kernel" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "msp430-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:73:18
+   |
+LL | fn msp430_ptr(f: extern "msp430-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "avr-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:83:15
+   |
+LL | fn avr_ptr(f: extern "avr-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "riscv-interrupt-m" is not supported on this target
+  --> $DIR/unsupported.rs:96:17
+   |
+LL | fn riscv_ptr(f: extern "riscv-interrupt-m" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "x86-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:118:15
+   |
+LL | fn x86_ptr(f: extern "x86-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "thiscall" is not supported on this target
+  --> $DIR/unsupported.rs:141:20
+   |
+LL | fn thiscall_ptr(f: extern "thiscall" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "stdcall" is not supported on this target
+  --> $DIR/unsupported.rs:167:19
+   |
+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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
+  --> $DIR/unsupported.rs:187:21
+   |
+LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
+  --> $DIR/unsupported.rs:195:22
+   |
+LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
diff --git a/tests/ui/abi/unsupported.i686.stderr b/tests/ui/abi/unsupported.i686.stderr
index d7b76a4730b..94bd9b8af90 100644
--- a/tests/ui/abi/unsupported.i686.stderr
+++ b/tests/ui/abi/unsupported.i686.stderr
@@ -143,3 +143,80 @@ LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
 error: aborting due to 13 previous errors; 7 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
+Future incompatibility report: Future breakage diagnostic:
+warning: the calling convention "ptx-kernel" is not supported on this target
+  --> $DIR/unsupported.rs:35:15
+   |
+LL | fn ptx_ptr(f: extern "ptx-kernel" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "aapcs" is not supported on this target
+  --> $DIR/unsupported.rs:51:17
+   |
+LL | fn aapcs_ptr(f: extern "aapcs" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "msp430-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:73:18
+   |
+LL | fn msp430_ptr(f: extern "msp430-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "avr-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:83:15
+   |
+LL | fn avr_ptr(f: extern "avr-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "riscv-interrupt-m" is not supported on this target
+  --> $DIR/unsupported.rs:96:17
+   |
+LL | fn riscv_ptr(f: extern "riscv-interrupt-m" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
+  --> $DIR/unsupported.rs:187:21
+   |
+LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
+  --> $DIR/unsupported.rs:195:22
+   |
+LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
diff --git a/tests/ui/abi/unsupported.riscv32.stderr b/tests/ui/abi/unsupported.riscv32.stderr
index eef2ead4f0f..c6ff47283c6 100644
--- a/tests/ui/abi/unsupported.riscv32.stderr
+++ b/tests/ui/abi/unsupported.riscv32.stderr
@@ -185,3 +185,102 @@ LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
 error: aborting due to 17 previous errors; 9 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
+Future incompatibility report: Future breakage diagnostic:
+warning: the calling convention "ptx-kernel" is not supported on this target
+  --> $DIR/unsupported.rs:35:15
+   |
+LL | fn ptx_ptr(f: extern "ptx-kernel" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "aapcs" is not supported on this target
+  --> $DIR/unsupported.rs:51:17
+   |
+LL | fn aapcs_ptr(f: extern "aapcs" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "msp430-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:73:18
+   |
+LL | fn msp430_ptr(f: extern "msp430-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "avr-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:83:15
+   |
+LL | fn avr_ptr(f: extern "avr-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "x86-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:118:15
+   |
+LL | fn x86_ptr(f: extern "x86-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "thiscall" is not supported on this target
+  --> $DIR/unsupported.rs:141:20
+   |
+LL | fn thiscall_ptr(f: extern "thiscall" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "stdcall" is not supported on this target
+  --> $DIR/unsupported.rs:167:19
+   |
+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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
+  --> $DIR/unsupported.rs:187:21
+   |
+LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
+  --> $DIR/unsupported.rs:195:22
+   |
+LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
diff --git a/tests/ui/abi/unsupported.riscv64.stderr b/tests/ui/abi/unsupported.riscv64.stderr
index eef2ead4f0f..c6ff47283c6 100644
--- a/tests/ui/abi/unsupported.riscv64.stderr
+++ b/tests/ui/abi/unsupported.riscv64.stderr
@@ -185,3 +185,102 @@ LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
 error: aborting due to 17 previous errors; 9 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
+Future incompatibility report: Future breakage diagnostic:
+warning: the calling convention "ptx-kernel" is not supported on this target
+  --> $DIR/unsupported.rs:35:15
+   |
+LL | fn ptx_ptr(f: extern "ptx-kernel" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "aapcs" is not supported on this target
+  --> $DIR/unsupported.rs:51:17
+   |
+LL | fn aapcs_ptr(f: extern "aapcs" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "msp430-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:73:18
+   |
+LL | fn msp430_ptr(f: extern "msp430-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "avr-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:83:15
+   |
+LL | fn avr_ptr(f: extern "avr-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "x86-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:118:15
+   |
+LL | fn x86_ptr(f: extern "x86-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "thiscall" is not supported on this target
+  --> $DIR/unsupported.rs:141:20
+   |
+LL | fn thiscall_ptr(f: extern "thiscall" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "stdcall" is not supported on this target
+  --> $DIR/unsupported.rs:167:19
+   |
+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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
+  --> $DIR/unsupported.rs:187:21
+   |
+LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
+  --> $DIR/unsupported.rs:195:22
+   |
+LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
diff --git a/tests/ui/abi/unsupported.x64.stderr b/tests/ui/abi/unsupported.x64.stderr
index 80613d83e58..0a9f9a69123 100644
--- a/tests/ui/abi/unsupported.x64.stderr
+++ b/tests/ui/abi/unsupported.x64.stderr
@@ -185,3 +185,102 @@ LL | extern "C-cmse-nonsecure-entry" fn cmse_entry() {}
 error: aborting due to 17 previous errors; 9 warnings emitted
 
 For more information about this error, try `rustc --explain E0570`.
+Future incompatibility report: Future breakage diagnostic:
+warning: the calling convention "ptx-kernel" is not supported on this target
+  --> $DIR/unsupported.rs:35:15
+   |
+LL | fn ptx_ptr(f: extern "ptx-kernel" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "aapcs" is not supported on this target
+  --> $DIR/unsupported.rs:51:17
+   |
+LL | fn aapcs_ptr(f: extern "aapcs" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "msp430-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:73:18
+   |
+LL | fn msp430_ptr(f: extern "msp430-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "avr-interrupt" is not supported on this target
+  --> $DIR/unsupported.rs:83:15
+   |
+LL | fn avr_ptr(f: extern "avr-interrupt" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "riscv-interrupt-m" is not supported on this target
+  --> $DIR/unsupported.rs:96:17
+   |
+LL | fn riscv_ptr(f: extern "riscv-interrupt-m" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "thiscall" is not supported on this target
+  --> $DIR/unsupported.rs:141:20
+   |
+LL | fn thiscall_ptr(f: extern "thiscall" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "stdcall" is not supported on this target
+  --> $DIR/unsupported.rs:167:19
+   |
+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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
+  --> $DIR/unsupported.rs:187:21
+   |
+LL | fn cmse_call_ptr(f: extern "C-cmse-nonsecure-call" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
+Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-entry" is not supported on this target
+  --> $DIR/unsupported.rs:195:22
+   |
+LL | fn cmse_entry_ptr(f: extern "C-cmse-nonsecure-entry" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
diff --git a/tests/ui/associated-inherent-types/issue-109299-1.stderr b/tests/ui/associated-inherent-types/issue-109299-1.stderr
index 07a00b6b9a9..77a78da852f 100644
--- a/tests/ui/associated-inherent-types/issue-109299-1.stderr
+++ b/tests/ui/associated-inherent-types/issue-109299-1.stderr
@@ -2,7 +2,7 @@ error[E0220]: associated type `Cursor` not found for `Lexer<T>` in the current s
   --> $DIR/issue-109299-1.rs:10:40
    |
 LL | struct Lexer<T>(T);
-   | --------------- associated item `Cursor` not found for this struct
+   | --------------- associated type `Cursor` not found for this struct
 ...
 LL | type X = impl for<T> Fn() -> Lexer<T>::Cursor;
    |                                        ^^^^^^ associated item not found in `Lexer<T>`
@@ -14,7 +14,7 @@ error[E0220]: associated type `Cursor` not found for `Lexer<T>` in the current s
   --> $DIR/issue-109299-1.rs:10:40
    |
 LL | struct Lexer<T>(T);
-   | --------------- associated item `Cursor` not found for this struct
+   | --------------- associated type `Cursor` not found for this struct
 ...
 LL | type X = impl for<T> Fn() -> Lexer<T>::Cursor;
    |                                        ^^^^^^ associated item not found in `Lexer<T>`
diff --git a/tests/ui/associated-inherent-types/issue-109789.rs b/tests/ui/associated-inherent-types/issue-109789.rs
index 46dd4590141..e3c490b2dc8 100644
--- a/tests/ui/associated-inherent-types/issue-109789.rs
+++ b/tests/ui/associated-inherent-types/issue-109789.rs
@@ -20,5 +20,6 @@ fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
 //~| ERROR mismatched types
 //~| ERROR higher-ranked subtype error
 //~| ERROR higher-ranked subtype error
+//~| ERROR higher-ranked subtype error
 
 fn main() {}
diff --git a/tests/ui/associated-inherent-types/issue-109789.stderr b/tests/ui/associated-inherent-types/issue-109789.stderr
index c6ea6c5541d..db860a64826 100644
--- a/tests/ui/associated-inherent-types/issue-109789.stderr
+++ b/tests/ui/associated-inherent-types/issue-109789.stderr
@@ -31,6 +31,14 @@ LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 4 previous errors
+error: higher-ranked subtype error
+  --> $DIR/issue-109789.rs:18:1
+   |
+LL | fn bar(_: Foo<for<'a> fn(&'a ())>::Assoc) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/associated-inherent-types/issue-111404-1.rs b/tests/ui/associated-inherent-types/issue-111404-1.rs
index 3255bf20ebd..cad6d48b1c5 100644
--- a/tests/ui/associated-inherent-types/issue-111404-1.rs
+++ b/tests/ui/associated-inherent-types/issue-111404-1.rs
@@ -12,5 +12,6 @@ fn bar(_: fn(Foo<for<'b> fn(Foo<fn(&'b ())>::Assoc)>::Assoc)) {}
 //~| ERROR mismatched types [E0308]
 //~| ERROR higher-ranked subtype error
 //~| ERROR higher-ranked subtype error
+//~| ERROR higher-ranked subtype error
 
 fn main() {}
diff --git a/tests/ui/associated-inherent-types/issue-111404-1.stderr b/tests/ui/associated-inherent-types/issue-111404-1.stderr
index 5074c877a8e..ce49126c316 100644
--- a/tests/ui/associated-inherent-types/issue-111404-1.stderr
+++ b/tests/ui/associated-inherent-types/issue-111404-1.stderr
@@ -31,6 +31,14 @@ LL | fn bar(_: fn(Foo<for<'b> fn(Foo<fn(&'b ())>::Assoc)>::Assoc)) {}
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 4 previous errors
+error: higher-ranked subtype error
+  --> $DIR/issue-111404-1.rs:10:1
+   |
+LL | fn bar(_: fn(Foo<for<'b> fn(Foo<fn(&'b ())>::Assoc)>::Assoc)) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr
index 9bd5a842fdc..a247d6d5b45 100644
--- a/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr
+++ b/tests/ui/associated-inherent-types/not-found-self-type-differs-shadowing-trait-item.shadowed.stderr
@@ -2,7 +2,7 @@ error[E0220]: associated type `Pr` not found for `S<bool>` in the current scope
   --> $DIR/not-found-self-type-differs-shadowing-trait-item.rs:28:23
    |
 LL | struct S<T>(T);
-   | ----------- associated item `Pr` not found for this struct
+   | ----------- associated type `Pr` not found for this struct
 ...
 LL |     let _: S::<bool>::Pr = ();
    |                       ^^ associated item not found in `S<bool>`
diff --git a/tests/ui/associated-inherent-types/not-found-self-type-differs.stderr b/tests/ui/associated-inherent-types/not-found-self-type-differs.stderr
index 1871407c64f..6194c6ff4d7 100644
--- a/tests/ui/associated-inherent-types/not-found-self-type-differs.stderr
+++ b/tests/ui/associated-inherent-types/not-found-self-type-differs.stderr
@@ -2,7 +2,7 @@ error[E0220]: associated type `Proj` not found for `Family<Option<()>>` in the c
   --> $DIR/not-found-self-type-differs.rs:15:32
    |
 LL | struct Family<T>(T);
-   | ---------------- associated item `Proj` not found for this struct
+   | ---------------- associated type `Proj` not found for this struct
 ...
 LL |     let _: Family<Option<()>>::Proj;
    |                                ^^^^ associated item not found in `Family<Option<()>>`
@@ -15,7 +15,7 @@ error[E0220]: associated type `Proj` not found for `Family<PathBuf>` in the curr
   --> $DIR/not-found-self-type-differs.rs:16:40
    |
 LL | struct Family<T>(T);
-   | ---------------- associated item `Proj` not found for this struct
+   | ---------------- associated type `Proj` not found for this struct
 ...
 LL |     let _: Family<std::path::PathBuf>::Proj = ();
    |                                        ^^^^ associated item not found in `Family<PathBuf>`
diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr
index 73657906761..dd51192e06f 100644
--- a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr
+++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-0.stderr
@@ -2,7 +2,7 @@ error: the associated type `Yield` exists for `Container<[u8]>`, but its trait b
   --> $DIR/not-found-unsatisfied-bounds-0.rs:19:29
    |
 LL | struct Container<T: ?Sized>(T);
-   | --------------------------- associated item `Yield` not found for this struct
+   | --------------------------- associated type `Yield` not found for this struct
 ...
 LL |     let _: Container<[u8]>::Yield = 1;
    |                             ^^^^^ associated type cannot be referenced on `Container<[u8]>` due to unsatisfied trait bounds
@@ -14,7 +14,7 @@ error: the associated type `Combination` exists for `Duple<String, Rc<str>>`, bu
   --> $DIR/not-found-unsatisfied-bounds-0.rs:20:45
    |
 LL | struct Duple<T, U>(T, U);
-   | ------------------ associated item `Combination` not found for this struct
+   | ------------------ associated type `Combination` not found for this struct
 ...
 LL |     let _: Duple<String, std::rc::Rc<str>>::Combination;
    |                                             ^^^^^^^^^^^ associated type cannot be referenced on `Duple<String, Rc<str>>` due to unsatisfied trait bounds
diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr
index 0d5f781dc63..c27e1f49faa 100644
--- a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr
+++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-1.stderr
@@ -5,7 +5,7 @@ LL |     let _: Container<T>::Proj = String::new();
    |                          ^^^^ associated type cannot be referenced on `Container<T>` due to unsatisfied trait bounds
 ...
 LL | struct Container<T>(T);
-   | ------------------- associated item `Proj` not found for this struct
+   | ------------------- associated type `Proj` not found for this struct
    |
    = note: the following trait bounds were not satisfied:
            `T: Clone`
diff --git a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr
index 1613af6b8b1..db6c71a626f 100644
--- a/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr
+++ b/tests/ui/associated-inherent-types/not-found-unsatisfied-bounds-in-multiple-impls.stderr
@@ -2,7 +2,7 @@ error: the associated type `X` exists for `S<Featureless, Featureless>`, but its
   --> $DIR/not-found-unsatisfied-bounds-in-multiple-impls.rs:19:43
    |
 LL | struct S<A, B>(A, B);
-   | -------------- associated item `X` not found for this struct
+   | -------------- associated type `X` not found for this struct
 LL | struct Featureless;
    | ------------------ doesn't satisfy `Featureless: One` or `Featureless: Two`
 ...
diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.fixed b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.fixed
new file mode 100644
index 00000000000..7af986267aa
--- /dev/null
+++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.fixed
@@ -0,0 +1,40 @@
+//@ edition: 2021
+//@ run-rustfix
+#![feature(return_type_notation)]
+#![allow(dead_code)]
+
+trait Trait {
+    async fn method() {}
+}
+
+fn foo<T: Trait<method(..): Send>>() {}
+//~^ ERROR argument types not allowed with return type notation
+
+fn bar<T: Trait<method(..): Send>>() {}
+//~^ ERROR return type not allowed with return type notation
+
+fn baz<T: Trait<method(..): Send>>() {}
+//~^ ERROR return type notation arguments must be elided with `..`
+
+fn foo_path<T: Trait>() where T::method(..): Send {}
+//~^ ERROR argument types not allowed with return type notation
+
+fn bar_path<T: Trait>() where T::method(..): Send {}
+//~^ ERROR return type not allowed with return type notation
+
+fn bay_path<T: Trait>() where T::method(..): Send {}
+//~^ ERROR return type not allowed with return type notation
+
+fn baz_path<T: Trait>() where T::method(..): Send {}
+//~^ ERROR return type notation arguments must be elided with `..`
+
+fn foo_qualified<T: Trait>() where T::method(..): Send {}
+//~^ ERROR expected associated type
+
+fn bar_qualified<T: Trait>() where T::method(..): Send {}
+//~^ ERROR expected associated type
+
+fn baz_qualified<T: Trait>() where T::method(..): Send {}
+//~^ ERROR expected associated type
+
+fn main() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs
index 90fd2c2b4f3..983836e6433 100644
--- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs
+++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.rs
@@ -1,6 +1,7 @@
 //@ edition: 2021
-
+//@ run-rustfix
 #![feature(return_type_notation)]
+#![allow(dead_code)]
 
 trait Trait {
     async fn method() {}
diff --git a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr
index bd02b7d6534..e1245a04c7f 100644
--- a/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr
+++ b/tests/ui/associated-type-bounds/return-type-notation/bad-inputs-and-output.stderr
@@ -1,5 +1,5 @@
 error: return type not allowed with return type notation
-  --> $DIR/bad-inputs-and-output.rs:24:45
+  --> $DIR/bad-inputs-and-output.rs:25:45
    |
 LL | fn bay_path<T: Trait>() where T::method(..) -> (): Send {}
    |                                             ^^^^^
@@ -11,25 +11,43 @@ LL + fn bay_path<T: Trait>() where T::method(..): Send {}
    |
 
 error[E0575]: expected associated type, found associated function `Trait::method`
-  --> $DIR/bad-inputs-and-output.rs:30:36
+  --> $DIR/bad-inputs-and-output.rs:31:36
    |
 LL | fn foo_qualified<T: Trait>() where <T as Trait>::method(i32): Send {}
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^ not a associated type
+   |
+help: you might have meant to use the return type notation syntax
+   |
+LL - fn foo_qualified<T: Trait>() where <T as Trait>::method(i32): Send {}
+LL + fn foo_qualified<T: Trait>() where T::method(..): Send {}
+   |
 
 error[E0575]: expected associated type, found associated function `Trait::method`
-  --> $DIR/bad-inputs-and-output.rs:33:36
+  --> $DIR/bad-inputs-and-output.rs:34:36
    |
 LL | fn bar_qualified<T: Trait>() where <T as Trait>::method() -> (): Send {}
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not a associated type
+   |
+help: you might have meant to use the return type notation syntax
+   |
+LL - fn bar_qualified<T: Trait>() where <T as Trait>::method() -> (): Send {}
+LL + fn bar_qualified<T: Trait>() where T::method(..): Send {}
+   |
 
 error[E0575]: expected associated type, found associated function `Trait::method`
-  --> $DIR/bad-inputs-and-output.rs:36:36
+  --> $DIR/bad-inputs-and-output.rs:37:36
    |
 LL | fn baz_qualified<T: Trait>() where <T as Trait>::method(): Send {}
    |                                    ^^^^^^^^^^^^^^^^^^^^^^ not a associated type
+   |
+help: you might have meant to use the return type notation syntax
+   |
+LL - fn baz_qualified<T: Trait>() where <T as Trait>::method(): Send {}
+LL + fn baz_qualified<T: Trait>() where T::method(..): Send {}
+   |
 
 error: argument types not allowed with return type notation
-  --> $DIR/bad-inputs-and-output.rs:9:23
+  --> $DIR/bad-inputs-and-output.rs:10:23
    |
 LL | fn foo<T: Trait<method(i32): Send>>() {}
    |                       ^^^^^
@@ -41,7 +59,7 @@ LL + fn foo<T: Trait<method(..): Send>>() {}
    |
 
 error: return type not allowed with return type notation
-  --> $DIR/bad-inputs-and-output.rs:12:25
+  --> $DIR/bad-inputs-and-output.rs:13:25
    |
 LL | fn bar<T: Trait<method() -> (): Send>>() {}
    |                         ^^^^^^
@@ -53,7 +71,7 @@ LL + fn bar<T: Trait<method(..): Send>>() {}
    |
 
 error: return type notation arguments must be elided with `..`
-  --> $DIR/bad-inputs-and-output.rs:15:23
+  --> $DIR/bad-inputs-and-output.rs:16:23
    |
 LL | fn baz<T: Trait<method(): Send>>() {}
    |                       ^^
@@ -64,7 +82,7 @@ LL | fn baz<T: Trait<method(..): Send>>() {}
    |                        ++
 
 error: argument types not allowed with return type notation
-  --> $DIR/bad-inputs-and-output.rs:18:40
+  --> $DIR/bad-inputs-and-output.rs:19:40
    |
 LL | fn foo_path<T: Trait>() where T::method(i32): Send {}
    |                                        ^^^^^
@@ -76,7 +94,7 @@ LL + fn foo_path<T: Trait>() where T::method(..): Send {}
    |
 
 error: return type not allowed with return type notation
-  --> $DIR/bad-inputs-and-output.rs:21:42
+  --> $DIR/bad-inputs-and-output.rs:22:42
    |
 LL | fn bar_path<T: Trait>() where T::method() -> (): Send {}
    |                                          ^^^^^^
@@ -88,7 +106,7 @@ LL + fn bar_path<T: Trait>() where T::method(..): Send {}
    |
 
 error: return type notation arguments must be elided with `..`
-  --> $DIR/bad-inputs-and-output.rs:27:40
+  --> $DIR/bad-inputs-and-output.rs:28:40
    |
 LL | fn baz_path<T: Trait>() where T::method(): Send {}
    |                                        ^^
diff --git a/tests/ui/associated-types/ident-from-macro-expansion.rs b/tests/ui/associated-types/ident-from-macro-expansion.rs
new file mode 100644
index 00000000000..6aabe457140
--- /dev/null
+++ b/tests/ui/associated-types/ident-from-macro-expansion.rs
@@ -0,0 +1,23 @@
+trait Trait {}
+impl Trait for () {}
+
+macro_rules! fully_qualified {
+    ($id:ident) => {
+        <() as Trait>::$id
+    }
+}
+
+macro_rules! type_dependent {
+    ($t:ident, $id:ident) => {
+        T::$id
+    }
+}
+
+fn t<T: Trait>() {
+    let x: fully_qualified!(Assoc);
+    //~^ ERROR cannot find associated type `Assoc` in trait `Trait`
+    let x: type_dependent!(T, Assoc);
+    //~^ ERROR associated type `Assoc` not found for `T`
+}
+
+fn main() {}
diff --git a/tests/ui/associated-types/ident-from-macro-expansion.stderr b/tests/ui/associated-types/ident-from-macro-expansion.stderr
new file mode 100644
index 00000000000..dabf13c2c17
--- /dev/null
+++ b/tests/ui/associated-types/ident-from-macro-expansion.stderr
@@ -0,0 +1,22 @@
+error[E0576]: cannot find associated type `Assoc` in trait `Trait`
+  --> $DIR/ident-from-macro-expansion.rs:17:29
+   |
+LL |         <() as Trait>::$id
+   |                        --- due to this macro variable
+...
+LL |     let x: fully_qualified!(Assoc);
+   |                             ^^^^^ not found in `Trait`
+
+error[E0220]: associated type `Assoc` not found for `T`
+  --> $DIR/ident-from-macro-expansion.rs:19:31
+   |
+LL |         T::$id
+   |            --- due to this macro variable
+...
+LL |     let x: type_dependent!(T, Assoc);
+   |                               ^^^^^ associated type `Assoc` not found
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0220, E0576.
+For more information about an error, try `rustc --explain E0220`.
diff --git a/tests/ui/async-await/async-closures/kind-due-to-rpit.rs b/tests/ui/async-await/async-closures/kind-due-to-rpit.rs
new file mode 100644
index 00000000000..ad19d93b93a
--- /dev/null
+++ b/tests/ui/async-await/async-closures/kind-due-to-rpit.rs
@@ -0,0 +1,14 @@
+//@ edition: 2024
+
+// Make sure the error message is understandable when an `AsyncFn` goal is not satisfied
+// (due to closure kind), and that goal originates from an RPIT.
+
+fn repro(foo: impl Into<bool>) -> impl AsyncFn() {
+    let inner_fn = async move || {
+        //~^ ERROR expected a closure that implements the `AsyncFn` trait
+        let _ = foo.into();
+    };
+    inner_fn
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/async-closures/kind-due-to-rpit.stderr b/tests/ui/async-await/async-closures/kind-due-to-rpit.stderr
new file mode 100644
index 00000000000..982cc50e14f
--- /dev/null
+++ b/tests/ui/async-await/async-closures/kind-due-to-rpit.stderr
@@ -0,0 +1,17 @@
+error[E0525]: expected a closure that implements the `AsyncFn` trait, but this closure only implements `AsyncFnOnce`
+  --> $DIR/kind-due-to-rpit.rs:7:20
+   |
+LL | fn repro(foo: impl Into<bool>) -> impl AsyncFn() {
+   |                                   -------------- the requirement to implement `AsyncFn` derives from here
+LL |     let inner_fn = async move || {
+   |                    ^^^^^^^^^^^^^ this closure implements `AsyncFnOnce`, not `AsyncFn`
+LL |
+LL |         let _ = foo.into();
+   |                 --- closure is `AsyncFnOnce` because it moves the variable `foo` out of its environment
+LL |     };
+LL |     inner_fn
+   |     -------- return type was inferred to be `{async closure@$DIR/kind-due-to-rpit.rs:7:20: 7:33}` here
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0525`.
diff --git a/tests/ui/async-await/issues/issue-63388-2.rs b/tests/ui/async-await/issues/issue-63388-2.rs
index 8bb5cfa4a59..d9dc602bd1c 100644
--- a/tests/ui/async-await/issues/issue-63388-2.rs
+++ b/tests/ui/async-await/issues/issue-63388-2.rs
@@ -12,7 +12,6 @@ impl Xyz {
     ) -> &dyn Foo //~ ERROR missing lifetime specifier
     {
         foo
-        //~^ ERROR explicit lifetime required in the type of `foo` [E0621]
     }
 }
 
diff --git a/tests/ui/async-await/issues/issue-63388-2.stderr b/tests/ui/async-await/issues/issue-63388-2.stderr
index 7e3c0a1227d..45843bc72cd 100644
--- a/tests/ui/async-await/issues/issue-63388-2.stderr
+++ b/tests/ui/async-await/issues/issue-63388-2.stderr
@@ -12,16 +12,6 @@ help: consider using the `'a` lifetime
 LL |     ) -> &'a dyn Foo
    |           ++
 
-error[E0621]: explicit lifetime required in the type of `foo`
-  --> $DIR/issue-63388-2.rs:14:9
-   |
-LL |         foo: &dyn Foo, bar: &'a dyn Foo
-   |              -------- help: add explicit lifetime `'a` to the type of `foo`: `&'a (dyn Foo + 'a)`
-...
-LL |         foo
-   |         ^^^ lifetime `'a` required
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0106, E0621.
-For more information about an error, try `rustc --explain E0106`.
+For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/async-await/pin-ergonomics/sugar-self.rs b/tests/ui/async-await/pin-ergonomics/sugar-self.rs
new file mode 100644
index 00000000000..3d71b54b1ae
--- /dev/null
+++ b/tests/ui/async-await/pin-ergonomics/sugar-self.rs
@@ -0,0 +1,46 @@
+//@ check-pass
+
+#![feature(pin_ergonomics)]
+#![allow(dead_code, incomplete_features)]
+
+// Makes sure we can handle `&pin mut self` and `&pin const self` as sugar for
+// `self: Pin<&mut Self>` and `self: Pin<&Self>`.
+
+use std::pin::Pin;
+
+struct Foo;
+
+impl Foo {
+    fn baz(&pin mut self) {}
+
+    fn baz_const(&pin const self) {}
+
+    fn baz_lt<'a>(&'a pin mut self) {}
+
+    fn baz_const_lt(&'_ pin const self) {}
+}
+
+fn foo(_: &pin mut Foo) {}
+
+fn foo_const(_: &pin const Foo) {}
+
+fn bar(x: &pin mut Foo) {
+    // For the calls below to work we need to automatically reborrow,
+    // as if the user had written `foo(x.as_mut())`.
+    foo(x);
+    foo(x);
+
+    Foo::baz(x);
+    Foo::baz(x);
+
+    // make sure we can reborrow &mut as &.
+    foo_const(x);
+    Foo::baz_const(x);
+
+    let x: &pin const _ = Pin::new(&Foo);
+
+    foo_const(x); // make sure reborrowing from & to & works.
+    foo_const(x);
+}
+
+fn main() {}
diff --git a/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs b/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs
index 686dcb277f8..d94572ef5d6 100644
--- a/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs
+++ b/tests/ui/attributes/auxiliary/used_pre_main_constructor.rs
@@ -10,14 +10,15 @@
 
 #[cfg_attr(
     any(
-        target_os = "linux",
         target_os = "android",
+        target_os = "dragonfly",
         target_os = "freebsd",
+        target_os = "haiku",
+        target_os = "illumos",
+        target_os = "linux",
         target_os = "netbsd",
+        target_os = "nto",
         target_os = "openbsd",
-        target_os = "dragonfly",
-        target_os = "illumos",
-        target_os = "haiku"
     ),
     link_section = ".init_array"
 )]
diff --git a/tests/ui/attributes/decl_macro_ty_in_attr_macro.rs b/tests/ui/attributes/decl_macro_ty_in_attr_macro.rs
new file mode 100644
index 00000000000..e633c08be3a
--- /dev/null
+++ b/tests/ui/attributes/decl_macro_ty_in_attr_macro.rs
@@ -0,0 +1,20 @@
+// tests for #137662: using a ty or (or most other) fragment inside an attr macro wouldn't work
+// because of a missing code path. With $repr: tt it did work.
+//@ check-pass
+
+macro_rules! foo {
+    {
+        $repr:ty
+    } => {
+        #[repr($repr)]
+        pub enum Foo {
+            Bar = 0i32,
+        }
+    }
+}
+
+foo! {
+    i32
+}
+
+fn main() {}
diff --git a/tests/ui/c-variadic/variadic-ffi-2.rs b/tests/ui/c-variadic/variadic-ffi-2.rs
index 99f83f22d17..da7bb76fc14 100644
--- a/tests/ui/c-variadic/variadic-ffi-2.rs
+++ b/tests/ui/c-variadic/variadic-ffi-2.rs
@@ -1,8 +1,6 @@
-//@ ignore-arm stdcall isn't supported
 #![feature(extended_varargs_abi_support)]
 
-#[allow(unsupported_fn_ptr_calling_conventions)]
-fn baz(f: extern "stdcall" fn(usize, ...)) {
+fn baz(f: extern "Rust" fn(usize, ...)) {
     //~^ ERROR: C-variadic function must have a compatible calling convention,
     // like C, cdecl, system, aapcs, win64, sysv64 or efiapi
     f(22, 44);
diff --git a/tests/ui/c-variadic/variadic-ffi-2.stderr b/tests/ui/c-variadic/variadic-ffi-2.stderr
index e52de93a926..9f8dcefdb03 100644
--- a/tests/ui/c-variadic/variadic-ffi-2.stderr
+++ b/tests/ui/c-variadic/variadic-ffi-2.stderr
@@ -1,8 +1,8 @@
 error[E0045]: C-variadic function must have a compatible calling convention, like `C`, `cdecl`, `system`, `aapcs`, `win64`, `sysv64` or `efiapi`
-  --> $DIR/variadic-ffi-2.rs:5:11
+  --> $DIR/variadic-ffi-2.rs:3:11
    |
-LL | fn baz(f: extern "stdcall" fn(usize, ...)) {
-   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
+LL | fn baz(f: extern "Rust" fn(usize, ...)) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ C-variadic function must have a compatible calling convention
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/cast/cast-rfc0401-vtable-kinds.rs b/tests/ui/cast/cast-rfc0401-vtable-kinds.rs
index 5704a33cc87..78f6dca1818 100644
--- a/tests/ui/cast/cast-rfc0401-vtable-kinds.rs
+++ b/tests/ui/cast/cast-rfc0401-vtable-kinds.rs
@@ -2,8 +2,6 @@
 // Check that you can cast between different pointers to trait objects
 // whose vtable have the same kind (both lengths, or both trait pointers).
 
-#![feature(unsized_tuple_coercion)]
-
 trait Bar { //~ WARN trait `Bar` is never used
     fn bar(&self) { println!("Bar!"); }
 }
@@ -19,10 +17,6 @@ fn foo_to_bar<T:?Sized>(u: *const FooS<T>) -> *const BarS<T> {
     u as *const BarS<T>
 }
 
-fn tuple_i32_to_u32<T:?Sized>(u: *const (i32, T)) -> *const (u32, T) {
-    u as *const (u32, T)
-}
-
 
 fn main() {
     let s = FooS([0,1,2]);
@@ -31,14 +25,4 @@ fn main() {
     let bar_ref : *const BarS<[u32]> = foo_to_bar(u);
     let z : &BarS<[u32]> = unsafe{&*bar_ref};
     assert_eq!(&z.0, &[0,1,2]);
-
-    // this assumes that tuple reprs for (i32, _) and (u32, _) are
-    // the same.
-    let s = (0i32, [0, 1, 2]);
-    let u: &(i32, [u8]) = &s;
-    let u: *const (i32, [u8]) = u;
-    let u_u32 : *const (u32, [u8]) = tuple_i32_to_u32(u);
-    unsafe {
-        assert_eq!(&(*u_u32).1, &[0, 1, 2]);
-    }
 }
diff --git a/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr b/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr
index 4f57e2e7df7..01277fd632e 100644
--- a/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr
+++ b/tests/ui/cast/cast-rfc0401-vtable-kinds.stderr
@@ -1,5 +1,5 @@
 warning: trait `Bar` is never used
-  --> $DIR/cast-rfc0401-vtable-kinds.rs:7:7
+  --> $DIR/cast-rfc0401-vtable-kinds.rs:5:7
    |
 LL | trait Bar {
    |       ^^^
diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs
index 46e72ea0877..3a1e667d03a 100644
--- a/tests/ui/cast/ptr-to-trait-obj-add-auto.rs
+++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.rs
@@ -1,18 +1,20 @@
-//@ check-pass
-
 trait Trait<'a> {}
 
 fn add_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send) {
     x as _
-    //~^ warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on
-    //~| warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //~^ ERROR cannot add auto trait `Send` to dyn bound via pointer cast
+    //~| NOTE unsupported cast
+    //~| NOTE this could allow UB elsewhere
+    //~| HELP use `transmute` if you're sure this is sound
 }
 
 // (to test diagnostic list formatting)
 fn add_multiple_auto<'a>(x: *mut dyn Trait<'a>) -> *mut (dyn Trait<'a> + Send + Sync + Unpin) {
     x as _
-    //~^ warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on
-    //~| warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    //~^ ERROR cannot add auto traits `Send`, `Sync`, and `Unpin` to dyn bound via pointer cast
+    //~| NOTE unsupported cast
+    //~| NOTE this could allow UB elsewhere
+    //~| HELP use `transmute` if you're sure this is sound
 }
 
 fn main() {}
diff --git a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr
index e5ef8bf76b4..b64ca9b32bf 100644
--- a/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr
+++ b/tests/ui/cast/ptr-to-trait-obj-add-auto.stderr
@@ -1,43 +1,21 @@
-warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on
-  --> $DIR/ptr-to-trait-obj-add-auto.rs:6:5
+error[E0804]: cannot add auto trait `Send` to dyn bound via pointer cast
+  --> $DIR/ptr-to-trait-obj-add-auto.rs:4:5
    |
 LL |     x as _
-   |     ^^^^^^
+   |     ^^^^^^ unsupported cast
    |
-   = 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 #127323 <https://github.com/rust-lang/rust/issues/127323>
-   = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default
+   = note: this could allow UB elsewhere
+   = help: use `transmute` if you're sure this is sound
 
-warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on
+error[E0804]: cannot add auto traits `Send`, `Sync`, and `Unpin` to dyn bound via pointer cast
   --> $DIR/ptr-to-trait-obj-add-auto.rs:13:5
    |
 LL |     x as _
-   |     ^^^^^^
+   |     ^^^^^^ unsupported cast
    |
-   = 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 #127323 <https://github.com/rust-lang/rust/issues/127323>
+   = note: this could allow UB elsewhere
+   = help: use `transmute` if you're sure this is sound
 
-warning: 2 warnings emitted
-
-Future incompatibility report: Future breakage diagnostic:
-warning: adding an auto trait `Send` to a trait object in a pointer cast may cause UB later on
-  --> $DIR/ptr-to-trait-obj-add-auto.rs:6:5
-   |
-LL |     x as _
-   |     ^^^^^^
-   |
-   = 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 #127323 <https://github.com/rust-lang/rust/issues/127323>
-   = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default
-
-Future breakage diagnostic:
-warning: adding auto traits `Send`, `Sync`, and `Unpin` to a trait object in a pointer cast may cause UB later on
-  --> $DIR/ptr-to-trait-obj-add-auto.rs:13:5
-   |
-LL |     x as _
-   |     ^^^^^^
-   |
-   = 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 #127323 <https://github.com/rust-lang/rust/issues/127323>
-   = note: `#[warn(ptr_cast_add_auto_to_object)]` on by default
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0804`.
diff --git a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/gate_test.stderr b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/gate_test.stderr
index 63260b5c78f..beb0ab70cc7 100644
--- a/tests/ui/cmse-nonsecure/cmse-nonsecure-call/gate_test.stderr
+++ b/tests/ui/cmse-nonsecure/cmse-nonsecure-call/gate_test.stderr
@@ -11,3 +11,13 @@ LL |         core::mem::transmute::<usize, extern "C-cmse-nonsecure-call" fn(i32
 error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0658`.
+Future incompatibility report: Future breakage diagnostic:
+warning: the calling convention "C-cmse-nonsecure-call" is not supported on this target
+  --> $DIR/gate_test.rs:5:39
+   |
+LL |         core::mem::transmute::<usize, extern "C-cmse-nonsecure-call" fn(i32, i32, i32, i32) -> i32>(
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = 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>
+
diff --git a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs
index 24b87892753..15ca0577e4a 100644
--- a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs
+++ b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.rs
@@ -8,10 +8,14 @@ struct TestType<T>(::std::marker::PhantomData<T>);
 
 unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
 
-impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and negative implementation
+impl<T: MyTrait> !Send for TestType<T> {}
+//~^ ERROR found both positive and negative implementation
+//~| ERROR `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
 
-unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
+unsafe impl<T: 'static> Send for TestType<T> {}
+//~^ ERROR conflicting implementations
 
 impl !Send for TestType<i32> {}
+//~^ ERROR `!Send` impls cannot be specialized
 
 fn main() {}
diff --git a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
index 2463f38a922..c6aed150201 100644
--- a/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
+++ b/tests/ui/coherence/coherence-conflicting-negative-trait-impl.stderr
@@ -8,7 +8,7 @@ LL | impl<T: MyTrait> !Send for TestType<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
 
 error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>`
-  --> $DIR/coherence-conflicting-negative-trait-impl.rs:13:1
+  --> $DIR/coherence-conflicting-negative-trait-impl.rs:15:1
    |
 LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
    | ------------------------------------------------------ first implementation here
@@ -16,7 +16,32 @@ LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
 LL | unsafe impl<T: 'static> Send for TestType<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
 
-error: aborting due to 2 previous errors
+error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
+  --> $DIR/coherence-conflicting-negative-trait-impl.rs:11:9
+   |
+LL | impl<T: MyTrait> !Send for TestType<T> {}
+   |         ^^^^^^^
+   |
+note: the implementor must specify the same requirement
+  --> $DIR/coherence-conflicting-negative-trait-impl.rs:7:1
+   |
+LL | struct TestType<T>(::std::marker::PhantomData<T>);
+   | ^^^^^^^^^^^^^^^^^^
+
+error[E0366]: `!Send` impls cannot be specialized
+  --> $DIR/coherence-conflicting-negative-trait-impl.rs:18:1
+   |
+LL | impl !Send for TestType<i32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `i32` is not a generic parameter
+note: use the same sequence of generic lifetime, type and const parameters as the struct definition
+  --> $DIR/coherence-conflicting-negative-trait-impl.rs:7:1
+   |
+LL | struct TestType<T>(::std::marker::PhantomData<T>);
+   | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0119, E0751.
+Some errors have detailed explanations: E0119, E0366, E0367, E0751.
 For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr b/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr
index 77d1bdee5ac..bc81dd6f286 100644
--- a/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr
+++ b/tests/ui/coherence/coherence-impl-trait-for-marker-trait-negative.stderr
@@ -1,9 +1,3 @@
-error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
-  --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
-   |
-LL | impl !Marker1 for dyn Object + Marker2 {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
-
 error[E0321]: traits with a default impl, like `Marker1`, cannot be implemented for trait object `(dyn Object + Marker2 + 'static)`
   --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
    |
@@ -12,11 +6,11 @@ LL | impl !Marker1 for dyn Object + Marker2 {}
    |
    = note: a trait object implements `Marker1` if and only if `Marker1` is one of the trait object's trait bounds
 
-error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
-  --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:18:1
+error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker1`
+  --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:15:1
    |
-LL | impl !Marker2 for dyn Object + Marker2 {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
+LL | impl !Marker1 for dyn Object + Marker2 {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker1`
 
 error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + Marker2 + 'static)`
   --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:18:1
@@ -26,6 +20,12 @@ LL | impl !Marker2 for dyn Object + Marker2 {}
    |
    = note: a trait object implements `Marker2` if and only if `Marker2` is one of the trait object's trait bounds
 
+error[E0371]: the object type `(dyn Object + Marker2 + 'static)` automatically implements the trait `Marker2`
+  --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:18:1
+   |
+LL | impl !Marker2 for dyn Object + Marker2 {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `(dyn Object + Marker2 + 'static)` automatically implements trait `Marker2`
+
 error[E0321]: traits with a default impl, like `Marker2`, cannot be implemented for trait object `(dyn Object + 'static)`
   --> $DIR/coherence-impl-trait-for-marker-trait-negative.rs:26:1
    |
diff --git a/tests/ui/coherence/coherence-orphan.rs b/tests/ui/coherence/coherence-orphan.rs
index aee6647a788..665fa15c56e 100644
--- a/tests/ui/coherence/coherence-orphan.rs
+++ b/tests/ui/coherence/coherence-orphan.rs
@@ -8,12 +8,13 @@ use lib::TheTrait;
 struct TheType;
 
 impl TheTrait<usize> for isize {}
-//~^ ERROR E0117
+//~^ ERROR  only traits defined in the current crate can be implemented for primitive types
 
 impl TheTrait<TheType> for isize {}
 
 impl TheTrait<isize> for TheType {}
 
-impl !Send for Vec<isize> {} //~ ERROR E0117
+impl !Send for Vec<isize> {}
+//~^ ERROR only traits defined in the current crate can be implemented for types defined outside of the crate
 
 fn main() {}
diff --git a/tests/ui/coherence/coherence-overlap-negative-impls.rs b/tests/ui/coherence/coherence-overlap-negative-impls.rs
deleted file mode 100644
index ffcd56817e5..00000000000
--- a/tests/ui/coherence/coherence-overlap-negative-impls.rs
+++ /dev/null
@@ -1,44 +0,0 @@
-//@ check-pass
-//@ known-bug: #74629
-
-// Should fail. The `0` and `1` impls overlap, violating coherence. Eg, with
-// `T = Test, F = ()`, all bounds are true, making both impls applicable.
-// `Test: Fold<Nil>`, `Test: Fold<()>` are true because of `2`.
-// `Is<Test>: NotNil` is true because of `auto trait` and lack of negative impl.
-
-#![feature(negative_impls)]
-#![feature(auto_traits)]
-
-struct Nil;
-struct Cons<H>(H);
-struct Test;
-
-trait Fold<F> {}
-
-impl<T, F> Fold<F> for Cons<T>
-// 0
-where
-    T: Fold<Nil>,
-{
-}
-
-impl<T, F> Fold<F> for Cons<T>
-// 1
-where
-    T: Fold<F>,
-    private::Is<T>: private::NotNil,
-{
-}
-
-impl<F> Fold<F> for Test {} // 2
-
-mod private {
-    use crate::Nil;
-
-    pub struct Is<T>(T);
-    pub auto trait NotNil {}
-
-    impl !NotNil for Is<Nil> {}
-}
-
-fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr
index 30a45ce377e..b73611c79b2 100644
--- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr
@@ -54,12 +54,6 @@ warning: type `v17` should have an upper camel case name
 LL |     pub struct v17<const v10: usize, const v7: v11> {
    |                ^^^ help: convert the identifier to upper camel case (notice the capitalization): `V17`
 
-error[E0425]: cannot find function `v6` in this scope
-  --> $DIR/unevaluated-const-ice-119731.rs:13:35
-   |
-LL |     const v0: [[usize; v4]; v4] = v6(v8);
-   |                                   ^^ not found in this scope
-
 error: `[[usize; v4]; v4]` is forbidden as the type of a const generic parameter
   --> $DIR/unevaluated-const-ice-119731.rs:16:48
    |
@@ -72,6 +66,12 @@ help: add `#![feature(adt_const_params)]` to the crate attributes to enable more
 LL + #![feature(adt_const_params)]
    |
 
+error[E0425]: cannot find function `v6` in this scope
+  --> $DIR/unevaluated-const-ice-119731.rs:13:35
+   |
+LL |     const v0: [[usize; v4]; v4] = v6(v8);
+   |                                   ^^ not found in this scope
+
 error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#0}
   --> $DIR/unevaluated-const-ice-119731.rs:28:37
    |
diff --git a/tests/ui/const-generics/mgca/ambiguous-assoc-const.rs b/tests/ui/const-generics/mgca/ambiguous-assoc-const.rs
new file mode 100644
index 00000000000..d7df9c22afd
--- /dev/null
+++ b/tests/ui/const-generics/mgca/ambiguous-assoc-const.rs
@@ -0,0 +1,15 @@
+#![feature(min_generic_const_args)]
+#![expect(incomplete_features)]
+
+trait Tr {
+    const N: usize;
+}
+
+struct Blah<const N: usize>;
+
+fn foo() -> Blah<{ Tr::N }> {
+    //~^ ERROR ambiguous associated constant
+    todo!()
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/mgca/ambiguous-assoc-const.stderr b/tests/ui/const-generics/mgca/ambiguous-assoc-const.stderr
new file mode 100644
index 00000000000..11c63bdbcf4
--- /dev/null
+++ b/tests/ui/const-generics/mgca/ambiguous-assoc-const.stderr
@@ -0,0 +1,15 @@
+error[E0223]: ambiguous associated constant
+  --> $DIR/ambiguous-assoc-const.rs:10:20
+   |
+LL | fn foo() -> Blah<{ Tr::N }> {
+   |                    ^^^^^
+   |
+help: if there were a type named `Example` that implemented `Tr`, you could use the fully-qualified path
+   |
+LL - fn foo() -> Blah<{ Tr::N }> {
+LL + fn foo() -> Blah<{ <Example as Tr>::N }> {
+   |
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0223`.
diff --git a/tests/ui/const-generics/mgca/assoc-const-without-type_const.rs b/tests/ui/const-generics/mgca/assoc-const-without-type_const.rs
new file mode 100644
index 00000000000..a11314c11aa
--- /dev/null
+++ b/tests/ui/const-generics/mgca/assoc-const-without-type_const.rs
@@ -0,0 +1,14 @@
+#![feature(min_generic_const_args)]
+#![allow(incomplete_features)]
+
+pub trait Tr {
+    const SIZE: usize;
+}
+
+fn mk_array<T: Tr>(_x: T) -> [(); T::SIZE] {
+    //~^ ERROR type_const
+    [(); T::SIZE]
+    //~^ ERROR type_const
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr b/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr
new file mode 100644
index 00000000000..7872e096762
--- /dev/null
+++ b/tests/ui/const-generics/mgca/assoc-const-without-type_const.stderr
@@ -0,0 +1,18 @@
+error: use of trait associated const without `#[type_const]`
+  --> $DIR/assoc-const-without-type_const.rs:8:35
+   |
+LL | fn mk_array<T: Tr>(_x: T) -> [(); T::SIZE] {
+   |                                   ^^^^^^^
+   |
+   = note: the declaration in the trait must be marked with `#[type_const]`
+
+error: use of trait associated const without `#[type_const]`
+  --> $DIR/assoc-const-without-type_const.rs:10:10
+   |
+LL |     [(); T::SIZE]
+   |          ^^^^^^^
+   |
+   = note: the declaration in the trait must be marked with `#[type_const]`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/const-generics/mgca/assoc-const.rs b/tests/ui/const-generics/mgca/assoc-const.rs
new file mode 100644
index 00000000000..fb5b4308a7f
--- /dev/null
+++ b/tests/ui/const-generics/mgca/assoc-const.rs
@@ -0,0 +1,15 @@
+//@ check-pass
+
+#![feature(min_generic_const_args)]
+#![allow(incomplete_features)]
+
+pub trait Tr<X> {
+    #[type_const]
+    const SIZE: usize;
+}
+
+fn mk_array<T: Tr<bool>>(_x: T) -> [(); <T as Tr<bool>>::SIZE] {
+    [(); T::SIZE]
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/mgca/bad-type_const-syntax.rs b/tests/ui/const-generics/mgca/bad-type_const-syntax.rs
new file mode 100644
index 00000000000..1e9673a56b5
--- /dev/null
+++ b/tests/ui/const-generics/mgca/bad-type_const-syntax.rs
@@ -0,0 +1,17 @@
+trait Tr {
+    #[type_const()]
+    //~^ ERROR malformed
+    //~| ERROR experimental
+    const N: usize;
+}
+
+struct S;
+
+impl Tr for S {
+    #[type_const]
+    //~^ ERROR must only be applied to trait associated constants
+    //~| ERROR experimental
+    const N: usize = 0;
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr
new file mode 100644
index 00000000000..579aff849d6
--- /dev/null
+++ b/tests/ui/const-generics/mgca/bad-type_const-syntax.stderr
@@ -0,0 +1,35 @@
+error: malformed `type_const` attribute input
+  --> $DIR/bad-type_const-syntax.rs:2:5
+   |
+LL |     #[type_const()]
+   |     ^^^^^^^^^^^^^^^ help: must be of the form: `#[type_const]`
+
+error[E0658]: the `#[type_const]` attribute is an experimental feature
+  --> $DIR/bad-type_const-syntax.rs:2:5
+   |
+LL |     #[type_const()]
+   |     ^^^^^^^^^^^^^^^
+   |
+   = note: see issue #132980 <https://github.com/rust-lang/rust/issues/132980> for more information
+   = help: add `#![feature(min_generic_const_args)]` 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 `#[type_const]` attribute is an experimental feature
+  --> $DIR/bad-type_const-syntax.rs:11:5
+   |
+LL |     #[type_const]
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #132980 <https://github.com/rust-lang/rust/issues/132980> for more information
+   = help: add `#![feature(min_generic_const_args)]` 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: `#[type_const]` must only be applied to trait associated constants
+  --> $DIR/bad-type_const-syntax.rs:11:5
+   |
+LL |     #[type_const]
+   |     ^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/const-generics/mgca/inherent-const-gating.rs b/tests/ui/const-generics/mgca/inherent-const-gating.rs
new file mode 100644
index 00000000000..c39b8e6f7f6
--- /dev/null
+++ b/tests/ui/const-generics/mgca/inherent-const-gating.rs
@@ -0,0 +1,13 @@
+#![feature(min_generic_const_args)]
+#![allow(incomplete_features)]
+
+struct S;
+
+impl S {
+    const N: usize = 42;
+}
+
+fn main() {
+    let _x: [(); S::N] = todo!();
+    //~^ ERROR inherent associated types are unstable
+}
diff --git a/tests/ui/const-generics/mgca/inherent-const-gating.stderr b/tests/ui/const-generics/mgca/inherent-const-gating.stderr
new file mode 100644
index 00000000000..71bb11ae700
--- /dev/null
+++ b/tests/ui/const-generics/mgca/inherent-const-gating.stderr
@@ -0,0 +1,13 @@
+error[E0658]: inherent associated types are unstable
+  --> $DIR/inherent-const-gating.rs:11:18
+   |
+LL |     let _x: [(); S::N] = todo!();
+   |                  ^^^^
+   |
+   = note: see issue #8995 <https://github.com/rust-lang/rust/issues/8995> for more information
+   = help: add `#![feature(inherent_associated_types)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/consts/const-slice-array-deref.stderr b/tests/ui/consts/const-slice-array-deref.stderr
index 346685380cc..b1d06928088 100644
--- a/tests/ui/consts/const-slice-array-deref.stderr
+++ b/tests/ui/consts/const-slice-array-deref.stderr
@@ -5,6 +5,7 @@ LL | const ONE: [u16] = [1];
    |            ^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `[u16]`
+   = note: statics and constants must have a statically known size
 
 error[E0308]: mismatched types
   --> $DIR/const-slice-array-deref.rs:1:20
diff --git a/tests/ui/consts/const-unsized.stderr b/tests/ui/consts/const-unsized.stderr
index 7931d7adafd..8328e19aac2 100644
--- a/tests/ui/consts/const-unsized.stderr
+++ b/tests/ui/consts/const-unsized.stderr
@@ -5,6 +5,7 @@ LL | const CONST_0: dyn Debug + Sync = *(&0 as &(dyn Debug + Sync));
    |                ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
+   = note: statics and constants must have a statically known size
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/const-unsized.rs:7:18
@@ -13,6 +14,7 @@ LL | const CONST_FOO: str = *"foo";
    |                  ^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
+   = note: statics and constants must have a statically known size
 
 error[E0277]: the size for values of type `(dyn Debug + Sync + 'static)` cannot be known at compilation time
   --> $DIR/const-unsized.rs:11:18
@@ -21,6 +23,7 @@ LL | static STATIC_1: dyn Debug + Sync = *(&1 as &(dyn Debug + Sync));
    |                  ^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `(dyn Debug + Sync + 'static)`
+   = note: statics and constants must have a statically known size
 
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/const-unsized.rs:15:20
@@ -29,6 +32,7 @@ LL | static STATIC_BAR: str = *"bar";
    |                    ^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `str`
+   = note: statics and constants must have a statically known size
 
 error[E0507]: cannot move out of a shared reference
   --> $DIR/const-unsized.rs:3:35
diff --git a/tests/ui/consts/const_refs_to_static-ice-121413.stderr b/tests/ui/consts/const_refs_to_static-ice-121413.stderr
index 8665d9b6852..3980a7e9b93 100644
--- a/tests/ui/consts/const_refs_to_static-ice-121413.stderr
+++ b/tests/ui/consts/const_refs_to_static-ice-121413.stderr
@@ -30,6 +30,7 @@ LL |     static FOO: Sync = AtomicUsize::new(0);
    |                 ^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `(dyn Sync + 'static)`
+   = note: statics and constants must have a statically known size
 
 error: aborting due to 2 previous errors; 1 warning emitted
 
diff --git a/tests/ui/consts/dont-ctfe-unsized-initializer.rs b/tests/ui/consts/dont-ctfe-unsized-initializer.rs
new file mode 100644
index 00000000000..cca38b760dc
--- /dev/null
+++ b/tests/ui/consts/dont-ctfe-unsized-initializer.rs
@@ -0,0 +1,7 @@
+static S: str = todo!();
+//~^ ERROR the size for values of type `str` cannot be known at compilation time
+
+const C: str = todo!();
+//~^ ERROR the size for values of type `str` cannot be known at compilation time
+
+fn main() {}
diff --git a/tests/ui/consts/dont-ctfe-unsized-initializer.stderr b/tests/ui/consts/dont-ctfe-unsized-initializer.stderr
new file mode 100644
index 00000000000..e69790fc182
--- /dev/null
+++ b/tests/ui/consts/dont-ctfe-unsized-initializer.stderr
@@ -0,0 +1,21 @@
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/dont-ctfe-unsized-initializer.rs:1:11
+   |
+LL | static S: str = todo!();
+   |           ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+   = note: statics and constants must have a statically known size
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/dont-ctfe-unsized-initializer.rs:4:10
+   |
+LL | const C: str = todo!();
+   |          ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+   = note: statics and constants must have a statically known size
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/issue-39974.stderr b/tests/ui/consts/issue-39974.stderr
index a371ea5709e..d03f709b0ea 100644
--- a/tests/ui/consts/issue-39974.stderr
+++ b/tests/ui/consts/issue-39974.stderr
@@ -1,4 +1,10 @@
 error[E0308]: mismatched types
+  --> $DIR/issue-39974.rs:5:19
+   |
+LL |     f: [[f64; 2]; LENGTH],
+   |                   ^^^^^^ expected `usize`, found `f64`
+
+error[E0308]: mismatched types
   --> $DIR/issue-39974.rs:1:21
    |
 LL | const LENGTH: f64 = 2;
@@ -9,12 +15,6 @@ help: use a float literal
 LL | const LENGTH: f64 = 2.0;
    |                      ++
 
-error[E0308]: mismatched types
-  --> $DIR/issue-39974.rs:5:19
-   |
-LL |     f: [[f64; 2]; LENGTH],
-   |                   ^^^^^^ expected `usize`, found `f64`
-
 error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/coroutine/gen_block.e2024.stderr b/tests/ui/coroutine/gen_block.e2024.stderr
index 0491bdbc2e1..347f111e79f 100644
--- a/tests/ui/coroutine/gen_block.e2024.stderr
+++ b/tests/ui/coroutine/gen_block.e2024.stderr
@@ -18,16 +18,6 @@ LL |     let _ = #[coroutine] || {};
    = help: add `#![feature(coroutines)]` 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]: yield syntax is experimental
-  --> $DIR/gen_block.rs:16:16
-   |
-LL |     let _ = || yield true;
-   |                ^^^^^^^^^^
-   |
-   = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
-   = help: add `#![feature(coroutines)]` 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: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
   --> $DIR/gen_block.rs:16:16
    |
@@ -39,23 +29,13 @@ help: use `#[coroutine]` to make this closure a coroutine
 LL |     let _ = #[coroutine] || yield true;
    |             ++++++++++++
 
-error[E0658]: yield syntax is experimental
-  --> $DIR/gen_block.rs:20:29
-   |
-LL |     let _ = #[coroutine] || yield true;
-   |                             ^^^^^^^^^^
-   |
-   = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
-   = help: add `#![feature(coroutines)]` 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[E0282]: type annotations needed
   --> $DIR/gen_block.rs:7:13
    |
 LL |     let x = gen {};
    |             ^^^^^^ cannot infer type
 
-error: aborting due to 6 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0282, E0658.
 For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/coroutine/gen_block.none.stderr b/tests/ui/coroutine/gen_block.none.stderr
index 43437793005..ed744f2957a 100644
--- a/tests/ui/coroutine/gen_block.none.stderr
+++ b/tests/ui/coroutine/gen_block.none.stderr
@@ -71,7 +71,7 @@ LL |     let _ = || yield true;
    |                ^^^^^^^^^^
    |
    = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
-   = help: add `#![feature(coroutines)]` to the crate attributes to enable
+   = help: add `#![feature(yield_expr)]` 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: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
@@ -92,7 +92,7 @@ LL |     let _ = #[coroutine] || yield true;
    |                             ^^^^^^^^^^
    |
    = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
-   = help: add `#![feature(coroutines)]` to the crate attributes to enable
+   = help: add `#![feature(yield_expr)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error: aborting due to 11 previous errors
diff --git a/tests/ui/coroutine/gen_block.rs b/tests/ui/coroutine/gen_block.rs
index 4494d654eeb..e3734dd4cdf 100644
--- a/tests/ui/coroutine/gen_block.rs
+++ b/tests/ui/coroutine/gen_block.rs
@@ -14,12 +14,12 @@ fn main() {
     //[none]~^ ERROR: cannot find
 
     let _ = || yield true; //[none]~ ERROR yield syntax is experimental
-    //~^ ERROR yield syntax is experimental
+    //[none]~^ ERROR yield syntax is experimental
     //~^^ ERROR `yield` can only be used in
 
     let _ = #[coroutine] || yield true; //[none]~ ERROR yield syntax is experimental
     //~^ ERROR `#[coroutine]` attribute is an experimental feature
-    //~^^ ERROR yield syntax is experimental
+    //[none]~^^ ERROR yield syntax is experimental
 
     let _ = #[coroutine] || {};
     //~^ ERROR `#[coroutine]` attribute is an experimental feature
diff --git a/tests/ui/crate-loading/crateresolve1.stderr b/tests/ui/crate-loading/crateresolve1.stderr
index 47131a96bf4..b17330fb9d9 100644
--- a/tests/ui/crate-loading/crateresolve1.stderr
+++ b/tests/ui/crate-loading/crateresolve1.stderr
@@ -4,9 +4,9 @@ error[E0464]: multiple candidates for `rlib` dependency `crateresolve1` found
 LL | extern crate crateresolve1;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: candidate #1: $TEST_BUILD_DIR/crate-loading/crateresolve1/auxiliary/libcrateresolve1-1.somelib
-   = note: candidate #2: $TEST_BUILD_DIR/crate-loading/crateresolve1/auxiliary/libcrateresolve1-2.somelib
-   = note: candidate #3: $TEST_BUILD_DIR/crate-loading/crateresolve1/auxiliary/libcrateresolve1-3.somelib
+   = note: candidate #1: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-1.somelib
+   = note: candidate #2: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-2.somelib
+   = note: candidate #3: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-3.somelib
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/crate-loading/crateresolve2.stderr b/tests/ui/crate-loading/crateresolve2.stderr
index 3dc89dabde6..0c488f3fd07 100644
--- a/tests/ui/crate-loading/crateresolve2.stderr
+++ b/tests/ui/crate-loading/crateresolve2.stderr
@@ -4,9 +4,9 @@ error[E0464]: multiple candidates for `rmeta` dependency `crateresolve2` found
 LL | extern crate crateresolve2;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: candidate #1: $TEST_BUILD_DIR/crate-loading/crateresolve2/auxiliary/libcrateresolve2-1.rmeta
-   = note: candidate #2: $TEST_BUILD_DIR/crate-loading/crateresolve2/auxiliary/libcrateresolve2-2.rmeta
-   = note: candidate #3: $TEST_BUILD_DIR/crate-loading/crateresolve2/auxiliary/libcrateresolve2-3.rmeta
+   = note: candidate #1: $TEST_BUILD_DIR/auxiliary/libcrateresolve2-1.rmeta
+   = note: candidate #2: $TEST_BUILD_DIR/auxiliary/libcrateresolve2-2.rmeta
+   = note: candidate #3: $TEST_BUILD_DIR/auxiliary/libcrateresolve2-3.rmeta
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/diagnostic-width/E0271.ascii.stderr b/tests/ui/diagnostic-width/E0271.ascii.stderr
index 9a9c12a938f..ad5f53e44be 100644
--- a/tests/ui/diagnostic-width/E0271.ascii.stderr
+++ b/tests/ui/diagnostic-width/E0271.ascii.stderr
@@ -1,5 +1,5 @@
 error[E0271]: type mismatch resolving `<Result<..., ()> as Future>::Error == Foo`
-  --> $DIR/E0271.rs:20:5
+  --> $DIR/E0271.rs:19:5
    |
 LL | /     Box::new(
 LL | |         Ok::<_, ()>(
@@ -10,12 +10,12 @@ LL | |     )
    | |_____^ type mismatch resolving `<Result<..., ()> as Future>::Error == Foo`
    |
 note: expected this to be `Foo`
-  --> $DIR/E0271.rs:10:18
+  --> $DIR/E0271.rs:9:18
    |
 LL |     type Error = E;
    |                  ^
    = note: required for the cast from `Box<Result<..., ()>>` to `Box<...>`
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/E0271.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/diagnostic-width/E0271.rs b/tests/ui/diagnostic-width/E0271.rs
index 06187721041..522bfb5b93f 100644
--- a/tests/ui/diagnostic-width/E0271.rs
+++ b/tests/ui/diagnostic-width/E0271.rs
@@ -1,7 +1,6 @@
 //@ revisions: ascii unicode
 //@[ascii] compile-flags: --diagnostic-width=40 -Zwrite-long-types-to-disk=yes
 //@[unicode] compile-flags: -Zunstable-options --error-format=human-unicode --diagnostic-width=40 -Zwrite-long-types-to-disk=yes
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
 trait Future {
     type Error;
 }
diff --git a/tests/ui/diagnostic-width/E0271.unicode.stderr b/tests/ui/diagnostic-width/E0271.unicode.stderr
index 9c3deae6660..91adf834101 100644
--- a/tests/ui/diagnostic-width/E0271.unicode.stderr
+++ b/tests/ui/diagnostic-width/E0271.unicode.stderr
@@ -1,5 +1,5 @@
 error[E0271]: type mismatch resolving `<Result<..., ()> as Future>::Error == Foo`
-   ╭▸ $DIR/E0271.rs:20:5
+   ╭▸ $DIR/E0271.rs:19:5

 LL │ ┏     Box::new(
 LL │ ┃         Ok::<_, ()>(
@@ -10,12 +10,12 @@ LL │ ┃     )
    │ ┗━━━━━┛ type mismatch resolving `<Result<..., ()> as Future>::Error == Foo`
    ╰╴
 note: expected this to be `Foo`
-   ╭▸ $DIR/E0271.rs:10:18
+   ╭▸ $DIR/E0271.rs:9:18

 LL │     type Error = E;
    │                  ━
    ├ note: required for the cast from `Box<Result<..., ()>>` to `Box<...>`
-   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/E0271.long-type-$LONG_TYPE_HASH.txt'
    ╰ note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/diagnostic-width/binop.rs b/tests/ui/diagnostic-width/binop.rs
index 60ba40b8047..9e4e837f386 100644
--- a/tests/ui/diagnostic-width/binop.rs
+++ b/tests/ui/diagnostic-width/binop.rs
@@ -1,6 +1,4 @@
 //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
 type A = (i32, i32, i32, i32);
 type B = (A, A, A, A);
 type C = (B, B, B, B);
diff --git a/tests/ui/diagnostic-width/binop.stderr b/tests/ui/diagnostic-width/binop.stderr
index fd69129c33e..92723df5a9b 100644
--- a/tests/ui/diagnostic-width/binop.stderr
+++ b/tests/ui/diagnostic-width/binop.stderr
@@ -1,21 +1,21 @@
 error[E0369]: cannot add `(..., ..., ..., ...)` to `(..., ..., ..., ...)`
-  --> $DIR/binop.rs:10:7
+  --> $DIR/binop.rs:8:7
    |
 LL |     x + x;
    |     - ^ - (..., ..., ..., ...)
    |     |
    |     (..., ..., ..., ...)
    |
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/binop.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error[E0600]: cannot apply unary operator `!` to type `(..., ..., ..., ...)`
-  --> $DIR/binop.rs:14:5
+  --> $DIR/binop.rs:12:5
    |
 LL |     !x;
    |     ^^ cannot apply unary operator `!`
    |
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/binop.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/diagnostic-width/long-E0308.ascii.stderr b/tests/ui/diagnostic-width/long-E0308.ascii.stderr
index 83da5586188..d1fdd6c4433 100644
--- a/tests/ui/diagnostic-width/long-E0308.ascii.stderr
+++ b/tests/ui/diagnostic-width/long-E0308.ascii.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/long-E0308.rs:48:9
+  --> $DIR/long-E0308.rs:45:9
    |
 LL |        let x: Atype<
    |  _____________-
@@ -20,11 +20,11 @@ LL |  |     ))))))))))))))))))))))))))))));
    |
    = note: expected struct `Atype<Btype<..., i32>, i32>`
                 found enum `Result<Result<..., _>, _>`
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
-  --> $DIR/long-E0308.rs:61:26
+  --> $DIR/long-E0308.rs:58:26
    |
 LL |       ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O...
    |  __________________________^
@@ -36,11 +36,11 @@ LL | |     ))))))))))))))))))))))));
    |
    = note: expected enum `Option<Result<Option<...>, _>>`
               found enum `Result<Result<..., _>, _>`
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
-  --> $DIR/long-E0308.rs:92:9
+  --> $DIR/long-E0308.rs:89:9
    |
 LL |       let x: Atype<
    |  ____________-
@@ -56,11 +56,11 @@ LL | |     > = ();
    |
    = note: expected struct `Atype<Btype<..., i32>, i32>`
            found unit type `()`
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
-  --> $DIR/long-E0308.rs:95:17
+  --> $DIR/long-E0308.rs:92:17
    |
 LL |       let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(O...
    |  ____________--___^
@@ -74,7 +74,7 @@ LL | |     ))))))))))))))))))))))));
    |
    = note: expected unit type `()`
                    found enum `Result<Result<..., _>, _>`
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 4 previous errors
diff --git a/tests/ui/diagnostic-width/long-E0308.rs b/tests/ui/diagnostic-width/long-E0308.rs
index 26383d9418d..94e525e387e 100644
--- a/tests/ui/diagnostic-width/long-E0308.rs
+++ b/tests/ui/diagnostic-width/long-E0308.rs
@@ -2,9 +2,6 @@
 //@[ascii] compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
 //@[unicode] compile-flags: -Zunstable-options --json=diagnostic-unicode --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
 
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
-
 mod a {
     // Force the "short path for unique types" machinery to trip up
     pub struct Atype;
diff --git a/tests/ui/diagnostic-width/long-E0308.unicode.stderr b/tests/ui/diagnostic-width/long-E0308.unicode.stderr
index 54abf576dbd..69e5ca10067 100644
--- a/tests/ui/diagnostic-width/long-E0308.unicode.stderr
+++ b/tests/ui/diagnostic-width/long-E0308.unicode.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-   ╭▸ $DIR/long-E0308.rs:48:9
+   ╭▸ $DIR/long-E0308.rs:45:9

 LL │        let x: Atype<
    │ ┌─────────────┘
@@ -20,11 +20,11 @@ LL │  ┃     ))))))))))))))))))))))))))))));

    ├ note: expected struct `Atype<Btype<..., i32>, i32>`
    │            found enum `Result<Result<..., _>, _>`
-   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt'
    ╰ note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
-   ╭▸ $DIR/long-E0308.rs:61:26
+   ╭▸ $DIR/long-E0308.rs:58:26

 LL │       ))))))))))))))))) == Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(…
    │ ┏━━━━━━━━━━━━━━━━━━━━━━━━━━┛
@@ -36,11 +36,11 @@ LL │ ┃     ))))))))))))))))))))))));

    ├ note: expected enum `Option<Result<Option<...>, _>>`
    │          found enum `Result<Result<..., _>, _>`
-   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt'
    ╰ note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
-   ╭▸ $DIR/long-E0308.rs:92:9
+   ╭▸ $DIR/long-E0308.rs:89:9

 LL │       let x: Atype<
    │ ┌────────────┘
@@ -56,11 +56,11 @@ LL │ │     > = ();

    ├ note: expected struct `Atype<Btype<..., i32>, i32>`
    │       found unit type `()`
-   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt'
    ╰ note: consider using `--verbose` to print the full type name to the console
 
 error[E0308]: mismatched types
-   ╭▸ $DIR/long-E0308.rs:95:17
+   ╭▸ $DIR/long-E0308.rs:92:17

 LL │       let _: () = Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(Ok(…
    │ ┏━━━━━━━━━━━━┬─━━━┛
@@ -74,7 +74,7 @@ LL │ ┃     ))))))))))))))))))))))));

    ├ note: expected unit type `()`
    │               found enum `Result<Result<..., _>, _>`
-   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   ├ note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0308.long-type-$LONG_TYPE_HASH.txt'
    ╰ note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 4 previous errors
diff --git a/tests/ui/diagnostic-width/long-E0529.rs b/tests/ui/diagnostic-width/long-E0529.rs
index 3ebc4f5f8c8..759a902da7e 100644
--- a/tests/ui/diagnostic-width/long-E0529.rs
+++ b/tests/ui/diagnostic-width/long-E0529.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
+
 type A = (i32, i32, i32, i32);
 type B = (A, A, A, A);
 type C = (B, B, B, B);
diff --git a/tests/ui/diagnostic-width/long-E0529.stderr b/tests/ui/diagnostic-width/long-E0529.stderr
index da03e5fab2c..bf3144cc9b6 100644
--- a/tests/ui/diagnostic-width/long-E0529.stderr
+++ b/tests/ui/diagnostic-width/long-E0529.stderr
@@ -1,10 +1,10 @@
 error[E0529]: expected an array or slice, found `(..., ..., ..., ...)`
-  --> $DIR/long-E0529.rs:10:9
+  --> $DIR/long-E0529.rs:9:9
    |
 LL |     let [] = x;
    |         ^^ pattern cannot match with input type `(..., ..., ..., ...)`
    |
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0529.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/diagnostic-width/long-E0609.rs b/tests/ui/diagnostic-width/long-E0609.rs
index 39442bdeae0..a26d16ad12e 100644
--- a/tests/ui/diagnostic-width/long-E0609.rs
+++ b/tests/ui/diagnostic-width/long-E0609.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
+
 type A = (i32, i32, i32, i32);
 type B = (A, A, A, A);
 type C = (B, B, B, B);
diff --git a/tests/ui/diagnostic-width/long-E0609.stderr b/tests/ui/diagnostic-width/long-E0609.stderr
index 6815caa6b6b..36ef8545746 100644
--- a/tests/ui/diagnostic-width/long-E0609.stderr
+++ b/tests/ui/diagnostic-width/long-E0609.stderr
@@ -1,10 +1,10 @@
 error[E0609]: no field `field` on type `(..., ..., ..., ...)`
-  --> $DIR/long-E0609.rs:10:7
+  --> $DIR/long-E0609.rs:9:7
    |
 LL |     x.field;
    |       ^^^^^ unknown field
    |
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0609.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/diagnostic-width/long-E0614.rs b/tests/ui/diagnostic-width/long-E0614.rs
index 0b78444a00d..5e8b3324dd1 100644
--- a/tests/ui/diagnostic-width/long-E0614.rs
+++ b/tests/ui/diagnostic-width/long-E0614.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
+
 type A = (i32, i32, i32, i32);
 type B = (A, A, A, A);
 type C = (B, B, B, B);
diff --git a/tests/ui/diagnostic-width/long-E0614.stderr b/tests/ui/diagnostic-width/long-E0614.stderr
index 1c16ff617fa..18da20da945 100644
--- a/tests/ui/diagnostic-width/long-E0614.stderr
+++ b/tests/ui/diagnostic-width/long-E0614.stderr
@@ -1,10 +1,10 @@
 error[E0614]: type `(..., ..., ..., ...)` cannot be dereferenced
-  --> $DIR/long-E0614.rs:10:5
+  --> $DIR/long-E0614.rs:9:5
    |
 LL |     *x;
    |     ^^ can't be dereferenced
    |
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0614.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/diagnostic-width/long-E0618.rs b/tests/ui/diagnostic-width/long-E0618.rs
index f8626ab9455..b499bedc394 100644
--- a/tests/ui/diagnostic-width/long-E0618.rs
+++ b/tests/ui/diagnostic-width/long-E0618.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
+
 type A = (i32, i32, i32, i32);
 type B = (A, A, A, A);
 type C = (B, B, B, B);
diff --git a/tests/ui/diagnostic-width/long-E0618.stderr b/tests/ui/diagnostic-width/long-E0618.stderr
index f0838cbddcc..05bf999c142 100644
--- a/tests/ui/diagnostic-width/long-E0618.stderr
+++ b/tests/ui/diagnostic-width/long-E0618.stderr
@@ -1,5 +1,5 @@
 error[E0618]: expected function, found `(..., ..., ..., ...)`
-  --> $DIR/long-E0618.rs:10:5
+  --> $DIR/long-E0618.rs:9:5
    |
 LL | fn foo(x: D) {
    |        - `x` has type `(..., ..., ..., ...)`
@@ -8,7 +8,7 @@ LL |     x();
    |     |
    |     call expression requires function
    |
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-E0618.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/diagnostic-width/long-e0277.rs b/tests/ui/diagnostic-width/long-e0277.rs
index 9b3bd8bb728..369fd8daea7 100644
--- a/tests/ui/diagnostic-width/long-e0277.rs
+++ b/tests/ui/diagnostic-width/long-e0277.rs
@@ -1,6 +1,4 @@
 //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
 type A = (i32, i32, i32, i32);
 type B = (A, A, A, A);
 type C = (B, B, B, B);
diff --git a/tests/ui/diagnostic-width/long-e0277.stderr b/tests/ui/diagnostic-width/long-e0277.stderr
index a57270df7e2..ff897151165 100644
--- a/tests/ui/diagnostic-width/long-e0277.stderr
+++ b/tests/ui/diagnostic-width/long-e0277.stderr
@@ -1,21 +1,21 @@
 error[E0277]: the trait bound `(..., ..., ..., ...): Trait` is not satisfied
-  --> $DIR/long-e0277.rs:14:21
+  --> $DIR/long-e0277.rs:12:21
    |
 LL |     require_trait::<D>();
    |                     ^ unsatisfied trait bound
    |
    = help: the trait `Trait` is not implemented for `(..., ..., ..., ...)`
 help: this trait has no implementations, consider adding one
-  --> $DIR/long-e0277.rs:9:1
+  --> $DIR/long-e0277.rs:7:1
    |
 LL | trait Trait {}
    | ^^^^^^^^^^^
 note: required by a bound in `require_trait`
-  --> $DIR/long-e0277.rs:11:21
+  --> $DIR/long-e0277.rs:9:21
    |
 LL | fn require_trait<T: Trait>() {}
    |                     ^^^^^ required by this bound in `require_trait`
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/long-e0277.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/diagnostic-width/non-copy-type-moved.rs b/tests/ui/diagnostic-width/non-copy-type-moved.rs
index a220c62775e..845457f7e30 100644
--- a/tests/ui/diagnostic-width/non-copy-type-moved.rs
+++ b/tests/ui/diagnostic-width/non-copy-type-moved.rs
@@ -1,6 +1,4 @@
 //@ compile-flags: --diagnostic-width=60 -Zwrite-long-types-to-disk=yes
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
 
 type A = (String, String, String, String);
 type B = (A, A, A, A);
diff --git a/tests/ui/diagnostic-width/non-copy-type-moved.stderr b/tests/ui/diagnostic-width/non-copy-type-moved.stderr
index 254542c7b39..16c01c858b7 100644
--- a/tests/ui/diagnostic-width/non-copy-type-moved.stderr
+++ b/tests/ui/diagnostic-width/non-copy-type-moved.stderr
@@ -1,5 +1,5 @@
 error[E0382]: use of moved value: `x`
-  --> $DIR/non-copy-type-moved.rs:16:14
+  --> $DIR/non-copy-type-moved.rs:14:14
    |
 LL | fn foo(x: D) {
    |        - move occurs because `x` has type `(..., ..., ..., ...)`, which does not implement the `Copy` trait
@@ -8,7 +8,7 @@ LL |     let _a = x;
 LL |     let _b = x;
    |              ^ value used here after move
    |
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/non-copy-type-moved.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 help: consider cloning the value if the performance cost is acceptable
    |
diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs
index c8845af3183..13fe967ba5f 100644
--- a/tests/ui/diagnostic-width/secondary-label-with-long-type.rs
+++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.rs
@@ -1,6 +1,4 @@
 //@ compile-flags: --diagnostic-width=100 -Zwrite-long-types-to-disk=yes
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
 
 type A = (i32, i32, i32, i32);
 type B = (A, A, A, A);
diff --git a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr
index a95e1709148..a99657ca113 100644
--- a/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr
+++ b/tests/ui/diagnostic-width/secondary-label-with-long-type.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/secondary-label-with-long-type.rs:11:9
+  --> $DIR/secondary-label-with-long-type.rs:9:9
    |
 LL |     let () = x;
    |         ^^   - this expression has type `((..., ..., ..., ...), ..., ..., ...)`
@@ -8,7 +8,7 @@ LL |     let () = x;
    |
    = note:  expected tuple `((..., ..., ..., ...), ..., ..., ...)`
            found unit type `()`
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/secondary-label-with-long-type.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/dst/dst-bad-assign-3.rs b/tests/ui/dst/dst-bad-assign-3.rs
index d199864d99c..f96ecf7762c 100644
--- a/tests/ui/dst/dst-bad-assign-3.rs
+++ b/tests/ui/dst/dst-bad-assign-3.rs
@@ -1,8 +1,6 @@
 // Forbid assignment into a dynamically sized type.
 
-#![feature(unsized_tuple_coercion)]
-
-type Fat<T> = (isize, &'static str, T);
+struct Fat<T: ?Sized>(isize, &'static str, T);
 
 #[derive(PartialEq,Eq)]
 struct Bar;
@@ -28,7 +26,7 @@ impl ToBar for Bar1 {
 
 pub fn main() {
     // Assignment.
-    let f5: &mut Fat<dyn ToBar> = &mut (5, "some str", Bar1 {f :42});
+    let f5: &mut Fat<dyn ToBar> = &mut Fat(5, "some str", Bar1 {f :42});
     let z: Box<dyn ToBar> = Box::new(Bar1 {f: 36});
     f5.2 = Bar1 {f: 36};
     //~^ ERROR mismatched types
diff --git a/tests/ui/dst/dst-bad-assign-3.stderr b/tests/ui/dst/dst-bad-assign-3.stderr
index 007f6b898be..4aa1677e751 100644
--- a/tests/ui/dst/dst-bad-assign-3.stderr
+++ b/tests/ui/dst/dst-bad-assign-3.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/dst-bad-assign-3.rs:33:12
+  --> $DIR/dst-bad-assign-3.rs:31:12
    |
 LL |     f5.2 = Bar1 {f: 36};
    |     ----   ^^^^^^^^^^^^ expected `dyn ToBar`, found `Bar1`
@@ -11,7 +11,7 @@ LL |     f5.2 = Bar1 {f: 36};
    = help: `Bar1` implements `ToBar` so you could box the found value and coerce it to the trait object `Box<dyn ToBar>`, you will have to change the expected type as well
 
 error[E0277]: the size for values of type `dyn ToBar` cannot be known at compilation time
-  --> $DIR/dst-bad-assign-3.rs:33:5
+  --> $DIR/dst-bad-assign-3.rs:31:5
    |
 LL |     f5.2 = Bar1 {f: 36};
    |     ^^^^ doesn't have a size known at compile-time
diff --git a/tests/ui/dst/dst-bad-coerce1.rs b/tests/ui/dst/dst-bad-coerce1.rs
index 7ef237e39e3..5ee0bfa9fbf 100644
--- a/tests/ui/dst/dst-bad-coerce1.rs
+++ b/tests/ui/dst/dst-bad-coerce1.rs
@@ -1,7 +1,5 @@
 // Attempt to change the type as well as unsizing.
 
-#![feature(unsized_tuple_coercion)]
-
 struct Fat<T: ?Sized> {
     ptr: T
 }
@@ -21,16 +19,4 @@ pub fn main() {
     let f2: &Fat<Foo> = &f1;
     let f3: &Fat<dyn Bar> = f2;
     //~^ ERROR `Foo: Bar` is not satisfied
-
-    // Tuple with a vec of isize.
-    let f1 = ([1, 2, 3],);
-    let f2: &([isize; 3],) = &f1;
-    let f3: &([usize],) = f2;
-    //~^ ERROR mismatched types
-
-    // Tuple with a trait.
-    let f1 = (Foo,);
-    let f2: &(Foo,) = &f1;
-    let f3: &(dyn Bar,) = f2;
-    //~^ ERROR `Foo: Bar` is not satisfied
 }
diff --git a/tests/ui/dst/dst-bad-coerce1.stderr b/tests/ui/dst/dst-bad-coerce1.stderr
index 455d15e935f..68456b8642c 100644
--- a/tests/ui/dst/dst-bad-coerce1.stderr
+++ b/tests/ui/dst/dst-bad-coerce1.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/dst-bad-coerce1.rs:16:29
+  --> $DIR/dst-bad-coerce1.rs:14:29
    |
 LL |     let f3: &Fat<[usize]> = f2;
    |             -------------   ^^ expected `&Fat<[usize]>`, found `&Fat<[isize; 3]>`
@@ -10,43 +10,19 @@ LL |     let f3: &Fat<[usize]> = f2;
               found reference `&Fat<[isize; 3]>`
 
 error[E0277]: the trait bound `Foo: Bar` is not satisfied
-  --> $DIR/dst-bad-coerce1.rs:22:29
+  --> $DIR/dst-bad-coerce1.rs:20:29
    |
 LL |     let f3: &Fat<dyn Bar> = f2;
    |                             ^^ the trait `Bar` is not implemented for `Foo`
    |
 help: this trait has no implementations, consider adding one
-  --> $DIR/dst-bad-coerce1.rs:10:1
+  --> $DIR/dst-bad-coerce1.rs:8:1
    |
 LL | trait Bar { fn bar(&self) {} }
    | ^^^^^^^^^
    = note: required for the cast from `&Fat<Foo>` to `&Fat<dyn Bar>`
 
-error[E0308]: mismatched types
-  --> $DIR/dst-bad-coerce1.rs:28:27
-   |
-LL |     let f3: &([usize],) = f2;
-   |             -----------   ^^ expected `&([usize],)`, found `&([isize; 3],)`
-   |             |
-   |             expected due to this
-   |
-   = note: expected reference `&([usize],)`
-              found reference `&([isize; 3],)`
-
-error[E0277]: the trait bound `Foo: Bar` is not satisfied
-  --> $DIR/dst-bad-coerce1.rs:34:27
-   |
-LL |     let f3: &(dyn Bar,) = f2;
-   |                           ^^ the trait `Bar` is not implemented for `Foo`
-   |
-help: this trait has no implementations, consider adding one
-  --> $DIR/dst-bad-coerce1.rs:10:1
-   |
-LL | trait Bar { fn bar(&self) {} }
-   | ^^^^^^^^^
-   = note: required for the cast from `&(Foo,)` to `&(dyn Bar,)`
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0277, E0308.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/dst/dst-bad-coerce3.rs b/tests/ui/dst/dst-bad-coerce3.rs
index fd5ee3b57bb..508f009c33e 100644
--- a/tests/ui/dst/dst-bad-coerce3.rs
+++ b/tests/ui/dst/dst-bad-coerce3.rs
@@ -1,7 +1,5 @@
 // Attempt to extend the lifetime as well as unsizing.
 
-#![feature(unsized_tuple_coercion)]
-
 struct Fat<T: ?Sized> {
     ptr: T
 }
@@ -20,16 +18,6 @@ fn baz<'a>() {
     let f1 = Fat { ptr: Foo };
     let f2: &Fat<Foo> = &f1; //~ ERROR `f1` does not live long enough
     let f3: &'a Fat<dyn Bar> = f2;
-
-    // Tuple with a vec of ints.
-    let f1 = ([1, 2, 3],);
-    let f2: &([isize; 3],) = &f1; //~ ERROR `f1` does not live long enough
-    let f3: &'a ([isize],) = f2;
-
-    // Tuple with a trait.
-    let f1 = (Foo,);
-    let f2: &(Foo,) = &f1; //~ ERROR `f1` does not live long enough
-    let f3: &'a (dyn Bar,) = f2;
 }
 
 pub fn main() {
diff --git a/tests/ui/dst/dst-bad-coerce3.stderr b/tests/ui/dst/dst-bad-coerce3.stderr
index 1254250bcbd..177535b8c7c 100644
--- a/tests/ui/dst/dst-bad-coerce3.stderr
+++ b/tests/ui/dst/dst-bad-coerce3.stderr
@@ -1,5 +1,5 @@
 error[E0597]: `f1` does not live long enough
-  --> $DIR/dst-bad-coerce3.rs:16:32
+  --> $DIR/dst-bad-coerce3.rs:14:32
    |
 LL | fn baz<'a>() {
    |        -- lifetime `'a` defined here
@@ -15,7 +15,7 @@ LL | }
    | - `f1` dropped here while still borrowed
 
 error[E0597]: `f1` does not live long enough
-  --> $DIR/dst-bad-coerce3.rs:21:25
+  --> $DIR/dst-bad-coerce3.rs:19:25
    |
 LL | fn baz<'a>() {
    |        -- lifetime `'a` defined here
@@ -26,41 +26,9 @@ LL |     let f2: &Fat<Foo> = &f1;
    |                         ^^^ borrowed value does not live long enough
 LL |     let f3: &'a Fat<dyn Bar> = f2;
    |             ---------------- type annotation requires that `f1` is borrowed for `'a`
-...
-LL | }
-   | - `f1` dropped here while still borrowed
-
-error[E0597]: `f1` does not live long enough
-  --> $DIR/dst-bad-coerce3.rs:26:30
-   |
-LL | fn baz<'a>() {
-   |        -- lifetime `'a` defined here
-...
-LL |     let f1 = ([1, 2, 3],);
-   |         -- binding `f1` declared here
-LL |     let f2: &([isize; 3],) = &f1;
-   |                              ^^^ borrowed value does not live long enough
-LL |     let f3: &'a ([isize],) = f2;
-   |             -------------- type annotation requires that `f1` is borrowed for `'a`
-...
-LL | }
-   | - `f1` dropped here while still borrowed
-
-error[E0597]: `f1` does not live long enough
-  --> $DIR/dst-bad-coerce3.rs:31:23
-   |
-LL | fn baz<'a>() {
-   |        -- lifetime `'a` defined here
-...
-LL |     let f1 = (Foo,);
-   |         -- binding `f1` declared here
-LL |     let f2: &(Foo,) = &f1;
-   |                       ^^^ borrowed value does not live long enough
-LL |     let f3: &'a (dyn Bar,) = f2;
-   |             -------------- type annotation requires that `f1` is borrowed for `'a`
 LL | }
    | - `f1` dropped here while still borrowed
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/dst/dst-bad-coerce4.rs b/tests/ui/dst/dst-bad-coerce4.rs
index 9f297915e58..25410aa4fac 100644
--- a/tests/ui/dst/dst-bad-coerce4.rs
+++ b/tests/ui/dst/dst-bad-coerce4.rs
@@ -1,7 +1,5 @@
 // Attempt to coerce from unsized to sized.
 
-#![feature(unsized_tuple_coercion)]
-
 struct Fat<T: ?Sized> {
     ptr: T
 }
@@ -14,12 +12,4 @@ pub fn main() {
     //~| expected `&Fat<[isize; 3]>`, found `&Fat<[isize]>`
     //~| expected reference `&Fat<[isize; 3]>`
     //~| found reference `&Fat<[isize]>`
-
-    // Tuple with a vec of isizes.
-    let f1: &([isize],) = &([1, 2, 3],);
-    let f2: &([isize; 3],) = f1;
-    //~^ ERROR mismatched types
-    //~| expected `&([isize; 3],)`, found `&([isize],)`
-    //~| expected reference `&([isize; 3],)`
-    //~| found reference `&([isize],)`
 }
diff --git a/tests/ui/dst/dst-bad-coerce4.stderr b/tests/ui/dst/dst-bad-coerce4.stderr
index 46e7dba817c..5c14c0bfedd 100644
--- a/tests/ui/dst/dst-bad-coerce4.stderr
+++ b/tests/ui/dst/dst-bad-coerce4.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/dst-bad-coerce4.rs:12:32
+  --> $DIR/dst-bad-coerce4.rs:10:32
    |
 LL |     let f2: &Fat<[isize; 3]> = f1;
    |             ----------------   ^^ expected `&Fat<[isize; 3]>`, found `&Fat<[isize]>`
@@ -9,17 +9,6 @@ LL |     let f2: &Fat<[isize; 3]> = f1;
    = note: expected reference `&Fat<[isize; 3]>`
               found reference `&Fat<[isize]>`
 
-error[E0308]: mismatched types
-  --> $DIR/dst-bad-coerce4.rs:20:30
-   |
-LL |     let f2: &([isize; 3],) = f1;
-   |             --------------   ^^ expected `&([isize; 3],)`, found `&([isize],)`
-   |             |
-   |             expected due to this
-   |
-   = note: expected reference `&([isize; 3],)`
-              found reference `&([isize],)`
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/dst/dst-bad-deep-2.rs b/tests/ui/dst/dst-bad-deep-2.rs
index e587399135d..76d35751369 100644
--- a/tests/ui/dst/dst-bad-deep-2.rs
+++ b/tests/ui/dst/dst-bad-deep-2.rs
@@ -3,11 +3,11 @@
 // because it would require stack allocation of an unsized temporary (*g in the
 // test).
 
-#![feature(unsized_tuple_coercion)]
+struct Fat<T: ?Sized>(T);
 
 pub fn main() {
-    let f: ([isize; 3],) = ([5, 6, 7],);
-    let g: &([isize],) = &f;
-    let h: &(([isize],),) = &(*g,);
+    let f: Fat<[isize; 3]> = Fat([5, 6, 7]);
+    let g: &Fat<[isize]> = &f;
+    let h: &Fat<Fat<[isize]>> = &Fat(*g);
     //~^ ERROR the size for values of type
 }
diff --git a/tests/ui/dst/dst-bad-deep-2.stderr b/tests/ui/dst/dst-bad-deep-2.stderr
index c7e9854340f..de3f71d206f 100644
--- a/tests/ui/dst/dst-bad-deep-2.stderr
+++ b/tests/ui/dst/dst-bad-deep-2.stderr
@@ -1,13 +1,17 @@
 error[E0277]: the size for values of type `[isize]` cannot be known at compilation time
-  --> $DIR/dst-bad-deep-2.rs:11:30
+  --> $DIR/dst-bad-deep-2.rs:11:38
    |
-LL |     let h: &(([isize],),) = &(*g,);
-   |                              ^^^^^ doesn't have a size known at compile-time
+LL |     let h: &Fat<Fat<[isize]>> = &Fat(*g);
+   |                                      ^^ doesn't have a size known at compile-time
    |
-   = help: within `(([isize],),)`, the trait `Sized` is not implemented for `[isize]`
-   = note: required because it appears within the type `([isize],)`
-   = note: required because it appears within the type `(([isize],),)`
-   = note: tuples must have a statically known size to be initialized
+   = help: within `Fat<[isize]>`, the trait `Sized` is not implemented for `[isize]`
+note: required because it appears within the type `Fat<[isize]>`
+  --> $DIR/dst-bad-deep-2.rs:6:8
+   |
+LL | struct Fat<T: ?Sized>(T);
+   |        ^^^
+   = note: all function arguments must have a statically known size
+   = help: unsized fn params are gated as an unstable feature
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/dynamically-sized-types/dst-irrefutable-bind.rs b/tests/ui/dynamically-sized-types/dst-irrefutable-bind.rs
index 5e352e930d8..f4576229864 100644
--- a/tests/ui/dynamically-sized-types/dst-irrefutable-bind.rs
+++ b/tests/ui/dynamically-sized-types/dst-irrefutable-bind.rs
@@ -1,5 +1,4 @@
 //@ run-pass
-#![feature(unsized_tuple_coercion)]
 
 struct Test<T: ?Sized>(T);
 
@@ -14,14 +13,4 @@ fn main() {
     let slice = &[1,2,3];
     let x = Test(&slice);
     let Test(&_slice) = x;
-
-
-    let x = (10, [1,2,3]);
-    let x : &(i32, [i32]) = &x;
-
-    let & ref _y = x;
-
-    let slice = &[1,2,3];
-    let x = (10, &slice);
-    let (_, &_slice) = x;
 }
diff --git a/tests/ui/dynamically-sized-types/dst-raw.rs b/tests/ui/dynamically-sized-types/dst-raw.rs
index c32ee67dab9..111848c5a7f 100644
--- a/tests/ui/dynamically-sized-types/dst-raw.rs
+++ b/tests/ui/dynamically-sized-types/dst-raw.rs
@@ -1,9 +1,6 @@
 //@ run-pass
 // Test DST raw pointers
 
-
-#![feature(unsized_tuple_coercion)]
-
 trait Trait {
     fn foo(&self) -> isize;
 }
@@ -38,14 +35,6 @@ pub fn main() {
     };
     assert_eq!(r, 42);
 
-    // raw DST tuple
-    let p = (A { f: 42 },);
-    let o: *const (dyn Trait,) = &p;
-    let r = unsafe {
-        (&*o).0.foo()
-    };
-    assert_eq!(r, 42);
-
     // raw slice
     let a: *const [_] = &[1, 2, 3];
     unsafe {
@@ -73,15 +62,6 @@ pub fn main() {
         assert_eq!(len, 3);
     }
 
-    // raw DST tuple with slice
-    let c: *const ([_],) = &([1, 2, 3],);
-    unsafe {
-        let b = (&*c).0[0];
-        assert_eq!(b, 1);
-        let len = (&*c).0.len();
-        assert_eq!(len, 3);
-    }
-
     // all of the above with *mut
     let mut x = A { f: 42 };
     let z: *mut dyn Trait = &mut x;
@@ -97,13 +77,6 @@ pub fn main() {
     };
     assert_eq!(r, 42);
 
-    let mut p = (A { f: 42 },);
-    let o: *mut (dyn Trait,) = &mut p;
-    let r = unsafe {
-        (&*o).0.foo()
-    };
-    assert_eq!(r, 42);
-
     let a: *mut [_] = &mut [1, 2, 3];
     unsafe {
         let b = (*a)[2];
@@ -127,12 +100,4 @@ pub fn main() {
         let len = (&*c).f.len();
         assert_eq!(len, 3);
     }
-
-    let c: *mut ([_],) = &mut ([1, 2, 3],);
-    unsafe {
-        let b = (&*c).0[0];
-        assert_eq!(b, 1);
-        let len = (&*c).0.len();
-        assert_eq!(len, 3);
-    }
 }
diff --git a/tests/ui/dynamically-sized-types/dst-trait-tuple.rs b/tests/ui/dynamically-sized-types/dst-trait-tuple.rs
deleted file mode 100644
index 6ab8829859b..00000000000
--- a/tests/ui/dynamically-sized-types/dst-trait-tuple.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-//@ run-pass
-#![allow(type_alias_bounds)]
-
-#![allow(unused_features)]
-#![feature(unsized_tuple_coercion)]
-
-type Fat<T: ?Sized> = (isize, &'static str, T);
-
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-struct Bar;
-
-#[derive(Copy, Clone, PartialEq, Eq)]
-struct Bar1 {
-    f: isize
-}
-
-trait ToBar {
-    fn to_bar(&self) -> Bar;
-    fn to_val(&self) -> isize;
-}
-
-impl ToBar for Bar {
-    fn to_bar(&self) -> Bar {
-        *self
-    }
-    fn to_val(&self) -> isize {
-        0
-    }
-}
-impl ToBar for Bar1 {
-    fn to_bar(&self) -> Bar {
-        Bar
-    }
-    fn to_val(&self) -> isize {
-        self.f
-    }
-}
-
-// x is a fat pointer
-fn foo(x: &Fat<dyn ToBar>) {
-    assert_eq!(x.0, 5);
-    assert_eq!(x.1, "some str");
-    assert_eq!(x.2.to_bar(), Bar);
-    assert_eq!(x.2.to_val(), 42);
-
-    let y = &x.2;
-    assert_eq!(y.to_bar(), Bar);
-    assert_eq!(y.to_val(), 42);
-}
-
-fn bar(x: &dyn ToBar) {
-    assert_eq!(x.to_bar(), Bar);
-    assert_eq!(x.to_val(), 42);
-}
-
-fn baz(x: &Fat<Fat<dyn ToBar>>) {
-    assert_eq!(x.0, 5);
-    assert_eq!(x.1, "some str");
-    assert_eq!((x.2).0, 8);
-    assert_eq!((x.2).1, "deep str");
-    assert_eq!((x.2).2.to_bar(), Bar);
-    assert_eq!((x.2).2.to_val(), 42);
-
-    let y = &(x.2).2;
-    assert_eq!(y.to_bar(), Bar);
-    assert_eq!(y.to_val(), 42);
-
-}
-
-pub fn main() {
-    let f1 = (5, "some str", Bar1 {f :42});
-    foo(&f1);
-    let f2 = &f1;
-    foo(f2);
-    let f3: &Fat<dyn ToBar> = f2;
-    foo(f3);
-    let f4: &Fat<dyn ToBar> = &f1;
-    foo(f4);
-    let f5: &Fat<dyn ToBar> = &(5, "some str", Bar1 {f :42});
-    foo(f5);
-
-    // Zero size object.
-    let f6: &Fat<dyn ToBar> = &(5, "some str", Bar);
-    assert_eq!(f6.2.to_bar(), Bar);
-
-    // &*
-    //
-    let f7: Box<dyn ToBar> = Box::new(Bar1 {f :42});
-    bar(&*f7);
-
-    // Deep nesting
-    let f1 = (5, "some str", (8, "deep str", Bar1 {f :42}));
-    baz(&f1);
-    let f2 = &f1;
-    baz(f2);
-    let f3: &Fat<Fat<dyn ToBar>> = f2;
-    baz(f3);
-    let f4: &Fat<Fat<dyn ToBar>> = &f1;
-    baz(f4);
-    let f5: &Fat<Fat<dyn ToBar>> = &(5, "some str", (8, "deep str", Bar1 {f :42}));
-    baz(f5);
-}
diff --git a/tests/ui/dynamically-sized-types/dst-tuple-no-reorder.rs b/tests/ui/dynamically-sized-types/dst-tuple-no-reorder.rs
deleted file mode 100644
index ad48d88e480..00000000000
--- a/tests/ui/dynamically-sized-types/dst-tuple-no-reorder.rs
+++ /dev/null
@@ -1,26 +0,0 @@
-//@ run-pass
-
-#![feature(unsized_tuple_coercion)]
-
-// Ensure that unsizable fields that might be accessed don't get reordered
-
-fn nonzero_size() {
-    let sized: (u8, [u32; 2]) = (123, [456, 789]);
-    let unsize: &(u8, [u32]) = &sized;
-    assert_eq!(unsize.0, 123);
-    assert_eq!(unsize.1.len(), 2);
-    assert_eq!(unsize.1[0], 456);
-    assert_eq!(unsize.1[1], 789);
-}
-
-fn zst() {
-    let sized: (u8, [u32; 0]) = (123, []);
-    let unsize: &(u8, [u32]) = &sized;
-    assert_eq!(unsize.0, 123);
-    assert_eq!(unsize.1.len(), 0);
-}
-
-pub fn main() {
-    nonzero_size();
-    zst();
-}
diff --git a/tests/ui/dynamically-sized-types/dst-tuple-sole.rs b/tests/ui/dynamically-sized-types/dst-tuple-sole.rs
deleted file mode 100644
index dc3363b9bde..00000000000
--- a/tests/ui/dynamically-sized-types/dst-tuple-sole.rs
+++ /dev/null
@@ -1,79 +0,0 @@
-//@ run-pass
-#![allow(stable_features)]
-#![allow(type_alias_bounds)]
-
-// As dst-tuple.rs, but the unsized field is the only field in the tuple.
-
-
-#![feature(unsized_tuple_coercion)]
-
-type Fat<T: ?Sized> = (T,);
-
-// x is a fat pointer
-fn foo(x: &Fat<[isize]>) {
-    let y = &x.0;
-    assert_eq!(x.0.len(), 3);
-    assert_eq!(y[0], 1);
-    assert_eq!(x.0[1], 2);
-}
-
-fn foo2<T:ToBar>(x: &Fat<[T]>) {
-    let y = &x.0;
-    let bar = Bar;
-    assert_eq!(x.0.len(), 3);
-    assert_eq!(y[0].to_bar(), bar);
-    assert_eq!(x.0[1].to_bar(), bar);
-}
-
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-struct Bar;
-
-trait ToBar {
-    fn to_bar(&self) -> Bar;
-}
-
-impl ToBar for Bar {
-    fn to_bar(&self) -> Bar {
-        *self
-    }
-}
-
-pub fn main() {
-    // With a vec of ints.
-    let f1 = ([1, 2, 3],);
-    foo(&f1);
-    let f2 = &f1;
-    foo(f2);
-    let f3: &Fat<[isize]> = f2;
-    foo(f3);
-    let f4: &Fat<[isize]> = &f1;
-    foo(f4);
-    let f5: &Fat<[isize]> = &([1, 2, 3],);
-    foo(f5);
-
-    // With a vec of Bars.
-    let bar = Bar;
-    let f1 = ([bar, bar, bar],);
-    foo2(&f1);
-    let f2 = &f1;
-    foo2(f2);
-    let f3: &Fat<[Bar]> = f2;
-    foo2(f3);
-    let f4: &Fat<[Bar]> = &f1;
-    foo2(f4);
-    let f5: &Fat<[Bar]> = &([bar, bar, bar],);
-    foo2(f5);
-
-    // Assignment.
-    let f5: &mut Fat<[isize]> = &mut ([1, 2, 3],);
-    f5.0[1] = 34;
-    assert_eq!(f5.0[0], 1);
-    assert_eq!(f5.0[1], 34);
-    assert_eq!(f5.0[2], 3);
-
-    // Zero size vec.
-    let f5: &Fat<[isize]> = &([],);
-    assert!(f5.0.is_empty());
-    let f5: &Fat<[Bar]> = &([],);
-    assert!(f5.0.is_empty());
-}
diff --git a/tests/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs b/tests/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs
deleted file mode 100644
index b4ee0fb4070..00000000000
--- a/tests/ui/dynamically-sized-types/dst-tuple-zst-offsets.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-//@ run-pass
-
-#![feature(unsized_tuple_coercion)]
-
-// Check that we do not change the offsets of ZST fields when unsizing
-
-fn scalar_layout() {
-    let sized: &(u8, [(); 13]) = &(123, [(); 13]);
-    let unsize: &(u8, [()]) = sized;
-    assert_eq!(sized.1.as_ptr(), unsize.1.as_ptr());
-}
-
-fn scalarpair_layout() {
-    let sized: &(u8, u16, [(); 13]) = &(123, 456, [(); 13]);
-    let unsize: &(u8, u16, [()]) = sized;
-    assert_eq!(sized.2.as_ptr(), unsize.2.as_ptr());
-}
-
-pub fn main() {
-    scalar_layout();
-    scalarpair_layout();
-}
diff --git a/tests/ui/dynamically-sized-types/dst-tuple.rs b/tests/ui/dynamically-sized-types/dst-tuple.rs
deleted file mode 100644
index 52fc69f7809..00000000000
--- a/tests/ui/dynamically-sized-types/dst-tuple.rs
+++ /dev/null
@@ -1,119 +0,0 @@
-//@ run-pass
-#![allow(type_alias_bounds)]
-
-#![feature(unsized_tuple_coercion)]
-
-type Fat<T: ?Sized> = (isize, &'static str, T);
-
-// x is a fat pointer
-fn foo(x: &Fat<[isize]>) {
-    let y = &x.2;
-    assert_eq!(x.2.len(), 3);
-    assert_eq!(y[0], 1);
-    assert_eq!(x.2[1], 2);
-    assert_eq!(x.0, 5);
-    assert_eq!(x.1, "some str");
-}
-
-fn foo2<T:ToBar>(x: &Fat<[T]>) {
-    let y = &x.2;
-    let bar = Bar;
-    assert_eq!(x.2.len(), 3);
-    assert_eq!(y[0].to_bar(), bar);
-    assert_eq!(x.2[1].to_bar(), bar);
-    assert_eq!(x.0, 5);
-    assert_eq!(x.1, "some str");
-}
-
-fn foo3(x: &Fat<Fat<[isize]>>) {
-    let y = &(x.2).2;
-    assert_eq!(x.0, 5);
-    assert_eq!(x.1, "some str");
-    assert_eq!((x.2).0, 8);
-    assert_eq!((x.2).1, "deep str");
-    assert_eq!((x.2).2.len(), 3);
-    assert_eq!(y[0], 1);
-    assert_eq!((x.2).2[1], 2);
-}
-
-
-#[derive(Copy, Clone, PartialEq, Eq, Debug)]
-struct Bar;
-
-trait ToBar {
-    fn to_bar(&self) -> Bar;
-}
-
-impl ToBar for Bar {
-    fn to_bar(&self) -> Bar {
-        *self
-    }
-}
-
-pub fn main() {
-    // With a vec of ints.
-    let f1 = (5, "some str", [1, 2, 3]);
-    foo(&f1);
-    let f2 = &f1;
-    foo(f2);
-    let f3: &Fat<[isize]> = f2;
-    foo(f3);
-    let f4: &Fat<[isize]> = &f1;
-    foo(f4);
-    let f5: &Fat<[isize]> = &(5, "some str", [1, 2, 3]);
-    foo(f5);
-
-    // With a vec of Bars.
-    let bar = Bar;
-    let f1 = (5, "some str", [bar, bar, bar]);
-    foo2(&f1);
-    let f2 = &f1;
-    foo2(f2);
-    let f3: &Fat<[Bar]> = f2;
-    foo2(f3);
-    let f4: &Fat<[Bar]> = &f1;
-    foo2(f4);
-    let f5: &Fat<[Bar]> = &(5, "some str", [bar, bar, bar]);
-    foo2(f5);
-
-    // Assignment.
-    let f5: &mut Fat<[isize]> = &mut (5, "some str", [1, 2, 3]);
-    f5.2[1] = 34;
-    assert_eq!(f5.2[0], 1);
-    assert_eq!(f5.2[1], 34);
-    assert_eq!(f5.2[2], 3);
-
-    // Zero size vec.
-    let f5: &Fat<[isize]> = &(5, "some str", []);
-    assert!(f5.2.is_empty());
-    let f5: &Fat<[Bar]> = &(5, "some str", []);
-    assert!(f5.2.is_empty());
-
-    // Deeply nested.
-    let f1 = (5, "some str", (8, "deep str", [1, 2, 3]));
-    foo3(&f1);
-    let f2 = &f1;
-    foo3(f2);
-    let f3: &Fat<Fat<[isize]>> = f2;
-    foo3(f3);
-    let f4: &Fat<Fat<[isize]>> = &f1;
-    foo3(f4);
-    let f5: &Fat<Fat<[isize]>> = &(5, "some str", (8, "deep str", [1, 2, 3]));
-    foo3(f5);
-
-    // Box.
-    let f1 = Box::new([1, 2, 3]);
-    assert_eq!((*f1)[1], 2);
-    let f2: Box<[isize]> = f1;
-    assert_eq!((*f2)[1], 2);
-
-    // Nested Box.
-    let f1 : Box<Fat<[isize; 3]>> = Box::new((5, "some str", [1, 2, 3]));
-    foo(&*f1);
-    let f2 : Box<Fat<[isize]>> = f1;
-    foo(&*f2);
-
-    let f3 : Box<Fat<[isize]>> =
-        Box::<Fat<[_; 3]>>::new((5, "some str", [1, 2, 3]));
-    foo(&*f3);
-}
diff --git a/tests/ui/error-codes/E0275.rs b/tests/ui/error-codes/E0275.rs
index df7b606155e..28a9676f03e 100644
--- a/tests/ui/error-codes/E0275.rs
+++ b/tests/ui/error-codes/E0275.rs
@@ -1,4 +1,3 @@
-//@ normalize-stderr: "long-type-\d+" -> "long-type-hash"
 trait Foo {}
 
 struct Bar<T>(T);
diff --git a/tests/ui/error-codes/E0275.stderr b/tests/ui/error-codes/E0275.stderr
index b5075408340..3b31c87320a 100644
--- a/tests/ui/error-codes/E0275.stderr
+++ b/tests/ui/error-codes/E0275.stderr
@@ -1,12 +1,12 @@
 error[E0275]: overflow evaluating the requirement `Bar<Bar<Bar<Bar<Bar<Bar<Bar<...>>>>>>>: Foo`
-  --> $DIR/E0275.rs:6:33
+  --> $DIR/E0275.rs:5:33
    |
 LL | impl<T> Foo for T where Bar<T>: Foo {}
    |                                 ^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`E0275`)
 note: required for `Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<Bar<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
-  --> $DIR/E0275.rs:6:9
+  --> $DIR/E0275.rs:5:9
    |
 LL | impl<T> Foo for T where Bar<T>: Foo {}
    |         ^^^     ^               --- unsatisfied trait bound introduced here
diff --git a/tests/ui/error-codes/E0462.stderr b/tests/ui/error-codes/E0462.stderr
index 18f20d79385..be32001fad4 100644
--- a/tests/ui/error-codes/E0462.stderr
+++ b/tests/ui/error-codes/E0462.stderr
@@ -5,7 +5,7 @@ LL | extern crate found_staticlib;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the following crate versions were found:
-           crate `found_staticlib`: $TEST_BUILD_DIR/error-codes/E0462/auxiliary/libfound_staticlib.somelib
+           crate `found_staticlib`: $TEST_BUILD_DIR/auxiliary/libfound_staticlib.somelib
    = help: please recompile that crate using --crate-type lib
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/error-codes/E0464.stderr b/tests/ui/error-codes/E0464.stderr
index edb0b1cf41e..ec18978a59a 100644
--- a/tests/ui/error-codes/E0464.stderr
+++ b/tests/ui/error-codes/E0464.stderr
@@ -4,9 +4,9 @@ error[E0464]: multiple candidates for `rlib` dependency `crateresolve1` found
 LL | extern crate crateresolve1;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: candidate #1: $TEST_BUILD_DIR/error-codes/E0464/auxiliary/libcrateresolve1-1.somelib
-   = note: candidate #2: $TEST_BUILD_DIR/error-codes/E0464/auxiliary/libcrateresolve1-2.somelib
-   = note: candidate #3: $TEST_BUILD_DIR/error-codes/E0464/auxiliary/libcrateresolve1-3.somelib
+   = note: candidate #1: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-1.somelib
+   = note: candidate #2: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-2.somelib
+   = note: candidate #3: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-3.somelib
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/error-codes/E0523.stderr b/tests/ui/error-codes/E0523.stderr
index c6e65b55e2b..f4072d69104 100644
--- a/tests/ui/error-codes/E0523.stderr
+++ b/tests/ui/error-codes/E0523.stderr
@@ -4,9 +4,9 @@ error[E0464]: multiple candidates for `rlib` dependency `crateresolve1` found
 LL | extern crate crateresolve1;
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: candidate #1: $TEST_BUILD_DIR/error-codes/E0523/auxiliary/libcrateresolve1-1.somelib
-   = note: candidate #2: $TEST_BUILD_DIR/error-codes/E0523/auxiliary/libcrateresolve1-2.somelib
-   = note: candidate #3: $TEST_BUILD_DIR/error-codes/E0523/auxiliary/libcrateresolve1-3.somelib
+   = note: candidate #1: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-1.somelib
+   = note: candidate #2: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-2.somelib
+   = note: candidate #3: $TEST_BUILD_DIR/auxiliary/libcrateresolve1-3.somelib
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/error-codes/E0582.stderr b/tests/ui/error-codes/E0582.stderr
index 64b527cdcc2..ac97a6ff00a 100644
--- a/tests/ui/error-codes/E0582.stderr
+++ b/tests/ui/error-codes/E0582.stderr
@@ -14,7 +14,7 @@ error[E0308]: mismatched types
   --> $DIR/E0582.rs:22:5
    |
 LL |     bar(mk_unexpected_char_err)
-   |     ^^^ one type is more general than the other
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
    |
    = note: expected enum `Option<&_>`
               found enum `Option<&'a _>`
diff --git a/tests/ui/extern/issue-36122-accessing-externed-dst.stderr b/tests/ui/extern/issue-36122-accessing-externed-dst.stderr
index 64178e6f843..6f805aec1df 100644
--- a/tests/ui/extern/issue-36122-accessing-externed-dst.stderr
+++ b/tests/ui/extern/issue-36122-accessing-externed-dst.stderr
@@ -5,6 +5,7 @@ LL |         static symbol: [usize];
    |                        ^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `[usize]`
+   = note: statics and constants must have a statically known size
 
 error[E0133]: use of extern static is unsafe and requires unsafe function or block
   --> $DIR/issue-36122-accessing-externed-dst.rs:5:20
diff --git a/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr b/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr
index d8dbd94696e..aa9c67f0151 100644
--- a/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr
+++ b/tests/ui/feature-gates/feature-gate-abi_gpu_kernel.stderr
@@ -112,3 +112,14 @@ error: aborting due to 12 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0570, E0658.
 For more information about an error, try `rustc --explain E0570`.
+Future incompatibility report: Future breakage diagnostic:
+warning: the calling convention "gpu-kernel" is not supported on this target
+  --> $DIR/feature-gate-abi_gpu_kernel.rs:37:11
+   |
+LL | type A1 = extern "gpu-kernel" 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>
+   = note: `#[warn(unsupported_fn_ptr_calling_conventions)]` on by default
+
diff --git a/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr b/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr
index 032d7adf77a..381e7a210be 100644
--- a/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr
+++ b/tests/ui/feature-gates/feature-gate-coroutines.e2024.stderr
@@ -45,7 +45,7 @@ LL |     yield true;
    |     ^^^^^^^^^^
    |
    = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
-   = help: add `#![feature(coroutines)]` to the crate attributes to enable
+   = help: add `#![feature(yield_expr)]` 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: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
@@ -66,7 +66,7 @@ LL |     let _ = || yield true;
    |                ^^^^^^^^^^
    |
    = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
-   = help: add `#![feature(coroutines)]` to the crate attributes to enable
+   = help: add `#![feature(yield_expr)]` 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: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
diff --git a/tests/ui/feature-gates/feature-gate-coroutines.none.stderr b/tests/ui/feature-gates/feature-gate-coroutines.none.stderr
index 032d7adf77a..381e7a210be 100644
--- a/tests/ui/feature-gates/feature-gate-coroutines.none.stderr
+++ b/tests/ui/feature-gates/feature-gate-coroutines.none.stderr
@@ -45,7 +45,7 @@ LL |     yield true;
    |     ^^^^^^^^^^
    |
    = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
-   = help: add `#![feature(coroutines)]` to the crate attributes to enable
+   = help: add `#![feature(yield_expr)]` 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: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
@@ -66,7 +66,7 @@ LL |     let _ = || yield true;
    |                ^^^^^^^^^^
    |
    = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
-   = help: add `#![feature(coroutines)]` to the crate attributes to enable
+   = help: add `#![feature(yield_expr)]` 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: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
diff --git a/tests/ui/feature-gates/feature-gate-min-generic-const-args.rs b/tests/ui/feature-gates/feature-gate-min-generic-const-args.rs
index 171509876d1..1cf755b2c56 100644
--- a/tests/ui/feature-gates/feature-gate-min-generic-const-args.rs
+++ b/tests/ui/feature-gates/feature-gate-min-generic-const-args.rs
@@ -1,8 +1,10 @@
 trait Trait {
+    #[type_const]
+    //~^ ERROR experimental
     const ASSOC: usize;
 }
 
-// FIXME(min_generic_const_args): implement support for this, behind the feature gate
+// FIXME(mgca): add suggestion for mgca to this error
 fn foo<T: Trait>() -> [u8; <T as Trait>::ASSOC] {
     //~^ ERROR generic parameters may not be used in const operations
     loop {}
diff --git a/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr b/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr
index 04d96b4c11e..af528a3c1b7 100644
--- a/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr
+++ b/tests/ui/feature-gates/feature-gate-min-generic-const-args.stderr
@@ -1,5 +1,5 @@
 error: generic parameters may not be used in const operations
-  --> $DIR/feature-gate-min-generic-const-args.rs:6:29
+  --> $DIR/feature-gate-min-generic-const-args.rs:8:29
    |
 LL | fn foo<T: Trait>() -> [u8; <T as Trait>::ASSOC] {
    |                             ^ cannot perform const operation using `T`
@@ -7,5 +7,16 @@ LL | fn foo<T: Trait>() -> [u8; <T as Trait>::ASSOC] {
    = note: type parameters may not be used in const expressions
    = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
 
-error: aborting due to 1 previous error
+error[E0658]: the `#[type_const]` attribute is an experimental feature
+  --> $DIR/feature-gate-min-generic-const-args.rs:2:5
+   |
+LL |     #[type_const]
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #132980 <https://github.com/rust-lang/rust/issues/132980> for more information
+   = help: add `#![feature(min_generic_const_args)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 2 previous errors
 
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs
index 4624faf1e53..663a83a665c 100644
--- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs
+++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs
@@ -7,9 +7,13 @@ struct Foo;
 impl Foo {
     fn foo(self: Pin<&mut Self>) {
     }
+    fn foo_sugar(&pin mut self) {} //~ ERROR pinned reference syntax is experimental
+    fn foo_sugar_const(&pin const self) {} //~ ERROR pinned reference syntax is experimental
 }
 
-fn foo(x: Pin<&mut Foo>) {
+fn foo(mut x: Pin<&mut Foo>) {
+    Foo::foo_sugar(x.as_mut());
+    Foo::foo_sugar_const(x.as_ref());
     let _y: &pin mut Foo = x; //~ ERROR pinned reference syntax is experimental
 }
 
@@ -27,4 +31,38 @@ fn baz(mut x: Pin<&mut Foo>) {
 
 fn baz_sugar(_: &pin const Foo) {} //~ ERROR pinned reference syntax is experimental
 
+#[cfg(any())]
+mod not_compiled {
+    use std::pin::Pin;
+
+    struct Foo;
+
+    impl Foo {
+        fn foo(self: Pin<&mut Self>) {
+        }
+        fn foo_sugar(&pin mut self) {} //~ ERROR pinned reference syntax is experimental
+        fn foo_sugar_const(&pin const self) {} //~ ERROR pinned reference syntax is experimental
+    }
+
+    fn foo(mut x: Pin<&mut Foo>) {
+        Foo::foo_sugar(x.as_mut());
+        Foo::foo_sugar_const(x.as_ref());
+        let _y: &pin mut Foo = x; //~ ERROR pinned reference syntax is experimental
+    }
+
+    fn foo_sugar(_: &pin mut Foo) {} //~ ERROR pinned reference syntax is experimental
+
+    fn bar(x: Pin<&mut Foo>) {
+        foo(x);
+        foo(x);
+    }
+
+    fn baz(mut x: Pin<&mut Foo>) {
+        x.foo();
+        x.foo();
+    }
+
+    fn baz_sugar(_: &pin const Foo) {} //~ ERROR pinned reference syntax is experimental
+}
+
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr
index dd93a7be1ad..8ed7543d86e 100644
--- a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr
+++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr
@@ -1,5 +1,25 @@
 error[E0658]: pinned reference syntax is experimental
-  --> $DIR/feature-gate-pin_ergonomics.rs:13:14
+  --> $DIR/feature-gate-pin_ergonomics.rs:10:19
+   |
+LL |     fn foo_sugar(&pin mut self) {}
+   |                   ^^^
+   |
+   = note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
+   = help: add `#![feature(pin_ergonomics)]` 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]: pinned reference syntax is experimental
+  --> $DIR/feature-gate-pin_ergonomics.rs:11:25
+   |
+LL |     fn foo_sugar_const(&pin const self) {}
+   |                         ^^^
+   |
+   = note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
+   = help: add `#![feature(pin_ergonomics)]` 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]: pinned reference syntax is experimental
+  --> $DIR/feature-gate-pin_ergonomics.rs:17:14
    |
 LL |     let _y: &pin mut Foo = x;
    |              ^^^
@@ -9,7 +29,7 @@ LL |     let _y: &pin mut Foo = x;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: pinned reference syntax is experimental
-  --> $DIR/feature-gate-pin_ergonomics.rs:16:18
+  --> $DIR/feature-gate-pin_ergonomics.rs:20:18
    |
 LL | fn foo_sugar(_: &pin mut Foo) {}
    |                  ^^^
@@ -19,7 +39,7 @@ LL | fn foo_sugar(_: &pin mut Foo) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: pinned reference syntax is experimental
-  --> $DIR/feature-gate-pin_ergonomics.rs:28:18
+  --> $DIR/feature-gate-pin_ergonomics.rs:32:18
    |
 LL | fn baz_sugar(_: &pin const Foo) {}
    |                  ^^^
@@ -28,8 +48,58 @@ LL | fn baz_sugar(_: &pin const Foo) {}
    = help: add `#![feature(pin_ergonomics)]` 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]: pinned reference syntax is experimental
+  --> $DIR/feature-gate-pin_ergonomics.rs:43:23
+   |
+LL |         fn foo_sugar(&pin mut self) {}
+   |                       ^^^
+   |
+   = note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
+   = help: add `#![feature(pin_ergonomics)]` 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]: pinned reference syntax is experimental
+  --> $DIR/feature-gate-pin_ergonomics.rs:44:29
+   |
+LL |         fn foo_sugar_const(&pin const self) {}
+   |                             ^^^
+   |
+   = note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
+   = help: add `#![feature(pin_ergonomics)]` 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]: pinned reference syntax is experimental
+  --> $DIR/feature-gate-pin_ergonomics.rs:50:18
+   |
+LL |         let _y: &pin mut Foo = x;
+   |                  ^^^
+   |
+   = note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
+   = help: add `#![feature(pin_ergonomics)]` 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]: pinned reference syntax is experimental
+  --> $DIR/feature-gate-pin_ergonomics.rs:53:22
+   |
+LL |     fn foo_sugar(_: &pin mut Foo) {}
+   |                      ^^^
+   |
+   = note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
+   = help: add `#![feature(pin_ergonomics)]` 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]: pinned reference syntax is experimental
+  --> $DIR/feature-gate-pin_ergonomics.rs:65:22
+   |
+LL |     fn baz_sugar(_: &pin const Foo) {}
+   |                      ^^^
+   |
+   = note: see issue #130494 <https://github.com/rust-lang/rust/issues/130494> for more information
+   = help: add `#![feature(pin_ergonomics)]` 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[E0382]: use of moved value: `x`
-  --> $DIR/feature-gate-pin_ergonomics.rs:20:9
+  --> $DIR/feature-gate-pin_ergonomics.rs:24:9
    |
 LL | fn bar(x: Pin<&mut Foo>) {
    |        - move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
@@ -39,15 +109,15 @@ LL |     foo(x);
    |         ^ value used here after move
    |
 note: consider changing this parameter type in function `foo` to borrow instead if owning the value isn't necessary
-  --> $DIR/feature-gate-pin_ergonomics.rs:12:11
+  --> $DIR/feature-gate-pin_ergonomics.rs:14:15
    |
-LL | fn foo(x: Pin<&mut Foo>) {
-   |    ---    ^^^^^^^^^^^^^ this parameter takes ownership of the value
+LL | fn foo(mut x: Pin<&mut Foo>) {
+   |    ---        ^^^^^^^^^^^^^ this parameter takes ownership of the value
    |    |
    |    in this function
 
 error[E0382]: use of moved value: `x`
-  --> $DIR/feature-gate-pin_ergonomics.rs:25:5
+  --> $DIR/feature-gate-pin_ergonomics.rs:29:5
    |
 LL | fn baz(mut x: Pin<&mut Foo>) {
    |        ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
@@ -66,7 +136,7 @@ help: consider reborrowing the `Pin` instead of moving it
 LL |     x.as_mut().foo();
    |      +++++++++
 
-error: aborting due to 5 previous errors
+error: aborting due to 12 previous errors
 
 Some errors have detailed explanations: E0382, E0658.
 For more information about an error, try `rustc --explain E0382`.
diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib-elf.rs b/tests/ui/feature-gates/feature-gate-raw-dylib-elf.rs
new file mode 100644
index 00000000000..ec49e53d9b4
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-raw-dylib-elf.rs
@@ -0,0 +1,9 @@
+//@ only-elf
+//@ needs-dynamic-linking
+
+#[link(name = "meow", kind = "raw-dylib")] //~ ERROR: link kind `raw-dylib` is unstable on ELF platforms
+unsafe extern "C" {
+  safe fn meowmeow();
+}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-raw-dylib-elf.stderr b/tests/ui/feature-gates/feature-gate-raw-dylib-elf.stderr
new file mode 100644
index 00000000000..dfbf39f5a18
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-raw-dylib-elf.stderr
@@ -0,0 +1,13 @@
+error[E0658]: link kind `raw-dylib` is unstable on ELF platforms
+  --> $DIR/feature-gate-raw-dylib-elf.rs:4:30
+   |
+LL | #[link(name = "meow", kind = "raw-dylib")]
+   |                              ^^^^^^^^^^^
+   |
+   = note: see issue #135694 <https://github.com/rust-lang/rust/issues/135694> for more information
+   = help: add `#![feature(raw_dylib_elf)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs b/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs
index c3d62a231e5..b5fbcc9ccf8 100644
--- a/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs
+++ b/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.rs
@@ -1,4 +1,4 @@
 fn main() {
     let _ : &(dyn Send,) = &((),);
-    //~^ ERROR unsized tuple coercion is not stable enough
+    //~^ ERROR 2:28: 2:34: mismatched types [E0308]
 }
diff --git a/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.stderr b/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.stderr
index 251928658df..12847bd3c0d 100644
--- a/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.stderr
+++ b/tests/ui/feature-gates/feature-gate-unsized_tuple_coercion.stderr
@@ -1,13 +1,14 @@
-error[E0658]: unsized tuple coercion is not stable enough for use and is subject to change
+error[E0308]: mismatched types
   --> $DIR/feature-gate-unsized_tuple_coercion.rs:2:28
    |
 LL |     let _ : &(dyn Send,) = &((),);
-   |                            ^^^^^^
+   |             ------------   ^^^^^^ expected `&(dyn Send,)`, found `&((),)`
+   |             |
+   |             expected due to this
    |
-   = note: see issue #42877 <https://github.com/rust-lang/rust/issues/42877> for more information
-   = help: add `#![feature(unsized_tuple_coercion)]` 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: expected reference `&(dyn Send,)`
+              found reference `&((),)`
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0658`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr b/tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr
new file mode 100644
index 00000000000..6a8f01bbcce
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-where_clause_attrs.a.stderr
@@ -0,0 +1,883 @@
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:33:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:34:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:35:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:36:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:37:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:38:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:39:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:40:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:44:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:45:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:46:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:47:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:48:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:49:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:50:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:51:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:55:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:56:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:57:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:58:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:59:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:60:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:61:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:62:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:67:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:68:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:69:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:70:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:71:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:72:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:73:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:74:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:77:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:78:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:79:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:80:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:81:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:82:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:83:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:84:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:88:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:89:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:90:9
+   |
+LL |         #[cfg(all())] T: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:91:9
+   |
+LL |         #[cfg(any())] T: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:92:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:93:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:94:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:95:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:101:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:102:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:103:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:104:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:105:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:106:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:107:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:108:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:115:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:116:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:117:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:118:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:119:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:120:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:121:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:122:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:130:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:131:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:132:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:133:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:134:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:135:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:136:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:137:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:143:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:144:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:145:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:146:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:147:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:148:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:149:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:150:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:153:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:154:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:155:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:156:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:157:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:158:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:159:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:160:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 88 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr b/tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr
new file mode 100644
index 00000000000..6a8f01bbcce
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-where_clause_attrs.b.stderr
@@ -0,0 +1,883 @@
+error[E0658]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:33:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:34:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:35:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:36:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:37:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:38:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:39:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:40:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:44:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:45:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:46:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:47:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:48:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:49:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:50:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:51:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:55:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:56:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:57:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:58:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:59:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:60:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:61:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:62:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:67:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:68:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:69:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:70:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:71:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:72:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:73:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:74:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:77:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:78:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:79:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:80:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:81:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:82:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:83:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:84:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny;
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:88:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:89:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:90:9
+   |
+LL |         #[cfg(all())] T: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:91:9
+   |
+LL |         #[cfg(any())] T: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:92:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:93:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:94:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:95:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:101:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:102:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:103:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:104:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:105:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:106:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:107:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:108:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:115:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:116:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:117:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:118:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:119:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:120:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:121:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:122:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:130:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:131:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:132:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:133:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:134:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:135:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:136:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:137:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:143:5
+   |
+LL |     #[cfg(a)] T: TraitA,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:144:5
+   |
+LL |     #[cfg(b)] T: TraitB,
+   |     ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:145:5
+   |
+LL |     #[cfg(all())] T: TraitAll,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:146:5
+   |
+LL |     #[cfg(any())] T: TraitAny,
+   |     ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:147:5
+   |
+LL |     #[cfg_attr(a, cfg(a))] T: TraitAA,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:148:5
+   |
+LL |     #[cfg_attr(b, cfg(b))] T: TraitBB,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:149:5
+   |
+LL |     #[cfg_attr(all(), cfg(all()))] T: TraitAllAll,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:150:5
+   |
+LL |     #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:153:9
+   |
+LL |         #[cfg(a)] U: TraitA,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:154:9
+   |
+LL |         #[cfg(b)] U: TraitB,
+   |         ^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:155:9
+   |
+LL |         #[cfg(all())] U: TraitAll,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:156:9
+   |
+LL |         #[cfg(any())] U: TraitAny,
+   |         ^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:157:9
+   |
+LL |         #[cfg_attr(a, cfg(a))] U: TraitAA,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:158:9
+   |
+LL |         #[cfg_attr(b, cfg(b))] U: TraitBB,
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:159:9
+   |
+LL |         #[cfg_attr(all(), cfg(all()))] U: TraitAllAll,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` 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]: attributes in `where` clause are unstable
+  --> $DIR/feature-gate-where_clause_attrs.rs:160:9
+   |
+LL |         #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115590 <https://github.com/rust-lang/rust/issues/115590> for more information
+   = help: add `#![feature(where_clause_attrs)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 88 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-where_clause_attrs.rs b/tests/ui/feature-gates/feature-gate-where_clause_attrs.rs
new file mode 100644
index 00000000000..09c734a52de
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-where_clause_attrs.rs
@@ -0,0 +1,162 @@
+//@ revisions: a b
+
+#![crate_type = "lib"]
+use std::marker::PhantomData;
+
+#[cfg(a)]
+trait TraitA {}
+
+#[cfg(b)]
+trait TraitB {}
+
+#[cfg_attr(a, cfg(a))]
+trait TraitAA {}
+
+#[cfg_attr(b, cfg(b))]
+trait TraitBB {}
+
+#[cfg(all())]
+trait TraitAll {}
+
+#[cfg(any())]
+trait TraitAny {}
+
+#[cfg_attr(all(), cfg(all()))]
+trait TraitAllAll {}
+
+#[cfg_attr(any(), cfg(any()))]
+trait TraitAnyAny {}
+
+
+trait A<T>
+where
+    #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+{
+    type B<U>
+    where
+        #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable
+
+    fn foo<U>(&self)
+    where
+        #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable
+}
+
+impl<T> A<T> for T
+where
+    #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+{
+    type B<U> = () where
+        #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny; //~ ERROR attributes in `where` clause are unstable
+
+    fn foo<U>(&self)
+    where
+        #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+    {}
+}
+
+struct C<T>
+where
+    #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+{
+    _t: PhantomData<T>,
+}
+
+union D<T>
+where
+    #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+{
+
+    _t: PhantomData<T>,
+}
+
+enum E<T>
+where
+    #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+{
+    E(PhantomData<T>),
+}
+
+impl<T> C<T> where
+    #[cfg(a)] T: TraitA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(b)] T: TraitB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(all())] T: TraitAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg(any())] T: TraitAny, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(a, cfg(a))] T: TraitAA, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(b, cfg(b))] T: TraitBB, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(all(), cfg(all()))] T: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+    #[cfg_attr(any(), cfg(any()))] T: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+{
+    fn new<U>() where
+        #[cfg(a)] U: TraitA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(b)] U: TraitB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(all())] U: TraitAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg(any())] U: TraitAny, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(a, cfg(a))] U: TraitAA, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(b, cfg(b))] U: TraitBB, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(all(), cfg(all()))] U: TraitAllAll, //~ ERROR attributes in `where` clause are unstable
+        #[cfg_attr(any(), cfg(any()))] U: TraitAnyAny, //~ ERROR attributes in `where` clause are unstable
+    {}
+}
diff --git a/tests/ui/feature-gates/feature-gate-yield-expr.rs b/tests/ui/feature-gates/feature-gate-yield-expr.rs
new file mode 100644
index 00000000000..382bf89069e
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-yield-expr.rs
@@ -0,0 +1,9 @@
+//@ edition: 2024
+#![feature(stmt_expr_attributes)]
+
+fn main() {
+    yield (); //~ ERROR yield syntax is experimental
+    //~^ ERROR yield syntax is experimental
+    //~^^ ERROR `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
+    //~^^^ ERROR yield expression outside of coroutine literal
+}
diff --git a/tests/ui/feature-gates/feature-gate-yield-expr.stderr b/tests/ui/feature-gates/feature-gate-yield-expr.stderr
new file mode 100644
index 00000000000..ad8a15a0f36
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-yield-expr.stderr
@@ -0,0 +1,41 @@
+error[E0658]: yield syntax is experimental
+  --> $DIR/feature-gate-yield-expr.rs:5:5
+   |
+LL |     yield ();
+   |     ^^^^^^^^
+   |
+   = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
+   = help: add `#![feature(coroutines)]` 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]: yield syntax is experimental
+  --> $DIR/feature-gate-yield-expr.rs:5:5
+   |
+LL |     yield ();
+   |     ^^^^^^^^
+   |
+   = note: see issue #43122 <https://github.com/rust-lang/rust/issues/43122> for more information
+   = help: add `#![feature(yield_expr)]` 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: `yield` can only be used in `#[coroutine]` closures, or `gen` blocks
+  --> $DIR/feature-gate-yield-expr.rs:5:5
+   |
+LL |     yield ();
+   |     ^^^^^^^^
+   |
+help: use `#[coroutine]` to make this closure a coroutine
+   |
+LL | #[coroutine] fn main() {
+   | ++++++++++++
+
+error[E0627]: yield expression outside of coroutine literal
+  --> $DIR/feature-gate-yield-expr.rs:5:5
+   |
+LL |     yield ();
+   |     ^^^^^^^^
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0627, E0658.
+For more information about an error, try `rustc --explain E0627`.
diff --git a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs
index 7b6ba9f7f16..e22a49d0399 100644
--- a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.rs
@@ -1,5 +1,3 @@
-//@ normalize-stderr: "long-type-\d+" -> "long-type-hash"
-
 fn id(
     f: &dyn Fn(u32),
 ) -> &dyn Fn(
diff --git a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr
index be2eca3e61a..00a5948bdd4 100644
--- a/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hang-on-deeply-nested-dyn.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/hang-on-deeply-nested-dyn.rs:12:5
+  --> $DIR/hang-on-deeply-nested-dyn.rs:10:5
    |
 LL |   ) -> &dyn Fn(
    |  ______-
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs
index f880749ec83..ff6f4861e14 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs
@@ -1,5 +1,3 @@
-//@ normalize-stderr: "long-type-\d+" -> "long-type-hash"
-
 // rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream<Item=T>`
 // should act as assertion that item does not borrow from its stream;
 // but an earlier buggy rustc allowed `.map(|x: &_| x)` which does
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr
index ae364de8cc0..240e1c3dde1 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr
@@ -1,5 +1,5 @@
-error[E0599]: the method `filterx` exists for struct `Map<Repeat, {closure@hrtb-doesnt-borrow-self-1.rs:115:27}>`, but its trait bounds were not satisfied
-  --> $DIR/hrtb-doesnt-borrow-self-1.rs:116:22
+error[E0599]: the method `filterx` exists for struct `Map<Repeat, {closure@hrtb-doesnt-borrow-self-1.rs:113:27}>`, but its trait bounds were not satisfied
+  --> $DIR/hrtb-doesnt-borrow-self-1.rs:114:22
    |
 LL | pub struct Map<S, F> {
    | -------------------- method `filterx` not found for this struct because it doesn't satisfy `_: StreamExt`
@@ -8,16 +8,16 @@ LL |     let filter = map.filterx(|x: &_| true);
    |                      ^^^^^^^ method cannot be called due to unsatisfied trait bounds
    |
 note: the following trait bounds were not satisfied:
-      `&'a mut &Map<Repeat, {closure@$DIR/hrtb-doesnt-borrow-self-1.rs:115:27: 115:34}>: Stream`
-      `&'a mut &mut Map<Repeat, {closure@$DIR/hrtb-doesnt-borrow-self-1.rs:115:27: 115:34}>: Stream`
-      `&'a mut Map<Repeat, {closure@$DIR/hrtb-doesnt-borrow-self-1.rs:115:27: 115:34}>: Stream`
-  --> $DIR/hrtb-doesnt-borrow-self-1.rs:98:50
+      `&'a mut &Map<Repeat, {closure@$DIR/hrtb-doesnt-borrow-self-1.rs:113:27: 113:34}>: Stream`
+      `&'a mut &mut Map<Repeat, {closure@$DIR/hrtb-doesnt-borrow-self-1.rs:113:27: 113:34}>: Stream`
+      `&'a mut Map<Repeat, {closure@$DIR/hrtb-doesnt-borrow-self-1.rs:113:27: 113:34}>: Stream`
+  --> $DIR/hrtb-doesnt-borrow-self-1.rs:96:50
    |
 LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
    |         ---------     -                          ^^^^^^ unsatisfied trait bound introduced here
    = help: items from traits can only be used if the trait is implemented and in scope
 note: `StreamExt` defines an item `filterx`, perhaps you need to implement it
-  --> $DIR/hrtb-doesnt-borrow-self-1.rs:66:1
+  --> $DIR/hrtb-doesnt-borrow-self-1.rs:64:1
    |
 LL | pub trait StreamExt
    | ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs
index ff4c0cf24d6..d8a1f3fa69e 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs
@@ -1,5 +1,3 @@
-//@ normalize-stderr: "long-type-\d+" -> "long-type-hash"
-
 // rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream<Item=T`
 // should act as assertion that item does not borrow from its stream;
 // but an earlier buggy rustc allowed `.map(|x: &_| x)` which does
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.stderr
index eeb4e12fa8b..13041ea2bb0 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.stderr
@@ -1,5 +1,5 @@
-error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, fn(&u64) -> &u64 {identity::<u64>}>, {closure@hrtb-doesnt-borrow-self-2.rs:111:30}>`, but its trait bounds were not satisfied
-  --> $DIR/hrtb-doesnt-borrow-self-2.rs:112:24
+error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, fn(&u64) -> &u64 {identity::<u64>}>, {closure@hrtb-doesnt-borrow-self-2.rs:109:30}>`, but its trait bounds were not satisfied
+  --> $DIR/hrtb-doesnt-borrow-self-2.rs:110:24
    |
 LL | pub struct Filter<S, F> {
    | ----------------------- method `countx` not found for this struct because it doesn't satisfy `_: StreamExt`
@@ -8,16 +8,16 @@ LL |     let count = filter.countx();
    |                        ^^^^^^ method cannot be called due to unsatisfied trait bounds
    |
 note: the following trait bounds were not satisfied:
-      `&'a mut &Filter<Map<Repeat, for<'a> fn(&'a u64) -> &'a u64 {identity::<u64>}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream`
-      `&'a mut &mut Filter<Map<Repeat, for<'a> fn(&'a u64) -> &'a u64 {identity::<u64>}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream`
-      `&'a mut Filter<Map<Repeat, for<'a> fn(&'a u64) -> &'a u64 {identity::<u64>}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream`
-  --> $DIR/hrtb-doesnt-borrow-self-2.rs:98:50
+      `&'a mut &Filter<Map<Repeat, for<'a> fn(&'a u64) -> &'a u64 {identity::<u64>}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:109:30: 109:37}>: Stream`
+      `&'a mut &mut Filter<Map<Repeat, for<'a> fn(&'a u64) -> &'a u64 {identity::<u64>}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:109:30: 109:37}>: Stream`
+      `&'a mut Filter<Map<Repeat, for<'a> fn(&'a u64) -> &'a u64 {identity::<u64>}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:109:30: 109:37}>: Stream`
+  --> $DIR/hrtb-doesnt-borrow-self-2.rs:96:50
    |
 LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
    |         ---------     -                          ^^^^^^ unsatisfied trait bound introduced here
    = help: items from traits can only be used if the trait is implemented and in scope
 note: `StreamExt` defines an item `countx`, perhaps you need to implement it
-  --> $DIR/hrtb-doesnt-borrow-self-2.rs:66:1
+  --> $DIR/hrtb-doesnt-borrow-self-2.rs:64:1
    |
 LL | pub trait StreamExt
    | ^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr
index 31e11e12835..1c077a9b906 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-just-for-static.stderr
@@ -2,7 +2,7 @@ error: implementation of `Foo` is not general enough
   --> $DIR/hrtb-just-for-static.rs:24:5
    |
 LL |     want_hrtb::<StaticInt>()
-   |     ^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
    = note: `StaticInt` must implement `Foo<&'0 isize>`, for any lifetime `'0`...
    = note: ...but it actually implements `Foo<&'static isize>`
diff --git a/tests/ui/hygiene/generate-mod.stderr b/tests/ui/hygiene/generate-mod.stderr
index 32a2e145ca9..58b9c642dab 100644
--- a/tests/ui/hygiene/generate-mod.stderr
+++ b/tests/ui/hygiene/generate-mod.stderr
@@ -1,12 +1,18 @@
 error[E0412]: cannot find type `FromOutside` in this scope
   --> $DIR/generate-mod.rs:35:13
    |
+LL |     type A = $FromOutside;
+   |              ------------ due to this macro variable
+...
 LL |     genmod!(FromOutside, Outer);
    |             ^^^^^^^^^^^ not found in this scope
 
 error[E0412]: cannot find type `Outer` in this scope
   --> $DIR/generate-mod.rs:35:26
    |
+LL |     struct $Outer;
+   |            ------ due to this macro variable
+...
 LL |     genmod!(FromOutside, Outer);
    |                          ^^^^^ not found in this scope
 
diff --git a/tests/ui/hygiene/globs.stderr b/tests/ui/hygiene/globs.stderr
index 3f7a0ae7efa..31f25b182f1 100644
--- a/tests/ui/hygiene/globs.stderr
+++ b/tests/ui/hygiene/globs.stderr
@@ -50,6 +50,9 @@ error[E0425]: cannot find function `f` in this scope
 LL | n!(f);
    | ----- in this macro invocation
 ...
+LL |                     $j();
+   |                     -- due to this macro variable
+...
 LL |         n!(f);
    |            ^ not found in this scope
    |
@@ -63,6 +66,9 @@ error[E0425]: cannot find function `f` in this scope
 LL | n!(f);
    | ----- in this macro invocation
 ...
+LL |                     $j();
+   |                     -- due to this macro variable
+...
 LL |                 f
    |                 ^ not found in this scope
    |
diff --git a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs
index 21e2fda1c3a..b9b551c1b23 100644
--- a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs
+++ b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.rs
@@ -8,8 +8,6 @@ trait Foo {
 
 impl Foo for () {
     fn bar() -> i32 {
-        //~^ ERROR method `bar` has an incompatible type for trait
-        //~| ERROR method `bar` has an incompatible return type for trait
         0
     }
 }
diff --git a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr
index d575fedbb58..24896151bed 100644
--- a/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr
+++ b/tests/ui/impl-trait/in-trait/opaque-and-lifetime-mismatch.stderr
@@ -11,7 +11,7 @@ LL |     fn bar() -> Wrapper<'static, impl Sized>;
    |                         ++++++++
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/opaque-and-lifetime-mismatch.rs:18:24
+  --> $DIR/opaque-and-lifetime-mismatch.rs:16:24
    |
 LL |     fn foo() -> Wrapper<impl Sized>;
    |                        ^ expected named lifetime parameter
@@ -23,7 +23,7 @@ LL |     fn foo() -> Wrapper<'static, impl Sized>;
    |                         ++++++++
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/opaque-and-lifetime-mismatch.rs:24:24
+  --> $DIR/opaque-and-lifetime-mismatch.rs:22:24
    |
 LL |     fn foo() -> Wrapper<impl Sized> {
    |                        ^ expected named lifetime parameter
@@ -49,7 +49,7 @@ LL | struct Wrapper<'rom>(&'rom ());
    |        ^^^^^^^
 
 error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
-  --> $DIR/opaque-and-lifetime-mismatch.rs:18:17
+  --> $DIR/opaque-and-lifetime-mismatch.rs:16:17
    |
 LL |     fn foo() -> Wrapper<impl Sized>;
    |                 ^^^^^^^ ---------- help: remove the unnecessary generic argument
@@ -62,36 +62,8 @@ note: struct defined here, with 0 generic parameters
 LL | struct Wrapper<'rom>(&'rom ());
    |        ^^^^^^^
 
-error[E0053]: method `bar` has an incompatible return type for trait
-  --> $DIR/opaque-and-lifetime-mismatch.rs:10:17
-   |
-LL |     fn bar() -> i32 {
-   |                 ^^^
-   |                 |
-   |                 expected `Wrapper<'static>`, found `i32`
-   |                 return type in trait
-
-error[E0053]: method `bar` has an incompatible type for trait
-  --> $DIR/opaque-and-lifetime-mismatch.rs:10:17
-   |
-LL |     fn bar() -> i32 {
-   |                 ^^^ expected `Wrapper<'static>`, found `i32`
-   |
-note: type in trait
-  --> $DIR/opaque-and-lifetime-mismatch.rs:4:17
-   |
-LL |     fn bar() -> Wrapper<impl Sized>;
-   |                 ^^^^^^^^^^^^^^^^^^^
-   = note: expected signature `fn() -> Wrapper<'static>`
-              found signature `fn() -> i32`
-help: change the output type to match the trait
-   |
-LL -     fn bar() -> i32 {
-LL +     fn bar() -> Wrapper<'static> {
-   |
-
 error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
-  --> $DIR/opaque-and-lifetime-mismatch.rs:24:17
+  --> $DIR/opaque-and-lifetime-mismatch.rs:22:17
    |
 LL |     fn foo() -> Wrapper<impl Sized> {
    |                 ^^^^^^^ ---------- help: remove the unnecessary generic argument
@@ -104,7 +76,7 @@ note: struct defined here, with 0 generic parameters
 LL | struct Wrapper<'rom>(&'rom ());
    |        ^^^^^^^
 
-error: aborting due to 8 previous errors
+error: aborting due to 6 previous errors
 
-Some errors have detailed explanations: E0053, E0106, E0107.
-For more information about an error, try `rustc --explain E0053`.
+Some errors have detailed explanations: E0106, E0107.
+For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
index 4198095db65..73e7890f91f 100644
--- a/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
+++ b/tests/ui/impl-trait/opaque-used-in-extraneous-argument.stderr
@@ -75,7 +75,7 @@ error[E0061]: this function takes 0 arguments but 1 argument was supplied
   --> $DIR/opaque-used-in-extraneous-argument.rs:20:5
    |
 LL |     open_parent(&old_path)
-   |     ^^^^^^^^^^^ --------- unexpected argument of type `&impl Fn<{type error}> + FnOnce<{type error}, Output = {type error}> + 'static`
+   |     ^^^^^^^^^^^ --------- unexpected argument of type `&impl Fn<{type error}> + FnOnce<{type error}, Output = {type error}> + '_`
    |
 note: function defined here
   --> $DIR/opaque-used-in-extraneous-argument.rs:12:4
diff --git a/tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs
index 161fe23c899..8e30973cd3a 100644
--- a/tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs
+++ b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.rs
@@ -1,6 +1,5 @@
 fn no_elided_lt() -> impl Sized + use<'_> {}
 //~^ ERROR missing lifetime specifier
-//~| ERROR expected lifetime parameter in `use<...>` precise captures list, found `'_`
 
 fn static_lt() -> impl Sized + use<'static> {}
 //~^ ERROR expected lifetime parameter in `use<...>` precise captures list, found `'static`
diff --git a/tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr
index c8dac3a69cd..98f629f52cf 100644
--- a/tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr
+++ b/tests/ui/impl-trait/precise-capturing/bad-lifetimes.stderr
@@ -12,26 +12,20 @@ LL + fn no_elided_lt() -> impl Sized + use<'static> {}
    |
 
 error[E0261]: use of undeclared lifetime name `'missing`
-  --> $DIR/bad-lifetimes.rs:8:37
+  --> $DIR/bad-lifetimes.rs:7:37
    |
 LL | fn missing_lt() -> impl Sized + use<'missing> {}
    |              -                      ^^^^^^^^ undeclared lifetime
    |              |
    |              help: consider introducing lifetime `'missing` here: `<'missing>`
 
-error: expected lifetime parameter in `use<...>` precise captures list, found `'_`
-  --> $DIR/bad-lifetimes.rs:1:39
-   |
-LL | fn no_elided_lt() -> impl Sized + use<'_> {}
-   |                                       ^^
-
 error: expected lifetime parameter in `use<...>` precise captures list, found `'static`
-  --> $DIR/bad-lifetimes.rs:5:36
+  --> $DIR/bad-lifetimes.rs:4:36
    |
 LL | fn static_lt() -> impl Sized + use<'static> {}
    |                                    ^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0106, E0261.
 For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/impl-trait/unsize_tuple.rs b/tests/ui/impl-trait/unsize_tuple.rs
deleted file mode 100644
index 2678564f0e8..00000000000
--- a/tests/ui/impl-trait/unsize_tuple.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//! Test that we allow unsizing `([Opaque; N],)` to `([Concrete],)`.
-
-//@check-pass
-
-#![feature(unsized_tuple_coercion)]
-
-fn hello() -> ([impl Sized; 2],) {
-    if false {
-        let x = hello();
-        let _: &([i32],) = &x;
-    }
-    todo!()
-}
-
-fn main() {}
diff --git a/tests/ui/implied-bounds/from-trait-impl.rs b/tests/ui/implied-bounds/from-trait-impl.rs
index 6e126575aa9..5822c5474bd 100644
--- a/tests/ui/implied-bounds/from-trait-impl.rs
+++ b/tests/ui/implied-bounds/from-trait-impl.rs
@@ -12,6 +12,7 @@ where
 
 fn func1(foo: Foo<(&str,)>) {
     //~^ ERROR `&str` does not fulfill the required lifetime
+    //~| ERROR lifetime may not live long enough
     let _: &'static str = foo.0.0;
 }
 
@@ -19,5 +20,6 @@ trait TestTrait {}
 
 impl<X> TestTrait for [Foo<(X,)>; 1] {}
 //~^ ERROR `X` may not live long enough
+//~| ERROR `X` may not live long enough
 
 fn main() {}
diff --git a/tests/ui/implied-bounds/from-trait-impl.stderr b/tests/ui/implied-bounds/from-trait-impl.stderr
index 4151d206ae2..5f189d3385a 100644
--- a/tests/ui/implied-bounds/from-trait-impl.stderr
+++ b/tests/ui/implied-bounds/from-trait-impl.stderr
@@ -7,7 +7,21 @@ LL | fn func1(foo: Foo<(&str,)>) {
    = note: type must satisfy the static lifetime
 
 error[E0310]: the parameter type `X` may not live long enough
-  --> $DIR/from-trait-impl.rs:20:23
+  --> $DIR/from-trait-impl.rs:21:1
+   |
+LL | impl<X> TestTrait for [Foo<(X,)>; 1] {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | |
+   | the parameter type `X` must be valid for the static lifetime...
+   | ...so that the type `X` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound
+   |
+LL | impl<X: 'static> TestTrait for [Foo<(X,)>; 1] {}
+   |       +++++++++
+
+error[E0310]: the parameter type `X` may not live long enough
+  --> $DIR/from-trait-impl.rs:21:23
    |
 LL | impl<X> TestTrait for [Foo<(X,)>; 1] {}
    |                       ^^^^^^^^^^^^^^
@@ -20,7 +34,16 @@ help: consider adding an explicit lifetime bound
 LL | impl<X: 'static> TestTrait for [Foo<(X,)>; 1] {}
    |       +++++++++
 
-error: aborting due to 2 previous errors
+error: lifetime may not live long enough
+  --> $DIR/from-trait-impl.rs:13:1
+   |
+LL | fn func1(foo: Foo<(&str,)>) {
+   | ^^^^^^^^^^^^^^^^^^^-^^^^^^^
+   | |                  |
+   | |                  let's call the lifetime of this reference `'1`
+   | requires that `'1` must outlive `'static`
+
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0310, E0477.
 For more information about an error, try `rustc --explain E0310`.
diff --git a/tests/ui/implied-bounds/normalization-nested.lifetime.stderr b/tests/ui/implied-bounds/normalization-nested.lifetime.stderr
deleted file mode 100644
index c43cc0999f1..00000000000
--- a/tests/ui/implied-bounds/normalization-nested.lifetime.stderr
+++ /dev/null
@@ -1,10 +0,0 @@
-error: lifetime may not live long enough
-  --> $DIR/normalization-nested.rs:40:5
-   |
-LL | pub fn test_borrowck<'x>(_: Map<Vec<&'x ()>>, s: &'x str) -> &'static str {
-   |                      -- lifetime `'x` defined here
-LL |     s
-   |     ^ returning this value requires that `'x` must outlive `'static`
-
-error: aborting due to 1 previous error
-
diff --git a/tests/ui/implied-bounds/normalization-nested.rs b/tests/ui/implied-bounds/normalization-nested.rs
index 4527e33a291..9a0defd1667 100644
--- a/tests/ui/implied-bounds/normalization-nested.rs
+++ b/tests/ui/implied-bounds/normalization-nested.rs
@@ -3,9 +3,7 @@
 //
 //@ revisions: param_ty lifetime param_ty_no_compat lifetime_no_compat
 
-//@[param_ty] check-pass
-//@[param_ty_no_compat] check-pass
-//@[lifetime_no_compat] check-pass
+//@ check-pass
 //@[param_ty_no_compat] compile-flags: -Zno-implied-bounds-compat
 //@[lifetime_no_compat] compile-flags: -Zno-implied-bounds-compat
 
@@ -38,7 +36,6 @@ pub fn test_wfcheck<'x>(_: Map<Vec<&'x ()>>) {}
 
 pub fn test_borrowck<'x>(_: Map<Vec<&'x ()>>, s: &'x str) -> &'static str {
     s
-    //[lifetime]~^ ERROR lifetime may not live long enough
 }
 
 fn main() {}
diff --git a/tests/ui/implied-bounds/normalization-placeholder-leak.fail.stderr b/tests/ui/implied-bounds/normalization-placeholder-leak.fail.stderr
index a591d0f5d4d..8919919d04e 100644
--- a/tests/ui/implied-bounds/normalization-placeholder-leak.fail.stderr
+++ b/tests/ui/implied-bounds/normalization-placeholder-leak.fail.stderr
@@ -1,15 +1,45 @@
 error[E0477]: the type `&'lt u8` does not fulfill the required lifetime
+  --> $DIR/normalization-placeholder-leak.rs:31:5
+   |
+LL |     fn test_lifetime<'lt, T: Trait>(_: Foo<&'lt u8>) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0477]: the type `&'lt u8` does not fulfill the required lifetime
   --> $DIR/normalization-placeholder-leak.rs:31:40
    |
 LL |     fn test_lifetime<'lt, T: Trait>(_: Foo<&'lt u8>) {}
    |                                        ^^^^^^^^^^^^
 
 error[E0477]: the type `<T as AnotherTrait>::Ty2<'lt>` does not fulfill the required lifetime
-  --> $DIR/normalization-placeholder-leak.rs:36:44
+  --> $DIR/normalization-placeholder-leak.rs:38:5
+   |
+LL |     fn test_alias<'lt, T: AnotherTrait>(_: Foo<T::Ty2::<'lt>>) {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0477]: the type `<T as AnotherTrait>::Ty2<'lt>` does not fulfill the required lifetime
+  --> $DIR/normalization-placeholder-leak.rs:38:44
    |
 LL |     fn test_alias<'lt, T: AnotherTrait>(_: Foo<T::Ty2::<'lt>>) {}
    |                                            ^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: lifetime may not live long enough
+  --> $DIR/normalization-placeholder-leak.rs:31:5
+   |
+LL |     fn test_lifetime<'lt, T: Trait>(_: Foo<&'lt u8>) {}
+   |     ^^^^^^^^^^^^^^^^^---^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |                |
+   |     |                lifetime `'lt` defined here
+   |     requires that `'lt` must outlive `'static`
+
+error: lifetime may not live long enough
+  --> $DIR/normalization-placeholder-leak.rs:38:5
+   |
+LL |     fn test_alias<'lt, T: AnotherTrait>(_: Foo<T::Ty2::<'lt>>) {}
+   |     ^^^^^^^^^^^^^^---^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     |             |
+   |     |             lifetime `'lt` defined here
+   |     requires that `'lt` must outlive `'static`
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0477`.
diff --git a/tests/ui/implied-bounds/normalization-placeholder-leak.rs b/tests/ui/implied-bounds/normalization-placeholder-leak.rs
index a9dfa69cfd6..3a15897db82 100644
--- a/tests/ui/implied-bounds/normalization-placeholder-leak.rs
+++ b/tests/ui/implied-bounds/normalization-placeholder-leak.rs
@@ -30,11 +30,15 @@ mod fail {
     // don't use the bound to prove `'lt: 'static`.
     fn test_lifetime<'lt, T: Trait>(_: Foo<&'lt u8>) {}
     //[fail]~^ ERROR `&'lt u8` does not fulfill the required lifetime
+    //[fail]~| ERROR `&'lt u8` does not fulfill the required lifetime
+    //[fail]~| ERROR may not live long enough
 
     // implied bound: `T::Ty2<'lt>: placeholder('x)`.
     // don't use the bound to prove `T::Ty2<'lt>: 'static`.
     fn test_alias<'lt, T: AnotherTrait>(_: Foo<T::Ty2::<'lt>>) {}
     //[fail]~^ ERROR `<T as AnotherTrait>::Ty2<'lt>` does not fulfill the required lifetime
+    //[fail]~| ERROR `<T as AnotherTrait>::Ty2<'lt>` does not fulfill the required lifetime
+    //[fail]~| ERROR may not live long enough
 }
 
 
diff --git a/tests/ui/implied-bounds/sod_service_chain.rs b/tests/ui/implied-bounds/sod_service_chain.rs
index 7443a29f30c..032483e1be4 100644
--- a/tests/ui/implied-bounds/sod_service_chain.rs
+++ b/tests/ui/implied-bounds/sod_service_chain.rs
@@ -27,11 +27,19 @@ pub struct ServiceChainBuilder<P: Service, S: Service<Input = P::Output>> {
 }
 impl<P: Service, S: Service<Input = P::Output>> ServiceChainBuilder<P, S> {
     pub fn next<NS: Service<Input = S::Output>>(
+        //~^ the associated type
+        //~| the associated type
+        //~| the associated type
+        //~| the associated type
+        //~| the associated type
+        //~| the associated type
+        //~| may not live long enough
         self,
     ) -> ServiceChainBuilder<ServiceChain<P, S>, NS> {
         //~^ the associated type
         //~| the associated type
         //~| the associated type
+        //~| the associated type
         panic!();
     }
 }
diff --git a/tests/ui/implied-bounds/sod_service_chain.stderr b/tests/ui/implied-bounds/sod_service_chain.stderr
index 1c0ef573e7d..f5221fc1105 100644
--- a/tests/ui/implied-bounds/sod_service_chain.stderr
+++ b/tests/ui/implied-bounds/sod_service_chain.stderr
@@ -1,5 +1,39 @@
 error[E0310]: the associated type `<P as Service>::Error` may not live long enough
-  --> $DIR/sod_service_chain.rs:31:10
+  --> $DIR/sod_service_chain.rs:29:5
+   |
+LL | /     pub fn next<NS: Service<Input = S::Output>>(
+...  |
+LL | |         self,
+LL | |     ) -> ServiceChainBuilder<ServiceChain<P, S>, NS> {
+   | |                                                    ^
+   | |                                                    |
+   | |____________________________________________________the associated type `<P as Service>::Error` must be valid for the static lifetime...
+   |                                                      ...so that the type `<P as Service>::Error` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound
+   |
+LL |     ) -> ServiceChainBuilder<ServiceChain<P, S>, NS> where <P as Service>::Error: 'static {
+   |                                                      ++++++++++++++++++++++++++++++++++++
+
+error[E0310]: the associated type `<S as Service>::Error` may not live long enough
+  --> $DIR/sod_service_chain.rs:29:5
+   |
+LL | /     pub fn next<NS: Service<Input = S::Output>>(
+...  |
+LL | |         self,
+LL | |     ) -> ServiceChainBuilder<ServiceChain<P, S>, NS> {
+   | |                                                    ^
+   | |                                                    |
+   | |____________________________________________________the associated type `<S as Service>::Error` must be valid for the static lifetime...
+   |                                                      ...so that the type `<S as Service>::Error` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound
+   |
+LL |     ) -> ServiceChainBuilder<ServiceChain<P, S>, NS> where <S as Service>::Error: 'static {
+   |                                                      ++++++++++++++++++++++++++++++++++++
+
+error[E0310]: the associated type `<P as Service>::Error` may not live long enough
+  --> $DIR/sod_service_chain.rs:38:10
    |
 LL |     ) -> ServiceChainBuilder<ServiceChain<P, S>, NS> {
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -13,7 +47,7 @@ LL |     ) -> ServiceChainBuilder<ServiceChain<P, S>, NS> where <P as Service>::
    |                                                      ++++++++++++++++++++++++++++++++++++
 
 error[E0310]: the associated type `<S as Service>::Error` may not live long enough
-  --> $DIR/sod_service_chain.rs:31:10
+  --> $DIR/sod_service_chain.rs:38:10
    |
 LL |     ) -> ServiceChainBuilder<ServiceChain<P, S>, NS> {
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -26,6 +60,42 @@ help: consider adding an explicit lifetime bound
 LL |     ) -> ServiceChainBuilder<ServiceChain<P, S>, NS> where <S as Service>::Error: 'static {
    |                                                      ++++++++++++++++++++++++++++++++++++
 
-error: aborting due to 2 previous errors
+error[E0310]: the associated type `<P as Service>::Error` may not live long enough
+  --> $DIR/sod_service_chain.rs:29:5
+   |
+LL | /     pub fn next<NS: Service<Input = S::Output>>(
+...  |
+LL | |         self,
+LL | |     ) -> ServiceChainBuilder<ServiceChain<P, S>, NS> {
+   | |                                                    ^
+   | |                                                    |
+   | |____________________________________________________the associated type `<P as Service>::Error` must be valid for the static lifetime...
+   |                                                      ...so that the type `<P as Service>::Error` will meet its required lifetime bounds
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: consider adding an explicit lifetime bound
+   |
+LL |     ) -> ServiceChainBuilder<ServiceChain<P, S>, NS> where <P as Service>::Error: 'static {
+   |                                                      ++++++++++++++++++++++++++++++++++++
+
+error[E0310]: the associated type `<S as Service>::Error` may not live long enough
+  --> $DIR/sod_service_chain.rs:29:5
+   |
+LL | /     pub fn next<NS: Service<Input = S::Output>>(
+...  |
+LL | |         self,
+LL | |     ) -> ServiceChainBuilder<ServiceChain<P, S>, NS> {
+   | |                                                    ^
+   | |                                                    |
+   | |____________________________________________________the associated type `<S as Service>::Error` must be valid for the static lifetime...
+   |                                                      ...so that the type `<S as Service>::Error` will meet its required lifetime bounds
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: consider adding an explicit lifetime bound
+   |
+LL |     ) -> ServiceChainBuilder<ServiceChain<P, S>, NS> where <S as Service>::Error: 'static {
+   |                                                      ++++++++++++++++++++++++++++++++++++
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0310`.
diff --git a/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr b/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr
index 1fea73529a8..c61ca699b0d 100644
--- a/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr
+++ b/tests/ui/inference/issue-86094-suggest-add-return-to-coerce-ret-ty.stderr
@@ -8,10 +8,6 @@ help: consider specifying the generic arguments
    |
 LL |         Err::<T, MyError>(MyError);
    |            ++++++++++++++
-help: you might have meant to return this to infer its type parameters
-   |
-LL |         return Err(MyError);
-   |         ++++++
 
 error[E0282]: type annotations needed
   --> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:14:9
@@ -23,10 +19,6 @@ help: consider specifying the generic arguments
    |
 LL |         Ok::<(), E>(());
    |           +++++++++
-help: you might have meant to return this to infer its type parameters
-   |
-LL |         return Ok(());
-   |         ++++++
 
 error[E0308]: mismatched types
   --> $DIR/issue-86094-suggest-add-return-to-coerce-ret-ty.rs:21:20
diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs
index 62fc079d9d9..e28b8f373da 100644
--- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs
+++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.rs
@@ -3,9 +3,6 @@
 //@ error-pattern: reached the recursion limit while instantiating
 //@ error-pattern: reached the recursion limit finding the struct tail
 
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'"
-
 // Regression test for #114484: This used to ICE during monomorphization, because we treated
 // `<VirtualWrapper<...> as Pointee>::Metadata` as a rigid projection after reaching the recursion
 // limit when finding the struct tail.
diff --git a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr
index b67e000bf74..475e26fd0f0 100644
--- a/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr
+++ b/tests/ui/infinite/infinite-instantiation-struct-tail-ice-114484.stderr
@@ -18,7 +18,7 @@ error: reached the recursion limit finding the struct tail for `[u8; 256]`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>`
-  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:29:18
+  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18
    |
 LL |         unsafe { virtualize_my_trait(L, self) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -43,7 +43,7 @@ error: reached the recursion limit finding the struct tail for `SomeData<256>`
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>`
-  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:29:18
+  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18
    |
 LL |         unsafe { virtualize_my_trait(L, self) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -68,7 +68,7 @@ error: reached the recursion limit finding the struct tail for `VirtualWrapper<S
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 note: the above error was encountered while instantiating `fn virtualize_my_trait::<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<SomeData<256>, 0>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>, 1>>`
-  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:29:18
+  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:26:18
    |
 LL |         unsafe { virtualize_my_trait(L, self) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -76,11 +76,11 @@ LL |         unsafe { virtualize_my_trait(L, self) }
 error: reached the recursion limit while instantiating `<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<VirtualWrapper<..., 1>, 1>, 1>, 1>, 1> as MyTrait>::virtualize`
    |
 note: `<VirtualWrapper<T, L> as MyTrait>::virtualize` defined here
-  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:28:5
+  --> $DIR/infinite-instantiation-struct-tail-ice-114484.rs:25:5
    |
 LL |     fn virtualize(&self) -> &dyn MyTrait {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/infinite-instantiation-struct-tail-ice-114484.long-type.txt'
 
 error: aborting due to 13 previous errors
 
diff --git a/tests/ui/infinite/infinite-instantiation.rs b/tests/ui/infinite/infinite-instantiation.rs
index d5cb8e79592..7898cc1ffc1 100644
--- a/tests/ui/infinite/infinite-instantiation.rs
+++ b/tests/ui/infinite/infinite-instantiation.rs
@@ -1,6 +1,4 @@
 //@ build-fail
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'"
 
 trait ToOpt: Sized {
     fn to_option(&self) -> Option<Self>;
diff --git a/tests/ui/infinite/infinite-instantiation.stderr b/tests/ui/infinite/infinite-instantiation.stderr
index 71c745cf5eb..d7a4a49961a 100644
--- a/tests/ui/infinite/infinite-instantiation.stderr
+++ b/tests/ui/infinite/infinite-instantiation.stderr
@@ -1,15 +1,15 @@
 error: reached the recursion limit while instantiating `function::<Option<Option<Option<Option<Option<...>>>>>>`
-  --> $DIR/infinite-instantiation.rs:23:9
+  --> $DIR/infinite-instantiation.rs:21:9
    |
 LL |         function(counter - 1, t.to_option());
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `function` defined here
-  --> $DIR/infinite-instantiation.rs:21:1
+  --> $DIR/infinite-instantiation.rs:19:1
    |
 LL | fn function<T:ToOpt + Clone>(counter: usize, t: T) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/infinite-instantiation.long-type.txt'
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/invalid-compile-flags/print-without-arg.stderr b/tests/ui/invalid-compile-flags/print-without-arg.stderr
index a18d2779cad..05d42247d41 100644
--- a/tests/ui/invalid-compile-flags/print-without-arg.stderr
+++ b/tests/ui/invalid-compile-flags/print-without-arg.stderr
@@ -1,5 +1,5 @@
 error: Argument to option 'print' missing
        Usage:
-           --print [crate-name|file-names|sysroot|target-libdir|cfg|check-cfg|calling-conventions|target-list|target-cpus|target-features|relocation-models|code-models|tls-models|target-spec-json|all-target-specs-json|native-static-libs|stack-protector-strategies|link-args|deployment-target]
+           --print [all-target-specs-json|calling-conventions|cfg|check-cfg|code-models|crate-name|deployment-target|file-names|host-tuple|link-args|native-static-libs|relocation-models|split-debuginfo|stack-protector-strategies|sysroot|target-cpus|target-features|target-libdir|target-list|target-spec-json|tls-models]
                                Compiler information to print on stdout
 
diff --git a/tests/ui/issues/issue-106755.rs b/tests/ui/issues/issue-106755.rs
index 689b1d885ae..d7e7122ebda 100644
--- a/tests/ui/issues/issue-106755.rs
+++ b/tests/ui/issues/issue-106755.rs
@@ -10,10 +10,13 @@ struct TestType<T>(::std::marker::PhantomData<T>);
 
 unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
 
-impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR found both positive and negative implementation
+impl<T: MyTrait> !Send for TestType<T> {}
+//~^ ERROR found both positive and negative implementation
+//~| ERROR `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
 
 unsafe impl<T: 'static> Send for TestType<T> {} //~ ERROR conflicting implementations
 
 impl !Send for TestType<i32> {}
+//~^ ERROR `!Send` impls cannot be specialized
 
 fn main() {}
diff --git a/tests/ui/issues/issue-106755.stderr b/tests/ui/issues/issue-106755.stderr
index 54397034062..da6b8c5c563 100644
--- a/tests/ui/issues/issue-106755.stderr
+++ b/tests/ui/issues/issue-106755.stderr
@@ -8,7 +8,7 @@ LL | impl<T: MyTrait> !Send for TestType<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
 
 error[E0119]: conflicting implementations of trait `Send` for type `TestType<_>`
-  --> $DIR/issue-106755.rs:15:1
+  --> $DIR/issue-106755.rs:17:1
    |
 LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
    | ------------------------------------------------------ first implementation here
@@ -16,7 +16,32 @@ LL | unsafe impl<T: MyTrait + 'static> Send for TestType<T> {}
 LL | unsafe impl<T: 'static> Send for TestType<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `TestType<_>`
 
-error: aborting due to 2 previous errors
+error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
+  --> $DIR/issue-106755.rs:13:9
+   |
+LL | impl<T: MyTrait> !Send for TestType<T> {}
+   |         ^^^^^^^
+   |
+note: the implementor must specify the same requirement
+  --> $DIR/issue-106755.rs:9:1
+   |
+LL | struct TestType<T>(::std::marker::PhantomData<T>);
+   | ^^^^^^^^^^^^^^^^^^
+
+error[E0366]: `!Send` impls cannot be specialized
+  --> $DIR/issue-106755.rs:19:1
+   |
+LL | impl !Send for TestType<i32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `i32` is not a generic parameter
+note: use the same sequence of generic lifetime, type and const parameters as the struct definition
+  --> $DIR/issue-106755.rs:9:1
+   |
+LL | struct TestType<T>(::std::marker::PhantomData<T>);
+   | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0119, E0751.
+Some errors have detailed explanations: E0119, E0366, E0367, E0751.
 For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/issues/issue-13497.rs b/tests/ui/issues/issue-13497.rs
index 7f786a54b9f..4b2795aa841 100644
--- a/tests/ui/issues/issue-13497.rs
+++ b/tests/ui/issues/issue-13497.rs
@@ -3,7 +3,6 @@ fn read_lines_borrowed1() -> Vec<
 > {
     let rawLines: Vec<String> = vec!["foo  ".to_string(), "  bar".to_string()];
     rawLines.iter().map(|l| l.trim()).collect()
-    //~^ ERROR: cannot return value referencing
 }
 
 fn main() {}
diff --git a/tests/ui/issues/issue-13497.stderr b/tests/ui/issues/issue-13497.stderr
index 8016b55d6aa..ee111f1d262 100644
--- a/tests/ui/issues/issue-13497.stderr
+++ b/tests/ui/issues/issue-13497.stderr
@@ -15,16 +15,6 @@ LL -     &str
 LL +     String
    |
 
-error[E0515]: cannot return value referencing local variable `rawLines`
-  --> $DIR/issue-13497.rs:5:5
-   |
-LL |     rawLines.iter().map(|l| l.trim()).collect()
-   |     --------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |     |
-   |     returns a value referencing data owned by the current function
-   |     `rawLines` is borrowed here
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0106, E0515.
-For more information about an error, try `rustc --explain E0106`.
+For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/issues/issue-20413.rs b/tests/ui/issues/issue-20413.rs
index 7766f375599..138a235e675 100644
--- a/tests/ui/issues/issue-20413.rs
+++ b/tests/ui/issues/issue-20413.rs
@@ -1,4 +1,3 @@
-//@ normalize-stderr: "long-type-\d+" -> "long-type-hash"
 trait Foo {
     fn answer(self);
 }
diff --git a/tests/ui/issues/issue-20413.stderr b/tests/ui/issues/issue-20413.stderr
index 5d442eb9898..42f3cd2d062 100644
--- a/tests/ui/issues/issue-20413.stderr
+++ b/tests/ui/issues/issue-20413.stderr
@@ -1,5 +1,5 @@
 error[E0392]: type parameter `T` is never used
-  --> $DIR/issue-20413.rs:6:15
+  --> $DIR/issue-20413.rs:5:15
    |
 LL | struct NoData<T>;
    |               ^ unused type parameter
@@ -8,14 +8,14 @@ LL | struct NoData<T>;
    = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
 
 error[E0275]: overflow evaluating the requirement `NoData<NoData<NoData<NoData<NoData<NoData<NoData<...>>>>>>>: Foo`
-  --> $DIR/issue-20413.rs:9:36
+  --> $DIR/issue-20413.rs:8:36
    |
 LL | impl<T> Foo for T where NoData<T>: Foo {
    |                                    ^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
 note: required for `NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<NoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Foo`
-  --> $DIR/issue-20413.rs:9:9
+  --> $DIR/issue-20413.rs:8:9
    |
 LL | impl<T> Foo for T where NoData<T>: Foo {
    |         ^^^     ^                  --- unsatisfied trait bound introduced here
@@ -23,19 +23,19 @@ LL | impl<T> Foo for T where NoData<T>: Foo {
    = note: required for `NoData<T>` to implement `Foo`
 
 error[E0275]: overflow evaluating the requirement `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<...>>>>>>>: Bar`
-  --> $DIR/issue-20413.rs:28:42
+  --> $DIR/issue-20413.rs:27:42
    |
 LL | impl<T> Bar for T where EvenLessData<T>: Baz {
    |                                          ^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
 note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz`
-  --> $DIR/issue-20413.rs:35:9
+  --> $DIR/issue-20413.rs:34:9
    |
 LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
    |         ^^^     ^                        --- unsatisfied trait bound introduced here
 note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar`
-  --> $DIR/issue-20413.rs:28:9
+  --> $DIR/issue-20413.rs:27:9
    |
 LL | impl<T> Bar for T where EvenLessData<T>: Baz {
    |         ^^^     ^                        --- unsatisfied trait bound introduced here
@@ -43,19 +43,19 @@ LL | impl<T> Bar for T where EvenLessData<T>: Baz {
    = note: required for `EvenLessData<T>` to implement `Baz`
 
 error[E0275]: overflow evaluating the requirement `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<...>>>>>>>: Baz`
-  --> $DIR/issue-20413.rs:35:42
+  --> $DIR/issue-20413.rs:34:42
    |
 LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
    |                                          ^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_20413`)
 note: required for `AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Bar`
-  --> $DIR/issue-20413.rs:28:9
+  --> $DIR/issue-20413.rs:27:9
    |
 LL | impl<T> Bar for T where EvenLessData<T>: Baz {
    |         ^^^     ^                        --- unsatisfied trait bound introduced here
 note: required for `EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<EvenLessData<AlmostNoData<T>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `Baz`
-  --> $DIR/issue-20413.rs:35:9
+  --> $DIR/issue-20413.rs:34:9
    |
 LL | impl<T> Baz for T where AlmostNoData<T>: Bar {
    |         ^^^     ^                        --- unsatisfied trait bound introduced here
diff --git a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs
index ebaf244ac9c..05adde45204 100644
--- a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs
+++ b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.rs
@@ -1,6 +1,4 @@
 //@ build-fail
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'"
 
 trait Mirror {
     type Image;
diff --git a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr
index fbbf80021be..945fa605e14 100644
--- a/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr
+++ b/tests/ui/issues/issue-37311-type-length-limit/issue-37311.stderr
@@ -1,15 +1,15 @@
 error: reached the recursion limit while instantiating `<(&(&(..., ...), ...), ...) as Foo>::recurse`
-  --> $DIR/issue-37311.rs:18:9
+  --> $DIR/issue-37311.rs:16:9
    |
 LL |         (self, self).recurse();
    |         ^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `<T as Foo>::recurse` defined here
-  --> $DIR/issue-37311.rs:17:5
+  --> $DIR/issue-37311.rs:15:5
    |
 LL |     fn recurse(&self) {
    |     ^^^^^^^^^^^^^^^^^
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/issue-37311.long-type.txt'
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-54410.stderr b/tests/ui/issues/issue-54410.stderr
index 97e5990750e..2cd5a2a49ef 100644
--- a/tests/ui/issues/issue-54410.stderr
+++ b/tests/ui/issues/issue-54410.stderr
@@ -5,6 +5,7 @@ LL |     pub static mut symbol: [i8];
    |                            ^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `[i8]`
+   = note: statics and constants must have a statically known size
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-67552.rs b/tests/ui/issues/issue-67552.rs
index 8c7e95bd2e3..53f0e931d60 100644
--- a/tests/ui/issues/issue-67552.rs
+++ b/tests/ui/issues/issue-67552.rs
@@ -1,7 +1,5 @@
 //@ build-fail
 //@ compile-flags: -Copt-level=0
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'"
 
 fn main() {
     rec(Empty);
diff --git a/tests/ui/issues/issue-67552.stderr b/tests/ui/issues/issue-67552.stderr
index f94cd78c870..def0a29f3e5 100644
--- a/tests/ui/issues/issue-67552.stderr
+++ b/tests/ui/issues/issue-67552.stderr
@@ -1,17 +1,17 @@
 error: reached the recursion limit while instantiating `rec::<&mut &mut &mut &mut &mut ...>`
-  --> $DIR/issue-67552.rs:30:9
+  --> $DIR/issue-67552.rs:28:9
    |
 LL |         rec(identity(&mut it))
    |         ^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `rec` defined here
-  --> $DIR/issue-67552.rs:23:1
+  --> $DIR/issue-67552.rs:21:1
    |
 LL | / fn rec<T>(mut it: T)
 LL | | where
 LL | |     T: Iterator,
    | |________________^
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/issue-67552.long-type.txt'
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/issues/issue-8727.rs b/tests/ui/issues/issue-8727.rs
index 7767729109e..1883287f140 100644
--- a/tests/ui/issues/issue-8727.rs
+++ b/tests/ui/issues/issue-8727.rs
@@ -2,8 +2,6 @@
 // recursions.
 
 //@ build-fail
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'"
 
 fn generic<T>() { //~ WARN function cannot return without recursing
     generic::<Option<T>>();
diff --git a/tests/ui/issues/issue-8727.stderr b/tests/ui/issues/issue-8727.stderr
index 22286eb8d7b..04158962a01 100644
--- a/tests/ui/issues/issue-8727.stderr
+++ b/tests/ui/issues/issue-8727.stderr
@@ -1,5 +1,5 @@
 warning: function cannot return without recursing
-  --> $DIR/issue-8727.rs:8:1
+  --> $DIR/issue-8727.rs:6:1
    |
 LL | fn generic<T>() {
    | ^^^^^^^^^^^^^^^ cannot return without recursing
@@ -10,17 +10,17 @@ LL |     generic::<Option<T>>();
    = note: `#[warn(unconditional_recursion)]` on by default
 
 error: reached the recursion limit while instantiating `generic::<Option<Option<Option<Option<Option<...>>>>>>`
-  --> $DIR/issue-8727.rs:9:5
+  --> $DIR/issue-8727.rs:7:5
    |
 LL |     generic::<Option<T>>();
    |     ^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `generic` defined here
-  --> $DIR/issue-8727.rs:8:1
+  --> $DIR/issue-8727.rs:6:1
    |
 LL | fn generic<T>() {
    | ^^^^^^^^^^^^^^^
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/issue-8727.long-type.txt'
 
 error: aborting due to 1 previous error; 1 warning emitted
 
diff --git a/tests/ui/json/json-multiple.stderr b/tests/ui/json/json-multiple.stderr
index 7689fb94a6c..e285817cffb 100644
--- a/tests/ui/json/json-multiple.stderr
+++ b/tests/ui/json/json-multiple.stderr
@@ -1 +1 @@
-{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/json/json-multiple/libjson_multiple.rlib","emit":"link"}
+{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/libjson_multiple.rlib","emit":"link"}
diff --git a/tests/ui/json/json-options.stderr b/tests/ui/json/json-options.stderr
index 668fc18097f..fff4ec9a6df 100644
--- a/tests/ui/json/json-options.stderr
+++ b/tests/ui/json/json-options.stderr
@@ -1 +1 @@
-{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/json/json-options/libjson_options.rlib","emit":"link"}
+{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/libjson_options.rlib","emit":"link"}
diff --git a/tests/ui/layout/debug.stderr b/tests/ui/layout/debug.stderr
index 07cad776692..80b35ff6ad4 100644
--- a/tests/ui/layout/debug.stderr
+++ b/tests/ui/layout/debug.stderr
@@ -10,7 +10,7 @@ error: layout_of(E) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Arbitrary {
@@ -49,7 +49,7 @@ error: layout_of(E) = Layout {
                            abi: Align(1 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -71,7 +71,7 @@ error: layout_of(E) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -112,7 +112,7 @@ error: layout_of(S) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: ScalarPair(
+           backend_repr: ScalarPair(
                Initialized {
                    value: Int(
                        I32,
@@ -160,7 +160,7 @@ error: layout_of(U) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Union(
@@ -186,7 +186,7 @@ error: layout_of(Result<i32, i32>) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: ScalarPair(
+           backend_repr: ScalarPair(
                Initialized {
                    value: Int(
                        I32,
@@ -238,7 +238,7 @@ error: layout_of(Result<i32, i32>) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I32,
@@ -277,7 +277,7 @@ error: layout_of(Result<i32, i32>) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I32,
@@ -327,7 +327,7 @@ error: layout_of(i32) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I32,
@@ -357,7 +357,7 @@ error: layout_of(V) = Layout {
                abi: Align(2 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Union(
@@ -383,7 +383,7 @@ error: layout_of(W) = Layout {
                abi: Align(2 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Union(
@@ -409,7 +409,7 @@ error: layout_of(Y) = Layout {
                abi: Align(2 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Union(
@@ -435,7 +435,7 @@ error: layout_of(P1) = Layout {
                abi: Align(1 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Union(
@@ -461,7 +461,7 @@ error: layout_of(P2) = Layout {
                abi: Align(1 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Union(
@@ -487,7 +487,7 @@ error: layout_of(P3) = Layout {
                abi: Align(1 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Union(
@@ -513,7 +513,7 @@ error: layout_of(P4) = Layout {
                abi: Align(1 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Union(
@@ -539,7 +539,7 @@ error: layout_of(P5) = Layout {
                abi: Align(1 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Union {
                    value: Int(
                        I8,
@@ -570,7 +570,7 @@ error: layout_of(MaybeUninit<u8>) = Layout {
                abi: Align(1 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Union {
                    value: Int(
                        I8,
diff --git a/tests/ui/layout/hexagon-enum.stderr b/tests/ui/layout/hexagon-enum.stderr
index b802b400b18..9c3a8662d4f 100644
--- a/tests/ui/layout/hexagon-enum.stderr
+++ b/tests/ui/layout/hexagon-enum.stderr
@@ -4,7 +4,7 @@ error: layout_of(A) = Layout {
                abi: Align(1 bytes),
                pref: Align(1 bytes),
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I8,
@@ -49,7 +49,7 @@ error: layout_of(A) = Layout {
                            abi: Align(1 bytes),
                            pref: Align(1 bytes),
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -82,7 +82,7 @@ error: layout_of(B) = Layout {
                abi: Align(1 bytes),
                pref: Align(1 bytes),
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I8,
@@ -127,7 +127,7 @@ error: layout_of(B) = Layout {
                            abi: Align(1 bytes),
                            pref: Align(1 bytes),
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -160,7 +160,7 @@ error: layout_of(C) = Layout {
                abi: Align(2 bytes),
                pref: Align(2 bytes),
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I16,
@@ -205,7 +205,7 @@ error: layout_of(C) = Layout {
                            abi: Align(2 bytes),
                            pref: Align(2 bytes),
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -238,7 +238,7 @@ error: layout_of(P) = Layout {
                abi: Align(4 bytes),
                pref: Align(4 bytes),
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I32,
@@ -283,7 +283,7 @@ error: layout_of(P) = Layout {
                            abi: Align(4 bytes),
                            pref: Align(4 bytes),
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -316,7 +316,7 @@ error: layout_of(T) = Layout {
                abi: Align(4 bytes),
                pref: Align(4 bytes),
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I32,
@@ -361,7 +361,7 @@ error: layout_of(T) = Layout {
                            abi: Align(4 bytes),
                            pref: Align(4 bytes),
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/layout/issue-84108.stderr b/tests/ui/layout/issue-84108.stderr
index 8ddce285e23..e296abfc3b5 100644
--- a/tests/ui/layout/issue-84108.stderr
+++ b/tests/ui/layout/issue-84108.stderr
@@ -30,6 +30,15 @@ LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42);
    = note: only the last element of a tuple may have a dynamically sized type
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/issue-84108.rs:15:13
+   |
+LL | static BAZ: ([u8], usize) = ([], 0);
+   |             ^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+   = note: only the last element of a tuple may have a dynamically sized type
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
   --> $DIR/issue-84108.rs:9:12
    |
 LL | const BAR: (&Path, [u8], usize) = ("hello", [], 42);
@@ -56,15 +65,6 @@ LL | static BAZ: ([u8], usize) = ([], 0);
    |
    = help: the trait `Sized` is not implemented for `[u8]`
    = note: only the last element of a tuple may have a dynamically sized type
-
-error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/issue-84108.rs:15:13
-   |
-LL | static BAZ: ([u8], usize) = ([], 0);
-   |             ^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `[u8]`
-   = note: only the last element of a tuple may have a dynamically sized type
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
 error[E0308]: mismatched types
diff --git a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
index 3bdb9c5c143..ef7f0cd2d1c 100644
--- a/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
+++ b/tests/ui/layout/issue-96158-scalarpair-payload-might-be-uninit.stderr
@@ -4,7 +4,7 @@ error: layout_of(MissingPayloadField) = Layout {
                abi: Align(1 bytes),
                pref: $PREF_ALIGN,
            },
-           abi: ScalarPair(
+           backend_repr: ScalarPair(
                Initialized {
                    value: Int(
                        I8,
@@ -55,7 +55,7 @@ error: layout_of(MissingPayloadField) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I8,
@@ -93,7 +93,7 @@ error: layout_of(MissingPayloadField) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -126,7 +126,7 @@ error: layout_of(CommonPayloadField) = Layout {
                abi: Align(1 bytes),
                pref: $PREF_ALIGN,
            },
-           abi: ScalarPair(
+           backend_repr: ScalarPair(
                Initialized {
                    value: Int(
                        I8,
@@ -178,7 +178,7 @@ error: layout_of(CommonPayloadField) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I8,
@@ -217,7 +217,7 @@ error: layout_of(CommonPayloadField) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I8,
@@ -267,7 +267,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout {
                abi: Align(1 bytes),
                pref: $PREF_ALIGN,
            },
-           abi: ScalarPair(
+           backend_repr: ScalarPair(
                Initialized {
                    value: Int(
                        I8,
@@ -318,7 +318,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I8,
@@ -356,7 +356,7 @@ error: layout_of(CommonPayloadFieldIsMaybeUninit) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I8,
@@ -405,7 +405,7 @@ error: layout_of(NicheFirst) = Layout {
                abi: Align(1 bytes),
                pref: $PREF_ALIGN,
            },
-           abi: ScalarPair(
+           backend_repr: ScalarPair(
                Initialized {
                    value: Int(
                        I8,
@@ -460,7 +460,7 @@ error: layout_of(NicheFirst) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I8,
@@ -510,7 +510,7 @@ error: layout_of(NicheFirst) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -532,7 +532,7 @@ error: layout_of(NicheFirst) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -565,7 +565,7 @@ error: layout_of(NicheSecond) = Layout {
                abi: Align(1 bytes),
                pref: $PREF_ALIGN,
            },
-           abi: ScalarPair(
+           backend_repr: ScalarPair(
                Initialized {
                    value: Int(
                        I8,
@@ -620,7 +620,7 @@ error: layout_of(NicheSecond) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I8,
@@ -670,7 +670,7 @@ error: layout_of(NicheSecond) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -692,7 +692,7 @@ error: layout_of(NicheSecond) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/layout/issue-96185-overaligned-enum.stderr b/tests/ui/layout/issue-96185-overaligned-enum.stderr
index 1d4e4436448..a9081afc509 100644
--- a/tests/ui/layout/issue-96185-overaligned-enum.stderr
+++ b/tests/ui/layout/issue-96185-overaligned-enum.stderr
@@ -4,7 +4,7 @@ error: layout_of(Aligned1) = Layout {
                abi: Align(8 bytes),
                pref: $PREF_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Arbitrary {
@@ -43,7 +43,7 @@ error: layout_of(Aligned1) = Layout {
                            abi: Align(8 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -67,7 +67,7 @@ error: layout_of(Aligned1) = Layout {
                            abi: Align(8 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -104,7 +104,7 @@ error: layout_of(Aligned2) = Layout {
                abi: Align(1 bytes),
                pref: $PREF_ALIGN,
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I8,
@@ -149,7 +149,7 @@ error: layout_of(Aligned2) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -173,7 +173,7 @@ error: layout_of(Aligned2) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/layout/thumb-enum.stderr b/tests/ui/layout/thumb-enum.stderr
index 07153fee027..b635d1a45bb 100644
--- a/tests/ui/layout/thumb-enum.stderr
+++ b/tests/ui/layout/thumb-enum.stderr
@@ -4,7 +4,7 @@ error: layout_of(A) = Layout {
                abi: Align(1 bytes),
                pref: Align(4 bytes),
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I8,
@@ -49,7 +49,7 @@ error: layout_of(A) = Layout {
                            abi: Align(1 bytes),
                            pref: Align(4 bytes),
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -82,7 +82,7 @@ error: layout_of(B) = Layout {
                abi: Align(1 bytes),
                pref: Align(4 bytes),
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I8,
@@ -127,7 +127,7 @@ error: layout_of(B) = Layout {
                            abi: Align(1 bytes),
                            pref: Align(4 bytes),
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -160,7 +160,7 @@ error: layout_of(C) = Layout {
                abi: Align(2 bytes),
                pref: Align(4 bytes),
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I16,
@@ -205,7 +205,7 @@ error: layout_of(C) = Layout {
                            abi: Align(2 bytes),
                            pref: Align(4 bytes),
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -238,7 +238,7 @@ error: layout_of(P) = Layout {
                abi: Align(4 bytes),
                pref: Align(4 bytes),
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I32,
@@ -283,7 +283,7 @@ error: layout_of(P) = Layout {
                            abi: Align(4 bytes),
                            pref: Align(4 bytes),
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -316,7 +316,7 @@ error: layout_of(T) = Layout {
                abi: Align(4 bytes),
                pref: Align(4 bytes),
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I32,
@@ -361,7 +361,7 @@ error: layout_of(T) = Layout {
                            abi: Align(4 bytes),
                            pref: Align(4 bytes),
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/layout/zero-sized-array-enum-niche.stderr b/tests/ui/layout/zero-sized-array-enum-niche.stderr
index 33d2eede220..1ba184bdace 100644
--- a/tests/ui/layout/zero-sized-array-enum-niche.stderr
+++ b/tests/ui/layout/zero-sized-array-enum-niche.stderr
@@ -4,7 +4,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout {
                abi: Align(4 bytes),
                pref: $PREF_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Arbitrary {
@@ -43,7 +43,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout {
                            abi: Align(4 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -69,7 +69,7 @@ error: layout_of(Result<[u32; 0], bool>) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -115,7 +115,7 @@ error: layout_of(MultipleAlignments) = Layout {
                abi: Align(4 bytes),
                pref: $PREF_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Arbitrary {
@@ -154,7 +154,7 @@ error: layout_of(MultipleAlignments) = Layout {
                            abi: Align(2 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -180,7 +180,7 @@ error: layout_of(MultipleAlignments) = Layout {
                            abi: Align(4 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -206,7 +206,7 @@ error: layout_of(MultipleAlignments) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -252,7 +252,7 @@ error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
                abi: Align(4 bytes),
                pref: $PREF_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Arbitrary {
@@ -291,7 +291,7 @@ error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
                            abi: Align(4 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -317,7 +317,7 @@ error: layout_of(Result<[u32; 0], Packed<NonZero<u16>>>) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -363,7 +363,7 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
                abi: Align(4 bytes),
                pref: $PREF_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Arbitrary {
@@ -406,7 +406,7 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
                            abi: Align(4 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -432,7 +432,7 @@ error: layout_of(Result<[u32; 0], Packed<U16IsZero>>) = Layout {
                            abi: Align(1 bytes),
                            pref: $PREF_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/lifetimes/issue-26638.rs b/tests/ui/lifetimes/issue-26638.rs
index 11c730165f2..e73cf21bd6c 100644
--- a/tests/ui/lifetimes/issue-26638.rs
+++ b/tests/ui/lifetimes/issue-26638.rs
@@ -3,7 +3,6 @@ fn parse_type(iter: Box<dyn Iterator<Item=&str>+'static>) -> &str { iter.next()
 
 fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
 //~^ ERROR missing lifetime specifier [E0106]
-//~| ERROR mismatched types
 //~| ERROR function takes 1 argument but 0 arguments were supplied
 
 fn parse_type_3() -> &str { unimplemented!() }
diff --git a/tests/ui/lifetimes/issue-26638.stderr b/tests/ui/lifetimes/issue-26638.stderr
index bdf91136765..74a1676f684 100644
--- a/tests/ui/lifetimes/issue-26638.stderr
+++ b/tests/ui/lifetimes/issue-26638.stderr
@@ -32,7 +32,7 @@ LL + fn parse_type_2(iter: fn(&u8)->&u8) -> String { iter() }
    |
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/issue-26638.rs:9:22
+  --> $DIR/issue-26638.rs:8:22
    |
 LL | fn parse_type_3() -> &str { unimplemented!() }
    |                      ^ expected named lifetime parameter
@@ -59,18 +59,7 @@ help: provide the argument
 LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter(/* &u8 */) }
    |                                                    +++++++++
 
-error[E0308]: mismatched types
-  --> $DIR/issue-26638.rs:4:47
-   |
-LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() }
-   |                                        ----   ^^^^^^ expected `&str`, found `&u8`
-   |                                        |
-   |                                        expected `&'static str` because of return type
-   |
-   = note: expected reference `&'static str`
-              found reference `&u8`
-
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0061, E0106, E0308.
+Some errors have detailed explanations: E0061, E0106.
 For more information about an error, try `rustc --explain E0061`.
diff --git a/tests/ui/linkage-attr/raw-dylib/elf/multiple-libraries.rs b/tests/ui/linkage-attr/raw-dylib/elf/multiple-libraries.rs
new file mode 100644
index 00000000000..f4715ff2d3d
--- /dev/null
+++ b/tests/ui/linkage-attr/raw-dylib/elf/multiple-libraries.rs
@@ -0,0 +1,37 @@
+//@ only-elf
+//@ needs-dynamic-linking
+// FIXME(raw_dylib_elf): Debug the failures on other targets.
+//@ only-gnu
+//@ only-x86_64
+
+//@ revisions: with without
+
+//@ [without] build-fail
+//@ [without] regex-error-pattern:error: linking with `.*` failed
+//@ [without] dont-check-compiler-stderr
+
+//@ [with] build-pass
+
+//! Ensures that linking fails when there's an undefined symbol,
+//! and that it does succeed with raw-dylib.
+
+#![feature(raw_dylib_elf)]
+#![allow(incomplete_features)]
+
+#[cfg_attr(with, link(name = "rawdylibbutforcats", kind = "raw-dylib"))]
+#[cfg_attr(without, link(name = "rawdylibbutforcats"))]
+unsafe extern "C" {
+  safe fn meooooooooooooooow();
+}
+
+
+#[cfg_attr(with, link(name = "rawdylibbutfordogs", kind = "raw-dylib"))]
+#[cfg_attr(without, link(name = "rawdylibbutfordogs"))]
+unsafe extern "C" {
+  safe fn woooooooooooooooooof();
+}
+
+fn main() {
+  meooooooooooooooow();
+  woooooooooooooooooof();
+}
diff --git a/tests/ui/linkage-attr/raw-dylib/elf/single-symbol.rs b/tests/ui/linkage-attr/raw-dylib/elf/single-symbol.rs
new file mode 100644
index 00000000000..fe9c7884e54
--- /dev/null
+++ b/tests/ui/linkage-attr/raw-dylib/elf/single-symbol.rs
@@ -0,0 +1,28 @@
+//@ only-elf
+//@ needs-dynamic-linking
+// FIXME(raw_dylib_elf): Debug the failures on other targets.
+//@ only-gnu
+//@ only-x86_64
+//@ revisions: with without
+
+//@ [without] build-fail
+//@ [without] regex-error-pattern:error: linking with `.*` failed
+//@ [without] dont-check-compiler-stderr
+
+//@ [with] build-pass
+
+//! Ensures that linking fails when there's an undefined symbol,
+//! and that it does succeed with raw-dylib.
+
+#![feature(raw_dylib_elf)]
+#![allow(incomplete_features)]
+
+#[cfg_attr(with, link(name = "rawdylibbutforcats", kind = "raw-dylib"))]
+#[cfg_attr(without, link(name = "rawdylibbutforcats"))]
+unsafe extern "C" {
+  safe fn meooooooooooooooow();
+}
+
+fn main() {
+  meooooooooooooooow();
+}
diff --git a/tests/ui/linkage-attr/raw-dylib/elf/verbatim.rs b/tests/ui/linkage-attr/raw-dylib/elf/verbatim.rs
new file mode 100644
index 00000000000..72cba18d841
--- /dev/null
+++ b/tests/ui/linkage-attr/raw-dylib/elf/verbatim.rs
@@ -0,0 +1,29 @@
+//@ only-elf
+//@ needs-dynamic-linking
+// FIXME(raw_dylib_elf): Debug the failures on other targets.
+//@ only-gnu
+//@ only-x86_64
+
+//@ revisions: with without
+
+//@ [without] build-fail
+//@ [without] regex-error-pattern:error: linking with `.*` failed
+//@ [without] dont-check-compiler-stderr
+
+//@ [with] build-pass
+
+//! Ensures that linking fails when there's an undefined symbol,
+//! and that it does succeed with raw-dylib, but with verbatim.
+
+#![feature(raw_dylib_elf)]
+#![allow(incomplete_features)]
+
+#[cfg_attr(with, link(name = "rawdylibbutforcats", kind = "raw-dylib", modifiers = "+verbatim"))]
+#[cfg_attr(without, link(name = "rawdylibbutforcats", modifiers = "+verbatim"))]
+unsafe extern "C" {
+  safe fn meooooooooooooooow();
+}
+
+fn main() {
+  meooooooooooooooow();
+}
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs b/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.rs
index e69a4537935..e69a4537935 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.stderr b/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.stderr
index 90cca83d1c1..90cca83d1c1 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/dlltool-failed.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/dlltool-failed.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-invalid-format.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs
index 50ad8a173ad..50ad8a173ad 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-invalid-format.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr
index d2cf7a0ba1f..d2cf7a0ba1f 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-invalid-format.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-invalid-format.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-multiple.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs
index cf456b9b261..cf456b9b261 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-multiple.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-multiple.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr
index 8e65baf65df..8e65baf65df 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-multiple.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-multiple.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unknown-value.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs
index b3859ba1ce6..b3859ba1ce6 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unknown-value.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr
index 4b8b90eb6e2..4b8b90eb6e2 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unknown-value.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unknown-value.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs
index 3ead5cb1fd7..3ead5cb1fd7 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.stderr
index 75cadc471c4..75cadc471c4 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-unsupported-link-kind.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-unsupported-link-kind.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-x86-only.rs b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs
index ab0dcda64e6..ab0dcda64e6 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-x86-only.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-x86-only.stderr b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.stderr
index 757f1f7994e..757f1f7994e 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/import-name-type-x86-only.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/import-name-type-x86-only.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs b/tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.rs
index 057242246f0..057242246f0 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.stderr b/tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.stderr
index 4bbad9b30a7..4bbad9b30a7 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/invalid-dlltool.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/invalid-dlltool.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-and-name.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-and-name.rs
index b04c2facbcd..b04c2facbcd 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-and-name.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-and-name.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-and-name.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-and-name.stderr
index f1e54d37827..f1e54d37827 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-and-name.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-and-name.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.rs
index 9b7e8d70743..9b7e8d70743 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-invalid-format.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.stderr
index 6341e57a0be..6341e57a0be 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-invalid-format.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-invalid-format.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.rs
index 6b8cd49566d..6b8cd49566d 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-missing-argument.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.stderr
index 1b04bb228e7..1b04bb228e7 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-missing-argument.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-missing-argument.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-multiple.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.rs
index f5fb1649cdc..f5fb1649cdc 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-multiple.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-multiple.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.stderr
index 2e6cf3761c2..2e6cf3761c2 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-multiple.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-multiple.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.rs
index 5982c771033..5982c771033 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.stderr
index 8f279508720..8f279508720 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-not-foreign-fn.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-not-foreign-fn.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-large.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-large.rs
index 9d741630fc9..9d741630fc9 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-large.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-large.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-large.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-large.stderr
index 811145e77ee..811145e77ee 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-large.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-large.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.rs
index 9988115fd8b..9988115fd8b 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.stderr
index d5ce8aff34f..d5ce8aff34f 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-too-many-arguments.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-too-many-arguments.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-unsupported-link-kind.rs
index 14e915d602a..14e915d602a 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-unsupported-link-kind.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-unsupported-link-kind.stderr
index 200b8f62874..200b8f62874 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/link-ordinal-unsupported-link-kind.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/link-ordinal-unsupported-link-kind.stderr
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.rs b/tests/ui/linkage-attr/raw-dylib/windows/multiple-declarations.rs
index bf3c5e4d435..bf3c5e4d435 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/multiple-declarations.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr b/tests/ui/linkage-attr/raw-dylib/windows/multiple-declarations.stderr
index b766b5c8dd8..b766b5c8dd8 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/multiple-declarations.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/multiple-declarations.stderr
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.elf.stderr b/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.elf.stderr
new file mode 100644
index 00000000000..70945ed6fc0
--- /dev/null
+++ b/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.elf.stderr
@@ -0,0 +1,13 @@
+error[E0658]: link kind `raw-dylib` is unstable on ELF platforms
+  --> $DIR/raw-dylib-windows-only.rs:6:29
+   |
+LL | #[link(name = "foo", kind = "raw-dylib")]
+   |                             ^^^^^^^^^^^
+   |
+   = note: see issue #135694 <https://github.com/rust-lang/rust/issues/135694> for more information
+   = help: add `#![feature(raw_dylib_elf)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr b/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.notelf.stderr
index ede20cb8c3f..daed15d784a 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.notelf.stderr
@@ -1,5 +1,5 @@
 error[E0455]: link kind `raw-dylib` is only supported on Windows targets
-  --> $DIR/raw-dylib-windows-only.rs:3:29
+  --> $DIR/raw-dylib-windows-only.rs:6:29
    |
 LL | #[link(name = "foo", kind = "raw-dylib")]
    |                             ^^^^^^^^^^^
diff --git a/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.rs b/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.rs
new file mode 100644
index 00000000000..935c59b5aaa
--- /dev/null
+++ b/tests/ui/linkage-attr/raw-dylib/windows/raw-dylib-windows-only.rs
@@ -0,0 +1,9 @@
+//@ revisions: elf notelf
+//@ [elf] only-elf
+//@ [notelf] ignore-windows
+//@ [notelf] ignore-elf
+//@ compile-flags: --crate-type lib
+#[link(name = "foo", kind = "raw-dylib")]
+//[notelf]~^ ERROR: link kind `raw-dylib` is only supported on Windows targets
+//[elf]~^^ ERROR: link kind `raw-dylib` is unstable on ELF platforms
+extern "C" {}
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.rs b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs
index 48af6b009d3..48af6b009d3 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.rs
+++ b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.rs
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr
index ef022404e7f..ef022404e7f 100644
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/unsupported-abi.stderr
+++ b/tests/ui/linkage-attr/raw-dylib/windows/unsupported-abi.stderr
diff --git a/tests/ui/lint/clashing-extern-fn.stderr b/tests/ui/lint/clashing-extern-fn.stderr
index 118b18b224c..0c27547a6ed 100644
--- a/tests/ui/lint/clashing-extern-fn.stderr
+++ b/tests/ui/lint/clashing-extern-fn.stderr
@@ -17,7 +17,7 @@ LL |             fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZero<usiz
    = help: consider adding a `#[repr(C)]`, `#[repr(transparent)]`, or integer `#[repr(...)]` attribute to this enum
    = note: enum has no representation hint
 
-warning: `extern` block uses type `Option<(usize) is 0..=>`, which is not FFI-safe
+warning: `extern` block uses type `Option<(usize) is 0..>`, which is not FFI-safe
   --> $DIR/clashing-extern-fn.rs:502:54
    |
 LL |             fn pt_non_zero_usize_opt_full_range() -> Option<pattern_type!(usize is 0..)>;
diff --git a/tests/ui/lint/removed-lints/README.md b/tests/ui/lint/removed-lints/README.md
new file mode 100644
index 00000000000..abe7ee04115
--- /dev/null
+++ b/tests/ui/lint/removed-lints/README.md
@@ -0,0 +1,4 @@
+# Removed lints
+
+This directory contains tests to confirm that lints that have been
+removed do not cause errors and produce the appropriate warnings.
diff --git a/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs
new file mode 100644
index 00000000000..7fb635487ff
--- /dev/null
+++ b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.rs
@@ -0,0 +1,5 @@
+//@ check-pass
+
+#![deny(ptr_cast_add_auto_to_object)]
+//~^ WARN  lint `ptr_cast_add_auto_to_object` has been removed
+fn main() {}
diff --git a/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr
new file mode 100644
index 00000000000..36b5e847d80
--- /dev/null
+++ b/tests/ui/lint/removed-lints/ptr_cast_add_auto_to_object.stderr
@@ -0,0 +1,10 @@
+warning: lint `ptr_cast_add_auto_to_object` has been removed: converted into hard error, see issue #127323 <https://github.com/rust-lang/rust/issues/127323> for more information
+  --> $DIR/ptr_cast_add_auto_to_object.rs:3:9
+   |
+LL | #![deny(ptr_cast_add_auto_to_object)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `#[warn(renamed_and_removed_lints)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/macros/macro-parameter-span.stderr b/tests/ui/macros/macro-parameter-span.stderr
index 247750a8ad7..44c8c56dff9 100644
--- a/tests/ui/macros/macro-parameter-span.stderr
+++ b/tests/ui/macros/macro-parameter-span.stderr
@@ -1,6 +1,9 @@
 error[E0425]: cannot find value `x` in this scope
   --> $DIR/macro-parameter-span.rs:11:9
    |
+LL |         $id
+   |         --- due to this macro variable
+...
 LL |         x
    |         ^ not found in this scope
 
diff --git a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr
index ce7694ecb1d..d9646760cea 100644
--- a/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr
+++ b/tests/ui/macros/rfc-3086-metavar-expr/syntax-errors.stderr
@@ -338,6 +338,9 @@ LL |     no_curly__no_rhs_dollar__no_round!(a);
 error[E0425]: cannot find value `a` in this scope
   --> $DIR/syntax-errors.rs:152:37
    |
+LL |     ( $i:ident ) => { count($i) };
+   |                             -- due to this macro variable
+...
 LL |     no_curly__rhs_dollar__no_round!(a);
    |                                     ^ not found in this scope
 
diff --git a/tests/ui/methods/ident-from-macro-expansion.rs b/tests/ui/methods/ident-from-macro-expansion.rs
new file mode 100644
index 00000000000..38d2fee0e53
--- /dev/null
+++ b/tests/ui/methods/ident-from-macro-expansion.rs
@@ -0,0 +1,18 @@
+macro_rules! dot {
+    ($id:ident) => {
+        ().$id();
+    }
+}
+
+macro_rules! dispatch {
+    ($id:ident) => {
+        <()>::$id();
+    }
+}
+
+fn main() {
+    dot!(hello);
+    //~^ ERROR no method named `hello` found for unit type `()` in the current scope
+    dispatch!(hello);
+    //~^ ERROR no function or associated item named `hello` found for unit type `()` in the current scope
+}
diff --git a/tests/ui/methods/ident-from-macro-expansion.stderr b/tests/ui/methods/ident-from-macro-expansion.stderr
new file mode 100644
index 00000000000..b596ce29f6f
--- /dev/null
+++ b/tests/ui/methods/ident-from-macro-expansion.stderr
@@ -0,0 +1,21 @@
+error[E0599]: no method named `hello` found for unit type `()` in the current scope
+  --> $DIR/ident-from-macro-expansion.rs:14:10
+   |
+LL |         ().$id();
+   |            --- due to this macro variable
+...
+LL |     dot!(hello);
+   |          ^^^^^ method not found in `()`
+
+error[E0599]: no function or associated item named `hello` found for unit type `()` in the current scope
+  --> $DIR/ident-from-macro-expansion.rs:16:15
+   |
+LL |         <()>::$id();
+   |               --- due to this macro variable
+...
+LL |     dispatch!(hello);
+   |               ^^^^^ function or associated item not found in `()`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/methods/inherent-bound-in-probe.rs b/tests/ui/methods/inherent-bound-in-probe.rs
index 9b9eb91559b..4add93e808d 100644
--- a/tests/ui/methods/inherent-bound-in-probe.rs
+++ b/tests/ui/methods/inherent-bound-in-probe.rs
@@ -1,5 +1,3 @@
-//@ normalize-stderr: "long-type-\d+" -> "long-type-hash"
-
 // Fixes #110131
 //
 // The issue is that we were constructing an `ImplDerived` cause code for the
diff --git a/tests/ui/methods/inherent-bound-in-probe.stderr b/tests/ui/methods/inherent-bound-in-probe.stderr
index 433ef02a2aa..77aed390c9a 100644
--- a/tests/ui/methods/inherent-bound-in-probe.stderr
+++ b/tests/ui/methods/inherent-bound-in-probe.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `Helper<'a, T>` is not an iterator
-  --> $DIR/inherent-bound-in-probe.rs:40:21
+  --> $DIR/inherent-bound-in-probe.rs:38:21
    |
 LL |     type IntoIter = Helper<'a, T>;
    |                     ^^^^^^^^^^^^^ `Helper<'a, T>` is not an iterator
@@ -9,14 +9,14 @@ note: required by a bound in `std::iter::IntoIterator::IntoIter`
   --> $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
 
 error[E0275]: overflow evaluating the requirement `&_: IntoIterator`
-  --> $DIR/inherent-bound-in-probe.rs:44:9
+  --> $DIR/inherent-bound-in-probe.rs:42:9
    |
 LL |         Helper::new(&self.0)
    |         ^^^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inherent_bound_in_probe`)
 note: required for `&BitReaderWrapper<_>` to implement `IntoIterator`
-  --> $DIR/inherent-bound-in-probe.rs:34:13
+  --> $DIR/inherent-bound-in-probe.rs:32:13
    |
 LL | impl<'a, T> IntoIterator for &'a BitReaderWrapper<T>
    |             ^^^^^^^^^^^^     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -26,7 +26,7 @@ LL |     &'a T: IntoIterator<Item = &'a u8>,
    = note: 126 redundant requirements hidden
    = note: required for `&BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<BitReaderWrapper<_>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>` to implement `IntoIterator`
 note: required by a bound in `Helper`
-  --> $DIR/inherent-bound-in-probe.rs:18:12
+  --> $DIR/inherent-bound-in-probe.rs:16:12
    |
 LL | struct Helper<'a, T>
    |        ------ required by a bound in this struct
diff --git a/tests/ui/nll/issue-97997.rs b/tests/ui/nll/issue-97997.rs
index c64e720b12f..8e0fbe89ac2 100644
--- a/tests/ui/nll/issue-97997.rs
+++ b/tests/ui/nll/issue-97997.rs
@@ -12,5 +12,4 @@ fn main() {
 
     <fn(&u8) as Foo>::ASSOC;
     //~^ ERROR implementation of `Foo` is not general enough
-    //~| ERROR implementation of `Foo` is not general enough
 }
diff --git a/tests/ui/nll/issue-97997.stderr b/tests/ui/nll/issue-97997.stderr
index 89eaf77adf0..ff08daaeaac 100644
--- a/tests/ui/nll/issue-97997.stderr
+++ b/tests/ui/nll/issue-97997.stderr
@@ -7,15 +7,5 @@ LL |     <fn(&u8) as Foo>::ASSOC;
    = note: `Foo` would have to be implemented for the type `for<'a> fn(&'a u8)`
    = note: ...but `Foo` is actually implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0`
 
-error: implementation of `Foo` is not general enough
-  --> $DIR/issue-97997.rs:13:5
-   |
-LL |     <fn(&u8) as Foo>::ASSOC;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
-   |
-   = note: `Foo` would have to be implemented for the type `for<'a> fn(&'a u8)`
-   = note: ...but `Foo` is actually implemented for the type `fn(&'0 u8)`, for some specific lifetime `'0`
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/bounds-lifetime-where.rs b/tests/ui/parser/bounds-lifetime-where.rs
index 7ff75233d3a..730be7139be 100644
--- a/tests/ui/parser/bounds-lifetime-where.rs
+++ b/tests/ui/parser/bounds-lifetime-where.rs
@@ -5,6 +5,6 @@ type A where 'a:, = u8; // OK
 type A where 'a: 'b + 'c = u8; // OK
 type A where = u8; // OK
 type A where 'a: 'b + = u8; // OK
-type A where , = u8; //~ ERROR expected one of `;`, `=`, `where`, lifetime, or type, found `,`
+type A where , = u8; //~ ERROR expected one of `#`, `;`, `=`, `where`, lifetime, or type, found `,`
 
 fn main() {}
diff --git a/tests/ui/parser/bounds-lifetime-where.stderr b/tests/ui/parser/bounds-lifetime-where.stderr
index 9dd963afc79..5aadb5fff32 100644
--- a/tests/ui/parser/bounds-lifetime-where.stderr
+++ b/tests/ui/parser/bounds-lifetime-where.stderr
@@ -1,8 +1,8 @@
-error: expected one of `;`, `=`, `where`, lifetime, or type, found `,`
+error: expected one of `#`, `;`, `=`, `where`, lifetime, or type, found `,`
   --> $DIR/bounds-lifetime-where.rs:8:14
    |
 LL | type A where , = u8;
-   |              ^ expected one of `;`, `=`, `where`, lifetime, or type
+   |              ^ expected one of `#`, `;`, `=`, `where`, lifetime, or type
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr b/tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr
index 196a46d7ea5..6245f81d533 100644
--- a/tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr
+++ b/tests/ui/parser/issues/misplaced-return-type-where-in-next-line-issue-126311.stderr
@@ -2,7 +2,7 @@ error: return type should be specified after the function parameters
   --> $DIR/misplaced-return-type-where-in-next-line-issue-126311.rs:5:15
    |
 LL |     K: Clone, -> Result<u8, String>
-   |               ^^ expected one of `{`, lifetime, or type
+   |               ^^ expected one of `#`, `{`, lifetime, or type
    |
 help: place the return type after the function parameters
    |
diff --git a/tests/ui/parser/ranges-precedence.rs b/tests/ui/parser/ranges-precedence.rs
index 14dd6488ff2..783799f7099 100644
--- a/tests/ui/parser/ranges-precedence.rs
+++ b/tests/ui/parser/ranges-precedence.rs
@@ -1,7 +1,8 @@
 //@ run-pass
+//@ edition: 2021
 // Test that the precedence of ranges is correct
 
-
+use core::ops::{Add, RangeTo};
 
 struct Foo {
     foo: usize,
@@ -11,6 +12,13 @@ impl Foo {
     fn bar(&self) -> usize { 5 }
 }
 
+impl Add<RangeTo<usize>> for Foo {
+    type Output = usize;
+    fn add(self, range: RangeTo<usize>) -> Self::Output {
+        self.foo + range.end
+    }
+}
+
 fn main() {
     let x = 1+3..4+5;
     assert_eq!(x, (4..9));
@@ -49,4 +57,22 @@ fn main() {
 
     let y = ..;
     assert_eq!(y, (..));
+
+    let reference = &..0;
+    assert_eq!(*reference, ..0);
+    let reference2 = &&..0;
+    assert_eq!(**reference2, ..0);
+
+    let closure = || ..0;
+    assert_eq!(closure(), ..0);
+
+    let sum = Foo { foo: 3 } + ..4;
+    assert_eq!(sum, 7);
+
+    macro_rules! expr {
+        ($e:expr) => {};
+    }
+    expr!(!..0);
+    expr!(-..0);
+    expr!(*..0);
 }
diff --git a/tests/ui/recursion/issue-23122-2.rs b/tests/ui/recursion/issue-23122-2.rs
index 3e14fa92dd0..95e1f60d8b0 100644
--- a/tests/ui/recursion/issue-23122-2.rs
+++ b/tests/ui/recursion/issue-23122-2.rs
@@ -1,4 +1,3 @@
-//@ normalize-stderr: "long-type-\d+" -> "long-type-hash"
 trait Next {
     type Next: Next;
 }
diff --git a/tests/ui/recursion/issue-23122-2.stderr b/tests/ui/recursion/issue-23122-2.stderr
index 10463ab2c33..c5774cc1888 100644
--- a/tests/ui/recursion/issue-23122-2.stderr
+++ b/tests/ui/recursion/issue-23122-2.stderr
@@ -1,12 +1,12 @@
 error[E0275]: overflow evaluating the requirement `<<<<<<<... as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next: Sized`
-  --> $DIR/issue-23122-2.rs:11:17
+  --> $DIR/issue-23122-2.rs:10:17
    |
 LL |     type Next = <GetNext<T::Next> as Next>::Next;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_23122_2`)
 note: required for `GetNext<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<T as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next as Next>::Next>` to implement `Next`
-  --> $DIR/issue-23122-2.rs:10:15
+  --> $DIR/issue-23122-2.rs:9:15
    |
 LL | impl<T: Next> Next for GetNext<T> {
    |      -        ^^^^     ^^^^^^^^^^
diff --git a/tests/ui/recursion/issue-83150.rs b/tests/ui/recursion/issue-83150.rs
index ea1bef4fce3..b720c168187 100644
--- a/tests/ui/recursion/issue-83150.rs
+++ b/tests/ui/recursion/issue-83150.rs
@@ -1,7 +1,6 @@
-//~ ERROR overflow evaluating the requirement `Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>: Iterator`
+//~ ERROR overflow evaluating the requirement `Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: Iterator`
 //@ build-fail
 //@ compile-flags: -Copt-level=0
-//@ normalize-stderr: "long-type-\d+" -> "long-type-hash"
 
 fn main() {
     let mut iter = 0u8..1;
diff --git a/tests/ui/recursion/issue-83150.stderr b/tests/ui/recursion/issue-83150.stderr
index 92a39a44e4f..600922f1e57 100644
--- a/tests/ui/recursion/issue-83150.stderr
+++ b/tests/ui/recursion/issue-83150.stderr
@@ -1,5 +1,5 @@
 warning: function cannot return without recursing
-  --> $DIR/issue-83150.rs:11:1
+  --> $DIR/issue-83150.rs:10:1
    |
 LL | fn func<T: Iterator<Item = u8>>(iter: &mut T) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
@@ -10,12 +10,12 @@ LL |     func(&mut iter.map(|x| x + 1))
    = help: a `loop` may express intention better if this is on purpose
    = note: `#[warn(unconditional_recursion)]` on by default
 
-error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>: Iterator`
+error[E0275]: overflow evaluating the requirement `Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>: Iterator`
    |
    = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_83150`)
-   = note: required for `&mut Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>` to implement `Iterator`
+   = note: required for `&mut Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>` to implement `Iterator`
    = note: 65 redundant requirements hidden
-   = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>, {closure@$DIR/issue-83150.rs:13:24: 13:27}>` to implement `Iterator`
+   = note: required for `&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut Map<&mut std::ops::Range<u8>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>, {closure@$DIR/issue-83150.rs:12:24: 12:27}>` to implement `Iterator`
 
 error: aborting due to 1 previous error; 1 warning emitted
 
diff --git a/tests/ui/recursion/recursion.rs b/tests/ui/recursion/recursion.rs
index ce56fe974b7..5cd4012a9d2 100644
--- a/tests/ui/recursion/recursion.rs
+++ b/tests/ui/recursion/recursion.rs
@@ -1,7 +1,5 @@
 //@ build-fail
 //@ compile-flags:-C overflow-checks=off
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'"
 
 enum Nil {NilValue}
 struct Cons<T> {head:isize, tail:T}
diff --git a/tests/ui/recursion/recursion.stderr b/tests/ui/recursion/recursion.stderr
index cb9f67ba741..f959805defc 100644
--- a/tests/ui/recursion/recursion.stderr
+++ b/tests/ui/recursion/recursion.stderr
@@ -1,15 +1,15 @@
 error: reached the recursion limit while instantiating `test::<Cons<Cons<Cons<Cons<Cons<...>>>>>>`
-  --> $DIR/recursion.rs:19:11
+  --> $DIR/recursion.rs:17:11
    |
 LL |     _ => {test (n-1, i+1, Cons {head:2*i+1, tail:first}, Cons{head:i*i, tail:second})}
    |           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: `test` defined here
-  --> $DIR/recursion.rs:17:1
+  --> $DIR/recursion.rs:15:1
    |
 LL | fn test<T:Dot> (n:isize, i:isize, first:T, second:T) ->isize {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/recursion.long-type.txt'
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/regions/issue-102374.rs b/tests/ui/regions/issue-102374.rs
index d640c29b2f4..e0a1164211a 100644
--- a/tests/ui/regions/issue-102374.rs
+++ b/tests/ui/regions/issue-102374.rs
@@ -1,4 +1,3 @@
-//@ normalize-stderr: "long-type-\d+" -> "long-type-hash"
 use std::cell::Cell;
 
 #[rustfmt::skip]
diff --git a/tests/ui/regions/issue-102374.stderr b/tests/ui/regions/issue-102374.stderr
index e07dca0c7ee..5416125d1c7 100644
--- a/tests/ui/regions/issue-102374.stderr
+++ b/tests/ui/regions/issue-102374.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/issue-102374.rs:17:5
+  --> $DIR/issue-102374.rs:16:5
    |
 LL | ) -> i32 {
    |      --- expected `i32` because of return type
diff --git a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr
index 42fcaee2d4a..c11acc98637 100644
--- a/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.aarch64-unknown-linux-gnu.stderr
@@ -4,7 +4,7 @@ error: layout_of(Univariant) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I32,
@@ -49,7 +49,7 @@ error: layout_of(Univariant) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Scalar(
+                       backend_repr: Scalar(
                            Initialized {
                                value: Int(
                                    I32,
@@ -92,7 +92,7 @@ error: layout_of(TwoVariants) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: ScalarPair(
+           backend_repr: ScalarPair(
                Initialized {
                    value: Int(
                        I32,
@@ -143,7 +143,7 @@ error: layout_of(TwoVariants) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I32,
@@ -181,7 +181,7 @@ error: layout_of(TwoVariants) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I32,
@@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                abi: Align(8 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Arbitrary {
@@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
index bb2c6e70dc7..a7888155dea 100644
--- a/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.armebv7r-none-eabi.stderr
@@ -4,7 +4,7 @@ error: layout_of(Univariant) = Layout {
                abi: Align(1 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I8,
@@ -49,7 +49,7 @@ error: layout_of(Univariant) = Layout {
                            abi: Align(1 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Scalar(
+                       backend_repr: Scalar(
                            Initialized {
                                value: Int(
                                    I8,
@@ -92,7 +92,7 @@ error: layout_of(TwoVariants) = Layout {
                abi: Align(1 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: ScalarPair(
+           backend_repr: ScalarPair(
                Initialized {
                    value: Int(
                        I8,
@@ -143,7 +143,7 @@ error: layout_of(TwoVariants) = Layout {
                            abi: Align(1 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I8,
@@ -181,7 +181,7 @@ error: layout_of(TwoVariants) = Layout {
                            abi: Align(1 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I8,
@@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                abi: Align(8 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Arbitrary {
@@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
index 42fcaee2d4a..c11acc98637 100644
--- a/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.i686-pc-windows-msvc.stderr
@@ -4,7 +4,7 @@ error: layout_of(Univariant) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I32,
@@ -49,7 +49,7 @@ error: layout_of(Univariant) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Scalar(
+                       backend_repr: Scalar(
                            Initialized {
                                value: Int(
                                    I32,
@@ -92,7 +92,7 @@ error: layout_of(TwoVariants) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: ScalarPair(
+           backend_repr: ScalarPair(
                Initialized {
                    value: Int(
                        I32,
@@ -143,7 +143,7 @@ error: layout_of(TwoVariants) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I32,
@@ -181,7 +181,7 @@ error: layout_of(TwoVariants) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I32,
@@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                abi: Align(8 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Arbitrary {
@@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr
index 42fcaee2d4a..c11acc98637 100644
--- a/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr
+++ b/tests/ui/repr/repr-c-dead-variants.x86_64-unknown-linux-gnu.stderr
@@ -4,7 +4,7 @@ error: layout_of(Univariant) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I32,
@@ -49,7 +49,7 @@ error: layout_of(Univariant) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Scalar(
+                       backend_repr: Scalar(
                            Initialized {
                                value: Int(
                                    I32,
@@ -92,7 +92,7 @@ error: layout_of(TwoVariants) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: ScalarPair(
+           backend_repr: ScalarPair(
                Initialized {
                    value: Int(
                        I32,
@@ -143,7 +143,7 @@ error: layout_of(TwoVariants) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I32,
@@ -181,7 +181,7 @@ error: layout_of(TwoVariants) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I32,
@@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                abi: Align(8 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Arbitrary {
@@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherField) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/repr/repr-c-int-dead-variants.stderr b/tests/ui/repr/repr-c-int-dead-variants.stderr
index f852212deb9..f63574182c2 100644
--- a/tests/ui/repr/repr-c-int-dead-variants.stderr
+++ b/tests/ui/repr/repr-c-int-dead-variants.stderr
@@ -4,7 +4,7 @@ error: layout_of(UnivariantU8) = Layout {
                abi: Align(1 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I8,
@@ -49,7 +49,7 @@ error: layout_of(UnivariantU8) = Layout {
                            abi: Align(1 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Scalar(
+                       backend_repr: Scalar(
                            Initialized {
                                value: Int(
                                    I8,
@@ -92,7 +92,7 @@ error: layout_of(TwoVariantsU8) = Layout {
                abi: Align(1 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: ScalarPair(
+           backend_repr: ScalarPair(
                Initialized {
                    value: Int(
                        I8,
@@ -143,7 +143,7 @@ error: layout_of(TwoVariantsU8) = Layout {
                            abi: Align(1 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I8,
@@ -181,7 +181,7 @@ error: layout_of(TwoVariantsU8) = Layout {
                            abi: Align(1 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: ScalarPair(
+                       backend_repr: ScalarPair(
                            Initialized {
                                value: Int(
                                    I8,
@@ -230,7 +230,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
                abi: Align(8 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Memory {
+           backend_repr: Memory {
                sized: true,
            },
            fields: Arbitrary {
@@ -269,7 +269,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -299,7 +299,7 @@ error: layout_of(DeadBranchHasOtherFieldU8) = Layout {
                            abi: Align(8 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
diff --git a/tests/ui/return/tail-expr-as-potential-return.rs b/tests/ui/return/tail-expr-as-potential-return.rs
index 11ecddb049b..2e638f1897c 100644
--- a/tests/ui/return/tail-expr-as-potential-return.rs
+++ b/tests/ui/return/tail-expr-as-potential-return.rs
@@ -60,7 +60,6 @@ fn method() -> Option<i32> {
         Receiver.generic();
         //~^ ERROR type annotations needed
         //~| HELP consider specifying the generic argument
-        //~| HELP you might have meant to return this to infer its type parameters
     }
 
     None
diff --git a/tests/ui/return/tail-expr-as-potential-return.stderr b/tests/ui/return/tail-expr-as-potential-return.stderr
index 756de2b5a16..8105b2df3fe 100644
--- a/tests/ui/return/tail-expr-as-potential-return.stderr
+++ b/tests/ui/return/tail-expr-as-potential-return.stderr
@@ -57,10 +57,6 @@ help: consider specifying the generic argument
    |
 LL |         Receiver.generic::<T>();
    |                         +++++
-help: you might have meant to return this to infer its type parameters
-   |
-LL |         return Receiver.generic();
-   |         ++++++
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.rs b/tests/ui/rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.rs
deleted file mode 100644
index 3b982857db8..00000000000
--- a/tests/ui/rfcs/rfc-2627-raw-dylib/raw-dylib-windows-only.rs
+++ /dev/null
@@ -1,5 +0,0 @@
-//@ ignore-windows
-//@ compile-flags: --crate-type lib
-#[link(name = "foo", kind = "raw-dylib")]
-//~^ ERROR: link kind `raw-dylib` is only supported on Windows targets
-extern "C" {}
diff --git a/tests/ui/rmeta/emit-artifact-notifications.stderr b/tests/ui/rmeta/emit-artifact-notifications.stderr
index 4f68a2d74ed..c002be7bcff 100644
--- a/tests/ui/rmeta/emit-artifact-notifications.stderr
+++ b/tests/ui/rmeta/emit-artifact-notifications.stderr
@@ -1 +1 @@
-{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/rmeta/emit-artifact-notifications/libemit_artifact_notifications.rmeta","emit":"metadata"}
+{"$message_type":"artifact","artifact":"$TEST_BUILD_DIR/libemit_artifact_notifications.rmeta","emit":"metadata"}
diff --git a/tests/ui/specialization/defaultimpl/validation.rs b/tests/ui/specialization/defaultimpl/validation.rs
index 4049c4ea14c..14771be8982 100644
--- a/tests/ui/specialization/defaultimpl/validation.rs
+++ b/tests/ui/specialization/defaultimpl/validation.rs
@@ -6,12 +6,17 @@ struct Z;
 
 default impl S {} //~ ERROR inherent impls cannot be `default`
 
-default unsafe impl Send for S {} //~ ERROR impls of auto traits cannot be default
-//~^ ERROR `S` cannot be sent between threads safely
-default impl !Send for Z {} //~ ERROR impls of auto traits cannot be default
-                            //~^ ERROR negative impls cannot be default impls
+default unsafe impl Send for S {}
+//~^ ERROR impls of auto traits cannot be default
+
+default impl !Send for Z {}
+//~^ ERROR impls of auto traits cannot be default
+//~| ERROR negative impls cannot be default impls
+//~| ERROR `!Send` impl requires `Z: Send` but the struct it is implemented for does not
 
 trait Tr {}
-default impl !Tr for S {} //~ ERROR negative impls cannot be default impls
+
+default impl !Tr for S {}
+//~^ ERROR negative impls cannot be default impls
 
 fn main() {}
diff --git a/tests/ui/specialization/defaultimpl/validation.stderr b/tests/ui/specialization/defaultimpl/validation.stderr
index f56f16162a2..d034386b842 100644
--- a/tests/ui/specialization/defaultimpl/validation.stderr
+++ b/tests/ui/specialization/defaultimpl/validation.stderr
@@ -26,22 +26,20 @@ LL | default unsafe impl Send for S {}
    | |
    | default because of this
 
-error[E0277]: `S` cannot be sent between threads safely
-  --> $DIR/validation.rs:9:1
+error[E0367]: `!Send` impl requires `Z: Send` but the struct it is implemented for does not
+  --> $DIR/validation.rs:12:1
    |
-LL | default unsafe impl Send for S {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `S` cannot be sent between threads safely
-   |
-   = help: the trait `Send` is not implemented for `S`
-   = help: the trait `Send` is implemented for `S`
-   = help: see issue #48214
-help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+LL | default impl !Send for Z {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
    |
-LL + #![feature(trivial_bounds)]
+note: the implementor must specify the same requirement
+  --> $DIR/validation.rs:5:1
    |
+LL | struct Z;
+   | ^^^^^^^^
 
 error: impls of auto traits cannot be default
-  --> $DIR/validation.rs:11:15
+  --> $DIR/validation.rs:12:15
    |
 LL | default impl !Send for Z {}
    | -------       ^^^^ auto trait
@@ -49,18 +47,18 @@ LL | default impl !Send for Z {}
    | default because of this
 
 error[E0750]: negative impls cannot be default impls
-  --> $DIR/validation.rs:11:1
+  --> $DIR/validation.rs:12:1
    |
 LL | default impl !Send for Z {}
    | ^^^^^^^      ^
 
 error[E0750]: negative impls cannot be default impls
-  --> $DIR/validation.rs:15:1
+  --> $DIR/validation.rs:19:1
    |
 LL | default impl !Tr for S {}
    | ^^^^^^^      ^
 
 error: aborting due to 6 previous errors; 1 warning emitted
 
-Some errors have detailed explanations: E0277, E0750.
-For more information about an error, try `rustc --explain E0277`.
+Some errors have detailed explanations: E0367, E0750.
+For more information about an error, try `rustc --explain E0367`.
diff --git a/tests/ui/specialization/specialization-overlap-negative.rs b/tests/ui/specialization/specialization-overlap-negative.rs
index 550d3708295..244f21c7ba9 100644
--- a/tests/ui/specialization/specialization-overlap-negative.rs
+++ b/tests/ui/specialization/specialization-overlap-negative.rs
@@ -6,6 +6,8 @@ trait MyTrait {}
 struct TestType<T>(::std::marker::PhantomData<T>);
 
 unsafe impl<T: Clone> Send for TestType<T> {}
-impl<T: MyTrait> !Send for TestType<T> {} //~ ERROR E0751
+impl<T: MyTrait> !Send for TestType<T> {}
+//~^ ERROR found both positive and negative implementation of trait `Send` for type `TestType<_>`
+//~| ERROR `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
 
 fn main() {}
diff --git a/tests/ui/specialization/specialization-overlap-negative.stderr b/tests/ui/specialization/specialization-overlap-negative.stderr
index a8e99953e2b..4874e897726 100644
--- a/tests/ui/specialization/specialization-overlap-negative.stderr
+++ b/tests/ui/specialization/specialization-overlap-negative.stderr
@@ -16,6 +16,19 @@ LL | unsafe impl<T: Clone> Send for TestType<T> {}
 LL | impl<T: MyTrait> !Send for TestType<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ negative implementation here
 
-error: aborting due to 1 previous error; 1 warning emitted
+error[E0367]: `!Send` impl requires `T: MyTrait` but the struct it is implemented for does not
+  --> $DIR/specialization-overlap-negative.rs:9:9
+   |
+LL | impl<T: MyTrait> !Send for TestType<T> {}
+   |         ^^^^^^^
+   |
+note: the implementor must specify the same requirement
+  --> $DIR/specialization-overlap-negative.rs:6:1
+   |
+LL | struct TestType<T>(::std::marker::PhantomData<T>);
+   | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors; 1 warning emitted
 
-For more information about this error, try `rustc --explain E0751`.
+Some errors have detailed explanations: E0367, E0751.
+For more information about an error, try `rustc --explain E0367`.
diff --git a/tests/ui/static/issue-24446.stderr b/tests/ui/static/issue-24446.stderr
index 033caf07d8e..0e6e338c5ef 100644
--- a/tests/ui/static/issue-24446.stderr
+++ b/tests/ui/static/issue-24446.stderr
@@ -14,6 +14,7 @@ LL |     static foo: dyn Fn() -> u32 = || -> u32 {
    |                 ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `(dyn Fn() -> u32 + 'static)`
+   = note: statics and constants must have a statically known size
 
 error[E0308]: mismatched types
   --> $DIR/issue-24446.rs:2:35
diff --git a/tests/ui/statics/unsized_type2.stderr b/tests/ui/statics/unsized_type2.stderr
index ffbbe218c87..3f9b0879c16 100644
--- a/tests/ui/statics/unsized_type2.stderr
+++ b/tests/ui/statics/unsized_type2.stderr
@@ -10,6 +10,7 @@ note: required because it appears within the type `Foo`
    |
 LL | pub struct Foo {
    |            ^^^
+   = note: statics and constants must have a statically known size
 
 error[E0308]: mismatched types
   --> $DIR/unsized_type2.rs:14:45
diff --git a/tests/ui/stats/input-stats.stderr b/tests/ui/stats/input-stats.stderr
index 9b1568fa116..dbc9e7d254c 100644
--- a/tests/ui/stats/input-stats.stderr
+++ b/tests/ui/stats/input-stats.stderr
@@ -8,8 +8,8 @@ ast-stats-1 ExprField                 48 ( 0.7%)             1            48
 ast-stats-1 Attribute                 64 ( 1.0%)             2            32
 ast-stats-1 - DocComment                32 ( 0.5%)             1
 ast-stats-1 - Normal                    32 ( 0.5%)             1
-ast-stats-1 WherePredicate            64 ( 1.0%)             1            64
-ast-stats-1 - BoundPredicate            64 ( 1.0%)             1
+ast-stats-1 WherePredicate            72 ( 1.1%)             1            72
+ast-stats-1 - BoundPredicate            72 ( 1.1%)             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
@@ -37,14 +37,14 @@ ast-stats-1 Expr                     576 ( 8.6%)             8            72
 ast-stats-1 - Match                     72 ( 1.1%)             1
 ast-stats-1 - Path                      72 ( 1.1%)             1
 ast-stats-1 - Struct                    72 ( 1.1%)             1
-ast-stats-1 - Lit                      144 ( 2.2%)             2
+ast-stats-1 - Lit                      144 ( 2.1%)             2
 ast-stats-1 - Block                    216 ( 3.2%)             3
 ast-stats-1 PathSegment              744 (11.1%)            31            24
 ast-stats-1 Ty                       896 (13.4%)            14            64
 ast-stats-1 - Ptr                       64 ( 1.0%)             1
 ast-stats-1 - Ref                       64 ( 1.0%)             1
 ast-stats-1 - ImplicitSelf             128 ( 1.9%)             2
-ast-stats-1 - Path                     640 ( 9.6%)            10
+ast-stats-1 - Path                     640 ( 9.5%)            10
 ast-stats-1 Item                   1_224 (18.3%)             9           136
 ast-stats-1 - Enum                     136 ( 2.0%)             1
 ast-stats-1 - ForeignMod               136 ( 2.0%)             1
@@ -53,7 +53,7 @@ ast-stats-1 - Trait                    136 ( 2.0%)             1
 ast-stats-1 - Fn                       272 ( 4.1%)             2
 ast-stats-1 - Use                      408 ( 6.1%)             3
 ast-stats-1 ----------------------------------------------------------------
-ast-stats-1 Total                  6_696                   116
+ast-stats-1 Total                  6_704                   116
 ast-stats-1
 ast-stats-2 POST EXPANSION AST STATS
 ast-stats-2 Name                Accumulated Size         Count     Item Size
@@ -62,8 +62,8 @@ 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 ExprField                 48 ( 0.7%)             1            48
-ast-stats-2 WherePredicate            64 ( 0.9%)             1            64
-ast-stats-2 - BoundPredicate            64 ( 0.9%)             1
+ast-stats-2 WherePredicate            72 ( 1.0%)             1            72
+ast-stats-2 - BoundPredicate            72 ( 1.0%)             1
 ast-stats-2 Local                     80 ( 1.1%)             1            80
 ast-stats-2 ForeignItem               88 ( 1.2%)             1            88
 ast-stats-2 - Fn                        88 ( 1.2%)             1
@@ -104,16 +104,16 @@ ast-stats-2 - Ptr                       64 ( 0.9%)             1
 ast-stats-2 - Ref                       64 ( 0.9%)             1
 ast-stats-2 - ImplicitSelf             128 ( 1.7%)             2
 ast-stats-2 - Path                     640 ( 8.7%)            10
-ast-stats-2 Item                   1_496 (20.4%)            11           136
-ast-stats-2 - Enum                     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 - Trait                    136 ( 1.9%)             1
+ast-stats-2 Item                   1_496 (20.3%)            11           136
+ast-stats-2 - Enum                     136 ( 1.8%)             1
+ast-stats-2 - ExternCrate              136 ( 1.8%)             1
+ast-stats-2 - ForeignMod               136 ( 1.8%)             1
+ast-stats-2 - Impl                     136 ( 1.8%)             1
+ast-stats-2 - Trait                    136 ( 1.8%)             1
 ast-stats-2 - Fn                       272 ( 3.7%)             2
 ast-stats-2 - Use                      544 ( 7.4%)             4
 ast-stats-2 ----------------------------------------------------------------
-ast-stats-2 Total                  7_344                   127
+ast-stats-2 Total                  7_352                   127
 ast-stats-2
 hir-stats HIR STATS
 hir-stats Name                Accumulated Size         Count     Item Size
diff --git a/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.rs b/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.rs
index 71d90ddd935..ba99b03539c 100644
--- a/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.rs
+++ b/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.rs
@@ -1,5 +1,5 @@
 #![feature(default_field_values)]
-struct A<'a> { //~ ERROR lifetime parameter `'a` is never used
+struct A<'a> {
     x: Vec<A> = Vec::new(), //~ ERROR missing lifetime specifier
 }
 
diff --git a/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.stderr b/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.stderr
index 20b9afe80cd..7100efc695c 100644
--- a/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.stderr
+++ b/tests/ui/structs/default-field-values/do-not-ice-on-invalid-lifetime.stderr
@@ -9,15 +9,6 @@ help: consider using the `'a` lifetime
 LL |     x: Vec<A<'a>> = Vec::new(),
    |             ++++
 
-error[E0392]: lifetime parameter `'a` is never used
-  --> $DIR/do-not-ice-on-invalid-lifetime.rs:2:10
-   |
-LL | struct A<'a> {
-   |          ^^ unused lifetime parameter
-   |
-   = help: consider removing `'a`, referring to it in a field, or using a marker such as `PhantomData`
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0106, E0392.
-For more information about an error, try `rustc --explain E0106`.
+For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/structs/default-field-values/failures.rs b/tests/ui/structs/default-field-values/failures.rs
index 0ac071d91d6..1e94eecb4f8 100644
--- a/tests/ui/structs/default-field-values/failures.rs
+++ b/tests/ui/structs/default-field-values/failures.rs
@@ -17,9 +17,9 @@ pub struct Bar {
 
 #[derive(Default)]
 pub struct Qux<const C: i32> {
-    bar: S = Self::S, //~ ERROR generic `Self` types are currently not permitted in anonymous constants
+    bar: S = Self::S,
     baz: i32 = foo(),
-    bat: i32 = <Qux<{ C }> as T>::K, //~ ERROR generic parameters may not be used in const operations
+    bat: i32 = <Qux<{ C }> as T>::K,
     bay: i32 = C,
 }
 
diff --git a/tests/ui/structs/default-field-values/failures.stderr b/tests/ui/structs/default-field-values/failures.stderr
index 65ec100fe2e..50553816462 100644
--- a/tests/ui/structs/default-field-values/failures.stderr
+++ b/tests/ui/structs/default-field-values/failures.stderr
@@ -6,27 +6,12 @@ LL |     Variant {}
    |
    = help: consider a manual implementation of `Default`
 
-error: generic parameters may not be used in const operations
-  --> $DIR/failures.rs:22:23
-   |
-LL |     bat: i32 = <Qux<{ C }> as T>::K,
-   |                       ^ cannot perform const operation using `C`
-   |
-   = help: const parameters may only be used as standalone arguments, i.e. `C`
-   = help: add `#![feature(generic_const_exprs)]` to allow generic const expressions
-
 error: default fields are not supported in tuple structs
   --> $DIR/failures.rs:26:22
    |
 LL | pub struct Rak(i32 = 42);
    |                      ^^ default fields are only supported on structs
 
-error: generic `Self` types are currently not permitted in anonymous constants
-  --> $DIR/failures.rs:20:14
-   |
-LL |     bar: S = Self::S,
-   |              ^^^^
-
 error[E0277]: the trait bound `S: Default` is not satisfied
   --> $DIR/failures.rs:14:5
    |
@@ -112,7 +97,7 @@ LL -     let _ = Rak(.., 0);
 LL +     let _ = Rak(0);
    |
 
-error: aborting due to 9 previous errors
+error: aborting due to 7 previous errors
 
 Some errors have detailed explanations: E0061, E0277, E0308.
 For more information about an error, try `rustc --explain E0061`.
diff --git a/tests/ui/structs/default-field-values/field-references-param.rs b/tests/ui/structs/default-field-values/field-references-param.rs
new file mode 100644
index 00000000000..ecee37edd42
--- /dev/null
+++ b/tests/ui/structs/default-field-values/field-references-param.rs
@@ -0,0 +1,29 @@
+//@ build-pass
+
+#![feature(default_field_values)]
+
+struct W<const X: usize>;
+
+impl<const X: usize> W<X> {
+    const fn new() -> Self { W }
+}
+
+struct Z<const X: usize> {
+    // No inference.
+    one: W<X> = W::<X>::new(),
+
+    // Inference works too.
+    two: W<X> = W::new(),
+
+    // An anon const that is too generic before substitution.
+    too_generic: usize = X + 1,
+}
+
+fn use_generically<const X: usize>() {
+    let x: Z<X> = Z { .. };
+}
+
+fn main() {
+    let x: Z<0> = Z { .. };
+    use_generically::<0>();
+}
diff --git a/tests/ui/structs/default-field-values/post-mono.direct.stderr b/tests/ui/structs/default-field-values/post-mono.direct.stderr
new file mode 100644
index 00000000000..cdd80620c48
--- /dev/null
+++ b/tests/ui/structs/default-field-values/post-mono.direct.stderr
@@ -0,0 +1,23 @@
+error[E0080]: evaluation of `Z::<1>::post_mono::{constant#0}` failed
+  --> $DIR/post-mono.rs:7:24
+   |
+LL |     post_mono: usize = X / 0,
+   |                        ^^^^^ attempt to divide `1_usize` by zero
+
+note: erroneous constant encountered
+  --> $DIR/post-mono.rs:17:19
+   |
+LL |     let x: Z<1> = Z { .. };
+   |                   ^^^^^^^^
+
+note: erroneous constant encountered
+  --> $DIR/post-mono.rs:17:19
+   |
+LL |     let x: Z<1> = Z { .. };
+   |                   ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/structs/default-field-values/post-mono.indirect.stderr b/tests/ui/structs/default-field-values/post-mono.indirect.stderr
new file mode 100644
index 00000000000..56c27a6e5dc
--- /dev/null
+++ b/tests/ui/structs/default-field-values/post-mono.indirect.stderr
@@ -0,0 +1,29 @@
+error[E0080]: evaluation of `Z::<1>::post_mono::{constant#0}` failed
+  --> $DIR/post-mono.rs:7:24
+   |
+LL |     post_mono: usize = X / 0,
+   |                        ^^^^^ attempt to divide `1_usize` by zero
+
+note: erroneous constant encountered
+  --> $DIR/post-mono.rs:12:19
+   |
+LL |     let x: Z<X> = Z { .. };
+   |                   ^^^^^^^^
+
+note: erroneous constant encountered
+  --> $DIR/post-mono.rs:12:19
+   |
+LL |     let x: Z<X> = Z { .. };
+   |                   ^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+note: the above error was encountered while instantiating `fn indirect::<1>`
+  --> $DIR/post-mono.rs:22:5
+   |
+LL |     indirect::<1>();
+   |     ^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/structs/default-field-values/post-mono.rs b/tests/ui/structs/default-field-values/post-mono.rs
new file mode 100644
index 00000000000..4de31f6e2fb
--- /dev/null
+++ b/tests/ui/structs/default-field-values/post-mono.rs
@@ -0,0 +1,23 @@
+//@ build-fail
+//@ revisions: direct indirect
+
+#![feature(default_field_values)]
+
+struct Z<const X: usize> {
+    post_mono: usize = X / 0,
+    //~^ ERROR evaluation of `Z::<1>::post_mono::{constant#0}` failed
+}
+
+fn indirect<const X: usize>() {
+    let x: Z<X> = Z { .. };
+}
+
+#[cfg(direct)]
+fn main() {
+    let x: Z<1> = Z { .. };
+}
+
+#[cfg(indirect)]
+fn main() {
+    indirect::<1>();
+}
diff --git a/tests/ui/structs/ident-from-macro-expansion.rs b/tests/ui/structs/ident-from-macro-expansion.rs
new file mode 100644
index 00000000000..56d31a42561
--- /dev/null
+++ b/tests/ui/structs/ident-from-macro-expansion.rs
@@ -0,0 +1,19 @@
+struct Foo {
+    inner: Inner,
+}
+
+struct Inner {
+    y: i32,
+}
+
+macro_rules! access {
+    ($expr:expr, $ident:ident) => {
+        $expr.$ident
+    }
+}
+
+fn main() {
+    let k = Foo { inner: Inner { y: 0 } };
+    access!(k, y);
+    //~^ ERROR no field `y` on type `Foo`
+}
diff --git a/tests/ui/structs/ident-from-macro-expansion.stderr b/tests/ui/structs/ident-from-macro-expansion.stderr
new file mode 100644
index 00000000000..be2ab7c2e99
--- /dev/null
+++ b/tests/ui/structs/ident-from-macro-expansion.stderr
@@ -0,0 +1,14 @@
+error[E0609]: no field `y` on type `Foo`
+  --> $DIR/ident-from-macro-expansion.rs:17:16
+   |
+LL |         $expr.$ident
+   |               ------ due to this macro variable
+...
+LL |     access!(k, y);
+   |                ^ unknown field
+   |
+   = note: available field is: `inner`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0609`.
diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs
index daec66709b6..443a7e3835e 100644
--- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs
+++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.rs
@@ -18,7 +18,6 @@ mod elided {
     // But that lifetime does not participate in resolution.
     async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
     //~^ ERROR missing lifetime specifier
-    //~| ERROR lifetime may not live long enough
 }
 
 mod underscore {
@@ -37,7 +36,6 @@ mod underscore {
     // But that lifetime does not participate in resolution.
     async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
     //~^ ERROR missing lifetime specifier
-    //~| ERROR lifetime may not live long enough
 }
 
 mod alone_in_path {
diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
index 204209179ad..24013c85c87 100644
--- a/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
+++ b/tests/ui/suggestions/impl-trait-missing-lifetime-gated.stderr
@@ -41,7 +41,7 @@ LL +     async fn i(mut x: impl Iterator<Item = &()>) -> Option<()> { x.next() }
    |
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:28:58
+  --> $DIR/impl-trait-missing-lifetime-gated.rs:27:58
    |
 LL |     fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
    |                                                          ^^ expected named lifetime parameter
@@ -64,7 +64,7 @@ LL +     fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() }
    |
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:38:64
+  --> $DIR/impl-trait-missing-lifetime-gated.rs:37:64
    |
 LL |     async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
    |                                                                ^^ expected named lifetime parameter
@@ -87,7 +87,7 @@ LL +     async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next(
    |
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:49:37
+  --> $DIR/impl-trait-missing-lifetime-gated.rs:47:37
    |
 LL |     fn g(mut x: impl Foo) -> Option<&()> { x.next() }
    |                                     ^ expected named lifetime parameter
@@ -108,7 +108,7 @@ LL +     fn g(mut x: impl Foo) -> Option<()> { x.next() }
    |
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:60:41
+  --> $DIR/impl-trait-missing-lifetime-gated.rs:58:41
    |
 LL |     fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
    |                                         ^ expected named lifetime parameter
@@ -129,7 +129,7 @@ LL +     fn g(mut x: impl Foo<()>) -> Option<()> { x.next() }
    |
 
 warning: elided lifetime has a name
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:66:57
+  --> $DIR/impl-trait-missing-lifetime-gated.rs:64:57
    |
 LL | fn resolved_anonymous<'a, T: 'a>(f: impl Fn(&'a str) -> &T) {
    |                       -- lifetime `'a` declared here    ^ this elided lifetime gets resolved as `'a`
@@ -162,16 +162,8 @@ help: consider introducing a named lifetime parameter
 LL |     fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&()> { x.next() }
    |         ++++                              ++
 
-error: lifetime may not live long enough
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:19:67
-   |
-LL |     async fn i(mut x: impl Iterator<Item = &()>) -> Option<&()> { x.next() }
-   |     -----------------------------------------------------------   ^^^^^^^^ returning this value requires that `'1` must outlive `'static`
-   |     |
-   |     return type `impl Future<Output = Option<&'static ()>>` contains a lifetime `'1`
-
 error[E0658]: anonymous lifetimes in `impl Trait` are unstable
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:25:35
+  --> $DIR/impl-trait-missing-lifetime-gated.rs:24:35
    |
 LL |     fn f(_: impl Iterator<Item = &'_ ()>) {}
    |                                   ^^ expected named lifetime parameter
@@ -185,7 +177,7 @@ LL +     fn f<'a>(_: impl Iterator<Item = &'a ()>) {}
    |
 
 error[E0658]: anonymous lifetimes in `impl Trait` are unstable
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:28:39
+  --> $DIR/impl-trait-missing-lifetime-gated.rs:27:39
    |
 LL |     fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
    |                                       ^^ expected named lifetime parameter
@@ -198,16 +190,8 @@ LL -     fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next()
 LL +     fn g<'a>(mut x: impl Iterator<Item = &'a ()>) -> Option<&'_ ()> { x.next() }
    |
 
-error: lifetime may not live long enough
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:38:73
-   |
-LL |     async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
-   |     -----------------------------------------------------------------   ^^^^^^^^ returning this value requires that `'1` must outlive `'static`
-   |     |
-   |     return type `impl Future<Output = Option<&'static ()>>` contains a lifetime `'1`
-
 error[E0658]: anonymous lifetimes in `impl Trait` are unstable
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:46:18
+  --> $DIR/impl-trait-missing-lifetime-gated.rs:44:18
    |
 LL |     fn f(_: impl Foo) {}
    |                  ^^^ expected named lifetime parameter
@@ -220,7 +204,7 @@ LL |     fn f<'a>(_: impl Foo<'a>) {}
    |         ++++            ++++
 
 error[E0658]: anonymous lifetimes in `impl Trait` are unstable
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:49:22
+  --> $DIR/impl-trait-missing-lifetime-gated.rs:47:22
    |
 LL |     fn g(mut x: impl Foo) -> Option<&()> { x.next() }
    |                      ^^^ expected named lifetime parameter
@@ -233,7 +217,7 @@ LL |     fn g<'a>(mut x: impl Foo<'a>) -> Option<&()> { x.next() }
    |         ++++                ++++
 
 error[E0658]: anonymous lifetimes in `impl Trait` are unstable
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:57:22
+  --> $DIR/impl-trait-missing-lifetime-gated.rs:55:22
    |
 LL |     fn f(_: impl Foo<()>) {}
    |                      ^ expected named lifetime parameter
@@ -246,7 +230,7 @@ LL |     fn f<'a>(_: impl Foo<'a, ()>) {}
    |         ++++             +++
 
 error[E0658]: anonymous lifetimes in `impl Trait` are unstable
-  --> $DIR/impl-trait-missing-lifetime-gated.rs:60:26
+  --> $DIR/impl-trait-missing-lifetime-gated.rs:58:26
    |
 LL |     fn g(mut x: impl Foo<()>) -> Option<&()> { x.next() }
    |                          ^ expected named lifetime parameter
@@ -258,7 +242,7 @@ help: consider introducing a named lifetime parameter
 LL |     fn g<'a>(mut x: impl Foo<'a, ()>) -> Option<&()> { x.next() }
    |         ++++                 +++
 
-error: aborting due to 16 previous errors; 1 warning emitted
+error: aborting due to 14 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0106, E0658.
 For more information about an error, try `rustc --explain E0106`.
diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime.rs b/tests/ui/suggestions/impl-trait-missing-lifetime.rs
index 12dc0e8216b..27f03431d09 100644
--- a/tests/ui/suggestions/impl-trait-missing-lifetime.rs
+++ b/tests/ui/suggestions/impl-trait-missing-lifetime.rs
@@ -8,7 +8,6 @@ fn f(_: impl Iterator<Item = &'_ ()>) {}
 // But that lifetime does not participate in resolution.
 fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
 //~^ ERROR missing lifetime specifier
-//~| ERROR lifetime may not live long enough
 
 // This is understood as `fn foo<'_1>(_: impl Iterator<Item = &'_1 ()>) {}`.
 async fn h(_: impl Iterator<Item = &'_ ()>) {}
@@ -16,6 +15,5 @@ async fn h(_: impl Iterator<Item = &'_ ()>) {}
 // But that lifetime does not participate in resolution.
 async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
 //~^ ERROR missing lifetime specifier
-//~| ERROR lifetime may not live long enough
 
 fn main() {}
diff --git a/tests/ui/suggestions/impl-trait-missing-lifetime.stderr b/tests/ui/suggestions/impl-trait-missing-lifetime.stderr
index dfbc883680b..c09c575c147 100644
--- a/tests/ui/suggestions/impl-trait-missing-lifetime.stderr
+++ b/tests/ui/suggestions/impl-trait-missing-lifetime.stderr
@@ -22,7 +22,7 @@ LL + fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() }
    |
 
 error[E0106]: missing lifetime specifier
-  --> $DIR/impl-trait-missing-lifetime.rs:17:60
+  --> $DIR/impl-trait-missing-lifetime.rs:16:60
    |
 LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
    |                                                            ^^ expected named lifetime parameter
@@ -44,20 +44,6 @@ LL - async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next(
 LL + async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<()> { x.next() }
    |
 
-error: lifetime may not live long enough
-  --> $DIR/impl-trait-missing-lifetime.rs:17:69
-   |
-LL | async fn i(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
-   | -----------------------------------------------------------------   ^^^^^^^^ returning this value requires that `'1` must outlive `'static`
-   | |
-   | return type `impl Future<Output = Option<&'static ()>>` contains a lifetime `'1`
-
-error: lifetime may not live long enough
-  --> $DIR/impl-trait-missing-lifetime.rs:9:63
-   |
-LL | fn g(mut x: impl Iterator<Item = &'_ ()>) -> Option<&'_ ()> { x.next() }
-   |      ----- has type `x`                                       ^^^^^^^^ returning this value requires that `'1` must outlive `'static`
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/suggestions/missing-lt-for-hrtb.rs b/tests/ui/suggestions/missing-lt-for-hrtb.rs
index a48c5665d67..04ea3d831c9 100644
--- a/tests/ui/suggestions/missing-lt-for-hrtb.rs
+++ b/tests/ui/suggestions/missing-lt-for-hrtb.rs
@@ -8,8 +8,6 @@ fn main() {
     let x = S(&|x| {
         println!("hi");
         x
-        //~^ ERROR lifetime may not live long enough
-        //~| ERROR lifetime may not live long enough
     });
     x.0(&X(&()));
 }
diff --git a/tests/ui/suggestions/missing-lt-for-hrtb.stderr b/tests/ui/suggestions/missing-lt-for-hrtb.stderr
index e8c536ac47d..fa515644431 100644
--- a/tests/ui/suggestions/missing-lt-for-hrtb.stderr
+++ b/tests/ui/suggestions/missing-lt-for-hrtb.stderr
@@ -31,28 +31,6 @@ help: consider using one of the available lifetimes here
 LL | struct V<'a>(&'a dyn for<'b> Fn(&X) -> &'lifetime X<'lifetime>);
    |                                         +++++++++  +++++++++++
 
-error: lifetime may not live long enough
-  --> $DIR/missing-lt-for-hrtb.rs:10:9
-   |
-LL |     let x = S(&|x| {
-   |                 -- return type of closure is &'2 X<'_>
-   |                 |
-   |                 has type `&'1 X<'_>`
-LL |         println!("hi");
-LL |         x
-   |         ^ returning this value requires that `'1` must outlive `'2`
-
-error: lifetime may not live long enough
-  --> $DIR/missing-lt-for-hrtb.rs:10:9
-   |
-LL |     let x = S(&|x| {
-   |                 -- return type of closure is &X<'4>
-   |                 |
-   |                 has type `&X<'3>`
-LL |         println!("hi");
-LL |         x
-   |         ^ returning this value requires that `'3` must outlive `'4`
-
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0106`.
diff --git a/tests/ui/target_modifiers/auxiliary/default_reg_struct_return.rs b/tests/ui/target_modifiers/auxiliary/default_reg_struct_return.rs
index 355e7c56e94..2bbdc839211 100644
--- a/tests/ui/target_modifiers/auxiliary/default_reg_struct_return.rs
+++ b/tests/ui/target_modifiers/auxiliary/default_reg_struct_return.rs
@@ -1,20 +1,7 @@
-//@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort
-// Auxiliary build problems with aarch64-apple:
-// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
-// Auxiliary build problems with i686-mingw: linker `cc` not found
-//@ only-x86
-//@ ignore-windows
-//@ ignore-apple
+//@ no-prefer-dynamic
+//@ compile-flags: --target i686-unknown-linux-gnu
 //@ needs-llvm-components: x86
+
+#![feature(no_core)]
 #![crate_type = "rlib"]
 #![no_core]
-#![feature(no_core, lang_items, repr_simd)]
-
-#[lang = "sized"]
-trait Sized {}
-#[lang = "copy"]
-trait Copy {}
-
-pub fn somefun() {}
-
-pub struct S;
diff --git a/tests/ui/target_modifiers/auxiliary/wrong_regparm.rs b/tests/ui/target_modifiers/auxiliary/wrong_regparm.rs
index 2e16f1ee747..267292faecd 100644
--- a/tests/ui/target_modifiers/auxiliary/wrong_regparm.rs
+++ b/tests/ui/target_modifiers/auxiliary/wrong_regparm.rs
@@ -1,20 +1,7 @@
-//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2 -Cpanic=abort
-// Auxiliary build problems with aarch64-apple:
-// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
-// Auxiliary build problems with i686-mingw: linker `cc` not found
-//@ only-x86
-//@ ignore-windows
-//@ ignore-apple
+//@ no-prefer-dynamic
+//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2
 //@ needs-llvm-components: x86
+
+#![feature(no_core)]
 #![crate_type = "rlib"]
 #![no_core]
-#![feature(no_core, lang_items, repr_simd)]
-
-#[lang = "sized"]
-trait Sized {}
-#[lang = "copy"]
-trait Copy {}
-
-pub fn somefun() {}
-
-pub struct S;
diff --git a/tests/ui/target_modifiers/auxiliary/wrong_regparm_and_ret.rs b/tests/ui/target_modifiers/auxiliary/wrong_regparm_and_ret.rs
index 39c6be9d589..82ee3e71d16 100644
--- a/tests/ui/target_modifiers/auxiliary/wrong_regparm_and_ret.rs
+++ b/tests/ui/target_modifiers/auxiliary/wrong_regparm_and_ret.rs
@@ -1,20 +1,7 @@
-//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2 -Zreg-struct-return=true -Cpanic=abort
-// Auxiliary build problems with aarch64-apple:
-// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
-// Auxiliary build problems with i686-mingw: linker `cc` not found
-//@ only-x86
-//@ ignore-windows
-//@ ignore-apple
+//@ no-prefer-dynamic
+//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=2 -Zreg-struct-return=true
 //@ needs-llvm-components: x86
+
+#![feature(no_core)]
 #![crate_type = "rlib"]
 #![no_core]
-#![feature(no_core, lang_items, repr_simd)]
-
-#[lang = "sized"]
-trait Sized {}
-#[lang = "copy"]
-trait Copy {}
-
-pub fn somefun() {}
-
-pub struct S;
diff --git a/tests/ui/target_modifiers/defaults_check.error.stderr b/tests/ui/target_modifiers/defaults_check.error.stderr
index c545dd71069..4833fe90677 100644
--- a/tests/ui/target_modifiers/defaults_check.error.stderr
+++ b/tests/ui/target_modifiers/defaults_check.error.stderr
@@ -1,7 +1,7 @@
 error: mixing `-Zreg-struct-return` will cause an ABI mismatch in crate `defaults_check`
-  --> $DIR/defaults_check.rs:20:1
+  --> $DIR/defaults_check.rs:15:1
    |
-LL | #![crate_type = "rlib"]
+LL | #![feature(no_core)]
    | ^
    |
    = help: the `-Zreg-struct-return` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
diff --git a/tests/ui/target_modifiers/defaults_check.rs b/tests/ui/target_modifiers/defaults_check.rs
index b8f4848d3a4..de72acd32bc 100644
--- a/tests/ui/target_modifiers/defaults_check.rs
+++ b/tests/ui/target_modifiers/defaults_check.rs
@@ -1,27 +1,20 @@
 // Tests that default unspecified target modifier value in dependency crate is ok linked
 // with the same value, explicitly specified
-//@ aux-crate:default_reg_struct_return=default_reg_struct_return.rs
+
+//@ aux-build:default_reg_struct_return.rs
 //@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort
-//@ revisions:error ok ok_explicit
+//@ needs-llvm-components: x86
+
+//@ revisions: ok ok_explicit error
 //@[ok] compile-flags:
 //@[ok_explicit] compile-flags: -Zreg-struct-return=false
 //@[error] compile-flags: -Zreg-struct-return=true
+//@[ok] check-pass
+//@[ok_explicit] check-pass
 
-// Auxiliary build problems with aarch64-apple:
-// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
-// Auxiliary build problems with i686-mingw: linker `cc` not found
-//@ only-x86
-//@ ignore-windows
-//@ ignore-apple
-//@ needs-llvm-components: x86
-//@[ok] build-pass
-//@[ok_explicit] build-pass
-
-#![crate_type = "rlib"]
+#![feature(no_core)]
 //[error]~^ ERROR mixing `-Zreg-struct-return` will cause an ABI mismatch in crate `defaults_check`
+#![crate_type = "rlib"]
 #![no_core]
-#![feature(no_core, lang_items, repr_simd)]
 
-fn foo() {
-    default_reg_struct_return::somefun();
-}
+extern crate default_reg_struct_return;
diff --git a/tests/ui/target_modifiers/incompatible_regparm.error_generated.stderr b/tests/ui/target_modifiers/incompatible_regparm.error_generated.stderr
index 692fc7a4e3f..81015694d05 100644
--- a/tests/ui/target_modifiers/incompatible_regparm.error_generated.stderr
+++ b/tests/ui/target_modifiers/incompatible_regparm.error_generated.stderr
@@ -1,7 +1,7 @@
 error: mixing `-Zregparm` will cause an ABI mismatch in crate `incompatible_regparm`
-  --> $DIR/incompatible_regparm.rs:16:1
+  --> $DIR/incompatible_regparm.rs:11:1
    |
-LL | #![crate_type = "rlib"]
+LL | #![feature(no_core)]
    | ^
    |
    = help: the `-Zregparm` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely
diff --git a/tests/ui/target_modifiers/incompatible_regparm.rs b/tests/ui/target_modifiers/incompatible_regparm.rs
index e866c5aa891..befe573b276 100644
--- a/tests/ui/target_modifiers/incompatible_regparm.rs
+++ b/tests/ui/target_modifiers/incompatible_regparm.rs
@@ -1,23 +1,16 @@
-//@ aux-crate:wrong_regparm=wrong_regparm.rs
-//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=1 -Cpanic=abort
-// Auxiliary build problems with aarch64-apple:
-// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
-// Auxiliary build problems with i686-mingw: linker `cc` not found
-//@ only-x86
-//@ ignore-windows
-//@ ignore-apple
+//@ aux-build:wrong_regparm.rs
+//@ compile-flags: --target i686-unknown-linux-gnu -Zregparm=1
 //@ needs-llvm-components: x86
-//@ revisions:error_generated allow_regparm_mismatch allow_no_value
 
+//@ revisions:allow_regparm_mismatch allow_no_value error_generated
 //@[allow_regparm_mismatch] compile-flags: -Cunsafe-allow-abi-mismatch=regparm
-//@[allow_regparm_mismatch] build-pass
 //@[allow_no_value] compile-flags: -Cunsafe-allow-abi-mismatch
+//@[error_generated] compile-flags:
+//@[allow_regparm_mismatch] check-pass
 
-#![crate_type = "rlib"]
+#![feature(no_core)]
 //[error_generated]~^ ERROR mixing `-Zregparm` will cause an ABI mismatch in crate `incompatible_regparm`
+#![crate_type = "rlib"]
 #![no_core]
-#![feature(no_core, lang_items, repr_simd)]
 
-fn foo() {
-    wrong_regparm::somefun();
-}
+extern crate wrong_regparm;
diff --git a/tests/ui/target_modifiers/two_flags.rs b/tests/ui/target_modifiers/two_flags.rs
index ca17117a267..d5b5a923ca0 100644
--- a/tests/ui/target_modifiers/two_flags.rs
+++ b/tests/ui/target_modifiers/two_flags.rs
@@ -1,23 +1,15 @@
-//@ aux-crate:wrong_regparm_and_ret=wrong_regparm_and_ret.rs
-//@ compile-flags: --target i686-unknown-linux-gnu -Cpanic=abort
-// Auxiliary build problems with aarch64-apple:
-// Shared library linking cc seems to convert "-m32" flag into -arch armv4t
-// Auxiliary build problems with i686-mingw: linker `cc` not found
-//@ only-x86
-//@ ignore-windows
-//@ ignore-apple
+//@ aux-build:wrong_regparm_and_ret.rs
+//@ compile-flags: --target i686-unknown-linux-gnu
 //@ needs-llvm-components: x86
-//@ revisions:two_allowed unknown_allowed
 
+//@ revisions:two_allowed unknown_allowed
 //@[two_allowed] compile-flags: -Cunsafe-allow-abi-mismatch=regparm,reg-struct-return
-//@[two_allowed] build-pass
 //@[unknown_allowed] compile-flags: -Cunsafe-allow-abi-mismatch=unknown_flag -Zregparm=2 -Zreg-struct-return=true
+//@[two_allowed] check-pass
 
-#![crate_type = "rlib"]
+#![feature(no_core)]
 //[unknown_allowed]~^ ERROR unknown target modifier `unknown_flag`, requested by `-Cunsafe-allow-abi-mismatch=unknown_flag`
+#![crate_type = "rlib"]
 #![no_core]
-#![feature(no_core, lang_items, repr_simd)]
 
-fn foo() {
-    wrong_regparm_and_ret::somefun();
-}
+extern crate wrong_regparm_and_ret;
diff --git a/tests/ui/target_modifiers/two_flags.unknown_allowed.stderr b/tests/ui/target_modifiers/two_flags.unknown_allowed.stderr
index c8040c6e389..248bde452f2 100644
--- a/tests/ui/target_modifiers/two_flags.unknown_allowed.stderr
+++ b/tests/ui/target_modifiers/two_flags.unknown_allowed.stderr
@@ -1,7 +1,7 @@
 error: unknown target modifier `unknown_flag`, requested by `-Cunsafe-allow-abi-mismatch=unknown_flag`
-  --> $DIR/two_flags.rs:16:1
+  --> $DIR/two_flags.rs:10:1
    |
-LL | #![crate_type = "rlib"]
+LL | #![feature(no_core)]
    | ^
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr
index 76e015a7238..4609e02716f 100644
--- a/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr
+++ b/tests/ui/trait-bounds/ice-unsized-tuple-const-issue-121443.stderr
@@ -11,6 +11,7 @@ LL | const TEST: Fn = some_fn;
    |             ^^ doesn't have a size known at compile-time
    |
    = help: the trait `Sized` is not implemented for `(dyn FnOnce() -> u8 + 'static)`
+   = note: statics and constants must have a statically known size
 
 error[E0277]: the size for values of type `(dyn FnOnce() -> u8 + 'static)` cannot be known at compilation time
   --> $DIR/ice-unsized-tuple-const-issue-121443.rs:11:14
diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs
new file mode 100644
index 00000000000..cd675a5efd1
--- /dev/null
+++ b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.rs
@@ -0,0 +1,22 @@
+#![feature(auto_traits, negative_impls)]
+
+auto trait Foo {}
+
+struct AdditionalLt<'a, T>(&'a (), T);
+impl<'a, T: 'a> !Foo for AdditionalLt<'a, T> {}
+//~^ ERROR `!Foo` impl requires `T: 'a` but the struct it is implemented for does not
+
+struct AdditionalBound<T>(T);
+trait Bound {}
+impl<T: Bound> !Foo for AdditionalBound<T> {}
+//~^ ERROR `!Foo` impl requires `T: Bound` but the struct it is implemented for does not
+
+struct TwoParam<T, U>(T, U);
+impl<T> !Foo for TwoParam<T, T> {}
+//~^ ERROR `!Foo` impls cannot be specialized
+
+struct ConcreteParam<T>(T);
+impl !Foo for ConcreteParam<i32> {}
+//~^ ERROR `!Foo` impls cannot be specialized
+
+fn main() {}
diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr
new file mode 100644
index 00000000000..ef783e90155
--- /dev/null
+++ b/tests/ui/traits/negative-impls/negated-auto-traits-validity-error.stderr
@@ -0,0 +1,54 @@
+error[E0367]: `!Foo` impl requires `T: 'a` but the struct it is implemented for does not
+  --> $DIR/negated-auto-traits-validity-error.rs:6:13
+   |
+LL | impl<'a, T: 'a> !Foo for AdditionalLt<'a, T> {}
+   |             ^^
+   |
+note: the implementor must specify the same requirement
+  --> $DIR/negated-auto-traits-validity-error.rs:5:1
+   |
+LL | struct AdditionalLt<'a, T>(&'a (), T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0367]: `!Foo` impl requires `T: Bound` but the struct it is implemented for does not
+  --> $DIR/negated-auto-traits-validity-error.rs:11:9
+   |
+LL | impl<T: Bound> !Foo for AdditionalBound<T> {}
+   |         ^^^^^
+   |
+note: the implementor must specify the same requirement
+  --> $DIR/negated-auto-traits-validity-error.rs:9:1
+   |
+LL | struct AdditionalBound<T>(T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0366]: `!Foo` impls cannot be specialized
+  --> $DIR/negated-auto-traits-validity-error.rs:15:1
+   |
+LL | impl<T> !Foo for TwoParam<T, T> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `T` is mentioned multiple times
+note: use the same sequence of generic lifetime, type and const parameters as the struct definition
+  --> $DIR/negated-auto-traits-validity-error.rs:14:1
+   |
+LL | struct TwoParam<T, U>(T, U);
+   | ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0366]: `!Foo` impls cannot be specialized
+  --> $DIR/negated-auto-traits-validity-error.rs:19:1
+   |
+LL | impl !Foo for ConcreteParam<i32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `i32` is not a generic parameter
+note: use the same sequence of generic lifetime, type and const parameters as the struct definition
+  --> $DIR/negated-auto-traits-validity-error.rs:18:1
+   |
+LL | struct ConcreteParam<T>(T);
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 4 previous errors
+
+Some errors have detailed explanations: E0366, E0367.
+For more information about an error, try `rustc --explain E0366`.
diff --git a/tests/ui/traits/negative-impls/negated-auto-traits-validity.rs b/tests/ui/traits/negative-impls/negated-auto-traits-validity.rs
new file mode 100644
index 00000000000..76996b5593e
--- /dev/null
+++ b/tests/ui/traits/negative-impls/negated-auto-traits-validity.rs
@@ -0,0 +1,22 @@
+//@ check-pass
+
+#![feature(auto_traits, negative_impls)]
+
+auto trait Foo {}
+auto trait Bar {}
+
+struct NeedsOutlives<'a, T>(&'a T);
+
+impl<'a, T: 'a> !Foo for NeedsOutlives<'a, T> {}
+
+// Leaving out the lifetime bound
+impl<'a, T> !Bar for NeedsOutlives<'a, T> {}
+
+struct NeedsSend<T: Send>(T);
+
+impl<T: Send> !Foo for NeedsSend<T> {}
+
+// Leaving off the trait bound
+impl<T> !Bar for NeedsSend<T> {}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/unsize-good.rs b/tests/ui/traits/next-solver/unsize-good.rs
index 4456e4f2188..f3d8b08e693 100644
--- a/tests/ui/traits/next-solver/unsize-good.rs
+++ b/tests/ui/traits/next-solver/unsize-good.rs
@@ -1,8 +1,6 @@
 //@ compile-flags: -Znext-solver
 //@ check-pass
 
-#![feature(unsized_tuple_coercion)]
-
 trait Foo {}
 
 impl Foo for i32 {}
@@ -15,10 +13,6 @@ fn main() {
     let y = [1, 2, 3];
     let _: &[i32] = &y;
 
-    // Tuple unsizing
-    let hi = (1i32,);
-    let _: &(dyn Foo,) = &hi;
-
     // Dropping auto traits
     let a: &(dyn Foo + Send) = &1;
     let _: &dyn Foo = a;
diff --git a/tests/ui/traits/on_unimplemented_long_types.rs b/tests/ui/traits/on_unimplemented_long_types.rs
index c652b71e51a..d6c3e8ef75f 100644
--- a/tests/ui/traits/on_unimplemented_long_types.rs
+++ b/tests/ui/traits/on_unimplemented_long_types.rs
@@ -1,6 +1,4 @@
 //@ compile-flags: --diagnostic-width=60 -Z write-long-types-to-disk=yes
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type-\d+.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type-hash.txt'"
 
 pub fn foo() -> impl std::fmt::Display {
     //~^ ERROR doesn't implement `std::fmt::Display`
diff --git a/tests/ui/traits/on_unimplemented_long_types.stderr b/tests/ui/traits/on_unimplemented_long_types.stderr
index 2705d7c501e..1628466e081 100644
--- a/tests/ui/traits/on_unimplemented_long_types.stderr
+++ b/tests/ui/traits/on_unimplemented_long_types.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `Option<Option<Option<...>>>` doesn't implement `std::fmt::Display`
-  --> $DIR/on_unimplemented_long_types.rs:5:17
+  --> $DIR/on_unimplemented_long_types.rs:3:17
    |
 LL |   pub fn foo() -> impl std::fmt::Display {
    |                   ^^^^^^^^^^^^^^^^^^^^^^ `Option<Option<Option<...>>>` cannot be formatted with the default formatter
@@ -15,7 +15,7 @@ LL | |     )))))))))))
    |
    = help: the trait `std::fmt::Display` is not implemented for `Option<Option<Option<...>>>`
    = note: in format strings you may be able to use `{:?}` (or {:#?} for pretty-print) instead
-   = note: the full name for the type has been written to '$TEST_BUILD_DIR/$FILE.long-type-hash.txt'
+   = note: the full name for the type has been written to '$TEST_BUILD_DIR/on_unimplemented_long_types.long-type-$LONG_TYPE_HASH.txt'
    = note: consider using `--verbose` to print the full type name to the console
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/traits/trait-upcasting/dyn-to-dyn-star.rs b/tests/ui/traits/trait-upcasting/dyn-to-dyn-star.rs
new file mode 100644
index 00000000000..5936c93efad
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/dyn-to-dyn-star.rs
@@ -0,0 +1,19 @@
+// While somewhat nonsensical, this is a cast from a wide pointer to a thin pointer.
+// Thus, we don't need to check an unsize goal here; there isn't any vtable casting
+// happening at all.
+
+// Regression test for <https://github.com/rust-lang/rust/issues/137579>.
+
+//@ check-pass
+
+#![allow(incomplete_features)]
+#![feature(dyn_star)]
+
+trait Foo {}
+trait Bar {}
+
+fn cast(x: *const dyn Foo) {
+    x as *const dyn* Bar;
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr
index b7c9c131c7d..c9af4bda572 100644
--- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check3.stderr
@@ -28,7 +28,7 @@ error[E0310]: the parameter type `A` may not live long enough
   --> $DIR/implied_lifetime_wf_check3.rs:52:5
    |
 LL |     test_type_param::assert_static::<A>()
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |     |
    |     the parameter type `A` must be valid for the static lifetime...
    |     ...so that the type `A` will meet its required lifetime bounds
diff --git a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr
index f23b978d0b6..060d68eb632 100644
--- a/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr
+++ b/tests/ui/type-alias-impl-trait/implied_lifetime_wf_check4_static.stderr
@@ -21,7 +21,7 @@ error[E0310]: the parameter type `A` may not live long enough
   --> $DIR/implied_lifetime_wf_check4_static.rs:17:5
    |
 LL |     assert_static::<A>()
-   |     ^^^^^^^^^^^^^^^^^^
+   |     ^^^^^^^^^^^^^^^^^^^^
    |     |
    |     the parameter type `A` must be valid for the static lifetime...
    |     ...so that the type `A` will meet its required lifetime bounds
diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.rs b/tests/ui/type-alias-impl-trait/issue-53092-2.rs
index 2383008d042..43df49adc42 100644
--- a/tests/ui/type-alias-impl-trait/issue-53092-2.rs
+++ b/tests/ui/type-alias-impl-trait/issue-53092-2.rs
@@ -2,10 +2,12 @@
 #![allow(dead_code)]
 
 type Bug<T, U> = impl Fn(T) -> U + Copy;
+//~^ ERROR cycle detected
 
 const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
-//~^ ERROR cycle detected
-//~| ERROR: non-defining opaque type use
+//~^ ERROR item does not constrain `Bug::{opaque#0}`, but has it in its signature
+//~| ERROR item does not constrain `Bug::{opaque#0}`, but has it in its signature
+//~| ERROR non-defining opaque type use in defining scope
 
 fn make_bug<T, U: From<T>>() -> Bug<T, U> {
     |x| x.into()
diff --git a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr
index ac580866704..678b0c84f78 100644
--- a/tests/ui/type-alias-impl-trait/issue-53092-2.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-53092-2.stderr
@@ -1,5 +1,5 @@
 error[E0792]: non-defining opaque type use in defining scope
-  --> $DIR/issue-53092-2.rs:6:18
+  --> $DIR/issue-53092-2.rs:7:18
    |
 LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
    |                  ^^^^^^^^^^^ argument `u8` is not a generic parameter
@@ -10,33 +10,59 @@ note: for this opaque type
 LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
    |                  ^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0391]: cycle detected when type-checking `CONST_BUG`
-  --> $DIR/issue-53092-2.rs:6:1
+error[E0391]: cycle detected when computing type of `Bug::{opaque#0}`
+  --> $DIR/issue-53092-2.rs:4:18
+   |
+LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
+   |                  ^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: ...which requires computing type of opaque `Bug::{opaque#0}`...
+  --> $DIR/issue-53092-2.rs:4:18
+   |
+LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
+   |                  ^^^^^^^^^^^^^^^^^^^^^^
+note: ...which requires type-checking `CONST_BUG`...
+  --> $DIR/issue-53092-2.rs:7:1
    |
 LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
    = note: ...which requires computing layout of `Bug<u8, ()>`...
    = note: ...which requires normalizing `Bug<u8, ()>`...
-note: ...which requires computing type of `Bug::{opaque#0}`...
+   = note: ...which again requires computing type of `Bug::{opaque#0}`, completing the cycle
+note: cycle used when checking that `Bug::{opaque#0}` is well-formed
   --> $DIR/issue-53092-2.rs:4:18
    |
 LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
    |                  ^^^^^^^^^^^^^^^^^^^^^^
-note: ...which requires computing type of opaque `Bug::{opaque#0}`...
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error: item does not constrain `Bug::{opaque#0}`, but has it in its signature
+  --> $DIR/issue-53092-2.rs:7:7
+   |
+LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
+   |       ^^^^^^^^^
+   |
+   = note: consider moving the opaque type's declaration and defining uses into a separate module
+note: this opaque type is in the signature
   --> $DIR/issue-53092-2.rs:4:18
    |
 LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
    |                  ^^^^^^^^^^^^^^^^^^^^^^
-   = note: ...which again requires type-checking `CONST_BUG`, completing the cycle
-note: cycle used when checking that `CONST_BUG` is well-formed
-  --> $DIR/issue-53092-2.rs:6:1
+
+error: item does not constrain `Bug::{opaque#0}`, but has it in its signature
+  --> $DIR/issue-53092-2.rs:7:61
    |
 LL | const CONST_BUG: Bug<u8, ()> = unsafe { std::mem::transmute(|_: u8| ()) };
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+   |                                                             ^^^^^^^
+   |
+   = note: consider moving the opaque type's declaration and defining uses into a separate module
+note: this opaque type is in the signature
+  --> $DIR/issue-53092-2.rs:4:18
+   |
+LL | type Bug<T, U> = impl Fn(T) -> U + Copy;
+   |                  ^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0391, E0792.
 For more information about an error, try `rustc --explain E0391`.
diff --git a/tests/ui/type/pattern_types/nested.rs b/tests/ui/type/pattern_types/nested.rs
index 9ca9c7923de..0d8cd22190e 100644
--- a/tests/ui/type/pattern_types/nested.rs
+++ b/tests/ui/type/pattern_types/nested.rs
@@ -18,10 +18,12 @@ const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
 
 const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
 //~^ ERROR: not a valid base type for range patterns
+//~| ERROR: not a valid base type for range patterns
 //~| ERROR: mismatched types
 
 const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
 //~^ ERROR: not a valid base type for range patterns
+//~| ERROR: not a valid base type for range patterns
 //~| ERROR: mismatched types
 
 const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
diff --git a/tests/ui/type/pattern_types/nested.stderr b/tests/ui/type/pattern_types/nested.stderr
index b753b0a9c9b..f79d12bc3f3 100644
--- a/tests/ui/type/pattern_types/nested.stderr
+++ b/tests/ui/type/pattern_types/nested.stderr
@@ -1,96 +1,184 @@
-error: `(u32) is 1..=` is not a valid base type for range patterns
-  --> $DIR/nested.rs:10:34
+error[E0308]: mismatched types
+  --> $DIR/nested.rs:10:63
    |
 LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                                                               ^ expected `(u32) is 1..`, found integer
    |
-note: range patterns only support integers
-  --> $DIR/nested.rs:10:63
+   = note: expected pattern type `(u32) is 1..`
+                      found type `{integer}`
+
+error[E0277]: `(u32) is 1..` is not a valid base type for range patterns
+  --> $DIR/nested.rs:10:34
    |
 LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
-   |                                                               ^^^
+   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported
+   |
+   = help: the trait `core::pat::RangePattern` is not implemented for `(u32) is 1..`
+   = help: the following other types implement trait `core::pat::RangePattern`:
+             char
+             i128
+             i16
+             i32
+             i64
+             i8
+             isize
+             u128
+           and 5 others
 
-error: `(i32) is 1..=` is not a valid base type for range patterns
+error[E0277]: `(i32) is 1..` is not a valid base type for range patterns
   --> $DIR/nested.rs:15:35
    |
 LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: range patterns only support integers
-  --> $DIR/nested.rs:15:64
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported
+   |
+   = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..`
+   = help: the following other types implement trait `core::pat::RangePattern`:
+             char
+             i128
+             i16
+             i32
+             i64
+             i8
+             isize
+             u128
+           and 5 others
+
+error[E0308]: mismatched types
+  --> $DIR/nested.rs:15:67
    |
 LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
-   |                                                                ^^^^^
+   |                                                                   ^^ expected `(i32) is 1..`, found integer
+   |
+   = note: expected pattern type `(i32) is 1..`
+                      found type `{integer}`
 
-error: `(i32) is 1..=` is not a valid base type for range patterns
+error[E0277]: `(i32) is 1..` is not a valid base type for range patterns
   --> $DIR/nested.rs:19:35
    |
 LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
-   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: range patterns only support integers
-  --> $DIR/nested.rs:19:64
-   |
-LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
-   |                                                                ^^^
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^ only integer types and `char` are supported
+   |
+   = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..`
+   = help: the following other types implement trait `core::pat::RangePattern`:
+             char
+             i128
+             i16
+             i32
+             i64
+             i8
+             isize
+             u128
+           and 5 others
 
-error: `()` is not a valid base type for range patterns
-  --> $DIR/nested.rs:23:35
+error[E0308]: mismatched types
+  --> $DIR/nested.rs:19:66
    |
-LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
-   |                                   ^^
+LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
+   |                                                                  ^
+   |                                                                  |
+   |                                                                  expected `(i32) is 1..`, found integer
+   |                                                                  arguments to this function are incorrect
    |
-note: range patterns only support integers
-  --> $DIR/nested.rs:23:41
+   = note: expected pattern type `(i32) is 1..`
+                      found type `{integer}`
+help: the return type of this call is `{integer}` due to the type of the argument passed
+  --> $DIR/nested.rs:19:66
    |
-LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
-   |                                         ^^^
+LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
+   |                                                                  ^ this argument influences the return type of `RangeSub`
+note: method defined here
+  --> $SRC_DIR/core/src/pat.rs:LL:COL
 
-error: `f32` is not a valid base type for range patterns
-  --> $DIR/nested.rs:27:35
-   |
-LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
-   |                                   ^^^
-   |
-note: range patterns only support integers
-  --> $DIR/nested.rs:27:42
+error[E0277]: `(i32) is 1..` is not a valid base type for range patterns
+  --> $DIR/nested.rs:19:66
    |
-LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
-   |                                          ^^^^^^^^^^
+LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
+   |                                                                  ^ only integer types and `char` are supported
+   |
+   = help: the trait `core::pat::RangePattern` is not implemented for `(i32) is 1..`
+   = help: the following other types implement trait `core::pat::RangePattern`:
+             char
+             i128
+             i16
+             i32
+             i64
+             i8
+             isize
+             u128
+           and 5 others
 
-error[E0308]: mismatched types
-  --> $DIR/nested.rs:10:63
+error[E0277]: `()` is not a valid base type for range patterns
+  --> $DIR/nested.rs:24:35
    |
-LL | const BAD_NESTING: pattern_type!(pattern_type!(u32 is 1..) is 0..) = todo!();
-   |                                                               ^ expected `(u32) is 1..=`, found integer
-   |
-   = note: expected pattern type `(u32) is 1..=`
-                      found type `{integer}`
+LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
+   |                                   ^^ only integer types and `char` are supported
+   |
+   = help: the trait `core::pat::RangePattern` is not implemented for `()`
+   = help: the following other types implement trait `core::pat::RangePattern`:
+             char
+             i128
+             i16
+             i32
+             i64
+             i8
+             isize
+             u128
+           and 5 others
 
 error[E0308]: mismatched types
-  --> $DIR/nested.rs:15:67
-   |
-LL | const BAD_NESTING2: pattern_type!(pattern_type!(i32 is 1..) is ..=-1) = todo!();
-   |                                                                   ^^ expected `(i32) is 1..=`, found integer
+  --> $DIR/nested.rs:24:43
    |
-   = note: expected pattern type `(i32) is 1..=`
-                      found type `{integer}`
-
-error[E0308]: mismatched types
-  --> $DIR/nested.rs:19:66
+LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
+   |                                           ^
+   |                                           |
+   |                                           expected `()`, found integer
+   |                                           arguments to this function are incorrect
    |
-LL | const BAD_NESTING3: pattern_type!(pattern_type!(i32 is 1..) is ..0) = todo!();
-   |                                                                  ^ expected `(i32) is 1..=`, found integer
+help: the return type of this call is `{integer}` due to the type of the argument passed
+  --> $DIR/nested.rs:24:43
    |
-   = note: expected pattern type `(i32) is 1..=`
-                      found type `{integer}`
+LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
+   |                                           ^ this argument influences the return type of `RangeSub`
+note: method defined here
+  --> $SRC_DIR/core/src/pat.rs:LL:COL
 
-error[E0308]: mismatched types
-  --> $DIR/nested.rs:23:43
+error[E0277]: `()` is not a valid base type for range patterns
+  --> $DIR/nested.rs:24:43
    |
 LL | const BAD_NESTING4: pattern_type!(() is ..0) = todo!();
-   |                                           ^ expected `()`, found integer
+   |                                           ^ only integer types and `char` are supported
+   |
+   = help: the trait `core::pat::RangePattern` is not implemented for `()`
+   = help: the following other types implement trait `core::pat::RangePattern`:
+             char
+             i128
+             i16
+             i32
+             i64
+             i8
+             isize
+             u128
+           and 5 others
+
+error[E0277]: `f32` is not a valid base type for range patterns
+  --> $DIR/nested.rs:29:49
+   |
+LL | const BAD_NESTING5: pattern_type!(f32 is 1.0 .. 2.0) = todo!();
+   |                                                 ^^^ only integer types and `char` are supported
+   |
+   = help: the trait `core::pat::RangePattern` is not implemented for `f32`
+   = help: the following other types implement trait `core::pat::RangePattern`:
+             i128
+             i16
+             i32
+             i64
+             i8
+             isize
+             u128
+             u16
+           and 4 others
 
-error: aborting due to 9 previous errors
+error: aborting due to 11 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0277, E0308.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/type/pattern_types/range_patterns.stderr b/tests/ui/type/pattern_types/range_patterns.stderr
index 690592ba0b8..cb24a303404 100644
--- a/tests/ui/type/pattern_types/range_patterns.stderr
+++ b/tests/ui/type/pattern_types/range_patterns.stderr
@@ -4,7 +4,7 @@ error: layout_of(NonZero<u32>) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I32,
@@ -44,13 +44,13 @@ error: layout_of(NonZero<u32>) = Layout {
 LL | type X = std::num::NonZeroU32;
    | ^^^^^^
 
-error: layout_of((u32) is 1..=) = Layout {
+error: layout_of((u32) is 1..) = Layout {
            size: Size(4 bytes),
            align: AbiAndPrefAlign {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I32,
@@ -83,13 +83,13 @@ error: layout_of((u32) is 1..=) = Layout {
 LL | type Y = pattern_type!(u32 is 1..);
    | ^^^^^^
 
-error: layout_of(Option<(u32) is 1..=>) = Layout {
+error: layout_of(Option<(u32) is 1..>) = Layout {
            size: Size(4 bytes),
            align: AbiAndPrefAlign {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I32,
@@ -129,7 +129,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout {
                            abi: Align(1 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -151,7 +151,7 @@ error: layout_of(Option<(u32) is 1..=>) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Scalar(
+                       backend_repr: Scalar(
                            Initialized {
                                value: Int(
                                    I32,
@@ -203,7 +203,7 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I32,
@@ -243,7 +243,7 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
                            abi: Align(1 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Memory {
+                       backend_repr: Memory {
                            sized: true,
                        },
                        fields: Arbitrary {
@@ -265,7 +265,7 @@ error: layout_of(Option<NonZero<u32>>) = Layout {
                            abi: Align(4 bytes),
                            pref: $SOME_ALIGN,
                        },
-                       abi: Scalar(
+                       backend_repr: Scalar(
                            Initialized {
                                value: Int(
                                    I32,
@@ -317,7 +317,7 @@ error: layout_of(NonZeroU32New) = Layout {
                abi: Align(4 bytes),
                pref: $SOME_ALIGN,
            },
-           abi: Scalar(
+           backend_repr: Scalar(
                Initialized {
                    value: Int(
                        I32,
diff --git a/tests/ui/type/pattern_types/range_patterns_unusable.stderr b/tests/ui/type/pattern_types/range_patterns_unusable.stderr
index 8377d417452..7daa41d7081 100644
--- a/tests/ui/type/pattern_types/range_patterns_unusable.stderr
+++ b/tests/ui/type/pattern_types/range_patterns_unusable.stderr
@@ -4,7 +4,7 @@ error[E0512]: cannot transmute between types of different sizes, or dependently-
 LL |     let _: Option<u32> = unsafe { std::mem::transmute(z) };
    |                                   ^^^^^^^^^^^^^^^^^^^
    |
-   = note: source type: `Option<(u32) is 1..=>` (32 bits)
+   = note: source type: `Option<(u32) is 1..>` (32 bits)
    = note: target type: `Option<u32>` (64 bits)
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/type/pattern_types/range_patterns_unusable_math.rs b/tests/ui/type/pattern_types/range_patterns_unusable_math.rs
index ece4009e1e7..6125063699b 100644
--- a/tests/ui/type/pattern_types/range_patterns_unusable_math.rs
+++ b/tests/ui/type/pattern_types/range_patterns_unusable_math.rs
@@ -11,5 +11,5 @@ type Z = Option<pattern_type!(u32 is 1..)>;
 
 fn main() {
     let x: Y = unsafe { std::mem::transmute(42_u32) };
-    let x = x + 1_u32; //~ ERROR cannot add `u32` to `(u32) is 1..=`
+    let x = x + 1_u32; //~ ERROR cannot add `u32` to `(u32) is 1..`
 }
diff --git a/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr b/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr
index 373615e3714..a64f1db3176 100644
--- a/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr
+++ b/tests/ui/type/pattern_types/range_patterns_unusable_math.stderr
@@ -1,10 +1,10 @@
-error[E0369]: cannot add `u32` to `(u32) is 1..=`
+error[E0369]: cannot add `u32` to `(u32) is 1..`
   --> $DIR/range_patterns_unusable_math.rs:14:15
    |
 LL |     let x = x + 1_u32;
    |             - ^ ----- u32
    |             |
-   |             (u32) is 1..=
+   |             (u32) is 1..
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/type/pattern_types/reverse_range.rs b/tests/ui/type/pattern_types/reverse_range.rs
index 6a245615f1a..e698e9dd541 100644
--- a/tests/ui/type/pattern_types/reverse_range.rs
+++ b/tests/ui/type/pattern_types/reverse_range.rs
@@ -1,14 +1,11 @@
 //! Check that the range start must be smaller than the range end
-//@ known-bug: unknown
-//@ failure-status: 101
-//@ normalize-stderr: "note: .*\n\n" -> ""
-//@ normalize-stderr: "thread 'rustc' panicked.*\n" -> ""
-//@ normalize-stderr: "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
-//@ rustc-env:RUST_BACKTRACE=0
-
-#![feature(pattern_types)]
+#![feature(pattern_types, const_trait_impl, pattern_type_range_trait)]
 #![feature(pattern_type_macro)]
 
 use std::pat::pattern_type;
 
 const NONE: pattern_type!(u8 is 1..0) = unsafe { std::mem::transmute(3_u8) };
+//~^ NOTE: exclusive range end at minimum value of type
+//~| ERROR: evaluation of constant value failed
+
+fn main() {}
diff --git a/tests/ui/type/pattern_types/reverse_range.stderr b/tests/ui/type/pattern_types/reverse_range.stderr
index b714ca7d9ab..90f8ef3261a 100644
--- a/tests/ui/type/pattern_types/reverse_range.stderr
+++ b/tests/ui/type/pattern_types/reverse_range.stderr
@@ -1,17 +1,9 @@
-error[E0601]: `main` function not found in crate `reverse_range`
-  --> $DIR/reverse_range.rs:14:78
+error[E0080]: evaluation of constant value failed
+  --> $DIR/reverse_range.rs:7:36
    |
 LL | const NONE: pattern_type!(u8 is 1..0) = unsafe { std::mem::transmute(3_u8) };
-   |                                                                              ^ consider adding a `main` function to `$DIR/reverse_range.rs`
+   |                                    ^ evaluation panicked: exclusive range end at minimum value of type
 
-
-assertion failed: end <= max_value
-error: the compiler unexpectedly panicked. this is a bug.
-
-query stack during panic:
-#0 [eval_to_allocation_raw] const-evaluating + checking `NONE`
-#1 [eval_to_const_value_raw] simplifying constant for the type system `NONE`
-... and 1 other queries... use `env RUST_BACKTRACE=1` to see the full query stack
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0601`.
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/type/pattern_types/validity.rs b/tests/ui/type/pattern_types/validity.rs
index 77a4e72f675..5a6a688e1b3 100644
--- a/tests/ui/type/pattern_types/validity.rs
+++ b/tests/ui/type/pattern_types/validity.rs
@@ -1,6 +1,6 @@
 //! Check that pattern types have their validity checked
 
-#![feature(pattern_types)]
+#![feature(pattern_types, const_trait_impl, pattern_type_range_trait)]
 #![feature(pattern_type_macro)]
 
 use std::pat::pattern_type;
diff --git a/tests/ui/type_length_limit.rs b/tests/ui/type_length_limit.rs
index b629455aced..87f5ffd76d7 100644
--- a/tests/ui/type_length_limit.rs
+++ b/tests/ui/type_length_limit.rs
@@ -2,9 +2,6 @@
 //@ compile-flags: -Copt-level=0 -Zenforce-type-length-limit
 //~^^ ERROR reached the type-length limit
 
-// The regex below normalizes the long type file name to make it suitable for compare-modes.
-//@ normalize-stderr: "'\$TEST_BUILD_DIR/.*\.long-type.txt'" -> "'$$TEST_BUILD_DIR/$$FILE.long-type.txt'"
-
 // Test that the type length limit can be changed.
 // The exact type depends on optimizations, so disable them.
 
diff --git a/tests/ui/type_length_limit.stderr b/tests/ui/type_length_limit.stderr
index d913b661c6f..198d133c08c 100644
--- a/tests/ui/type_length_limit.stderr
+++ b/tests/ui/type_length_limit.stderr
@@ -1,11 +1,11 @@
 error: reached the type-length limit while instantiating `std::mem::drop::<Option<((((..., ..., ...), ..., ...), ..., ...), ..., ...)>>`
-  --> $DIR/type_length_limit.rs:35:5
+  --> $DIR/type_length_limit.rs:32:5
    |
 LL |     drop::<Option<A>>(None);
    |     ^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider adding a `#![type_length_limit="4010"]` attribute to your crate
-   = note: the full type name has been written to '$TEST_BUILD_DIR/$FILE.long-type.txt'
+   = note: the full type name has been written to '$TEST_BUILD_DIR/type_length_limit.long-type.txt'
 
 error: reached the type-length limit while instantiating `<{closure@rt::lang_start<()>::{closure#0}} as FnMut<()>>::call_mut`
    |
diff --git a/tests/ui/typeck/issue-84768.stderr b/tests/ui/typeck/issue-84768.stderr
index 72784ba59c9..8a2200cbf68 100644
--- a/tests/ui/typeck/issue-84768.stderr
+++ b/tests/ui/typeck/issue-84768.stderr
@@ -20,7 +20,7 @@ help: the return type of this call is `{integer}` due to the type of the argumen
 LL |     <F as FnOnce(&mut u8)>::call_once(f, 1)
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-^
    |                                          |
-   |                                          this argument influences the return type of `FnOnce`
+   |                                          this argument influences the return type of `call_once`
 note: method defined here
   --> $SRC_DIR/core/src/ops/function.rs:LL:COL
 
diff --git a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
index 05071834883..edee7c4f5a1 100644
--- a/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
+++ b/tests/ui/ufcs/ufcs-qpath-self-mismatch.stderr
@@ -25,7 +25,7 @@ help: the return type of this call is `u32` due to the type of the argument pass
 LL |     <i32 as Add<i32>>::add(1u32, 2);
    |     ^^^^^^^^^^^^^^^^^^^^^^^----^^^^
    |                            |
-   |                            this argument influences the return type of `Add`
+   |                            this argument influences the return type of `add`
 note: method defined here
   --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
 help: change the type of the numeric literal from `u32` to `i32`
@@ -48,7 +48,7 @@ help: the return type of this call is `u32` due to the type of the argument pass
 LL |     <i32 as Add<i32>>::add(1, 2u32);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^----^
    |                               |
-   |                               this argument influences the return type of `Add`
+   |                               this argument influences the return type of `add`
 note: method defined here
   --> $SRC_DIR/core/src/ops/arith.rs:LL:COL
 help: change the type of the numeric literal from `u32` to `i32`
diff --git a/tests/ui/unpretty/deprecated-attr.rs b/tests/ui/unpretty/deprecated-attr.rs
new file mode 100644
index 00000000000..24a32d8a9ac
--- /dev/null
+++ b/tests/ui/unpretty/deprecated-attr.rs
@@ -0,0 +1,19 @@
+//@ compile-flags: -Zunpretty=hir
+//@ check-pass
+
+// FIXME(jdonszelmann): the pretty printing output for deprecated (and possibly more attrs) is
+// slightly broken.
+#[deprecated]
+pub struct PlainDeprecated;
+
+#[deprecated = "here's why this is deprecated"]
+pub struct DirectNote;
+
+#[deprecated(note = "here's why this is deprecated")]
+pub struct ExplicitNote;
+
+#[deprecated(since = "1.2.3", note = "here's why this is deprecated")]
+pub struct SinceAndNote;
+
+#[deprecated(note = "here's why this is deprecated", since = "1.2.3")]
+pub struct FlippedOrder;
diff --git a/tests/ui/unpretty/deprecated-attr.stdout b/tests/ui/unpretty/deprecated-attr.stdout
new file mode 100644
index 00000000000..675351351a0
--- /dev/null
+++ b/tests/ui/unpretty/deprecated-attr.stdout
@@ -0,0 +1,28 @@
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+//@ compile-flags: -Zunpretty=hir
+//@ check-pass
+
+// FIXME(jdonszelmann): the pretty printing output for deprecated (and possibly more attrs) is
+// slightly broken.
+#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote:
+suggestion: }span: }")]
+struct PlainDeprecated;
+
+#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote:
+here's why this is deprecatedsuggestion: }span: }")]
+struct DirectNote;
+
+#[attr="Deprecation{deprecation: Deprecation{since: Unspecifiednote:
+here's why this is deprecatedsuggestion: }span: }")]
+struct ExplicitNote;
+
+#[attr="Deprecation{deprecation: Deprecation{since: NonStandard(1.2.3)note:
+here's why this is deprecatedsuggestion: }span: }")]
+struct SinceAndNote;
+
+#[attr="Deprecation{deprecation: Deprecation{since: NonStandard(1.2.3)note:
+here's why this is deprecatedsuggestion: }span: }")]
+struct FlippedOrder;
diff --git a/tests/ui/unpretty/diagnostic-attr.rs b/tests/ui/unpretty/diagnostic-attr.rs
new file mode 100644
index 00000000000..27f5b693e69
--- /dev/null
+++ b/tests/ui/unpretty/diagnostic-attr.rs
@@ -0,0 +1,13 @@
+//@ compile-flags: -Zunpretty=hir
+//@ check-pass
+
+#[diagnostic::on_unimplemented(
+    message = "My Message for `ImportantTrait<{A}>` implemented for `{Self}`",
+    label = "My Label",
+    note = "Note 1",
+    note = "Note 2"
+)]
+pub trait ImportantTrait<A> {}
+
+#[diagnostic::do_not_recommend]
+impl<T> ImportantTrait<T> for T where T: Clone {}
diff --git a/tests/ui/unpretty/diagnostic-attr.stdout b/tests/ui/unpretty/diagnostic-attr.stdout
new file mode 100644
index 00000000000..e8696d04d38
--- /dev/null
+++ b/tests/ui/unpretty/diagnostic-attr.stdout
@@ -0,0 +1,16 @@
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+//@ compile-flags: -Zunpretty=hir
+//@ check-pass
+
+#[diagnostic::on_unimplemented(message =
+"My Message for `ImportantTrait<{A}>` implemented for `{Self}`", label =
+"My Label", note = "Note 1", note = "Note 2")]
+trait ImportantTrait<A> { }
+
+#[diagnostic::do_not_recommend]
+impl <T> ImportantTrait<T> for T where T: Clone
+    {#![diagnostic::do_not_recommend]
+}
diff --git a/tests/ui/unsafe-binders/type-mismatch.rs b/tests/ui/unsafe-binders/type-mismatch.rs
new file mode 100644
index 00000000000..9ac4e817c28
--- /dev/null
+++ b/tests/ui/unsafe-binders/type-mismatch.rs
@@ -0,0 +1,9 @@
+#![feature(unsafe_binders)]
+//~^ WARN the feature `unsafe_binders` is incomplete
+
+fn main() {
+    let x: unsafe<> i32 = 0;
+    //~^ ERROR mismatched types
+    let x: unsafe<'a> &'a i32 = &0;
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/unsafe-binders/type-mismatch.stderr b/tests/ui/unsafe-binders/type-mismatch.stderr
new file mode 100644
index 00000000000..e694b5d464d
--- /dev/null
+++ b/tests/ui/unsafe-binders/type-mismatch.stderr
@@ -0,0 +1,34 @@
+warning: the feature `unsafe_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/type-mismatch.rs:1:12
+   |
+LL | #![feature(unsafe_binders)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #130516 <https://github.com/rust-lang/rust/issues/130516> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0308]: mismatched types
+  --> $DIR/type-mismatch.rs:5:27
+   |
+LL |     let x: unsafe<> i32 = 0;
+   |            ------------   ^ expected `unsafe<> i32`, found integer
+   |            |
+   |            expected due to this
+   |
+   = note: expected unsafe binder `unsafe<> i32`
+                       found type `{integer}`
+
+error[E0308]: mismatched types
+  --> $DIR/type-mismatch.rs:7:33
+   |
+LL |     let x: unsafe<'a> &'a i32 = &0;
+   |            ------------------   ^^ expected `unsafe<'a> &i32`, found `&{integer}`
+   |            |
+   |            expected due to this
+   |
+   = note: expected unsafe binder `unsafe<'a> &'a i32`
+                  found reference `&{integer}`
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/unsafe-fields/unsafe-fields.rs b/tests/ui/unsafe-fields/unsafe-fields.rs
index 637471582d7..cb86479bb20 100644
--- a/tests/ui/unsafe-fields/unsafe-fields.rs
+++ b/tests/ui/unsafe-fields/unsafe-fields.rs
@@ -17,7 +17,7 @@ fn f(a: A) {
 }
 
 struct WithInvalidUnsafeField {
-    unsafe unsafe_noncopy_field: Vec<u32>, //~ ERROR
+    unsafe unsafe_noncopy_field: Vec<u32>,
 }
 
 struct WithManuallyDropUnsafeField {
diff --git a/tests/ui/unsafe-fields/unsafe-fields.stderr b/tests/ui/unsafe-fields/unsafe-fields.stderr
index a1c5d2b44cd..d0e2dc16a13 100644
--- a/tests/ui/unsafe-fields/unsafe-fields.stderr
+++ b/tests/ui/unsafe-fields/unsafe-fields.stderr
@@ -1,15 +1,3 @@
-error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be unsafe
-  --> $DIR/unsafe-fields.rs:20:5
-   |
-LL |     unsafe unsafe_noncopy_field: Vec<u32>,
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: unsafe fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
-help: wrap the field type in `ManuallyDrop<...>`
-   |
-LL |     unsafe unsafe_noncopy_field: std::mem::ManuallyDrop<Vec<u32>>,
-   |                                  +++++++++++++++++++++++        +
-
 error[E0133]: use of unsafe field is unsafe and requires unsafe block
   --> $DIR/unsafe-fields.rs:15:30
    |
@@ -69,7 +57,6 @@ LL |         &raw const self.unsafe_field
    |
    = note: unsafe fields may carry library invariants
 
-error: aborting due to 8 previous errors
+error: aborting due to 7 previous errors
 
-Some errors have detailed explanations: E0133, E0740.
-For more information about an error, try `rustc --explain E0133`.
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/unsized-locals/rust-call.rs b/tests/ui/unsized-locals/rust-call.rs
deleted file mode 100644
index ff4075aa4c0..00000000000
--- a/tests/ui/unsized-locals/rust-call.rs
+++ /dev/null
@@ -1,12 +0,0 @@
-#![feature(unsized_tuple_coercion)]
-#![feature(unboxed_closures)]
-#![feature(unsized_fn_params)]
-
-fn bad() -> extern "rust-call" fn(([u8],)) { todo!() }
-
-fn main() {
-    let f = bad();
-    let slice: Box<([u8],)> = Box::new(([1; 8],));
-    f(*slice);
-    //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
-}
diff --git a/tests/ui/unsized-locals/rust-call.stderr b/tests/ui/unsized-locals/rust-call.stderr
deleted file mode 100644
index 9eb0f3dabcc..00000000000
--- a/tests/ui/unsized-locals/rust-call.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/rust-call.rs:10:7
-   |
-LL |     f(*slice);
-   |       ^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: within `([u8],)`, the trait `Sized` is not implemented for `[u8]`
-   = note: required because it appears within the type `([u8],)`
-   = note: argument required to be sized due to `extern "rust-call"` ABI
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsized-locals/unsized-exprs-rpass.rs b/tests/ui/unsized-locals/unsized-exprs-rpass.rs
index a5aada20d3e..861583efc40 100644
--- a/tests/ui/unsized-locals/unsized-exprs-rpass.rs
+++ b/tests/ui/unsized-locals/unsized-exprs-rpass.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(incomplete_features, unused_braces, unused_parens)]
-#![feature(unsized_tuple_coercion, unsized_locals, unsized_fn_params)]
+#![feature(unsized_locals, unsized_fn_params)]
 
 struct A<X: ?Sized>(#[allow(dead_code)] X);
 
@@ -8,9 +8,6 @@ fn udrop<T: ?Sized>(_x: T) {}
 fn foo() -> Box<[u8]> {
     Box::new(*b"foo")
 }
-fn tfoo() -> Box<(i32, [u8])> {
-    Box::new((42, *b"foo"))
-}
 fn afoo() -> Box<A<[u8]>> {
     Box::new(A(*b"foo"))
 }
@@ -27,7 +24,6 @@ fn main() {
     udrop::<[u8]>(if true { *foo() } else { *foo() });
     udrop::<[u8]>({ *foo() });
     udrop::<[u8]>((*foo()));
-    udrop::<[u8]>((*tfoo()).1);
     *afoo() + 42;
     udrop as fn([u8]);
 }
diff --git a/tests/ui/unsized-locals/unsized-exprs.rs b/tests/ui/unsized-locals/unsized-exprs.rs
index 1729b9ffa86..8fe5dcba8a9 100644
--- a/tests/ui/unsized-locals/unsized-exprs.rs
+++ b/tests/ui/unsized-locals/unsized-exprs.rs
@@ -1,4 +1,4 @@
-#![feature(unsized_tuple_coercion, unsized_fn_params)]
+#![feature(unsized_fn_params)]
 
 struct A<X: ?Sized>(X);
 
@@ -6,9 +6,6 @@ fn udrop<T: ?Sized>(_x: T) {}
 fn foo() -> Box<[u8]> {
     Box::new(*b"foo")
 }
-fn tfoo() -> Box<(i32, [u8])> {
-    Box::new((42, *b"foo"))
-}
 fn afoo() -> Box<A<[u8]>> {
     Box::new(A(*b"foo"))
 }
@@ -19,8 +16,6 @@ impl std::ops::Add<i32> for A<[u8]> {
 }
 
 fn main() {
-    udrop::<(i32, [u8])>((42, *foo()));
-    //~^ERROR E0277
     udrop::<A<[u8]>>(A { 0: *foo() });
     //~^ERROR E0277
     udrop::<A<[u8]>>(A(*foo()));
diff --git a/tests/ui/unsized-locals/unsized-exprs.stderr b/tests/ui/unsized-locals/unsized-exprs.stderr
index 8a2ecf0f6c3..1b61254870f 100644
--- a/tests/ui/unsized-locals/unsized-exprs.stderr
+++ b/tests/ui/unsized-locals/unsized-exprs.stderr
@@ -1,15 +1,5 @@
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/unsized-exprs.rs:22:26
-   |
-LL |     udrop::<(i32, [u8])>((42, *foo()));
-   |                          ^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: within `({integer}, [u8])`, the trait `Sized` is not implemented for `[u8]`
-   = note: required because it appears within the type `({integer}, [u8])`
-   = note: tuples must have a statically known size to be initialized
-
-error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/unsized-exprs.rs:24:22
+  --> $DIR/unsized-exprs.rs:19:22
    |
 LL |     udrop::<A<[u8]>>(A { 0: *foo() });
    |                      ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -23,7 +13,7 @@ LL | struct A<X: ?Sized>(X);
    = note: structs must have a statically known size to be initialized
 
 error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
-  --> $DIR/unsized-exprs.rs:26:22
+  --> $DIR/unsized-exprs.rs:21:22
    |
 LL |     udrop::<A<[u8]>>(A(*foo()));
    |                      ^^^^^^^^^ doesn't have a size known at compile-time
@@ -36,6 +26,6 @@ LL | struct A<X: ?Sized>(X);
    |        ^
    = note: the return type of a function must have a statically known size
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/unsized-locals/unsized-exprs2.rs b/tests/ui/unsized-locals/unsized-exprs2.rs
index 127d8717e58..7706c8b8b8f 100644
--- a/tests/ui/unsized-locals/unsized-exprs2.rs
+++ b/tests/ui/unsized-locals/unsized-exprs2.rs
@@ -1,4 +1,4 @@
-#![feature(unsized_tuple_coercion, unsized_fn_params)]
+#![feature(unsized_fn_params)]
 
 struct A<X: ?Sized>(X);
 
@@ -6,9 +6,6 @@ fn udrop<T: ?Sized>(_x: T) {}
 fn foo() -> Box<[u8]> {
     Box::new(*b"foo")
 }
-fn tfoo() -> Box<(i32, [u8])> {
-    Box::new((42, *b"foo"))
-}
 fn afoo() -> Box<A<[u8]>> {
     Box::new(A(*b"foo"))
 }
diff --git a/tests/ui/unsized-locals/unsized-exprs2.stderr b/tests/ui/unsized-locals/unsized-exprs2.stderr
index 47b6d72acc7..79f0d93d421 100644
--- a/tests/ui/unsized-locals/unsized-exprs2.stderr
+++ b/tests/ui/unsized-locals/unsized-exprs2.stderr
@@ -1,5 +1,5 @@
 error[E0508]: cannot move out of type `[u8]`, a non-copy slice
-  --> $DIR/unsized-exprs2.rs:22:5
+  --> $DIR/unsized-exprs2.rs:19:5
    |
 LL |     udrop::<[u8]>(foo()[..]);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/unsized/unsized-tuple-impls.rs b/tests/ui/unsized/unsized-tuple-impls.rs
deleted file mode 100644
index a76e2df5750..00000000000
--- a/tests/ui/unsized/unsized-tuple-impls.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-//@ run-pass
-
-#![feature(unsized_tuple_coercion)]
-
-use std::collections::HashSet;
-
-fn main() {
-    let x : &(i32, i32, [i32]) = &(0, 1, [2, 3]);
-    let y : &(i32, i32, [i32]) = &(0, 1, [2, 3, 4]);
-    let mut a = [y, x];
-    a.sort();
-    assert_eq!(a, [x, y]);
-
-    assert_eq!(&format!("{:?}", a), "[(0, 1, [2, 3]), (0, 1, [2, 3, 4])]");
-
-    let mut h = HashSet::new();
-    h.insert(x);
-    h.insert(y);
-    assert!(h.contains(x));
-    assert!(h.contains(y));
-}
diff --git a/tests/ui/wf/wf-normalization-sized.next.stderr b/tests/ui/wf/wf-normalization-sized.next.stderr
index 83b56bb6b19..66c4f214415 100644
--- a/tests/ui/wf/wf-normalization-sized.next.stderr
+++ b/tests/ui/wf/wf-normalization-sized.next.stderr
@@ -7,16 +7,6 @@ LL | const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = ();
    = help: the trait `Sized` is not implemented for `[[[[[u8]]]]]`
    = note: slice and array elements must have `Sized` type
 
-error[E0277]: the size for values of type `[[[[[u8]]]]]` cannot be known at compilation time
-  --> $DIR/wf-normalization-sized.rs:19:11
-   |
-LL | const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = ();
-   |           ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
-   |
-   = help: the trait `Sized` is not implemented for `[[[[[u8]]]]]`
-   = note: slice and array elements must have `Sized` type
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/wf-normalization-sized.rs:22:11
    |
@@ -27,6 +17,16 @@ LL | const _: <Vec<str> as WellUnformed>::RequestNormalize = ();
 note: required by an implicit `Sized` bound in `Vec`
   --> $SRC_DIR/alloc/src/vec/mod.rs:LL:COL
 
+error[E0277]: the size for values of type `[[[[[u8]]]]]` cannot be known at compilation time
+  --> $DIR/wf-normalization-sized.rs:19:11
+   |
+LL | const _: <[[[[[[u8]]]]]] as WellUnformed>::RequestNormalize = ();
+   |           ^^^^^^^^^^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[[[[[u8]]]]]`
+   = note: slice and array elements must have `Sized` type
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
 error[E0277]: the size for values of type `str` cannot be known at compilation time
   --> $DIR/wf-normalization-sized.rs:22:11
    |
diff --git a/tests/ui/where-clauses/cfg_attribute.a.stderr b/tests/ui/where-clauses/cfg_attribute.a.stderr
new file mode 100644
index 00000000000..0ede890eb44
--- /dev/null
+++ b/tests/ui/where-clauses/cfg_attribute.a.stderr
@@ -0,0 +1,288 @@
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:32:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:43:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:54:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:66:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:76:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:87:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:100:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:114:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:129:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:144:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:155:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:165:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:178:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:32:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:35:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:66:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:69:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:100:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:103:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:114:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:117:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:129:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:132:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:144:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:147:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:155:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:158:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:178:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:181:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:43:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:46:9
+   |
+LL |         #[rustfmt::skip] ():;
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:54:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:57:9
+   |
+LL |         #[rustfmt::skip] ():;
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:76:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:79:9
+   |
+LL |         #[rustfmt::skip] ():;
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:87:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:90:9
+   |
+LL |         #[rustfmt::skip] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:165:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:168:9
+   |
+LL |         #[rustfmt::skip] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: aborting due to 39 previous errors
+
diff --git a/tests/ui/where-clauses/cfg_attribute.b.stderr b/tests/ui/where-clauses/cfg_attribute.b.stderr
new file mode 100644
index 00000000000..0ede890eb44
--- /dev/null
+++ b/tests/ui/where-clauses/cfg_attribute.b.stderr
@@ -0,0 +1,288 @@
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:32:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:43:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:54:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:66:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:76:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:87:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:100:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:114:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:129:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:144:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:155:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:165:11
+   |
+LL |         #[derive(Clone)] ():,
+   |           ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/cfg_attribute.rs:178:7
+   |
+LL |     #[derive(Clone)] ():,
+   |       ^^^^^^ not a non-macro attribute
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:32:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:35:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:66:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:69:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:100:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:103:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:114:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:117:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:129:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:132:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:144:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:147:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:155:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:158:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:178:5
+   |
+LL |     #[derive(Clone)] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:181:5
+   |
+LL |     #[rustfmt::skip] ():,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:43:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:46:9
+   |
+LL |         #[rustfmt::skip] ():;
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:54:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:57:9
+   |
+LL |         #[rustfmt::skip] ():;
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:76:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:79:9
+   |
+LL |         #[rustfmt::skip] ():;
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:87:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:90:9
+   |
+LL |         #[rustfmt::skip] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:165:9
+   |
+LL |         #[derive(Clone)] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/cfg_attribute.rs:168:9
+   |
+LL |         #[rustfmt::skip] ():,
+   |         ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: aborting due to 39 previous errors
+
diff --git a/tests/ui/where-clauses/cfg_attribute.rs b/tests/ui/where-clauses/cfg_attribute.rs
new file mode 100644
index 00000000000..8cbca0bee75
--- /dev/null
+++ b/tests/ui/where-clauses/cfg_attribute.rs
@@ -0,0 +1,183 @@
+//@ revisions: a b
+
+#![crate_type = "lib"]
+#![feature(alloc_error_handler)]
+#![feature(cfg_accessible)]
+#![feature(cfg_eval)]
+#![feature(custom_test_frameworks)]
+#![feature(derive_const)]
+#![feature(where_clause_attrs)]
+#![allow(soft_unstable)]
+
+use std::marker::PhantomData;
+
+#[cfg(a)]
+trait TraitA {}
+
+#[cfg(b)]
+trait TraitB {}
+
+#[cfg_attr(a, cfg(a))]
+trait TraitAA {}
+
+#[cfg_attr(b, cfg(b))]
+trait TraitBB {}
+
+trait A<T>
+where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+{
+    type B<U>
+    where
+        #[cfg(a)] U: TraitA,
+        #[cfg(b)] U: TraitB,
+        #[cfg_attr(a, cfg(a))] U: TraitAA,
+        #[cfg_attr(b, cfg(b))] U: TraitBB,
+        #[derive(Clone)] ():,
+        //~^ ERROR most attributes are not supported in `where` clauses
+        //~| ERROR expected non-macro attribute, found attribute macro `derive`
+        #[rustfmt::skip] ():; //~ ERROR most attributes are not supported in `where` clauses
+
+    fn foo<U>(&self)
+    where
+        #[cfg(a)] U: TraitA,
+        #[cfg(b)] U: TraitB,
+        #[cfg_attr(a, cfg(a))] U: TraitAA,
+        #[cfg_attr(b, cfg(b))] U: TraitBB,
+        #[derive(Clone)] ():,
+        //~^ ERROR most attributes are not supported in `where` clauses
+        //~| ERROR expected non-macro attribute, found attribute macro `derive`
+        #[rustfmt::skip] ():; //~ ERROR most attributes are not supported in `where` clauses
+}
+
+impl<T> A<T> for T
+where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+{
+    type B<U> = () where
+        #[cfg(a)] U: TraitA,
+        #[cfg(b)] U: TraitB,
+        #[cfg_attr(a, cfg(a))] U: TraitAA,
+        #[cfg_attr(b, cfg(b))] U: TraitBB,
+        #[derive(Clone)] ():,
+        //~^ ERROR most attributes are not supported in `where` clauses
+        //~| ERROR expected non-macro attribute, found attribute macro `derive`
+        #[rustfmt::skip] ():; //~ ERROR most attributes are not supported in `where` clauses
+
+    fn foo<U>(&self)
+    where
+        #[cfg(a)] U: TraitA,
+        #[cfg(b)] U: TraitB,
+        #[cfg_attr(a, cfg(a))] U: TraitAA,
+        #[cfg_attr(b, cfg(b))] U: TraitBB,
+        #[derive(Clone)] ():,
+        //~^ ERROR most attributes are not supported in `where` clauses
+        //~| ERROR expected non-macro attribute, found attribute macro `derive`
+        #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+    {}
+}
+
+struct C<T>
+where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+{
+    _t: PhantomData<T>,
+}
+
+union D<T>
+where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+{
+
+    _t: PhantomData<T>,
+}
+
+enum E<T>
+where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+{
+    E(PhantomData<T>),
+}
+
+#[allow(type_alias_bounds)]
+type F<T>
+where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+= T;
+
+impl<T> C<T> where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+{
+    fn new<U>() where
+        #[cfg(a)] U: TraitA,
+        #[cfg(b)] U: TraitB,
+        #[cfg_attr(a, cfg(a))] U: TraitAA,
+        #[cfg_attr(b, cfg(b))] U: TraitBB,
+        #[derive(Clone)] ():,
+        //~^ ERROR most attributes are not supported in `where` clauses
+        //~| ERROR expected non-macro attribute, found attribute macro `derive`
+        #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+    {}
+}
+
+fn foo<T>()
+where
+    #[cfg(a)] T: TraitA,
+    #[cfg(b)] T: TraitB,
+    #[cfg_attr(a, cfg(a))] T: TraitAA,
+    #[cfg_attr(b, cfg(b))] T: TraitBB,
+    #[derive(Clone)] ():,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] ():, //~ ERROR most attributes are not supported in `where` clauses
+{
+}
diff --git a/tests/ui/where-clauses/unsupported_attribute.rs b/tests/ui/where-clauses/unsupported_attribute.rs
new file mode 100644
index 00000000000..33128b383b9
--- /dev/null
+++ b/tests/ui/where-clauses/unsupported_attribute.rs
@@ -0,0 +1,36 @@
+#![crate_type = "lib"]
+#![feature(alloc_error_handler)]
+#![feature(cfg_accessible)]
+#![feature(cfg_eval)]
+#![feature(custom_test_frameworks)]
+#![feature(derive_const)]
+#![feature(where_clause_attrs)]
+#![allow(soft_unstable)]
+
+trait Trait {}
+
+fn foo<'a, T>()
+where
+    #[doc = "doc"] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[doc = "doc"] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+    #[ignore] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[ignore] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+    #[should_panic] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[should_panic] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+    #[macro_use] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[macro_use] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+    #[allow(unused)] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[allow(unused)] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+    #[deprecated] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[deprecated] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+    #[automatically_derived] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[automatically_derived] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+    #[derive(Clone)] T: Trait,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[derive(Clone)] 'a: 'static,
+    //~^ ERROR most attributes are not supported in `where` clauses
+    //~| ERROR expected non-macro attribute, found attribute macro `derive`
+    #[rustfmt::skip] T: Trait, //~ ERROR most attributes are not supported in `where` clauses
+    #[rustfmt::skip] 'a: 'static, //~ ERROR most attributes are not supported in `where` clauses
+{}
diff --git a/tests/ui/where-clauses/unsupported_attribute.stderr b/tests/ui/where-clauses/unsupported_attribute.stderr
new file mode 100644
index 00000000000..ecb28039f88
--- /dev/null
+++ b/tests/ui/where-clauses/unsupported_attribute.stderr
@@ -0,0 +1,158 @@
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/unsupported_attribute.rs:28:7
+   |
+LL |     #[derive(Clone)] T: Trait,
+   |       ^^^^^^ not a non-macro attribute
+
+error: expected non-macro attribute, found attribute macro `derive`
+  --> $DIR/unsupported_attribute.rs:31:7
+   |
+LL |     #[derive(Clone)] 'a: 'static,
+   |       ^^^^^^ not a non-macro attribute
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:14:5
+   |
+LL |     #[doc = "doc"] T: Trait,
+   |     ^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:15:5
+   |
+LL |     #[doc = "doc"] 'a: 'static,
+   |     ^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:16:5
+   |
+LL |     #[ignore] T: Trait,
+   |     ^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:17:5
+   |
+LL |     #[ignore] 'a: 'static,
+   |     ^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:18:5
+   |
+LL |     #[should_panic] T: Trait,
+   |     ^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:19:5
+   |
+LL |     #[should_panic] 'a: 'static,
+   |     ^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:20:5
+   |
+LL |     #[macro_use] T: Trait,
+   |     ^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:21:5
+   |
+LL |     #[macro_use] 'a: 'static,
+   |     ^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:22:5
+   |
+LL |     #[allow(unused)] T: Trait,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:23:5
+   |
+LL |     #[allow(unused)] 'a: 'static,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:24:5
+   |
+LL |     #[deprecated] T: Trait,
+   |     ^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:25:5
+   |
+LL |     #[deprecated] 'a: 'static,
+   |     ^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:26:5
+   |
+LL |     #[automatically_derived] T: Trait,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:27:5
+   |
+LL |     #[automatically_derived] 'a: 'static,
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:28:5
+   |
+LL |     #[derive(Clone)] T: Trait,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:31:5
+   |
+LL |     #[derive(Clone)] 'a: 'static,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:34:5
+   |
+LL |     #[rustfmt::skip] T: Trait,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: most attributes are not supported in `where` clauses
+  --> $DIR/unsupported_attribute.rs:35:5
+   |
+LL |     #[rustfmt::skip] 'a: 'static,
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = help: only `#[cfg]` and `#[cfg_attr]` are supported
+
+error: aborting due to 20 previous errors
+
diff --git a/triagebot.toml b/triagebot.toml
index ed352984fb1..7114c7ab27b 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -207,7 +207,7 @@ trigger_files = [
     "tests/rustdoc",
     "tests/rustdoc-ui",
     "tests/rustdoc-gui",
-    "tests/rustdoc-js",
+    "tests/rustdoc-js/",
     "tests/rustdoc-js-std",
     "tests/rustdoc-json",
 
@@ -701,6 +701,9 @@ cc = ["@davidtwco", "@wesleywiser"]
 [mentions."compiler/rustc_codegen_cranelift"]
 cc = ["@bjorn3"]
 
+[mentions."compiler/rustc_codegen_ssa"]
+cc = ["@WaffleLapkin"]
+
 [mentions."compiler/rustc_codegen_gcc"]
 cc = ["@antoyo", "@GuillaumeGomez"]
 
@@ -838,13 +841,7 @@ message = "Some changes occurred in GUI tests."
 cc = ["@GuillaumeGomez"]
 
 [mentions."tests/run-make/"]
-message = """
-This PR modifies `tests/run-make/`. If this PR is trying to port a Makefile
-run-make test to use rmake.rs, please update the
-[run-make port tracking issue](https://github.com/rust-lang/rust/issues/121876)
-so we can track our progress. You can either modify the tracking issue
-directly, or you can comment on the tracking issue and link this PR.
-"""
+message = "This PR modifies `run-make` tests."
 cc = ["@jieyouxu"]
 
 [mentions."src/rustdoc-json-types"]
@@ -1096,6 +1093,10 @@ title = "[stable"
 branch = "stable"
 
 [assign.adhoc_groups]
+compiler_leads = [
+    "@davidtwco",
+    "@wesleywiser",
+]
 compiler = [
     "@BoxyUwU",
     "@cjgillot",
@@ -1307,7 +1308,7 @@ project-exploit-mitigations = [
 "/tests/rustdoc" =                                       ["rustdoc"]
 "/tests/rustdoc-gui" =                                   ["rustdoc"]
 "/tests/rustdoc-js-std" =                                ["rustdoc"]
-"/tests/rustdoc-js" =                                    ["rustdoc"]
+"/tests/rustdoc-js/" =                                   ["rustdoc"]
 "/tests/rustdoc-json" =                                  ["@aDotInTheVoid"]
 "/tests/rustdoc-ui" =                                    ["rustdoc"]
 "/tests/ui" =                                            ["compiler"]
diff --git a/x b/x
index e656d37c1e4..551cfe6efbf 100755
--- a/x
+++ b/x
@@ -25,7 +25,13 @@ xpy=$(dirname "$(realpath "$0")")/x.py
 
 # On Windows, `py -3` sometimes works. We need to try it first because `python3`
 # sometimes tries to launch the app store on Windows.
-for SEARCH_PYTHON in py python3 python python2; do
+# On MacOS, `py` tries to install "Developer command line tools". Try `python3` first.
+# NOTE: running `bash -c ./x` from Windows doesn't set OSTYPE.
+case ${OSTYPE:-} in
+    cygwin*|msys*) SEARCH="py python3 python python2";;
+    *) SEARCH="python3 python py python2";;
+esac
+for SEARCH_PYTHON in $SEARCH; do
     if python=$(command -v $SEARCH_PYTHON) && [ -x "$python" ]; then
         if [ $SEARCH_PYTHON = py ]; then
             extra_arg="-3"