about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock2
-rw-r--r--compiler/rustc_abi/src/layout.rs13
-rw-r--r--compiler/rustc_abi/src/lib.rs22
-rw-r--r--compiler/rustc_ast/src/ast.rs11
-rw-r--r--compiler/rustc_ast/src/util/parser.rs6
-rw-r--r--compiler/rustc_borrowck/messages.ftl2
-rw-r--r--compiler/rustc_borrowck/src/session_diagnostics.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs11
-rw-r--r--compiler/rustc_codegen_cranelift/src/common.rs8
-rw-r--r--compiler/rustc_codegen_cranelift/src/debuginfo/types.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs5
-rw-r--r--compiler/rustc_codegen_cranelift/src/unsize.rs8
-rw-r--r--compiler/rustc_codegen_gcc/src/abi.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/asm.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/base.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/builder.rs15
-rw-r--r--compiler/rustc_codegen_gcc/src/common.rs38
-rw-r--r--compiler/rustc_codegen_gcc/src/consts.rs6
-rw-r--r--compiler/rustc_codegen_gcc/src/context.rs11
-rw-r--r--compiler/rustc_codegen_gcc/src/debuginfo.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/declare.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/int.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs8
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/simd.rs2
-rw-r--r--compiler/rustc_codegen_gcc/src/mono_item.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/type_.rs8
-rw-r--r--compiler/rustc_codegen_gcc/src/type_of.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/asm.rs545
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs12
-rw-r--r--compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs12
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs33
-rw-r--r--compiler/rustc_codegen_llvm/src/builder.rs145
-rw-r--r--compiler/rustc_codegen_llvm/src/callee.rs83
-rw-r--r--compiler/rustc_codegen_llvm/src/common.rs40
-rw-r--r--compiler/rustc_codegen_llvm/src/consts.rs77
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs23
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs17
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs28
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/declare.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs12
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs168
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs40
-rw-r--r--compiler/rustc_codegen_llvm/src/mono_item.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/type_.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/va_arg.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/command.rs26
-rw-r--r--compiler/rustc_codegen_ssa/src/back/linker.rs54
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/mod.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/rpath.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/back/symbol_export.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs40
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs107
-rw-r--r--compiler/rustc_codegen_ssa/src/codegen_attrs.rs31
-rw-r--r--compiler/rustc_codegen_ssa/src/common.rs7
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/mod.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs48
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs127
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs3
-rw-r--r--compiler/rustc_codegen_ssa/src/meth.rs12
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/analyze.rs12
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs20
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/constant.rs25
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs7
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs34
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs23
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/statement.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/size_of_val.rs25
-rw-r--r--compiler/rustc_codegen_ssa/src/target_features.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/asm.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/backend.rs28
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/builder.rs40
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/consts.rs14
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/debuginfo.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/declare.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/intrinsic.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/misc.rs5
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/mod.rs86
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/statics.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/traits/type_.rs39
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs19
-rw-r--r--compiler/rustc_driver_impl/src/signal_handler.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0796.md6
-rw-r--r--compiler/rustc_error_codes/src/lib.rs1
-rw-r--r--compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs2
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs36
-rw-r--r--compiler/rustc_errors/src/emitter.rs2
-rw-r--r--compiler/rustc_errors/src/json.rs12
-rw-r--r--compiler/rustc_errors/src/lib.rs37
-rw-r--r--compiler/rustc_feature/src/unstable.rs4
-rw-r--r--compiler/rustc_fluent_macro/src/fluent.rs17
-rw-r--r--compiler/rustc_hir/src/def.rs5
-rw-r--r--compiler/rustc_hir/src/hir.rs10
-rw-r--r--compiler/rustc_hir/src/lang_items.rs11
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl19
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/check/region.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs51
-rw-r--r--compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs13
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs62
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs11
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs26
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs13
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs37
-rw-r--r--compiler/rustc_interface/src/interface.rs4
-rw-r--r--compiler/rustc_lint/messages.ftl9
-rw-r--r--compiler/rustc_lint/src/context/diagnostics/check_cfg.rs14
-rw-r--r--compiler/rustc_lint/src/lib.rs8
-rw-r--r--compiler/rustc_lint/src/lints.rs35
-rw-r--r--compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs12
-rw-r--r--compiler/rustc_lint/src/static_mut_refs.rs154
-rw-r--r--compiler/rustc_lint/src/types.rs434
-rw-r--r--compiler/rustc_lint/src/types/literal.rs386
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs52
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp4
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp13
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h7
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp49
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp27
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp2
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs1
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs11
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs1
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_middle/src/ty/adjustment.rs3
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs4
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs4
-rw-r--r--compiler/rustc_middle/src/values.rs2
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs23
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs64
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters.rs231
-rw-r--r--compiler/rustc_mir_transform/src/coverage/graph.rs90
-rw-r--r--compiler/rustc_mir_transform/src/cross_crate_inline.rs2
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs10
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs36
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs11
-rw-r--r--compiler/rustc_parse/messages.ftl20
-rw-r--r--compiler/rustc_parse/src/errors.rs89
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs3
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs10
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs4
-rw-r--r--compiler/rustc_parse/src/parser/item.rs6
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs21
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs354
-rw-r--r--compiler/rustc_parse/src/parser/path.rs25
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs10
-rw-r--r--compiler/rustc_passes/src/check_attr.rs9
-rw-r--r--compiler/rustc_passes/src/layout_test.rs4
-rw-r--r--compiler/rustc_resolve/src/late.rs28
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs4
-rw-r--r--compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs5
-rw-r--r--compiler/rustc_session/src/config.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs57
-rw-r--r--compiler/rustc_symbol_mangling/src/lib.rs6
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs46
-rw-r--r--compiler/rustc_target/src/abi/call/m68k.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs7
-rw-r--r--compiler/rustc_target/src/abi/call/wasm.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/x86.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/x86_64.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/xtensa.rs2
-rw-r--r--compiler/rustc_target/src/spec/mod.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs24
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/traits/fulfillment_errors.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs3
-rw-r--r--config.example.toml2
-rw-r--r--library/alloc/src/alloc.rs8
-rw-r--r--library/alloc/src/collections/binary_heap/mod.rs1
-rw-r--r--library/alloc/src/collections/btree/map.rs2
-rw-r--r--library/alloc/src/collections/btree/set.rs1
-rw-r--r--library/alloc/src/collections/linked_list/tests.rs3
-rw-r--r--library/alloc/src/collections/vec_deque/mod.rs1
-rw-r--r--library/alloc/src/collections/vec_deque/tests.rs3
-rw-r--r--library/alloc/src/ffi/c_str.rs1
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/rc.rs115
-rw-r--r--library/alloc/src/slice.rs1
-rw-r--r--library/alloc/src/string.rs6
-rw-r--r--library/alloc/src/sync.rs141
-rw-r--r--library/alloc/src/vec/mod.rs78
-rw-r--r--library/alloc/tests/fmt.rs2
-rw-r--r--library/alloc/tests/vec.rs5
-rw-r--r--library/alloc/tests/vec_deque.rs3
-rw-r--r--library/core/src/alloc/layout.rs161
-rw-r--r--library/core/src/bool.rs1
-rw-r--r--library/core/src/cell/lazy.rs124
-rw-r--r--library/core/src/char/methods.rs42
-rw-r--r--library/core/src/cmp.rs1
-rw-r--r--library/core/src/iter/sources/repeat_n.rs60
-rw-r--r--library/core/src/iter/traits/iterator.rs3
-rw-r--r--library/core/src/lib.rs3
-rw-r--r--library/core/src/mem/maybe_uninit.rs7
-rw-r--r--library/core/src/num/f32.rs1
-rw-r--r--library/core/src/num/f64.rs1
-rw-r--r--library/core/src/num/mod.rs69
-rw-r--r--library/core/src/num/nonzero.rs10
-rw-r--r--library/core/src/option.rs2
-rw-r--r--library/core/src/panic/panic_info.rs12
-rw-r--r--library/core/src/panicking.rs4
-rw-r--r--library/core/src/ptr/alignment.rs5
-rw-r--r--library/core/src/result.rs1
-rw-r--r--library/core/src/slice/mod.rs1
-rw-r--r--library/core/src/str/mod.rs4
-rw-r--r--library/core/src/task/wake.rs1
-rw-r--r--library/core/tests/atomic.rs2
-rw-r--r--library/core/tests/iter/sources.rs24
-rw-r--r--library/core/tests/lazy.rs21
-rw-r--r--library/core/tests/lib.rs2
-rw-r--r--library/core/tests/num/int_macros.rs2
-rw-r--r--library/panic_unwind/src/seh.rs2
-rw-r--r--library/proc_macro/src/bridge/buffer.rs4
-rw-r--r--library/std/src/collections/hash/map.rs8
-rw-r--r--library/std/src/collections/hash/set.rs3
-rw-r--r--library/std/src/env.rs173
-rw-r--r--library/std/src/ffi/os_str.rs2
-rw-r--r--library/std/src/fs.rs27
-rw-r--r--library/std/src/io/mod.rs1
-rw-r--r--library/std/src/lib.rs1
-rw-r--r--library/std/src/os/unix/fs.rs1
-rw-r--r--library/std/src/path.rs3
-rw-r--r--library/std/src/sync/lazy_lock.rs119
-rw-r--r--library/std/src/sync/lazy_lock/tests.rs21
-rw-r--r--library/std/src/sync/mod.rs3
-rw-r--r--library/std/src/sync/once.rs10
-rw-r--r--library/std/src/sys/alloc/wasm.rs3
-rw-r--r--library/std/src/sys/pal/unsupported/process.rs11
-rw-r--r--library/std/src/sys/pal/windows/fs/remove_dir_all.rs15
-rw-r--r--library/std/src/sys/sync/once/futex.rs9
-rw-r--r--library/std/src/sys/sync/once/no_threads.rs9
-rw-r--r--library/std/src/sys/sync/once/queue.rs9
-rw-r--r--library/std/src/thread/local/tests.rs3
-rw-r--r--library/std/src/thread/mod.rs48
-rw-r--r--library/std/src/time.rs1
-rw-r--r--src/bootstrap/Cargo.lock13
-rw-r--r--src/bootstrap/Cargo.toml2
-rw-r--r--src/bootstrap/src/core/build_steps/doc.rs7
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs4
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs5
-rw-r--r--src/bootstrap/src/core/builder.rs1
-rw-r--r--src/bootstrap/src/core/config/config.rs11
-rw-r--r--src/bootstrap/src/core/config/tests.rs2
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile1
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile62
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile1
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile1
-rw-r--r--src/ci/github-actions/jobs.yml7
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md3
-rw-r--r--src/doc/rustc/src/platform-support/arm64e-apple-tvos.md37
-rw-r--r--src/doc/rustc/src/platform-support/trusty.md3
-rw-r--r--src/librustdoc/core.rs2
-rw-r--r--src/librustdoc/doctest.rs2
-rw-r--r--src/librustdoc/doctest/rust.rs13
-rw-r--r--src/librustdoc/html/render/mod.rs1
-rw-r--r--src/librustdoc/html/sources.rs1
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css11
-rw-r--r--src/librustdoc/html/static/js/main.js14
-rw-r--r--src/librustdoc/html/static/js/scrape-examples.js51
-rw-r--r--src/librustdoc/html/templates/scraped_source.html15
-rw-r--r--src/tools/build-manifest/src/main.rs5
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/entry.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/format_push_string.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/instant_subtraction.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_while_let_some.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_retain.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_strip.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/open_options.rs23
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/waker_clone_wake.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_clone.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/higher.rs8
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs28
-rw-r--r--src/tools/clippy/clippy_utils/src/paths.rs88
-rw-r--r--src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr13
-rw-r--r--src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs1
-rw-r--r--src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr58
-rw-r--r--src/tools/clippy/tests/ui/must_use_candidates.fixed7
-rw-r--r--src/tools/clippy/tests/ui/must_use_candidates.rs7
-rw-r--r--src/tools/clippy/tests/ui/must_use_candidates.stderr10
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr36
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.fixed2
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.rs2
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.stderr74
-rw-r--r--src/tools/compiletest/src/common.rs3
-rw-r--r--src/tools/compiletest/src/header.rs12
-rw-r--r--src/tools/compiletest/src/lib.rs3
-rw-r--r--src/tools/compiletest/src/runtest.rs2141
-rw-r--r--src/tools/compiletest/src/runtest/assembly.rs19
-rw-r--r--src/tools/compiletest/src/runtest/codegen.rs22
-rw-r--r--src/tools/compiletest/src/runtest/codegen_units.rs191
-rw-r--r--src/tools/compiletest/src/runtest/coverage.rs4
-rw-r--r--src/tools/compiletest/src/runtest/crash.rs25
-rw-r--r--src/tools/compiletest/src/runtest/debuginfo.rs509
-rw-r--r--src/tools/compiletest/src/runtest/incremental.rs128
-rw-r--r--src/tools/compiletest/src/runtest/js_doc.rs32
-rw-r--r--src/tools/compiletest/src/runtest/mir_opt.rs155
-rw-r--r--src/tools/compiletest/src/runtest/pretty.rs104
-rw-r--r--src/tools/compiletest/src/runtest/run_make.rs526
-rw-r--r--src/tools/compiletest/src/runtest/rustdoc.rs34
-rw-r--r--src/tools/compiletest/src/runtest/rustdoc_json.rs48
-rw-r--r--src/tools/compiletest/src/runtest/ui.rs233
-rw-r--r--src/tools/compiletest/src/runtest/valgrind.rs34
-rw-r--r--src/tools/miri/miri-script/src/args.rs2
-rw-r--r--src/tools/miri/miri-script/src/commands.rs6
-rw-r--r--src/tools/miri/miri-script/src/main.rs2
-rw-r--r--src/tools/miri/miri-script/src/util.rs4
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/alloc_addresses/reuse_pool.rs2
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs22
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs4
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs2
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs2
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs24
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs36
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs2
-rw-r--r--src/tools/miri/src/concurrency/sync.rs22
-rw-r--r--src/tools/miri/src/concurrency/vector_clock.rs2
-rw-r--r--src/tools/miri/src/diagnostics.rs2
-rw-r--r--src/tools/miri/src/eval.rs3
-rw-r--r--src/tools/miri/src/helpers.rs9
-rw-r--r--src/tools/miri/src/intrinsics/mod.rs4
-rw-r--r--src/tools/miri/src/intrinsics/simd.rs4
-rw-r--r--src/tools/miri/src/lib.rs8
-rw-r--r--src/tools/miri/src/machine.rs16
-rw-r--r--src/tools/miri/src/operator.rs2
-rw-r--r--src/tools/miri/src/shims/backtrace.rs2
-rw-r--r--src/tools/miri/src/shims/extern_static.rs8
-rw-r--r--src/tools/miri/src/shims/os_str.rs2
-rw-r--r--src/tools/miri/src/shims/panic.rs13
-rw-r--r--src/tools/miri/src/shims/tls.rs2
-rw-r--r--src/tools/miri/src/shims/unix/env.rs2
-rw-r--r--src/tools/miri/src/shims/unix/fs.rs4
-rw-r--r--src/tools/miri/src/shims/x86/aesni.rs2
-rw-r--r--src/tools/miri/src/shims/x86/avx.rs8
-rw-r--r--src/tools/miri/src/shims/x86/avx2.rs6
-rw-r--r--src/tools/miri/src/shims/x86/mod.rs4
-rw-r--r--src/tools/miri/src/shims/x86/sse.rs4
-rw-r--r--src/tools/miri/src/shims/x86/sse2.rs4
-rw-r--r--src/tools/miri/src/shims/x86/sse42.rs2
-rw-r--r--src/tools/miri/test-cargo-miri/src/main.rs2
-rw-r--r--src/tools/miri/test-cargo-miri/subcrate/main.rs2
-rw-r--r--src/tools/miri/test-cargo-miri/subcrate/test.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs2
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/windows_join_self.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/deallocate-bad-size.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/deallocate-twice.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/reallocate-bad-size.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/reallocate-change-alloc.rs2
-rw-r--r--src/tools/miri/tests/fail/alloc/reallocate-dangling.rs2
-rw-r--r--src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.rs2
-rw-r--r--src/tools/miri/tests/fail/both_borrows/zero-sized-protected.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/fence_after_load.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/mixed_size_read.rs2
-rw-r--r--src/tools/miri/tests/fail/data_race/mixed_size_write.rs2
-rw-r--r--src/tools/miri/tests/fail/should-pass/cpp20_rwc_syncs.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs2
-rw-r--r--src/tools/miri/tests/fail/tree_borrows/children-can-alias.rs2
-rw-r--r--src/tools/miri/tests/fail/uninit/padding-enum.rs5
-rw-r--r--src/tools/miri/tests/fail/uninit/padding-enum.stderr4
-rw-r--r--src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.rs2
-rw-r--r--src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs3
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs3
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/windows_init_once.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/concurrency/windows_join_multiple.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs24
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs3
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-fs.rs4
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-pipe.rs2
-rw-r--r--src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs4
-rw-r--r--src/tools/miri/tests/pass-dep/tokio/sleep.rs2
-rw-r--r--src/tools/miri/tests/pass/0weak_memory_consistency.rs2
-rw-r--r--src/tools/miri/tests/pass/async-drop.rs9
-rw-r--r--src/tools/miri/tests/pass/atomic.rs6
-rw-r--r--src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs2
-rw-r--r--src/tools/miri/tests/pass/catch.rs2
-rw-r--r--src/tools/miri/tests/pass/drop_on_array_elements.rs2
-rw-r--r--src/tools/miri/tests/pass/drop_on_fat_ptr_array_elements.rs2
-rw-r--r--src/tools/miri/tests/pass/drop_on_zst_array_elements.rs2
-rw-r--r--src/tools/miri/tests/pass/drop_through_owned_slice.rs2
-rw-r--r--src/tools/miri/tests/pass/intrinsics/portable-simd.rs2
-rw-r--r--src/tools/miri/tests/pass/panic/catch_panic.rs2
-rw-r--r--src/tools/miri/tests/pass/panic/concurrent-panic.rs2
-rw-r--r--src/tools/miri/tests/pass/path.rs2
-rw-r--r--src/tools/miri/tests/pass/shims/fs-symlink.rs2
-rw-r--r--src/tools/miri/tests/pass/shims/fs.rs4
-rw-r--r--src/tools/miri/tests/pass/static_memory_modification.rs3
-rw-r--r--src/tools/miri/tests/pass/static_mut.rs3
-rw-r--r--src/tools/miri/tests/pass/tls/tls_static.rs2
-rw-r--r--src/tools/miri/tests/pass/weak_memory/weak.rs2
-rw-r--r--src/tools/miri/tests/ui.rs33
-rw-r--r--src/tools/run-make-support/src/fs.rs180
-rw-r--r--src/tools/rustfmt/.github/workflows/check_diff.yml2
-rw-r--r--src/tools/rustfmt/.github/workflows/integration.yml2
-rw-r--r--src/tools/rustfmt/.github/workflows/linux.yml2
-rw-r--r--src/tools/rustfmt/.github/workflows/mac.yml3
-rw-r--r--src/tools/rustfmt/.github/workflows/rustdoc_check.yml2
-rw-r--r--src/tools/rustfmt/.github/workflows/upload-assets.yml2
-rw-r--r--src/tools/rustfmt/.github/workflows/windows.yml2
-rw-r--r--src/tools/rustfmt/CHANGELOG.md64
-rw-r--r--src/tools/rustfmt/Cargo.lock14
-rw-r--r--src/tools/rustfmt/Cargo.toml4
-rw-r--r--src/tools/rustfmt/Configurations.md17
-rw-r--r--src/tools/rustfmt/Contributing.md21
-rw-r--r--src/tools/rustfmt/build.rs19
-rw-r--r--src/tools/rustfmt/check_diff/Cargo.lock290
-rw-r--r--src/tools/rustfmt/check_diff/Cargo.toml4
-rw-r--r--src/tools/rustfmt/check_diff/src/lib.rs58
-rw-r--r--src/tools/rustfmt/check_diff/src/main.rs8
-rw-r--r--src/tools/rustfmt/check_diff/tests/bash_commands.rs12
-rw-r--r--src/tools/rustfmt/check_diff/tests/git.rs16
-rwxr-xr-xsrc/tools/rustfmt/ci/build_and_test.bat8
-rwxr-xr-xsrc/tools/rustfmt/ci/build_and_test.sh8
-rw-r--r--src/tools/rustfmt/config_proc_macro/Cargo.toml4
-rw-r--r--src/tools/rustfmt/config_proc_macro/src/utils.rs2
-rw-r--r--src/tools/rustfmt/rust-toolchain2
-rw-r--r--src/tools/rustfmt/rustfmt.toml3
-rw-r--r--src/tools/rustfmt/src/attr.rs76
-rw-r--r--src/tools/rustfmt/src/bin/main.rs334
-rw-r--r--src/tools/rustfmt/src/chains.rs191
-rw-r--r--src/tools/rustfmt/src/closures.rs93
-rw-r--r--src/tools/rustfmt/src/comment.rs60
-rw-r--r--src/tools/rustfmt/src/config/config_type.rs149
-rw-r--r--src/tools/rustfmt/src/config/file_lines.rs6
-rw-r--r--src/tools/rustfmt/src/config/mod.rs580
-rw-r--r--src/tools/rustfmt/src/config/options.rs201
-rw-r--r--src/tools/rustfmt/src/config/style_edition.rs2
-rw-r--r--src/tools/rustfmt/src/emitter/checkstyle.rs2
-rw-r--r--src/tools/rustfmt/src/emitter/json.rs2
-rw-r--r--src/tools/rustfmt/src/emitter/modified_lines.rs2
-rw-r--r--src/tools/rustfmt/src/expr.rs476
-rw-r--r--src/tools/rustfmt/src/formatting.rs2
-rw-r--r--src/tools/rustfmt/src/git-rustfmt/main.rs13
-rw-r--r--src/tools/rustfmt/src/ignore_path.rs9
-rw-r--r--src/tools/rustfmt/src/imports.rs218
-rw-r--r--src/tools/rustfmt/src/items.rs433
-rw-r--r--src/tools/rustfmt/src/lib.rs8
-rw-r--r--src/tools/rustfmt/src/lists.rs31
-rw-r--r--src/tools/rustfmt/src/macros.rs265
-rw-r--r--src/tools/rustfmt/src/matches.rs143
-rw-r--r--src/tools/rustfmt/src/missed_spans.rs14
-rw-r--r--src/tools/rustfmt/src/modules.rs2
-rw-r--r--src/tools/rustfmt/src/overflow.rs58
-rw-r--r--src/tools/rustfmt/src/pairs.rs99
-rw-r--r--src/tools/rustfmt/src/parse/macros/asm.rs2
-rw-r--r--src/tools/rustfmt/src/parse/macros/cfg_if.rs2
-rw-r--r--src/tools/rustfmt/src/parse/macros/mod.rs4
-rw-r--r--src/tools/rustfmt/src/parse/parser.rs6
-rw-r--r--src/tools/rustfmt/src/parse/session.rs9
-rw-r--r--src/tools/rustfmt/src/patterns.rs143
-rw-r--r--src/tools/rustfmt/src/reorder.rs27
-rw-r--r--src/tools/rustfmt/src/rewrite.rs68
-rw-r--r--src/tools/rustfmt/src/rustfmt_diff.rs2
-rw-r--r--src/tools/rustfmt/src/sort.rs368
-rw-r--r--src/tools/rustfmt/src/source_file.rs2
-rw-r--r--src/tools/rustfmt/src/spanned.rs9
-rw-r--r--src/tools/rustfmt/src/stmt.rs41
-rw-r--r--src/tools/rustfmt/src/string.rs4
-rw-r--r--src/tools/rustfmt/src/test/configuration_snippet.rs4
-rw-r--r--src/tools/rustfmt/src/test/mod.rs76
-rw-r--r--src/tools/rustfmt/src/types.rs371
-rw-r--r--src/tools/rustfmt/src/utils.rs16
-rw-r--r--src/tools/rustfmt/src/vertical.rs47
-rw-r--r--src/tools/rustfmt/src/visitor.rs48
-rw-r--r--src/tools/rustfmt/tests/config/issue-5801-v2.toml2
-rw-r--r--src/tools/rustfmt/tests/config/issue-6302.toml1
-rw-r--r--src/tools/rustfmt/tests/config/style-edition/just-style-edition/rustfmt.toml1
-rw-r--r--src/tools/rustfmt/tests/config/style-edition/just-version/rustfmt.toml1
-rw-r--r--src/tools/rustfmt/tests/config/style-edition/overrides/rustfmt.toml2
-rw-r--r--src/tools/rustfmt/tests/config/style-edition/style-edition-and-edition/rustfmt.toml2
-rw-r--r--src/tools/rustfmt/tests/config/style-edition/version-edition/rustfmt.toml2
-rw-r--r--src/tools/rustfmt/tests/config/style-edition/version-style-edition-and-edition/rustfmt.toml3
-rw-r--r--src/tools/rustfmt/tests/config/style-edition/version-style-edition/rustfmt.toml2
-rw-r--r--src/tools/rustfmt/tests/rustfmt/main.rs27
-rw-r--r--src/tools/rustfmt/tests/source/arrow_in_comments/arrow_in_single_comment.rs2
-rw-r--r--src/tools/rustfmt/tests/source/arrow_in_comments/multiple_arrows.rs2
-rw-r--r--src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/one.rs2
-rw-r--r--src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/two.rs2
-rw-r--r--src/tools/rustfmt/tests/source/configs/style_edition/overflow_delim_expr_2015.rs155
-rw-r--r--src/tools/rustfmt/tests/source/configs/style_edition/overflow_delim_expr_2024.rs155
-rw-r--r--src/tools/rustfmt/tests/source/fn-single-line/version_one.rs2
-rw-r--r--src/tools/rustfmt/tests/source/fn-single-line/version_two.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-2179/one.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-2179/two.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3213/version_one.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3213/version_two.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3227/two.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3270/one.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3270/two.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3272/v1.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3272/v2.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3278/version_one.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3278/version_two.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3295/two.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3302.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3701/one.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3701/two.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3805.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3840/version-two_hard-tabs.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-3840/version-two_soft-tabs.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-4381/style_edition_2015.rs3
-rw-r--r--src/tools/rustfmt/tests/source/issue-4530.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-4689/one.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-4689/two.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-5586.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-5655/one.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-5655/two.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-5801/comment_unexpectedly_wraps_before_max_width.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-5987/two.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-6147/case_rustfmt_v1.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue-6147/case_rustfmt_v2.rs2
-rw-r--r--src/tools/rustfmt/tests/source/issue_5027.rs2
-rw-r--r--src/tools/rustfmt/tests/source/let_else_v2.rs2
-rw-r--r--src/tools/rustfmt/tests/source/long-fn-1/version_one.rs2
-rw-r--r--src/tools/rustfmt/tests/source/long-fn-1/version_two.rs2
-rw-r--r--src/tools/rustfmt/tests/source/one_line_if_v1.rs2
-rw-r--r--src/tools/rustfmt/tests/source/one_line_if_v2.rs2
-rw-r--r--src/tools/rustfmt/tests/source/single-line-macro/v1.rs2
-rw-r--r--src/tools/rustfmt/tests/source/single-line-macro/v2.rs2
-rw-r--r--src/tools/rustfmt/tests/source/trailing_comments/hard_tabs.rs2
-rw-r--r--src/tools/rustfmt/tests/source/trailing_comments/soft_tabs.rs2
-rw-r--r--src/tools/rustfmt/tests/source/tuple_v2.rs2
-rw-r--r--src/tools/rustfmt/tests/source/type-alias-where-clauses-with-comments.rs31
-rw-r--r--src/tools/rustfmt/tests/source/type-alias-where-clauses.rs20
-rw-r--r--src/tools/rustfmt/tests/target/arrow_in_comments/arrow_in_single_comment.rs2
-rw-r--r--src/tools/rustfmt/tests/target/arrow_in_comments/multiple_arrows.rs2
-rw-r--r--src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/one.rs2
-rw-r--r--src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/two.rs2
-rw-r--r--src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2015.rs135
-rw-r--r--src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2024.rs120
-rw-r--r--src/tools/rustfmt/tests/target/configs/version/mapped.rs9
-rw-r--r--src/tools/rustfmt/tests/target/fn-single-line/version_one.rs2
-rw-r--r--src/tools/rustfmt/tests/target/fn-single-line/version_two.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-2179/one.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-2179/two.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3132.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3213/version_one.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3213/version_two.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3227/one.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3227/two.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3270/one.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3270/two.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3270/wrap.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3272/v1.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3272/v2.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3278/version_one.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3278/version_two.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3295/two.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3302.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3614/version_one.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3614/version_two.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3701/one.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3701/two.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3805.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3840/version-two_hard-tabs.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3840/version-two_soft-tabs.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-3882.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-4381/style_edition_2015.rs3
-rw-r--r--src/tools/rustfmt/tests/target/issue-4381/style_edition_2024.rs3
-rw-r--r--src/tools/rustfmt/tests/target/issue-4530.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-4689/one.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-4689/two.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-5586.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-5655/one.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-5655/two.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-5801/comment_does_not_wrap_within_max_width.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-5801/comment_unexpectedly_wraps_before_max_width.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-5987/one.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-5987/two.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-6109.rs7
-rw-r--r--src/tools/rustfmt/tests/target/issue-6147/case_rustfmt_v1.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue-6147/case_rustfmt_v2.rs2
-rw-r--r--src/tools/rustfmt/tests/target/issue_5027.rs2
-rw-r--r--src/tools/rustfmt/tests/target/let_else_v2.rs2
-rw-r--r--src/tools/rustfmt/tests/target/long-fn-1/version_one.rs2
-rw-r--r--src/tools/rustfmt/tests/target/long-fn-1/version_two.rs2
-rw-r--r--src/tools/rustfmt/tests/target/one_line_if_v1.rs2
-rw-r--r--src/tools/rustfmt/tests/target/one_line_if_v2.rs2
-rw-r--r--src/tools/rustfmt/tests/target/single-line-macro/v1.rs2
-rw-r--r--src/tools/rustfmt/tests/target/single-line-macro/v2.rs2
-rw-r--r--src/tools/rustfmt/tests/target/style_edition/default.rs10
-rw-r--r--src/tools/rustfmt/tests/target/style_edition/follows_edition.rs14
-rw-r--r--src/tools/rustfmt/tests/target/style_edition/overrides_edition_when_set.rs14
-rw-r--r--src/tools/rustfmt/tests/target/trailing_comments/hard_tabs.rs2
-rw-r--r--src/tools/rustfmt/tests/target/trailing_comments/soft_tabs.rs2
-rw-r--r--src/tools/rustfmt/tests/target/tuple_v2.rs2
-rw-r--r--src/tools/rustfmt/tests/target/type-alias-where-clauses-with-comments.rs39
-rw-r--r--src/tools/rustfmt/tests/target/type-alias-where-clauses.rs20
-rw-r--r--src/tools/tidy/src/issues.txt1
-rw-r--r--src/tools/tidy/src/lib.rs1
-rw-r--r--src/tools/tidy/src/main.rs1
-rw-r--r--src/tools/tidy/src/rustdoc_templates.rs58
-rw-r--r--tests/assembly/simd-bitmask.rs1
-rw-r--r--tests/assembly/simd-intrinsic-gather.rs1
-rw-r--r--tests/assembly/simd-intrinsic-mask-reduce.rs1
-rw-r--r--tests/assembly/simd-intrinsic-scatter.rs1
-rw-r--r--tests/assembly/simd-intrinsic-select.rs1
-rw-r--r--tests/assembly/stack-probes.rs1
-rw-r--r--tests/assembly/stack-protector/stack-protector-heuristics-effect.rs1
-rw-r--r--tests/assembly/targets/targets-macho.rs5
-rw-r--r--tests/codegen/align-byval.rs28
-rw-r--r--tests/codegen/enum/enum-early-otherwise-branch.rs1
-rw-r--r--tests/codegen/issue-97217.rs1
-rw-r--r--tests/codegen/issues/issue-110797-enum-jump-same.rs1
-rw-r--r--tests/codegen/issues/issue-118392.rs1
-rw-r--r--tests/codegen/issues/issue-44056-macos-tls-align.rs27
-rw-r--r--tests/codegen/maybeuninit-rvo.rs1
-rw-r--r--tests/codegen/option-niche-eq.rs1
-rw-r--r--tests/codegen/repr/transparent-byval-struct-ptr.rs (renamed from tests/codegen/repr/transparent-struct-ptr.rs)9
-rw-r--r--tests/codegen/repr/transparent-imm-array.rs3
-rw-r--r--tests/codegen/repr/transparent-opaque-ptr.rs113
-rw-r--r--tests/codegen/slice-pointer-nonnull-unwrap.rs1
-rw-r--r--tests/codegen/try_question_mark_nop.rs13
-rw-r--r--tests/codegen/unwind-landingpad-cold.rs1
-rw-r--r--tests/codegen/unwind-landingpad-inline.rs1
-rw-r--r--tests/coverage/mcdc/condition-limit.cov-map8
-rw-r--r--tests/coverage/mcdc/condition-limit.coverage1
-rw-r--r--tests/coverage/mcdc/condition-limit.rs1
-rw-r--r--tests/coverage/mcdc/if.cov-map28
-rw-r--r--tests/coverage/mcdc/if.coverage1
-rw-r--r--tests/coverage/mcdc/if.rs1
-rw-r--r--tests/coverage/mcdc/inlined_expressions.cov-map4
-rw-r--r--tests/coverage/mcdc/inlined_expressions.coverage1
-rw-r--r--tests/coverage/mcdc/inlined_expressions.rs1
-rw-r--r--tests/coverage/mcdc/nested_if.cov-map16
-rw-r--r--tests/coverage/mcdc/nested_if.coverage1
-rw-r--r--tests/coverage/mcdc/nested_if.rs1
-rw-r--r--tests/coverage/mcdc/non_control_flow.cov-map28
-rw-r--r--tests/coverage/mcdc/non_control_flow.coverage1
-rw-r--r--tests/coverage/mcdc/non_control_flow.rs1
-rw-r--r--tests/crashes/120016.rs19
-rw-r--r--tests/crashes/127804.rs12
-rw-r--r--tests/crashes/128119.rs15
-rw-r--r--tests/crashes/128232.rs15
-rw-r--r--tests/crashes/130310.rs15
-rw-r--r--tests/crashes/130411.rs6
-rw-r--r--tests/crashes/130413.rs17
-rw-r--r--tests/crashes/130425.rs13
-rw-r--r--tests/mir-opt/inline/cycle.main.Inline.panic-abort.diff21
-rw-r--r--tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff29
-rw-r--r--tests/mir-opt/inline/cycle.rs4
-rw-r--r--tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-abort.diff6
-rw-r--r--tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff6
-rw-r--r--tests/run-make/compiler-builtins/rmake.rs4
-rw-r--r--tests/run-make/embed-source-dwarf/rmake.rs5
-rw-r--r--tests/run-make/invalid-symlink-search-path/rmake.rs17
-rw-r--r--tests/run-make/symlinked-extern/rmake.rs24
-rw-r--r--tests/run-make/symlinked-libraries/rmake.rs15
-rw-r--r--tests/run-make/symlinked-rlib/rmake.rs2
-rw-r--r--tests/run-make/thumb-none-cortex-m/rmake.rs6
-rw-r--r--tests/rustdoc-gui/docblock-code-block-line-number.goml63
-rw-r--r--tests/rustdoc-gui/scrape-examples-layout.goml8
-rw-r--r--tests/rustdoc-ui/doctest/doctest-output-include-fail.md7
-rw-r--r--tests/rustdoc-ui/doctest/doctest-output-include-fail.rs7
-rw-r--r--tests/rustdoc-ui/doctest/doctest-output-include-fail.stdout24
-rw-r--r--tests/rustdoc-ui/doctest/doctest-output.stdout2
-rw-r--r--tests/ui-fulldeps/fluent-messages/many-lines.ftl11
-rw-r--r--tests/ui-fulldeps/fluent-messages/test.rs5
-rw-r--r--tests/ui-fulldeps/fluent-messages/test.stderr17
-rw-r--r--tests/ui-fulldeps/run-compiler-twice.rs2
-rw-r--r--tests/ui/abi/compatibility.rs1
-rw-r--r--tests/ui/abi/stack-probes-lto.rs1
-rw-r--r--tests/ui/abi/stack-probes.rs1
-rw-r--r--tests/ui/abi/statics/static-mut-foreign.rs5
-rw-r--r--tests/ui/abi/statics/static-mut-foreign.stderr31
-rw-r--r--tests/ui/array-slice-vec/slice-panic-1.rs2
-rw-r--r--tests/ui/array-slice-vec/slice-panic-2.rs2
-rw-r--r--tests/ui/array-slice-vec/slice.rs3
-rw-r--r--tests/ui/asm/inline-syntax.arm.stderr26
-rw-r--r--tests/ui/asm/inline-syntax.arm_llvm_18.stderr90
-rw-r--r--tests/ui/asm/inline-syntax.rs14
-rw-r--r--tests/ui/asm/inline-syntax.x86_64.stderr14
-rw-r--r--tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs1
-rw-r--r--tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr17
-rw-r--r--tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs1
-rw-r--r--tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr17
-rw-r--r--tests/ui/async-await/async-closures/foreign.rs5
-rw-r--r--tests/ui/async-await/async-closures/inline-body.rs34
-rw-r--r--tests/ui/async-await/issues/issue-67611-static-mut-refs.rs2
-rw-r--r--tests/ui/async-await/pin-reborrow-arg.rs36
-rw-r--r--tests/ui/async-await/pin-reborrow-const-as-mut.rs18
-rw-r--r--tests/ui/async-await/pin-reborrow-const-as-mut.stderr19
-rw-r--r--tests/ui/async-await/pin-reborrow-once.rs13
-rw-r--r--tests/ui/async-await/pin-reborrow-once.stderr12
-rw-r--r--tests/ui/async-await/pin-reborrow-self.rs24
-rw-r--r--tests/ui/async-await/pin-reborrow-shorter.rs14
-rw-r--r--tests/ui/binding/order-drop-with-match.rs2
-rw-r--r--tests/ui/borrowck/borrowck-access-permissions.rs1
-rw-r--r--tests/ui/borrowck/borrowck-access-permissions.stderr25
-rw-r--r--tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr11
-rw-r--r--tests/ui/borrowck/issue-20801.rs1
-rw-r--r--tests/ui/borrowck/issue-20801.stderr25
-rw-r--r--tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs3
-rw-r--r--tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr55
-rw-r--r--tests/ui/cfg/cfg-false-feature.rs2
-rw-r--r--tests/ui/check-cfg/raw-keywords.edition2015.stderr40
-rw-r--r--tests/ui/check-cfg/raw-keywords.edition2021.stderr40
-rw-r--r--tests/ui/check-cfg/raw-keywords.rs40
-rw-r--r--tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr11
-rw-r--r--tests/ui/coercion/coerce-issue-49593-box-never.rs8
-rw-r--r--tests/ui/compiletest-self-test/compile-flags-last.stderr3
-rw-r--r--tests/ui/const-generics/generic_arg_infer/issue-91614.stderr4
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-109141.rs3
-rw-r--r--tests/ui/const-generics/generic_const_exprs/issue-109141.stderr33
-rw-r--r--tests/ui/const-generics/generic_const_exprs/opaque_type.rs1
-rw-r--r--tests/ui/const-generics/generic_const_exprs/opaque_type.stderr14
-rw-r--r--tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.rs54
-rw-r--r--tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.stderr27
-rw-r--r--tests/ui/consts/const_let_assign2.stderr11
-rw-r--r--tests/ui/consts/issue-116186.rs2
-rw-r--r--tests/ui/consts/issue-116186.stderr11
-rw-r--r--tests/ui/consts/static-mut-refs.rs3
-rw-r--r--tests/ui/coroutine/static-mut-reference-across-yield.rs2
-rw-r--r--tests/ui/drop/drop-struct-as-object.rs3
-rw-r--r--tests/ui/drop/drop-struct-as-object.stderr2
-rw-r--r--tests/ui/drop/issue-23338-ensure-param-drop-order.rs3
-rw-r--r--tests/ui/drop/issue-23338-ensure-param-drop-order.stderr17
-rw-r--r--tests/ui/drop/issue-23611-enum-swap-in-drop.rs3
-rw-r--r--tests/ui/drop/issue-23611-enum-swap-in-drop.stderr17
-rw-r--r--tests/ui/drop/issue-48962.rs3
-rw-r--r--tests/ui/drop/repeat-drop.rs3
-rw-r--r--tests/ui/drop/static-issue-17302.rs (renamed from tests/ui/issues/issue-17302.rs)3
-rw-r--r--tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs19
-rw-r--r--tests/ui/duplicate/multiple-types-with-same-name-and-derive.stderr71
-rw-r--r--tests/ui/feature-gates/feature-gate-pin_ergonomics.rs15
-rw-r--r--tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr21
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs24
-rw-r--r--tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr41
-rw-r--r--tests/ui/for-loop-while/cleanup-rvalue-during-if-and-while.rs3
-rw-r--r--tests/ui/functional-struct-update/functional-struct-update-respects-privacy.rs4
-rw-r--r--tests/ui/functional-struct-update/functional-struct-update-respects-privacy.stderr2
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions1.stderr11
-rw-r--r--tests/ui/half-open-range-patterns/range_pat_interactions2.stderr23
-rw-r--r--tests/ui/impl-trait/issues/issue-62742.rs3
-rw-r--r--tests/ui/impl-trait/issues/issue-62742.stderr52
-rw-r--r--tests/ui/impl-trait/opaque-hidden-inferred-rpitit.rs16
-rw-r--r--tests/ui/inference/need_type_info/type-alias-indirect.stderr2
-rw-r--r--tests/ui/inference/need_type_info/type-alias.stderr6
-rw-r--r--tests/ui/instrument-coverage/mcdc-condition-limit.bad.stderr2
-rw-r--r--tests/ui/instrument-coverage/mcdc-condition-limit.rs1
-rw-r--r--tests/ui/invalid-compile-flags/print-without-arg.rs1
-rw-r--r--tests/ui/invalid-compile-flags/print-without-arg.stderr5
-rw-r--r--tests/ui/issues/issue-10734.rs3
-rw-r--r--tests/ui/issues/issue-15858.rs2
-rw-r--r--tests/ui/issues/issue-15858.stderr2
-rw-r--r--tests/ui/issues/issue-16151.rs3
-rw-r--r--tests/ui/issues/issue-39367.rs1
-rw-r--r--tests/ui/issues/issue-39367.stderr17
-rw-r--r--tests/ui/issues/issue-4734.rs3
-rw-r--r--tests/ui/issues/issue-54410.rs1
-rw-r--r--tests/ui/issues/issue-54410.stderr17
-rw-r--r--tests/ui/issues/issue-6892.rs2
-rw-r--r--tests/ui/issues/issue-8860.rs2
-rw-r--r--tests/ui/link-section.rs3
-rw-r--r--tests/ui/linkage-attr/linkage-attr-mutable-static.rs2
-rw-r--r--tests/ui/linkage-attr/linkage-attr-mutable-static.stderr2
-rw-r--r--tests/ui/lint/improper-types-stack-overflow-130310.rs20
-rw-r--r--tests/ui/lint/improper-types-stack-overflow-130310.stderr11
-rw-r--r--tests/ui/lint/static-mut-refs.e2021.stderr143
-rw-r--r--tests/ui/lint/static-mut-refs.e2024.stderr143
-rw-r--r--tests/ui/lint/static-mut-refs.rs95
-rw-r--r--tests/ui/lto/lto-still-runs-thread-dtors.rs3
-rw-r--r--tests/ui/macros/auxiliary/metavar_2018.rs14
-rw-r--r--tests/ui/macros/metavar_cross_edition_recursive_macros.rs38
-rw-r--r--tests/ui/methods/method-self-arg-trait.rs3
-rw-r--r--tests/ui/methods/method-self-arg.rs3
-rw-r--r--tests/ui/methods/receiver-equality.rs16
-rw-r--r--tests/ui/methods/receiver-equality.stderr12
-rw-r--r--tests/ui/mir/mir_early_return_scope.rs2
-rw-r--r--tests/ui/mismatched_types/mismatch-args-crash-issue-130400.rs8
-rw-r--r--tests/ui/mismatched_types/mismatch-args-crash-issue-130400.stderr26
-rw-r--r--tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr11
-rw-r--r--tests/ui/nll/issue-69114-static-mut-ty.rs3
-rw-r--r--tests/ui/nll/issue-69114-static-mut-ty.stderr4
-rw-r--r--tests/ui/numbers-arithmetic/shift-near-oflo.rs3
-rw-r--r--tests/ui/parser/bad-name.rs5
-rw-r--r--tests/ui/parser/bad-name.stderr20
-rw-r--r--tests/ui/parser/issues/issue-24375.stderr15
-rw-r--r--tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr8
-rw-r--r--tests/ui/parser/misspelled-keywords/impl-trait.stderr4
-rw-r--r--tests/ui/parser/misspelled-keywords/ref.stderr4
-rw-r--r--tests/ui/parser/pat-lt-bracket-6.stderr4
-rw-r--r--tests/ui/parser/pat-recover-exprs.rs28
-rw-r--r--tests/ui/parser/pat-recover-exprs.stderr76
-rw-r--r--tests/ui/parser/pat-recover-methodcalls.rs37
-rw-r--r--tests/ui/parser/pat-recover-methodcalls.stderr35
-rw-r--r--tests/ui/parser/pat-recover-ranges.stderr132
-rw-r--r--tests/ui/parser/recover/recover-pat-exprs.rs106
-rw-r--r--tests/ui/parser/recover/recover-pat-exprs.stderr772
-rw-r--r--tests/ui/parser/recover/recover-pat-issues.rs46
-rw-r--r--tests/ui/parser/recover/recover-pat-issues.stderr113
-rw-r--r--tests/ui/parser/recover/recover-pat-lets.rs20
-rw-r--r--tests/ui/parser/recover/recover-pat-lets.stderr52
-rw-r--r--tests/ui/parser/recover/recover-pat-ranges.rs (renamed from tests/ui/parser/pat-recover-ranges.rs)4
-rw-r--r--tests/ui/parser/recover/recover-pat-ranges.stderr216
-rw-r--r--tests/ui/parser/recover/recover-pat-wildcards.rs (renamed from tests/ui/parser/pat-recover-wildcards.rs)0
-rw-r--r--tests/ui/parser/recover/recover-pat-wildcards.stderr (renamed from tests/ui/parser/pat-recover-wildcards.stderr)43
-rw-r--r--tests/ui/parser/triple-colon-delegation.fixed44
-rw-r--r--tests/ui/parser/triple-colon-delegation.rs44
-rw-r--r--tests/ui/parser/triple-colon-delegation.stderr38
-rw-r--r--tests/ui/parser/triple-colon.fixed23
-rw-r--r--tests/ui/parser/triple-colon.rs23
-rw-r--r--tests/ui/parser/triple-colon.stderr146
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs16
-rw-r--r--tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr20
-rw-r--r--tests/ui/rust-2024/raw-gen-lt.rs8
-rw-r--r--tests/ui/self/where-for-self.rs2
-rw-r--r--tests/ui/simd/simd-bitmask-notpow2.rs3
-rw-r--r--tests/ui/static/reference-to-mut-static-safe.e2021.stderr26
-rw-r--r--tests/ui/static/reference-to-mut-static-safe.e2024.stderr24
-rw-r--r--tests/ui/static/reference-to-mut-static-safe.rs13
-rw-r--r--tests/ui/static/reference-to-mut-static-unsafe-fn.rs28
-rw-r--r--tests/ui/static/reference-to-mut-static-unsafe-fn.stderr75
-rw-r--r--tests/ui/static/reference-to-mut-static.e2021.stderr91
-rw-r--r--tests/ui/static/reference-to-mut-static.e2024.stderr75
-rw-r--r--tests/ui/static/reference-to-mut-static.rs50
-rw-r--r--tests/ui/static/safe-extern-statics-mut.rs2
-rw-r--r--tests/ui/static/safe-extern-statics-mut.stderr35
-rw-r--r--tests/ui/statics/issue-15261.stderr11
-rw-r--r--tests/ui/statics/static-mut-xc.rs5
-rw-r--r--tests/ui/statics/static-mut-xc.stderr75
-rw-r--r--tests/ui/statics/static-recursive.rs1
-rw-r--r--tests/ui/statics/static-recursive.stderr22
-rw-r--r--tests/ui/structs-enums/type-sizes.rs20
-rw-r--r--tests/ui/suggestions/mut-borrow-needed-by-trait.rs1
-rw-r--r--tests/ui/suggestions/mut-borrow-needed-by-trait.stderr16
-rw-r--r--tests/ui/thread-local/thread-local-issue-37508.rs3
-rw-r--r--tests/ui/traits/coherence-alias-hang.rs2
-rw-r--r--tests/ui/traits/impl.rs3
-rw-r--r--tests/ui/traits/impl.stderr2
-rw-r--r--tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr1
-rw-r--r--tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs3
-rw-r--r--tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr11
-rw-r--r--tests/ui/traits/sized-coniductive.rs14
-rw-r--r--tests/ui/typeck/auxiliary/foreign_struct_trait_unimplemented.rs1
-rw-r--r--tests/ui/typeck/foreign_struct_trait_unimplemented.rs15
-rw-r--r--tests/ui/typeck/foreign_struct_trait_unimplemented.stderr23
-rw-r--r--tests/ui/union/union-drop-assign.rs3
-rw-r--r--tests/ui/union/union-drop.rs2
-rw-r--r--tests/ui/unsafe/union-pat-in-param.rs19
-rw-r--r--tests/ui/unsafe/union-pat-in-param.stderr19
-rw-r--r--triagebot.toml1
879 files changed, 15457 insertions, 8556 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 1497d2d463a..e973d7f9a2a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -4630,7 +4630,7 @@ dependencies = [
 
 [[package]]
 name = "rustfmt-nightly"
-version = "1.7.1"
+version = "1.8.0"
 dependencies = [
  "annotate-snippets 0.9.2",
  "anyhow",
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index f4de4e06d1b..01593d34c97 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -527,15 +527,10 @@ impl<Cx: HasDataLayout> LayoutCalculator<Cx> {
             let count =
                 (niche_variants.end().index() as u128 - niche_variants.start().index() as u128) + 1;
 
-            // Find the field with the largest niche
-            let (field_index, niche, (niche_start, niche_scalar)) = variants[largest_variant_index]
-                .iter()
-                .enumerate()
-                .filter_map(|(j, field)| Some((j, field.largest_niche?)))
-                .max_by_key(|(_, niche)| niche.available(dl))
-                .and_then(|(j, niche)| Some((j, niche, niche.reserve(dl, count)?)))?;
-            let niche_offset =
-                niche.offset + variant_layouts[largest_variant_index].fields.offset(field_index);
+            // Use the largest niche in the largest variant.
+            let niche = variant_layouts[largest_variant_index].largest_niche?;
+            let (niche_start, niche_scalar) = niche.reserve(dl, count)?;
+            let niche_offset = niche.offset;
             let niche_size = niche.value.size(dl);
             let size = variant_layouts[largest_variant_index].size.align_to(align.abi);
 
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index 5668d8992c8..7bd2507d1ad 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -833,6 +833,28 @@ pub enum Integer {
 }
 
 impl Integer {
+    pub fn int_ty_str(self) -> &'static str {
+        use Integer::*;
+        match self {
+            I8 => "i8",
+            I16 => "i16",
+            I32 => "i32",
+            I64 => "i64",
+            I128 => "i128",
+        }
+    }
+
+    pub fn uint_ty_str(self) -> &'static str {
+        use Integer::*;
+        match self {
+            I8 => "u8",
+            I16 => "u16",
+            I32 => "u32",
+            I64 => "u64",
+            I128 => "u128",
+        }
+    }
+
     #[inline]
     pub fn size(self) -> Size {
         use Integer::*;
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index f433f2eca1a..ac65b7b22bc 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1293,7 +1293,7 @@ impl Expr {
             ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
             ExprKind::Unary(..) => ExprPrecedence::Unary,
             ExprKind::Lit(_) | ExprKind::IncludedBytes(..) => ExprPrecedence::Lit,
-            ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast,
+            ExprKind::Cast(..) => ExprPrecedence::Cast,
             ExprKind::Let(..) => ExprPrecedence::Let,
             ExprKind::If(..) => ExprPrecedence::If,
             ExprKind::While(..) => ExprPrecedence::While,
@@ -1317,17 +1317,18 @@ impl Expr {
             ExprKind::Break(..) => ExprPrecedence::Break,
             ExprKind::Continue(..) => ExprPrecedence::Continue,
             ExprKind::Ret(..) => ExprPrecedence::Ret,
-            ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
-            ExprKind::OffsetOf(..) => ExprPrecedence::OffsetOf,
-            ExprKind::MacCall(..) => ExprPrecedence::Mac,
             ExprKind::Struct(..) => ExprPrecedence::Struct,
             ExprKind::Repeat(..) => ExprPrecedence::Repeat,
             ExprKind::Paren(..) => ExprPrecedence::Paren,
             ExprKind::Try(..) => ExprPrecedence::Try,
             ExprKind::Yield(..) => ExprPrecedence::Yield,
             ExprKind::Yeet(..) => ExprPrecedence::Yeet,
-            ExprKind::FormatArgs(..) => ExprPrecedence::FormatArgs,
             ExprKind::Become(..) => ExprPrecedence::Become,
+            ExprKind::InlineAsm(..)
+            | ExprKind::Type(..)
+            | ExprKind::OffsetOf(..)
+            | ExprKind::FormatArgs(..)
+            | ExprKind::MacCall(..) => ExprPrecedence::Mac,
             ExprKind::Err(_) | ExprKind::Dummy => ExprPrecedence::Err,
         }
     }
diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs
index 8436c760d16..d8dad4550c0 100644
--- a/compiler/rustc_ast/src/util/parser.rs
+++ b/compiler/rustc_ast/src/util/parser.rs
@@ -265,10 +265,7 @@ pub enum ExprPrecedence {
     Field,
     Index,
     Try,
-    InlineAsm,
-    OffsetOf,
     Mac,
-    FormatArgs,
 
     Array,
     Repeat,
@@ -333,17 +330,14 @@ impl ExprPrecedence {
             | ExprPrecedence::ConstBlock
             | ExprPrecedence::Field
             | ExprPrecedence::ForLoop
-            | ExprPrecedence::FormatArgs
             | ExprPrecedence::Gen
             | ExprPrecedence::If
             | ExprPrecedence::Index
-            | ExprPrecedence::InlineAsm
             | ExprPrecedence::Lit
             | ExprPrecedence::Loop
             | ExprPrecedence::Mac
             | ExprPrecedence::Match
             | ExprPrecedence::MethodCall
-            | ExprPrecedence::OffsetOf
             | ExprPrecedence::Paren
             | ExprPrecedence::Path
             | ExprPrecedence::PostfixMatch
diff --git a/compiler/rustc_borrowck/messages.ftl b/compiler/rustc_borrowck/messages.ftl
index edb25e12864..ee4b2f95cb1 100644
--- a/compiler/rustc_borrowck/messages.ftl
+++ b/compiler/rustc_borrowck/messages.ftl
@@ -207,7 +207,7 @@ borrowck_simd_intrinsic_arg_const =
         *[other] {$arg}th
     } argument of `{$intrinsic}` is required to be a `const` item
 
-borrowck_suggest_create_freash_reborrow =
+borrowck_suggest_create_fresh_reborrow =
     consider reborrowing the `Pin` instead of moving it
 
 borrowck_suggest_iterate_over_slice =
diff --git a/compiler/rustc_borrowck/src/session_diagnostics.rs b/compiler/rustc_borrowck/src/session_diagnostics.rs
index 4a50b0f0704..b6c6960d4ca 100644
--- a/compiler/rustc_borrowck/src/session_diagnostics.rs
+++ b/compiler/rustc_borrowck/src/session_diagnostics.rs
@@ -415,7 +415,7 @@ pub(crate) enum CaptureReasonSuggest<'tcx> {
         span: Span,
     },
     #[suggestion(
-        borrowck_suggest_create_freash_reborrow,
+        borrowck_suggest_create_fresh_reborrow,
         applicability = "maybe-incorrect",
         code = ".as_mut()",
         style = "verbose"
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 4af4b39cc5b..8839829e2f5 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -785,8 +785,10 @@ fn codegen_stmt<'tcx>(
                 }
                 Rvalue::Repeat(ref operand, times) => {
                     let operand = codegen_operand(fx, operand);
-                    let times =
-                        fx.monomorphize(times).eval_target_usize(fx.tcx, ParamEnv::reveal_all());
+                    let times = fx
+                        .monomorphize(times)
+                        .try_to_target_usize(fx.tcx)
+                        .expect("expected monomorphic const in codegen");
                     if operand.layout().size.bytes() == 0 {
                         // Do nothing for ZST's
                     } else if fx.clif_type(operand.layout().ty) == Some(types::I8) {
@@ -944,7 +946,10 @@ fn codegen_stmt<'tcx>(
 fn codegen_array_len<'tcx>(fx: &mut FunctionCx<'_, '_, 'tcx>, place: CPlace<'tcx>) -> Value {
     match *place.layout().ty.kind() {
         ty::Array(_elem_ty, len) => {
-            let len = fx.monomorphize(len).eval_target_usize(fx.tcx, ParamEnv::reveal_all()) as i64;
+            let len = fx
+                .monomorphize(len)
+                .try_to_target_usize(fx.tcx)
+                .expect("expected monomorphic const in codegen") as i64;
             fx.bcx.ins().iconst(fx.pointer_type, len)
         }
         ty::Slice(_elem_ty) => place.to_ptr_unsized().1,
diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index b9000a3874f..22ca2070715 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -309,8 +309,6 @@ pub(crate) struct FunctionCx<'m, 'clif, 'tcx: 'm> {
 }
 
 impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
-    type LayoutOfResult = TyAndLayout<'tcx>;
-
     #[inline]
     fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
         RevealAllLayoutCx(self.tcx).handle_layout_err(err, span, ty)
@@ -318,8 +316,6 @@ impl<'tcx> LayoutOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
 }
 
 impl<'tcx> FnAbiOfHelpers<'tcx> for FunctionCx<'_, '_, 'tcx> {
-    type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
-
     #[inline]
     fn handle_fn_abi_err(
         &self,
@@ -450,8 +446,6 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
 pub(crate) struct RevealAllLayoutCx<'tcx>(pub(crate) TyCtxt<'tcx>);
 
 impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
-    type LayoutOfResult = TyAndLayout<'tcx>;
-
     #[inline]
     fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
         if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
@@ -466,8 +460,6 @@ impl<'tcx> LayoutOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
 }
 
 impl<'tcx> FnAbiOfHelpers<'tcx> for RevealAllLayoutCx<'tcx> {
-    type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
-
     #[inline]
     fn handle_fn_abi_err(
         &self,
diff --git a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs
index 7baf0a3868d..8a55a23128d 100644
--- a/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs
+++ b/compiler/rustc_codegen_cranelift/src/debuginfo/types.rs
@@ -44,7 +44,7 @@ impl DebugContext {
                 type_dbg,
                 ty,
                 *elem_ty,
-                len.eval_target_usize(tcx, ty::ParamEnv::reveal_all()),
+                len.try_to_target_usize(tcx).expect("expected monomorphic const in codegen"),
             ),
             // ty::Slice(_) | ty::Str
             // ty::Dynamic
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index a5621aec244..b96abb14b2e 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -131,9 +131,8 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
 
             let idx = generic_args[2]
                 .expect_const()
-                .eval(fx.tcx, ty::ParamEnv::reveal_all(), span)
-                .unwrap()
-                .1
+                .try_to_valtree()
+                .expect("expected monomorphic const in codegen")
                 .unwrap_branch();
 
             assert_eq!(x.layout(), y.layout());
diff --git a/compiler/rustc_codegen_cranelift/src/unsize.rs b/compiler/rustc_codegen_cranelift/src/unsize.rs
index e09cd16e89a..8cfe93b4d9c 100644
--- a/compiler/rustc_codegen_cranelift/src/unsize.rs
+++ b/compiler/rustc_codegen_cranelift/src/unsize.rs
@@ -24,10 +24,10 @@ pub(crate) fn unsized_info<'tcx>(
     let (source, target) =
         fx.tcx.struct_lockstep_tails_for_codegen(source, target, ParamEnv::reveal_all());
     match (&source.kind(), &target.kind()) {
-        (&ty::Array(_, len), &ty::Slice(_)) => fx
-            .bcx
-            .ins()
-            .iconst(fx.pointer_type, len.eval_target_usize(fx.tcx, ParamEnv::reveal_all()) as i64),
+        (&ty::Array(_, len), &ty::Slice(_)) => fx.bcx.ins().iconst(
+            fx.pointer_type,
+            len.try_to_target_usize(fx.tcx).expect("expected monomorphic const in codegen") as i64,
+        ),
         (&ty::Dynamic(data_a, _, src_dyn_kind), &ty::Dynamic(data_b, _, target_dyn_kind))
             if src_dyn_kind == target_dyn_kind =>
         {
diff --git a/compiler/rustc_codegen_gcc/src/abi.rs b/compiler/rustc_codegen_gcc/src/abi.rs
index 0a99e7213be..ed78d4ef19f 100644
--- a/compiler/rustc_codegen_gcc/src/abi.rs
+++ b/compiler/rustc_codegen_gcc/src/abi.rs
@@ -1,7 +1,7 @@
 #[cfg(feature = "master")]
 use gccjit::FnAttribute;
 use gccjit::{ToLValue, ToRValue, Type};
-use rustc_codegen_ssa::traits::{AbiBuilderMethods, BaseTypeMethods};
+use rustc_codegen_ssa::traits::{AbiBuilderMethods, BaseTypeCodegenMethods};
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::bug;
 use rustc_middle::ty::layout::LayoutOf;
diff --git a/compiler/rustc_codegen_gcc/src/asm.rs b/compiler/rustc_codegen_gcc/src/asm.rs
index 7c135289958..13a00f7e08d 100644
--- a/compiler/rustc_codegen_gcc/src/asm.rs
+++ b/compiler/rustc_codegen_gcc/src/asm.rs
@@ -5,8 +5,8 @@ use rustc_ast::ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_codegen_ssa::mir::operand::OperandValue;
 use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::traits::{
-    AsmBuilderMethods, AsmMethods, BaseTypeMethods, BuilderMethods, GlobalAsmOperandRef,
-    InlineAsmOperandRef,
+    AsmBuilderMethods, AsmCodegenMethods, BaseTypeCodegenMethods, BuilderMethods,
+    GlobalAsmOperandRef, InlineAsmOperandRef,
 };
 use rustc_middle::bug;
 use rustc_middle::ty::Instance;
@@ -770,7 +770,7 @@ fn dummy_output_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, reg: InlineAsmRegCl
     }
 }
 
-impl<'gcc, 'tcx> AsmMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
+impl<'gcc, 'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
     fn codegen_global_asm(
         &self,
         template: &[InlineAsmTemplatePiece],
diff --git a/compiler/rustc_codegen_gcc/src/base.rs b/compiler/rustc_codegen_gcc/src/base.rs
index 4940a7fa205..c0443faf24a 100644
--- a/compiler/rustc_codegen_gcc/src/base.rs
+++ b/compiler/rustc_codegen_gcc/src/base.rs
@@ -6,7 +6,7 @@ use std::time::Instant;
 use gccjit::{CType, FunctionType, GlobalKind};
 use rustc_codegen_ssa::base::maybe_create_entry_wrapper;
 use rustc_codegen_ssa::mono_item::MonoItemExt;
-use rustc_codegen_ssa::traits::DebugInfoMethods;
+use rustc_codegen_ssa::traits::DebugInfoCodegenMethods;
 use rustc_codegen_ssa::{ModuleCodegen, ModuleKind};
 use rustc_middle::dep_graph;
 use rustc_middle::mir::mono::Linkage;
diff --git a/compiler/rustc_codegen_gcc/src/builder.rs b/compiler/rustc_codegen_gcc/src/builder.rs
index 31d778823e0..9282d8699eb 100644
--- a/compiler/rustc_codegen_gcc/src/builder.rs
+++ b/compiler/rustc_codegen_gcc/src/builder.rs
@@ -14,8 +14,8 @@ use rustc_codegen_ssa::common::{
 use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
 use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::traits::{
-    BackendTypes, BaseTypeMethods, BuilderMethods, ConstMethods, HasCodegen, LayoutTypeMethods,
-    OverflowOp, StaticBuilderMethods,
+    BackendTypes, BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods,
+    LayoutTypeCodegenMethods, OverflowOp, StaticBuilderMethods,
 };
 use rustc_codegen_ssa::MemFlags;
 use rustc_data_structures::fx::FxHashSet;
@@ -23,7 +23,6 @@ use rustc_middle::bug;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
 use rustc_middle::ty::layout::{
     FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers,
-    TyAndLayout,
 };
 use rustc_middle::ty::{Instance, ParamEnv, Ty, TyCtxt};
 use rustc_span::def_id::DefId;
@@ -460,10 +459,6 @@ impl<'a, 'gcc, 'tcx> Builder<'a, 'gcc, 'tcx> {
     }
 }
 
-impl<'gcc, 'tcx> HasCodegen<'tcx> for Builder<'_, 'gcc, 'tcx> {
-    type CodegenCx = CodegenCx<'gcc, 'tcx>;
-}
-
 impl<'tcx> HasTyCtxt<'tcx> for Builder<'_, '_, 'tcx> {
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.cx.tcx()
@@ -477,8 +472,6 @@ impl HasDataLayout for Builder<'_, '_, '_> {
 }
 
 impl<'tcx> LayoutOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
-    type LayoutOfResult = TyAndLayout<'tcx>;
-
     #[inline]
     fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
         self.cx.handle_layout_err(err, span, ty)
@@ -486,8 +479,6 @@ impl<'tcx> LayoutOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
 }
 
 impl<'tcx> FnAbiOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
-    type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
-
     #[inline]
     fn handle_fn_abi_err(
         &self,
@@ -531,6 +522,8 @@ fn set_rvalue_location<'a, 'gcc, 'tcx>(
 }
 
 impl<'a, 'gcc, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'gcc, 'tcx> {
+    type CodegenCx = CodegenCx<'gcc, 'tcx>;
+
     fn build(cx: &'a CodegenCx<'gcc, 'tcx>, block: Block<'gcc>) -> Builder<'a, 'gcc, 'tcx> {
         Builder::with_cx(cx, block)
     }
diff --git a/compiler/rustc_codegen_gcc/src/common.rs b/compiler/rustc_codegen_gcc/src/common.rs
index dca6b6494f9..b7ed34858b5 100644
--- a/compiler/rustc_codegen_gcc/src/common.rs
+++ b/compiler/rustc_codegen_gcc/src/common.rs
@@ -1,5 +1,7 @@
 use gccjit::{LValue, RValue, ToRValue, Type};
-use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, MiscMethods, StaticMethods};
+use rustc_codegen_ssa::traits::{
+    BaseTypeCodegenMethods, ConstCodegenMethods, MiscCodegenMethods, StaticCodegenMethods,
+};
 use rustc_middle::mir::interpret::{ConstAllocation, GlobalAlloc, Scalar};
 use rustc_middle::mir::Mutability;
 use rustc_middle::ty::layout::LayoutOf;
@@ -55,7 +57,7 @@ pub fn type_is_pointer(typ: Type<'_>) -> bool {
     typ.get_pointee().is_some()
 }
 
-impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
+impl<'gcc, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
     fn const_null(&self, typ: Type<'gcc>) -> RValue<'gcc> {
         if type_is_pointer(typ) { self.context.new_null(typ) } else { self.const_int(typ, 0) }
     }
@@ -78,22 +80,14 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         self.const_undef(typ)
     }
 
-    fn const_int(&self, typ: Type<'gcc>, int: i64) -> RValue<'gcc> {
-        self.gcc_int(typ, int)
-    }
-
-    fn const_uint(&self, typ: Type<'gcc>, int: u64) -> RValue<'gcc> {
-        self.gcc_uint(typ, int)
-    }
-
-    fn const_uint_big(&self, typ: Type<'gcc>, num: u128) -> RValue<'gcc> {
-        self.gcc_uint_big(typ, num)
-    }
-
     fn const_bool(&self, val: bool) -> RValue<'gcc> {
         self.const_uint(self.type_i1(), val as u64)
     }
 
+    fn const_i8(&self, i: i8) -> RValue<'gcc> {
+        self.const_int(self.type_i8(), i as i64)
+    }
+
     fn const_i16(&self, i: i16) -> RValue<'gcc> {
         self.const_int(self.type_i16(), i as i64)
     }
@@ -102,8 +96,12 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         self.const_int(self.type_i32(), i as i64)
     }
 
-    fn const_i8(&self, i: i8) -> RValue<'gcc> {
-        self.const_int(self.type_i8(), i as i64)
+    fn const_int(&self, typ: Type<'gcc>, int: i64) -> RValue<'gcc> {
+        self.gcc_int(typ, int)
+    }
+
+    fn const_u8(&self, i: u8) -> RValue<'gcc> {
+        self.const_uint(self.type_u8(), i as u64)
     }
 
     fn const_u32(&self, i: u32) -> RValue<'gcc> {
@@ -128,8 +126,12 @@ impl<'gcc, 'tcx> ConstMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
         self.const_uint(self.usize_type, i)
     }
 
-    fn const_u8(&self, i: u8) -> RValue<'gcc> {
-        self.const_uint(self.type_u8(), i as u64)
+    fn const_uint(&self, typ: Type<'gcc>, int: u64) -> RValue<'gcc> {
+        self.gcc_uint(typ, int)
+    }
+
+    fn const_uint_big(&self, typ: Type<'gcc>, num: u128) -> RValue<'gcc> {
+        self.gcc_uint_big(typ, num)
     }
 
     fn const_real(&self, typ: Type<'gcc>, val: f64) -> RValue<'gcc> {
diff --git a/compiler/rustc_codegen_gcc/src/consts.rs b/compiler/rustc_codegen_gcc/src/consts.rs
index e5673cddc4a..68b9df946d0 100644
--- a/compiler/rustc_codegen_gcc/src/consts.rs
+++ b/compiler/rustc_codegen_gcc/src/consts.rs
@@ -1,7 +1,9 @@
 #[cfg(feature = "master")]
 use gccjit::{FnAttribute, VarAttribute, Visibility};
 use gccjit::{Function, GlobalKind, LValue, RValue, ToRValue, Type};
-use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods, StaticMethods};
+use rustc_codegen_ssa::traits::{
+    BaseTypeCodegenMethods, ConstCodegenMethods, StaticCodegenMethods,
+};
 use rustc_hir::def::DefKind;
 use rustc_middle::middle::codegen_fn_attrs::{CodegenFnAttrFlags, CodegenFnAttrs};
 use rustc_middle::mir::interpret::{
@@ -37,7 +39,7 @@ fn set_global_alignment<'gcc, 'tcx>(
     gv.set_alignment(align.bytes() as i32);
 }
 
-impl<'gcc, 'tcx> StaticMethods for CodegenCx<'gcc, 'tcx> {
+impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
     fn static_addr_of(&self, cv: RValue<'gcc>, align: Align, kind: Option<&str>) -> RValue<'gcc> {
         // TODO(antoyo): implement a proper rvalue comparison in libgccjit instead of doing the
         // following:
diff --git a/compiler/rustc_codegen_gcc/src/context.rs b/compiler/rustc_codegen_gcc/src/context.rs
index e330102fbd8..8e1a5b61285 100644
--- a/compiler/rustc_codegen_gcc/src/context.rs
+++ b/compiler/rustc_codegen_gcc/src/context.rs
@@ -5,20 +5,19 @@ use gccjit::{
 };
 use rustc_codegen_ssa::base::wants_msvc_seh;
 use rustc_codegen_ssa::errors as ssa_errors;
-use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeMethods, MiscMethods};
+use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, MiscCodegenMethods};
 use rustc_data_structures::base_n::{ToBaseN, ALPHANUMERIC_ONLY};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_middle::mir::mono::CodegenUnit;
 use rustc_middle::span_bug;
 use rustc_middle::ty::layout::{
     FnAbiError, FnAbiOf, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, HasTyCtxt, LayoutError,
-    LayoutOfHelpers, TyAndLayout,
+    LayoutOfHelpers,
 };
 use rustc_middle::ty::{self, Instance, ParamEnv, PolyExistentialTraitRef, Ty, TyCtxt};
 use rustc_session::Session;
 use rustc_span::source_map::respan;
 use rustc_span::{Span, DUMMY_SP};
-use rustc_target::abi::call::FnAbi;
 use rustc_target::abi::{HasDataLayout, PointeeInfo, Size, TargetDataLayout, VariantIdx};
 use rustc_target::spec::{HasTargetSpec, HasWasmCAbiOpt, Target, TlsModel, WasmCAbi};
 
@@ -426,7 +425,7 @@ impl<'gcc, 'tcx> BackendTypes for CodegenCx<'gcc, 'tcx> {
     type DIVariable = (); // TODO(antoyo)
 }
 
-impl<'gcc, 'tcx> MiscMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
+impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
     fn vtables(
         &self,
     ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<PolyExistentialTraitRef<'tcx>>), RValue<'gcc>>> {
@@ -572,8 +571,6 @@ impl<'gcc, 'tcx> HasWasmCAbiOpt for CodegenCx<'gcc, 'tcx> {
 }
 
 impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
-    type LayoutOfResult = TyAndLayout<'tcx>;
-
     #[inline]
     fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
         if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
@@ -585,8 +582,6 @@ impl<'gcc, 'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
 }
 
 impl<'gcc, 'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'gcc, 'tcx> {
-    type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
-
     #[inline]
     fn handle_fn_abi_err(
         &self,
diff --git a/compiler/rustc_codegen_gcc/src/debuginfo.rs b/compiler/rustc_codegen_gcc/src/debuginfo.rs
index f2ae9f9c8a6..1d859656b3e 100644
--- a/compiler/rustc_codegen_gcc/src/debuginfo.rs
+++ b/compiler/rustc_codegen_gcc/src/debuginfo.rs
@@ -2,7 +2,7 @@ use std::ops::Range;
 
 use gccjit::{Location, RValue};
 use rustc_codegen_ssa::mir::debuginfo::{DebugScope, FunctionDebugContext, VariableKind};
-use rustc_codegen_ssa::traits::{DebugInfoBuilderMethods, DebugInfoMethods};
+use rustc_codegen_ssa::traits::{DebugInfoBuilderMethods, DebugInfoCodegenMethods};
 use rustc_data_structures::sync::Lrc;
 use rustc_index::bit_set::BitSet;
 use rustc_index::{Idx, IndexVec};
@@ -206,7 +206,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
     }
 }
 
-impl<'gcc, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
+impl<'gcc, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
     fn create_vtable_debuginfo(
         &self,
         _ty: Ty<'tcx>,
diff --git a/compiler/rustc_codegen_gcc/src/declare.rs b/compiler/rustc_codegen_gcc/src/declare.rs
index a2b158ee0a7..46818045f0b 100644
--- a/compiler/rustc_codegen_gcc/src/declare.rs
+++ b/compiler/rustc_codegen_gcc/src/declare.rs
@@ -1,7 +1,7 @@
 #[cfg(feature = "master")]
 use gccjit::{FnAttribute, ToRValue};
 use gccjit::{Function, FunctionType, GlobalKind, LValue, RValue, Type};
-use rustc_codegen_ssa::traits::BaseTypeMethods;
+use rustc_codegen_ssa::traits::BaseTypeCodegenMethods;
 use rustc_middle::ty::Ty;
 use rustc_span::Symbol;
 use rustc_target::abi::call::FnAbi;
diff --git a/compiler/rustc_codegen_gcc/src/int.rs b/compiler/rustc_codegen_gcc/src/int.rs
index 92d5c1cbbb8..29f4db6738b 100644
--- a/compiler/rustc_codegen_gcc/src/int.rs
+++ b/compiler/rustc_codegen_gcc/src/int.rs
@@ -4,7 +4,7 @@
 
 use gccjit::{BinaryOp, ComparisonOp, FunctionType, Location, RValue, ToRValue, Type, UnaryOp};
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
-use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeMethods, BuilderMethods, OverflowOp};
+use rustc_codegen_ssa::traits::{BackendTypes, BaseTypeCodegenMethods, BuilderMethods, OverflowOp};
 use rustc_middle::ty::{ParamEnv, Ty};
 use rustc_target::abi::call::{ArgAbi, ArgAttributes, Conv, FnAbi, PassMode};
 use rustc_target::abi::Endian;
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index 9352a67e362..4fd033255fe 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -13,10 +13,10 @@ use rustc_codegen_ssa::errors::InvalidMonomorphization;
 use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
 use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
 use rustc_codegen_ssa::traits::{
-    ArgAbiMethods, BuilderMethods, ConstMethods, IntrinsicCallMethods,
+    ArgAbiBuilderMethods, BuilderMethods, ConstCodegenMethods, IntrinsicCallBuilderMethods,
 };
 #[cfg(feature = "master")]
-use rustc_codegen_ssa::traits::{BaseTypeMethods, MiscMethods};
+use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, MiscCodegenMethods};
 use rustc_codegen_ssa::MemFlags;
 use rustc_middle::bug;
 use rustc_middle::ty::layout::LayoutOf;
@@ -94,7 +94,7 @@ fn get_simple_intrinsic<'gcc, 'tcx>(
     Some(cx.context.get_builtin_function(gcc_name))
 }
 
-impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
+impl<'a, 'gcc, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
     fn codegen_intrinsic_call(
         &mut self,
         instance: Instance<'tcx>,
@@ -448,7 +448,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
     }
 }
 
-impl<'a, 'gcc, 'tcx> ArgAbiMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
+impl<'a, 'gcc, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
     fn store_fn_arg(
         &mut self,
         arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
index 2eabc1430db..28f6a0821fb 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/simd.rs
@@ -10,7 +10,7 @@ use rustc_codegen_ssa::errors::ExpectedPointerMutability;
 use rustc_codegen_ssa::errors::InvalidMonomorphization;
 use rustc_codegen_ssa::mir::operand::OperandRef;
 use rustc_codegen_ssa::mir::place::PlaceRef;
-use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods};
+use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods};
 #[cfg(feature = "master")]
 use rustc_hir as hir;
 use rustc_middle::mir::BinOp;
diff --git a/compiler/rustc_codegen_gcc/src/mono_item.rs b/compiler/rustc_codegen_gcc/src/mono_item.rs
index e6b22d51871..8a8b748750c 100644
--- a/compiler/rustc_codegen_gcc/src/mono_item.rs
+++ b/compiler/rustc_codegen_gcc/src/mono_item.rs
@@ -1,6 +1,6 @@
 #[cfg(feature = "master")]
 use gccjit::{FnAttribute, VarAttribute};
-use rustc_codegen_ssa::traits::PreDefineMethods;
+use rustc_codegen_ssa::traits::PreDefineCodegenMethods;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_middle::bug;
@@ -13,7 +13,7 @@ use crate::context::CodegenCx;
 use crate::type_of::LayoutGccExt;
 use crate::{attributes, base};
 
-impl<'gcc, 'tcx> PreDefineMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
+impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
     #[cfg_attr(not(feature = "master"), allow(unused_variables))]
     fn predefine_static(
         &self,
diff --git a/compiler/rustc_codegen_gcc/src/type_.rs b/compiler/rustc_codegen_gcc/src/type_.rs
index e20234c5ce7..4ea5544721d 100644
--- a/compiler/rustc_codegen_gcc/src/type_.rs
+++ b/compiler/rustc_codegen_gcc/src/type_.rs
@@ -5,7 +5,9 @@ use std::convert::TryInto;
 use gccjit::CType;
 use gccjit::{RValue, Struct, Type};
 use rustc_codegen_ssa::common::TypeKind;
-use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, TypeMembershipMethods};
+use rustc_codegen_ssa::traits::{
+    BaseTypeCodegenMethods, DerivedTypeCodegenMethods, TypeMembershipCodegenMethods,
+};
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::{bug, ty};
 use rustc_target::abi::{AddressSpace, Align, Integer, Size};
@@ -121,7 +123,7 @@ impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
     }
 }
 
-impl<'gcc, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
+impl<'gcc, 'tcx> BaseTypeCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
     fn type_i8(&self) -> Type<'gcc> {
         self.i8_type
     }
@@ -381,4 +383,4 @@ pub fn struct_fields<'gcc, 'tcx>(
     (result, packed)
 }
 
-impl<'gcc, 'tcx> TypeMembershipMethods<'tcx> for CodegenCx<'gcc, 'tcx> {}
+impl<'gcc, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {}
diff --git a/compiler/rustc_codegen_gcc/src/type_of.rs b/compiler/rustc_codegen_gcc/src/type_of.rs
index b7b1be5369c..cb45bbde2c2 100644
--- a/compiler/rustc_codegen_gcc/src/type_of.rs
+++ b/compiler/rustc_codegen_gcc/src/type_of.rs
@@ -1,7 +1,9 @@
 use std::fmt::Write;
 
 use gccjit::{Struct, Type};
-use rustc_codegen_ssa::traits::{BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods};
+use rustc_codegen_ssa::traits::{
+    BaseTypeCodegenMethods, DerivedTypeCodegenMethods, LayoutTypeCodegenMethods,
+};
 use rustc_middle::bug;
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::ty::print::with_no_trimmed_paths;
@@ -330,7 +332,7 @@ impl<'tcx> LayoutGccExt<'tcx> for TyAndLayout<'tcx> {
     }
 }
 
-impl<'gcc, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
+impl<'gcc, 'tcx> LayoutTypeCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
     fn backend_type(&self, layout: TyAndLayout<'tcx>) -> Type<'gcc> {
         layout.gcc_type(self)
     }
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index dea574a53cd..26718792f5f 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -285,7 +285,7 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
     }
 }
 
-impl<'ll, 'tcx> ArgAbiMethods<'tcx> for Builder<'_, 'll, 'tcx> {
+impl<'ll, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
     fn store_fn_arg(
         &mut self,
         arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
@@ -465,9 +465,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
                     cx.type_array(cx.type_i8(), self.ret.layout.size.bytes()),
                 );
                 attributes::apply_to_llfn(llfn, llvm::AttributePlace::Argument(i), &[sret]);
-                if cx.sess().opts.optimize != config::OptLevel::No
-                    && llvm_util::get_version() >= (18, 0, 0)
-                {
+                if cx.sess().opts.optimize != config::OptLevel::No {
                     attributes::apply_to_llfn(
                         llfn,
                         llvm::AttributePlace::Argument(i),
diff --git a/compiler/rustc_codegen_llvm/src/asm.rs b/compiler/rustc_codegen_llvm/src/asm.rs
index 1d91c3fb17d..430ba735243 100644
--- a/compiler/rustc_codegen_llvm/src/asm.rs
+++ b/compiler/rustc_codegen_llvm/src/asm.rs
@@ -356,7 +356,7 @@ impl<'ll, 'tcx> AsmBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
     }
 }
 
-impl<'tcx> AsmMethods<'tcx> for CodegenCx<'_, 'tcx> {
+impl<'tcx> AsmCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
     fn codegen_global_asm(
         &self,
         template: &[InlineAsmTemplatePiece],
@@ -520,24 +520,16 @@ pub(crate) fn inline_asm_call<'ll>(
 
 /// If the register is an xmm/ymm/zmm register then return its index.
 fn xmm_reg_index(reg: InlineAsmReg) -> Option<u32> {
+    use X86InlineAsmReg::*;
     match reg {
-        InlineAsmReg::X86(reg)
-            if reg as u32 >= X86InlineAsmReg::xmm0 as u32
-                && reg as u32 <= X86InlineAsmReg::xmm15 as u32 =>
-        {
-            Some(reg as u32 - X86InlineAsmReg::xmm0 as u32)
+        InlineAsmReg::X86(reg) if reg as u32 >= xmm0 as u32 && reg as u32 <= xmm15 as u32 => {
+            Some(reg as u32 - xmm0 as u32)
         }
-        InlineAsmReg::X86(reg)
-            if reg as u32 >= X86InlineAsmReg::ymm0 as u32
-                && reg as u32 <= X86InlineAsmReg::ymm15 as u32 =>
-        {
-            Some(reg as u32 - X86InlineAsmReg::ymm0 as u32)
+        InlineAsmReg::X86(reg) if reg as u32 >= ymm0 as u32 && reg as u32 <= ymm15 as u32 => {
+            Some(reg as u32 - ymm0 as u32)
         }
-        InlineAsmReg::X86(reg)
-            if reg as u32 >= X86InlineAsmReg::zmm0 as u32
-                && reg as u32 <= X86InlineAsmReg::zmm31 as u32 =>
-        {
-            Some(reg as u32 - X86InlineAsmReg::zmm0 as u32)
+        InlineAsmReg::X86(reg) if reg as u32 >= zmm0 as u32 && reg as u32 <= zmm31 as u32 => {
+            Some(reg as u32 - zmm0 as u32)
         }
         _ => None,
     }
@@ -545,50 +537,56 @@ fn xmm_reg_index(reg: InlineAsmReg) -> Option<u32> {
 
 /// If the register is an AArch64 integer register then return its index.
 fn a64_reg_index(reg: InlineAsmReg) -> Option<u32> {
-    match reg {
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x0) => Some(0),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x1) => Some(1),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x2) => Some(2),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x3) => Some(3),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x4) => Some(4),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x5) => Some(5),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x6) => Some(6),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x7) => Some(7),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x8) => Some(8),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x9) => Some(9),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x10) => Some(10),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x11) => Some(11),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x12) => Some(12),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x13) => Some(13),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x14) => Some(14),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x15) => Some(15),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x16) => Some(16),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x17) => Some(17),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x18) => Some(18),
-        // x19 is reserved
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x20) => Some(20),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x21) => Some(21),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x22) => Some(22),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x23) => Some(23),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x24) => Some(24),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x25) => Some(25),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x26) => Some(26),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x27) => Some(27),
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x28) => Some(28),
-        // x29 is reserved
-        InlineAsmReg::AArch64(AArch64InlineAsmReg::x30) => Some(30),
-        _ => None,
-    }
+    use AArch64InlineAsmReg::*;
+    // Unlike `a64_vreg_index`, we can't subtract `x0` to get the u32 because
+    // `x19` and `x29` are missing and the integer constants for the
+    // `x0`..`x30` enum variants don't all match the register number. E.g. the
+    // integer constant for `x18` is 18, but the constant for `x20` is 19.
+    Some(match reg {
+        InlineAsmReg::AArch64(r) => match r {
+            x0 => 0,
+            x1 => 1,
+            x2 => 2,
+            x3 => 3,
+            x4 => 4,
+            x5 => 5,
+            x6 => 6,
+            x7 => 7,
+            x8 => 8,
+            x9 => 9,
+            x10 => 10,
+            x11 => 11,
+            x12 => 12,
+            x13 => 13,
+            x14 => 14,
+            x15 => 15,
+            x16 => 16,
+            x17 => 17,
+            x18 => 18,
+            // x19 is reserved
+            x20 => 20,
+            x21 => 21,
+            x22 => 22,
+            x23 => 23,
+            x24 => 24,
+            x25 => 25,
+            x26 => 26,
+            x27 => 27,
+            x28 => 28,
+            // x29 is reserved
+            x30 => 30,
+            _ => return None,
+        },
+        _ => return None,
+    })
 }
 
 /// If the register is an AArch64 vector register then return its index.
 fn a64_vreg_index(reg: InlineAsmReg) -> Option<u32> {
+    use AArch64InlineAsmReg::*;
     match reg {
-        InlineAsmReg::AArch64(reg)
-            if reg as u32 >= AArch64InlineAsmReg::v0 as u32
-                && reg as u32 <= AArch64InlineAsmReg::v31 as u32 =>
-        {
-            Some(reg as u32 - AArch64InlineAsmReg::v0 as u32)
+        InlineAsmReg::AArch64(reg) if reg as u32 >= v0 as u32 && reg as u32 <= v31 as u32 => {
+            Some(reg as u32 - v0 as u32)
         }
         _ => None,
     }
@@ -596,6 +594,7 @@ fn a64_vreg_index(reg: InlineAsmReg) -> Option<u32> {
 
 /// Converts a register class to an LLVM constraint code.
 fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) -> String {
+    use InlineAsmRegClass::*;
     match reg {
         // For vector registers LLVM wants the register name to match the type size.
         InlineAsmRegOrRegClass::Reg(reg) => {
@@ -652,75 +651,66 @@ fn reg_to_llvm(reg: InlineAsmRegOrRegClass, layout: Option<&TyAndLayout<'_>>) ->
         // The constraints can be retrieved from
         // https://llvm.org/docs/LangRef.html#supported-constraint-code-list
         InlineAsmRegOrRegClass::RegClass(reg) => match reg {
-            InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg) => "w",
-            InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => "x",
-            InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
-                unreachable!("clobber-only")
-            }
-            InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
-            | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
-            | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8) => "t",
-            InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16)
-            | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low8)
-            | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low4) => "x",
-            InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
-            | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg) => "w",
-            InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => "f",
-            InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => "f",
-            InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => "h",
-            InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => "r",
-            InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => "l",
-            InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
-            InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
-            InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
-            | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
+            AArch64(AArch64InlineAsmRegClass::reg) => "r",
+            AArch64(AArch64InlineAsmRegClass::vreg) => "w",
+            AArch64(AArch64InlineAsmRegClass::vreg_low16) => "x",
+            AArch64(AArch64InlineAsmRegClass::preg) => unreachable!("clobber-only"),
+            Arm(ArmInlineAsmRegClass::reg) => "r",
+            Arm(ArmInlineAsmRegClass::sreg)
+            | Arm(ArmInlineAsmRegClass::dreg_low16)
+            | Arm(ArmInlineAsmRegClass::qreg_low8) => "t",
+            Arm(ArmInlineAsmRegClass::sreg_low16)
+            | Arm(ArmInlineAsmRegClass::dreg_low8)
+            | Arm(ArmInlineAsmRegClass::qreg_low4) => "x",
+            Arm(ArmInlineAsmRegClass::dreg) | Arm(ArmInlineAsmRegClass::qreg) => "w",
+            Hexagon(HexagonInlineAsmRegClass::reg) => "r",
+            LoongArch(LoongArchInlineAsmRegClass::reg) => "r",
+            LoongArch(LoongArchInlineAsmRegClass::freg) => "f",
+            Mips(MipsInlineAsmRegClass::reg) => "r",
+            Mips(MipsInlineAsmRegClass::freg) => "f",
+            Nvptx(NvptxInlineAsmRegClass::reg16) => "h",
+            Nvptx(NvptxInlineAsmRegClass::reg32) => "r",
+            Nvptx(NvptxInlineAsmRegClass::reg64) => "l",
+            PowerPC(PowerPCInlineAsmRegClass::reg) => "r",
+            PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => "b",
+            PowerPC(PowerPCInlineAsmRegClass::freg) => "f",
+            PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
                 unreachable!("clobber-only")
             }
-            InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => "f",
-            InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => {
-                unreachable!("clobber-only")
-            }
-            InlineAsmRegClass::X86(X86InlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd) => "Q",
-            InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_byte) => "q",
-            InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg)
-            | InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg) => "x",
-            InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => "v",
-            InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => "^Yk",
-            InlineAsmRegClass::X86(
+            RiscV(RiscVInlineAsmRegClass::reg) => "r",
+            RiscV(RiscVInlineAsmRegClass::freg) => "f",
+            RiscV(RiscVInlineAsmRegClass::vreg) => unreachable!("clobber-only"),
+            X86(X86InlineAsmRegClass::reg) => "r",
+            X86(X86InlineAsmRegClass::reg_abcd) => "Q",
+            X86(X86InlineAsmRegClass::reg_byte) => "q",
+            X86(X86InlineAsmRegClass::xmm_reg) | X86(X86InlineAsmRegClass::ymm_reg) => "x",
+            X86(X86InlineAsmRegClass::zmm_reg) => "v",
+            X86(X86InlineAsmRegClass::kreg) => "^Yk",
+            X86(
                 X86InlineAsmRegClass::x87_reg
                 | X86InlineAsmRegClass::mmx_reg
                 | X86InlineAsmRegClass::kreg0
                 | X86InlineAsmRegClass::tmm_reg,
             ) => unreachable!("clobber-only"),
-            InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => "r",
-            InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => "w",
-            InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_upper) => "d",
-            InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair) => "r",
-            InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => "w",
-            InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => "e",
-            InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::S390x(S390xInlineAsmRegClass::reg_addr) => "a",
-            InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => "f",
-            InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => "a",
-            InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => "d",
-            InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => "r",
-            InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => "f",
-            InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
-                bug!("LLVM backend does not support SPIR-V")
-            }
-            InlineAsmRegClass::Err => unreachable!(),
+            Wasm(WasmInlineAsmRegClass::local) => "r",
+            Bpf(BpfInlineAsmRegClass::reg) => "r",
+            Bpf(BpfInlineAsmRegClass::wreg) => "w",
+            Avr(AvrInlineAsmRegClass::reg) => "r",
+            Avr(AvrInlineAsmRegClass::reg_upper) => "d",
+            Avr(AvrInlineAsmRegClass::reg_pair) => "r",
+            Avr(AvrInlineAsmRegClass::reg_iw) => "w",
+            Avr(AvrInlineAsmRegClass::reg_ptr) => "e",
+            S390x(S390xInlineAsmRegClass::reg) => "r",
+            S390x(S390xInlineAsmRegClass::reg_addr) => "a",
+            S390x(S390xInlineAsmRegClass::freg) => "f",
+            Msp430(Msp430InlineAsmRegClass::reg) => "r",
+            M68k(M68kInlineAsmRegClass::reg) => "r",
+            M68k(M68kInlineAsmRegClass::reg_addr) => "a",
+            M68k(M68kInlineAsmRegClass::reg_data) => "d",
+            CSKY(CSKYInlineAsmRegClass::reg) => "r",
+            CSKY(CSKYInlineAsmRegClass::freg) => "f",
+            SpirV(SpirVInlineAsmRegClass::reg) => bug!("LLVM backend does not support SPIR-V"),
+            Err => unreachable!(),
         }
         .to_string(),
     }
@@ -732,44 +722,41 @@ fn modifier_to_llvm(
     reg: InlineAsmRegClass,
     modifier: Option<char>,
 ) -> Option<char> {
+    use InlineAsmRegClass::*;
     // The modifiers can be retrieved from
     // https://llvm.org/docs/LangRef.html#asm-template-argument-modifiers
     match reg {
-        InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => modifier,
-        InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg)
-        | InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
-            if modifier == Some('v') { None } else { modifier }
-        }
-        InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
-            unreachable!("clobber-only")
+        AArch64(AArch64InlineAsmRegClass::reg) => modifier,
+        AArch64(AArch64InlineAsmRegClass::vreg) | AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
+            if modifier == Some('v') {
+                None
+            } else {
+                modifier
+            }
         }
-        InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => None,
-        InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
-        | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => None,
-        InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
-        | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
-        | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low8) => Some('P'),
-        InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg)
-        | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8)
-        | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low4) => {
+        AArch64(AArch64InlineAsmRegClass::preg) => unreachable!("clobber-only"),
+        Arm(ArmInlineAsmRegClass::reg) => None,
+        Arm(ArmInlineAsmRegClass::sreg) | Arm(ArmInlineAsmRegClass::sreg_low16) => None,
+        Arm(ArmInlineAsmRegClass::dreg)
+        | Arm(ArmInlineAsmRegClass::dreg_low16)
+        | Arm(ArmInlineAsmRegClass::dreg_low8) => Some('P'),
+        Arm(ArmInlineAsmRegClass::qreg)
+        | Arm(ArmInlineAsmRegClass::qreg_low8)
+        | Arm(ArmInlineAsmRegClass::qreg_low4) => {
             if modifier.is_none() {
                 Some('q')
             } else {
                 modifier
             }
         }
-        InlineAsmRegClass::Hexagon(_) => None,
-        InlineAsmRegClass::LoongArch(_) => None,
-        InlineAsmRegClass::Mips(_) => None,
-        InlineAsmRegClass::Nvptx(_) => None,
-        InlineAsmRegClass::PowerPC(_) => None,
-        InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg)
-        | InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => None,
-        InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => {
-            unreachable!("clobber-only")
-        }
-        InlineAsmRegClass::X86(X86InlineAsmRegClass::reg)
-        | InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd) => match modifier {
+        Hexagon(_) => None,
+        LoongArch(_) => None,
+        Mips(_) => None,
+        Nvptx(_) => None,
+        PowerPC(_) => None,
+        RiscV(RiscVInlineAsmRegClass::reg) | RiscV(RiscVInlineAsmRegClass::freg) => None,
+        RiscV(RiscVInlineAsmRegClass::vreg) => unreachable!("clobber-only"),
+        X86(X86InlineAsmRegClass::reg) | X86(X86InlineAsmRegClass::reg_abcd) => match modifier {
             None if arch == InlineAsmArch::X86_64 => Some('q'),
             None => Some('k'),
             Some('l') => Some('b'),
@@ -779,10 +766,10 @@ fn modifier_to_llvm(
             Some('r') => Some('q'),
             _ => unreachable!(),
         },
-        InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_byte) => None,
-        InlineAsmRegClass::X86(reg @ X86InlineAsmRegClass::xmm_reg)
-        | InlineAsmRegClass::X86(reg @ X86InlineAsmRegClass::ymm_reg)
-        | InlineAsmRegClass::X86(reg @ X86InlineAsmRegClass::zmm_reg) => match (reg, modifier) {
+        X86(X86InlineAsmRegClass::reg_byte) => None,
+        X86(reg @ X86InlineAsmRegClass::xmm_reg)
+        | X86(reg @ X86InlineAsmRegClass::ymm_reg)
+        | X86(reg @ X86InlineAsmRegClass::zmm_reg) => match (reg, modifier) {
             (X86InlineAsmRegClass::xmm_reg, None) => Some('x'),
             (X86InlineAsmRegClass::ymm_reg, None) => Some('t'),
             (X86InlineAsmRegClass::zmm_reg, None) => Some('g'),
@@ -791,116 +778,97 @@ fn modifier_to_llvm(
             (_, Some('z')) => Some('g'),
             _ => unreachable!(),
         },
-        InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => None,
-        InlineAsmRegClass::X86(
+        X86(X86InlineAsmRegClass::kreg) => None,
+        X86(
             X86InlineAsmRegClass::x87_reg
             | X86InlineAsmRegClass::mmx_reg
             | X86InlineAsmRegClass::kreg0
             | X86InlineAsmRegClass::tmm_reg,
-        ) => {
-            unreachable!("clobber-only")
-        }
-        InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => None,
-        InlineAsmRegClass::Bpf(_) => None,
-        InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair)
-        | InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw)
-        | InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => match modifier {
+        ) => unreachable!("clobber-only"),
+        Wasm(WasmInlineAsmRegClass::local) => None,
+        Bpf(_) => None,
+        Avr(AvrInlineAsmRegClass::reg_pair)
+        | Avr(AvrInlineAsmRegClass::reg_iw)
+        | Avr(AvrInlineAsmRegClass::reg_ptr) => match modifier {
             Some('h') => Some('B'),
             Some('l') => Some('A'),
             _ => None,
         },
-        InlineAsmRegClass::Avr(_) => None,
-        InlineAsmRegClass::S390x(_) => None,
-        InlineAsmRegClass::Msp430(_) => None,
-        InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
-            bug!("LLVM backend does not support SPIR-V")
-        }
-        InlineAsmRegClass::M68k(_) => None,
-        InlineAsmRegClass::CSKY(_) => None,
-        InlineAsmRegClass::Err => unreachable!(),
+        Avr(_) => None,
+        S390x(_) => None,
+        Msp430(_) => None,
+        SpirV(SpirVInlineAsmRegClass::reg) => bug!("LLVM backend does not support SPIR-V"),
+        M68k(_) => None,
+        CSKY(_) => None,
+        Err => unreachable!(),
     }
 }
 
 /// Type to use for outputs that are discarded. It doesn't really matter what
 /// the type is, as long as it is valid for the constraint code.
 fn dummy_output_type<'ll>(cx: &CodegenCx<'ll, '_>, reg: InlineAsmRegClass) -> &'ll Type {
+    use InlineAsmRegClass::*;
     match reg {
-        InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::reg) => cx.type_i32(),
-        InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg)
-        | InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
+        AArch64(AArch64InlineAsmRegClass::reg) => cx.type_i32(),
+        AArch64(AArch64InlineAsmRegClass::vreg) | AArch64(AArch64InlineAsmRegClass::vreg_low16) => {
             cx.type_vector(cx.type_i64(), 2)
         }
-        InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::preg) => {
+        AArch64(AArch64InlineAsmRegClass::preg) => unreachable!("clobber-only"),
+        Arm(ArmInlineAsmRegClass::reg) => cx.type_i32(),
+        Arm(ArmInlineAsmRegClass::sreg) | Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(),
+        Arm(ArmInlineAsmRegClass::dreg)
+        | Arm(ArmInlineAsmRegClass::dreg_low16)
+        | Arm(ArmInlineAsmRegClass::dreg_low8) => cx.type_f64(),
+        Arm(ArmInlineAsmRegClass::qreg)
+        | Arm(ArmInlineAsmRegClass::qreg_low8)
+        | Arm(ArmInlineAsmRegClass::qreg_low4) => cx.type_vector(cx.type_i64(), 2),
+        Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(),
+        LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(),
+        LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(),
+        Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(),
+        Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(),
+        Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(),
+        Nvptx(NvptxInlineAsmRegClass::reg32) => cx.type_i32(),
+        Nvptx(NvptxInlineAsmRegClass::reg64) => cx.type_i64(),
+        PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(),
+        PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
+        PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
+        PowerPC(PowerPCInlineAsmRegClass::cr) | PowerPC(PowerPCInlineAsmRegClass::xer) => {
             unreachable!("clobber-only")
         }
-        InlineAsmRegClass::Arm(ArmInlineAsmRegClass::reg) => cx.type_i32(),
-        InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg)
-        | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg_low16) => cx.type_f32(),
-        InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg)
-        | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low16)
-        | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::dreg_low8) => cx.type_f64(),
-        InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg)
-        | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low8)
-        | InlineAsmRegClass::Arm(ArmInlineAsmRegClass::qreg_low4) => {
-            cx.type_vector(cx.type_i64(), 2)
-        }
-        InlineAsmRegClass::Hexagon(HexagonInlineAsmRegClass::reg) => cx.type_i32(),
-        InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::reg) => cx.type_i32(),
-        InlineAsmRegClass::LoongArch(LoongArchInlineAsmRegClass::freg) => cx.type_f32(),
-        InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg) => cx.type_i32(),
-        InlineAsmRegClass::Mips(MipsInlineAsmRegClass::freg) => cx.type_f32(),
-        InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg16) => cx.type_i16(),
-        InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg32) => cx.type_i32(),
-        InlineAsmRegClass::Nvptx(NvptxInlineAsmRegClass::reg64) => cx.type_i64(),
-        InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg) => cx.type_i32(),
-        InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::reg_nonzero) => cx.type_i32(),
-        InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::freg) => cx.type_f64(),
-        InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::cr)
-        | InlineAsmRegClass::PowerPC(PowerPCInlineAsmRegClass::xer) => {
-            unreachable!("clobber-only")
-        }
-        InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),
-        InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg) => cx.type_f32(),
-        InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::vreg) => {
-            unreachable!("clobber-only")
-        }
-        InlineAsmRegClass::X86(X86InlineAsmRegClass::reg)
-        | InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd) => cx.type_i32(),
-        InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_byte) => cx.type_i8(),
-        InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg)
-        | InlineAsmRegClass::X86(X86InlineAsmRegClass::ymm_reg)
-        | InlineAsmRegClass::X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(),
-        InlineAsmRegClass::X86(X86InlineAsmRegClass::kreg) => cx.type_i16(),
-        InlineAsmRegClass::X86(
+        RiscV(RiscVInlineAsmRegClass::reg) => cx.type_i32(),
+        RiscV(RiscVInlineAsmRegClass::freg) => cx.type_f32(),
+        RiscV(RiscVInlineAsmRegClass::vreg) => unreachable!("clobber-only"),
+        X86(X86InlineAsmRegClass::reg) | X86(X86InlineAsmRegClass::reg_abcd) => cx.type_i32(),
+        X86(X86InlineAsmRegClass::reg_byte) => cx.type_i8(),
+        X86(X86InlineAsmRegClass::xmm_reg)
+        | X86(X86InlineAsmRegClass::ymm_reg)
+        | X86(X86InlineAsmRegClass::zmm_reg) => cx.type_f32(),
+        X86(X86InlineAsmRegClass::kreg) => cx.type_i16(),
+        X86(
             X86InlineAsmRegClass::x87_reg
             | X86InlineAsmRegClass::mmx_reg
             | X86InlineAsmRegClass::kreg0
             | X86InlineAsmRegClass::tmm_reg,
-        ) => {
-            unreachable!("clobber-only")
-        }
-        InlineAsmRegClass::Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
-        InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(),
-        InlineAsmRegClass::Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(),
-        InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg) => cx.type_i8(),
-        InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_upper) => cx.type_i8(),
-        InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_pair) => cx.type_i16(),
-        InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_iw) => cx.type_i16(),
-        InlineAsmRegClass::Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(),
-        InlineAsmRegClass::S390x(
-            S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr,
-        ) => cx.type_i32(),
-        InlineAsmRegClass::S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
-        InlineAsmRegClass::Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(),
-        InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
-        InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
-        InlineAsmRegClass::M68k(M68kInlineAsmRegClass::reg_data) => cx.type_i32(),
-        InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::reg) => cx.type_i32(),
-        InlineAsmRegClass::CSKY(CSKYInlineAsmRegClass::freg) => cx.type_f32(),
-        InlineAsmRegClass::SpirV(SpirVInlineAsmRegClass::reg) => {
-            bug!("LLVM backend does not support SPIR-V")
-        }
-        InlineAsmRegClass::Err => unreachable!(),
+        ) => unreachable!("clobber-only"),
+        Wasm(WasmInlineAsmRegClass::local) => cx.type_i32(),
+        Bpf(BpfInlineAsmRegClass::reg) => cx.type_i64(),
+        Bpf(BpfInlineAsmRegClass::wreg) => cx.type_i32(),
+        Avr(AvrInlineAsmRegClass::reg) => cx.type_i8(),
+        Avr(AvrInlineAsmRegClass::reg_upper) => cx.type_i8(),
+        Avr(AvrInlineAsmRegClass::reg_pair) => cx.type_i16(),
+        Avr(AvrInlineAsmRegClass::reg_iw) => cx.type_i16(),
+        Avr(AvrInlineAsmRegClass::reg_ptr) => cx.type_i16(),
+        S390x(S390xInlineAsmRegClass::reg | S390xInlineAsmRegClass::reg_addr) => cx.type_i32(),
+        S390x(S390xInlineAsmRegClass::freg) => cx.type_f64(),
+        Msp430(Msp430InlineAsmRegClass::reg) => cx.type_i16(),
+        M68k(M68kInlineAsmRegClass::reg) => cx.type_i32(),
+        M68k(M68kInlineAsmRegClass::reg_addr) => cx.type_i32(),
+        M68k(M68kInlineAsmRegClass::reg_data) => cx.type_i32(),
+        CSKY(CSKYInlineAsmRegClass::reg) => cx.type_i32(),
+        CSKY(CSKYInlineAsmRegClass::freg) => cx.type_f32(),
+        SpirV(SpirVInlineAsmRegClass::reg) => bug!("LLVM backend does not support SPIR-V"),
+        Err => unreachable!(),
     }
 }
 
@@ -940,9 +908,10 @@ fn llvm_fixup_input<'ll, 'tcx>(
     layout: &TyAndLayout<'tcx>,
     instance: Instance<'_>,
 ) -> &'ll Value {
+    use InlineAsmRegClass::*;
     let dl = &bx.tcx.data_layout;
     match (reg, layout.abi) {
-        (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
+        (AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
             if let Primitive::Int(Integer::I8, _) = s.primitive() {
                 let vec_ty = bx.cx.type_vector(bx.cx.type_i8(), 8);
                 bx.insert_element(bx.const_undef(vec_ty), value, bx.const_i32(0))
@@ -950,7 +919,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
                 value
             }
         }
-        (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
+        (AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
             if s.primitive() != Primitive::Float(Float::F128) =>
         {
             let elem_ty = llvm_asm_scalar_type(bx.cx, s);
@@ -963,26 +932,25 @@ fn llvm_fixup_input<'ll, 'tcx>(
             }
             bx.insert_element(bx.const_undef(vec_ty), value, bx.const_i32(0))
         }
-        (
-            InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16),
-            Abi::Vector { element, count },
-        ) if layout.size.bytes() == 8 => {
+        (AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Vector { element, count })
+            if layout.size.bytes() == 8 =>
+        {
             let elem_ty = llvm_asm_scalar_type(bx.cx, element);
             let vec_ty = bx.cx.type_vector(elem_ty, count);
             let indices: Vec<_> = (0..count * 2).map(|x| bx.const_i32(x as i32)).collect();
             bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices))
         }
-        (InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
+        (X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
             if s.primitive() == Primitive::Float(Float::F64) =>
         {
             bx.bitcast(value, bx.cx.type_i64())
         }
         (
-            InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
+            X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
             Abi::Vector { .. },
         ) if layout.size.bytes() == 64 => bx.bitcast(value, bx.cx.type_vector(bx.cx.type_f64(), 8)),
         (
-            InlineAsmRegClass::X86(
+            X86(
                 X86InlineAsmRegClass::xmm_reg
                 | X86InlineAsmRegClass::ymm_reg
                 | X86InlineAsmRegClass::zmm_reg,
@@ -994,7 +962,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
             bx.bitcast(value, bx.type_vector(bx.type_i32(), 4))
         }
         (
-            InlineAsmRegClass::X86(
+            X86(
                 X86InlineAsmRegClass::xmm_reg
                 | X86InlineAsmRegClass::ymm_reg
                 | X86InlineAsmRegClass::zmm_reg,
@@ -1009,7 +977,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
             bx.bitcast(value, bx.type_vector(bx.type_i16(), 8))
         }
         (
-            InlineAsmRegClass::X86(
+            X86(
                 X86InlineAsmRegClass::xmm_reg
                 | X86InlineAsmRegClass::ymm_reg
                 | X86InlineAsmRegClass::zmm_reg,
@@ -1018,10 +986,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
         ) if element.primitive() == Primitive::Float(Float::F16) => {
             bx.bitcast(value, bx.type_vector(bx.type_i16(), count))
         }
-        (
-            InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
-            Abi::Scalar(s),
-        ) => {
+        (Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16), Abi::Scalar(s)) => {
             if let Primitive::Int(Integer::I32, _) = s.primitive() {
                 bx.bitcast(value, bx.cx.type_f32())
             } else {
@@ -1029,7 +994,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
             }
         }
         (
-            InlineAsmRegClass::Arm(
+            Arm(
                 ArmInlineAsmRegClass::dreg
                 | ArmInlineAsmRegClass::dreg_low8
                 | ArmInlineAsmRegClass::dreg_low16,
@@ -1043,7 +1008,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
             }
         }
         (
-            InlineAsmRegClass::Arm(
+            Arm(
                 ArmInlineAsmRegClass::dreg
                 | ArmInlineAsmRegClass::dreg_low8
                 | ArmInlineAsmRegClass::dreg_low16
@@ -1055,7 +1020,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
         ) if element.primitive() == Primitive::Float(Float::F16) => {
             bx.bitcast(value, bx.type_vector(bx.type_i16(), count))
         }
-        (InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
+        (Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
             match s.primitive() {
                 // MIPS only supports register-length arithmetics.
                 Primitive::Int(Integer::I8 | Integer::I16, _) => bx.zext(value, bx.cx.type_i32()),
@@ -1064,7 +1029,7 @@ fn llvm_fixup_input<'ll, 'tcx>(
                 _ => value,
             }
         }
-        (InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
+        (RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
             if s.primitive() == Primitive::Float(Float::F16)
                 && !any_target_feature_enabled(bx, instance, &[sym::zfhmin, sym::zfh]) =>
         {
@@ -1086,15 +1051,16 @@ fn llvm_fixup_output<'ll, 'tcx>(
     layout: &TyAndLayout<'tcx>,
     instance: Instance<'_>,
 ) -> &'ll Value {
+    use InlineAsmRegClass::*;
     match (reg, layout.abi) {
-        (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
+        (AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
             if let Primitive::Int(Integer::I8, _) = s.primitive() {
                 bx.extract_element(value, bx.const_i32(0))
             } else {
                 value
             }
         }
-        (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
+        (AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
             if s.primitive() != Primitive::Float(Float::F128) =>
         {
             value = bx.extract_element(value, bx.const_i32(0));
@@ -1103,26 +1069,25 @@ fn llvm_fixup_output<'ll, 'tcx>(
             }
             value
         }
-        (
-            InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16),
-            Abi::Vector { element, count },
-        ) if layout.size.bytes() == 8 => {
+        (AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Vector { element, count })
+            if layout.size.bytes() == 8 =>
+        {
             let elem_ty = llvm_asm_scalar_type(bx.cx, element);
             let vec_ty = bx.cx.type_vector(elem_ty, count * 2);
             let indices: Vec<_> = (0..count).map(|x| bx.const_i32(x as i32)).collect();
             bx.shuffle_vector(value, bx.const_undef(vec_ty), bx.const_vector(&indices))
         }
-        (InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
+        (X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
             if s.primitive() == Primitive::Float(Float::F64) =>
         {
             bx.bitcast(value, bx.cx.type_f64())
         }
         (
-            InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
+            X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
             Abi::Vector { .. },
         ) if layout.size.bytes() == 64 => bx.bitcast(value, layout.llvm_type(bx.cx)),
         (
-            InlineAsmRegClass::X86(
+            X86(
                 X86InlineAsmRegClass::xmm_reg
                 | X86InlineAsmRegClass::ymm_reg
                 | X86InlineAsmRegClass::zmm_reg,
@@ -1134,7 +1099,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
             bx.bitcast(value, bx.type_f128())
         }
         (
-            InlineAsmRegClass::X86(
+            X86(
                 X86InlineAsmRegClass::xmm_reg
                 | X86InlineAsmRegClass::ymm_reg
                 | X86InlineAsmRegClass::zmm_reg,
@@ -1145,7 +1110,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
             bx.extract_element(value, bx.const_usize(0))
         }
         (
-            InlineAsmRegClass::X86(
+            X86(
                 X86InlineAsmRegClass::xmm_reg
                 | X86InlineAsmRegClass::ymm_reg
                 | X86InlineAsmRegClass::zmm_reg,
@@ -1154,10 +1119,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
         ) if element.primitive() == Primitive::Float(Float::F16) => {
             bx.bitcast(value, bx.type_vector(bx.type_f16(), count))
         }
-        (
-            InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
-            Abi::Scalar(s),
-        ) => {
+        (Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16), Abi::Scalar(s)) => {
             if let Primitive::Int(Integer::I32, _) = s.primitive() {
                 bx.bitcast(value, bx.cx.type_i32())
             } else {
@@ -1165,7 +1127,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
             }
         }
         (
-            InlineAsmRegClass::Arm(
+            Arm(
                 ArmInlineAsmRegClass::dreg
                 | ArmInlineAsmRegClass::dreg_low8
                 | ArmInlineAsmRegClass::dreg_low16,
@@ -1179,7 +1141,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
             }
         }
         (
-            InlineAsmRegClass::Arm(
+            Arm(
                 ArmInlineAsmRegClass::dreg
                 | ArmInlineAsmRegClass::dreg_low8
                 | ArmInlineAsmRegClass::dreg_low16
@@ -1191,7 +1153,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
         ) if element.primitive() == Primitive::Float(Float::F16) => {
             bx.bitcast(value, bx.type_vector(bx.type_f16(), count))
         }
-        (InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
+        (Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
             match s.primitive() {
                 // MIPS only supports register-length arithmetics.
                 Primitive::Int(Integer::I8, _) => bx.trunc(value, bx.cx.type_i8()),
@@ -1201,7 +1163,7 @@ fn llvm_fixup_output<'ll, 'tcx>(
                 _ => value,
             }
         }
-        (InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
+        (RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
             if s.primitive() == Primitive::Float(Float::F16)
                 && !any_target_feature_enabled(bx, instance, &[sym::zfhmin, sym::zfh]) =>
         {
@@ -1220,39 +1182,39 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
     layout: &TyAndLayout<'tcx>,
     instance: Instance<'_>,
 ) -> &'ll Type {
+    use InlineAsmRegClass::*;
     match (reg, layout.abi) {
-        (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
+        (AArch64(AArch64InlineAsmRegClass::vreg), Abi::Scalar(s)) => {
             if let Primitive::Int(Integer::I8, _) = s.primitive() {
                 cx.type_vector(cx.type_i8(), 8)
             } else {
                 layout.llvm_type(cx)
             }
         }
-        (InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
+        (AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Scalar(s))
             if s.primitive() != Primitive::Float(Float::F128) =>
         {
             let elem_ty = llvm_asm_scalar_type(cx, s);
             let count = 16 / layout.size.bytes();
             cx.type_vector(elem_ty, count)
         }
-        (
-            InlineAsmRegClass::AArch64(AArch64InlineAsmRegClass::vreg_low16),
-            Abi::Vector { element, count },
-        ) if layout.size.bytes() == 8 => {
+        (AArch64(AArch64InlineAsmRegClass::vreg_low16), Abi::Vector { element, count })
+            if layout.size.bytes() == 8 =>
+        {
             let elem_ty = llvm_asm_scalar_type(cx, element);
             cx.type_vector(elem_ty, count * 2)
         }
-        (InlineAsmRegClass::X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
+        (X86(X86InlineAsmRegClass::reg_abcd), Abi::Scalar(s))
             if s.primitive() == Primitive::Float(Float::F64) =>
         {
             cx.type_i64()
         }
         (
-            InlineAsmRegClass::X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
+            X86(X86InlineAsmRegClass::xmm_reg | X86InlineAsmRegClass::zmm_reg),
             Abi::Vector { .. },
         ) if layout.size.bytes() == 64 => cx.type_vector(cx.type_f64(), 8),
         (
-            InlineAsmRegClass::X86(
+            X86(
                 X86InlineAsmRegClass::xmm_reg
                 | X86InlineAsmRegClass::ymm_reg
                 | X86InlineAsmRegClass::zmm_reg,
@@ -1264,7 +1226,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
             cx.type_vector(cx.type_i32(), 4)
         }
         (
-            InlineAsmRegClass::X86(
+            X86(
                 X86InlineAsmRegClass::xmm_reg
                 | X86InlineAsmRegClass::ymm_reg
                 | X86InlineAsmRegClass::zmm_reg,
@@ -1272,7 +1234,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
             Abi::Scalar(s),
         ) if s.primitive() == Primitive::Float(Float::F16) => cx.type_vector(cx.type_i16(), 8),
         (
-            InlineAsmRegClass::X86(
+            X86(
                 X86InlineAsmRegClass::xmm_reg
                 | X86InlineAsmRegClass::ymm_reg
                 | X86InlineAsmRegClass::zmm_reg,
@@ -1281,10 +1243,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
         ) if element.primitive() == Primitive::Float(Float::F16) => {
             cx.type_vector(cx.type_i16(), count)
         }
-        (
-            InlineAsmRegClass::Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16),
-            Abi::Scalar(s),
-        ) => {
+        (Arm(ArmInlineAsmRegClass::sreg | ArmInlineAsmRegClass::sreg_low16), Abi::Scalar(s)) => {
             if let Primitive::Int(Integer::I32, _) = s.primitive() {
                 cx.type_f32()
             } else {
@@ -1292,7 +1251,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
             }
         }
         (
-            InlineAsmRegClass::Arm(
+            Arm(
                 ArmInlineAsmRegClass::dreg
                 | ArmInlineAsmRegClass::dreg_low8
                 | ArmInlineAsmRegClass::dreg_low16,
@@ -1306,7 +1265,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
             }
         }
         (
-            InlineAsmRegClass::Arm(
+            Arm(
                 ArmInlineAsmRegClass::dreg
                 | ArmInlineAsmRegClass::dreg_low8
                 | ArmInlineAsmRegClass::dreg_low16
@@ -1318,7 +1277,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
         ) if element.primitive() == Primitive::Float(Float::F16) => {
             cx.type_vector(cx.type_i16(), count)
         }
-        (InlineAsmRegClass::Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
+        (Mips(MipsInlineAsmRegClass::reg), Abi::Scalar(s)) => {
             match s.primitive() {
                 // MIPS only supports register-length arithmetics.
                 Primitive::Int(Integer::I8 | Integer::I16, _) => cx.type_i32(),
@@ -1327,7 +1286,7 @@ fn llvm_fixup_output_type<'ll, 'tcx>(
                 _ => layout.llvm_type(cx),
             }
         }
-        (InlineAsmRegClass::RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
+        (RiscV(RiscVInlineAsmRegClass::freg), Abi::Scalar(s))
             if s.primitive() == Primitive::Float(Float::F16)
                 && !any_target_feature_enabled(cx, instance, &[sym::zfhmin, sym::zfh]) =>
         {
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 9d4497d73a8..6df63eec513 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -403,8 +403,9 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
     if codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
         to_add.push(AttributeKind::Naked.create_attr(cx.llcx));
         // HACK(jubilee): "indirect branch tracking" works by attaching prologues to functions.
-        // And it is a module-level attribute, so the alternative is pulling naked functions into new LLVM modules.
-        // Otherwise LLVM's "naked" functions come with endbr prefixes per https://github.com/rust-lang/rust/issues/98768
+        // And it is a module-level attribute, so the alternative is pulling naked functions into
+        // new LLVM modules. Otherwise LLVM's "naked" functions come with endbr prefixes per
+        // https://github.com/rust-lang/rust/issues/98768
         to_add.push(AttributeKind::NoCfCheck.create_attr(cx.llcx));
         if llvm_util::get_version() < (19, 0, 0) {
             // Prior to LLVM 19, branch-target-enforcement was disabled by setting the attribute to
@@ -454,7 +455,8 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
             flags |= AllocKindFlags::Zeroed;
         }
         to_add.push(llvm::CreateAllocKindAttr(cx.llcx, flags));
-        // apply to return place instead of function (unlike all other attributes applied in this function)
+        // apply to return place instead of function (unlike all other attributes applied in this
+        // function)
         let no_alias = AttributeKind::NoAlias.create_attr(cx.llcx);
         attributes::apply_to_llfn(llfn, AttributePlace::ReturnValue, &[no_alias]);
     }
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 2ebe0be53aa..66479ad7f34 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -156,15 +156,15 @@ fn get_bitcode_slice_from_object_data<'a>(
     obj: &'a [u8],
     cgcx: &CodegenContext<LlvmCodegenBackend>,
 ) -> Result<&'a [u8], LtoBitcodeFromRlib> {
-    // We're about to assume the data here is an object file with sections, but if it's raw LLVM IR that
-    // won't work. Fortunately, if that's what we have we can just return the object directly, so we sniff
-    // the relevant magic strings here and return.
+    // We're about to assume the data here is an object file with sections, but if it's raw LLVM IR
+    // that won't work. Fortunately, if that's what we have we can just return the object directly,
+    // so we sniff the relevant magic strings here and return.
     if obj.starts_with(b"\xDE\xC0\x17\x0B") || obj.starts_with(b"BC\xC0\xDE") {
         return Ok(obj);
     }
-    // We drop the "__LLVM," prefix here because on Apple platforms there's a notion of "segment name"
-    // which in the public API for sections gets treated as part of the section name, but internally
-    // in MachOObjectFile.cpp gets treated separately.
+    // We drop the "__LLVM," prefix here because on Apple platforms there's a notion of "segment
+    // name" which in the public API for sections gets treated as part of the section name, but
+    // internally in MachOObjectFile.cpp gets treated separately.
     let section_name = bitcode_section_name(cgcx).trim_start_matches("__LLVM,");
     let mut len = 0;
     let data = unsafe {
diff --git a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs
index 681ac75c877..76529e0c83b 100644
--- a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs
+++ b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs
@@ -30,7 +30,7 @@ impl OwnedTargetMachine {
         data_sections: bool,
         unique_section_names: bool,
         trap_unreachable: bool,
-        singletree: bool,
+        singlethread: bool,
         verbose_asm: bool,
         emit_stack_size_section: bool,
         relax_elf_relocations: bool,
@@ -62,7 +62,7 @@ impl OwnedTargetMachine {
                 data_sections,
                 unique_section_names,
                 trap_unreachable,
-                singletree,
+                singlethread,
                 verbose_asm,
                 emit_stack_size_section,
                 relax_elf_relocations,
@@ -86,15 +86,17 @@ impl Deref for OwnedTargetMachine {
     type Target = llvm::TargetMachine;
 
     fn deref(&self) -> &Self::Target {
-        // SAFETY: constructing ensures we have a valid pointer created by llvm::LLVMRustCreateTargetMachine
+        // SAFETY: constructing ensures we have a valid pointer created by
+        // llvm::LLVMRustCreateTargetMachine.
         unsafe { self.tm_unique.as_ref() }
     }
 }
 
 impl Drop for OwnedTargetMachine {
     fn drop(&mut self) {
-        // SAFETY: constructing ensures we have a valid pointer created by llvm::LLVMRustCreateTargetMachine
-        // OwnedTargetMachine is not copyable so there is no double free or use after free
+        // SAFETY: constructing ensures we have a valid pointer created by
+        // llvm::LLVMRustCreateTargetMachine OwnedTargetMachine is not copyable so there is no
+        // double free or use after free.
         unsafe {
             llvm::LLVMRustDisposeTargetMachine(self.tm_unique.as_mut());
         }
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index b1b692cc027..d2c4ea8171b 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -38,7 +38,7 @@ use crate::errors::{
     CopyBitcode, FromLlvmDiag, FromLlvmOptimizationDiag, LlvmError, UnknownCompression,
     WithLlvmError, WriteBytecode,
 };
-use crate::llvm::diagnostic::OptimizationDiagnosticKind;
+use crate::llvm::diagnostic::OptimizationDiagnosticKind::*;
 use crate::llvm::{self, DiagnosticInfo, PassManager};
 use crate::type_::Type;
 use crate::{base, common, llvm_util, LlvmCodegenBackend, ModuleLlvm};
@@ -157,7 +157,8 @@ fn to_pass_builder_opt_level(cfg: config::OptLevel) -> llvm::PassBuilderOptLevel
 fn to_llvm_relocation_model(relocation_model: RelocModel) -> llvm::RelocModel {
     match relocation_model {
         RelocModel::Static => llvm::RelocModel::Static,
-        // LLVM doesn't have a PIE relocation model, it represents PIE as PIC with an extra attribute.
+        // LLVM doesn't have a PIE relocation model, it represents PIE as PIC with an extra
+        // attribute.
         RelocModel::Pic | RelocModel::Pie => llvm::RelocModel::PIC,
         RelocModel::DynamicNoPic => llvm::RelocModel::DynamicNoPic,
         RelocModel::Ropi => llvm::RelocModel::ROPI,
@@ -188,8 +189,8 @@ pub(crate) fn target_machine_factory(
     let use_softfp = if sess.target.arch == "arm" && sess.target.abi == "eabihf" {
         sess.opts.cg.soft_float
     } else {
-        // `validate_commandline_args_with_session_available` has already warned about this being ignored.
-        // Let's make sure LLVM doesn't suddenly start using this flag on more targets.
+        // `validate_commandline_args_with_session_available` has already warned about this being
+        // ignored. Let's make sure LLVM doesn't suddenly start using this flag on more targets.
         false
     };
 
@@ -446,13 +447,12 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
                 column: opt.column,
                 pass_name: &opt.pass_name,
                 kind: match opt.kind {
-                    OptimizationDiagnosticKind::OptimizationRemark => "success",
-                    OptimizationDiagnosticKind::OptimizationMissed
-                    | OptimizationDiagnosticKind::OptimizationFailure => "missed",
-                    OptimizationDiagnosticKind::OptimizationAnalysis
-                    | OptimizationDiagnosticKind::OptimizationAnalysisFPCommute
-                    | OptimizationDiagnosticKind::OptimizationAnalysisAliasing => "analysis",
-                    OptimizationDiagnosticKind::OptimizationRemarkOther => "other",
+                    OptimizationRemark => "success",
+                    OptimizationMissed | OptimizationFailure => "missed",
+                    OptimizationAnalysis
+                    | OptimizationAnalysisFPCommute
+                    | OptimizationAnalysisAliasing => "analysis",
+                    OptimizationRemarkOther => "other",
                 },
                 message: &opt.message,
             });
@@ -945,11 +945,12 @@ fn create_section_with_flags_asm(section_name: &str, section_flags: &str, data:
 }
 
 fn target_is_apple(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool {
-    cgcx.opts.target_triple.triple().contains("-ios")
-        || cgcx.opts.target_triple.triple().contains("-darwin")
-        || cgcx.opts.target_triple.triple().contains("-tvos")
-        || cgcx.opts.target_triple.triple().contains("-watchos")
-        || cgcx.opts.target_triple.triple().contains("-visionos")
+    let triple = cgcx.opts.target_triple.triple();
+    triple.contains("-ios")
+        || triple.contains("-darwin")
+        || triple.contains("-tvos")
+        || triple.contains("-watchos")
+        || triple.contains("-visionos")
 }
 
 fn target_is_aix(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool {
diff --git a/compiler/rustc_codegen_llvm/src/builder.rs b/compiler/rustc_codegen_llvm/src/builder.rs
index 40783825cae..6ffe90997f5 100644
--- a/compiler/rustc_codegen_llvm/src/builder.rs
+++ b/compiler/rustc_codegen_llvm/src/builder.rs
@@ -26,13 +26,13 @@ use smallvec::SmallVec;
 use tracing::{debug, instrument};
 
 use crate::abi::FnAbiLlvmExt;
+use crate::attributes;
 use crate::common::Funclet;
 use crate::context::CodegenCx;
 use crate::llvm::{self, AtomicOrdering, AtomicRmwBinOp, BasicBlock, False, True};
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
-use crate::{attributes, llvm_util};
 
 // All Builders must have an llfn associated with them
 #[must_use]
@@ -93,8 +93,6 @@ impl HasTargetSpec for Builder<'_, '_, '_> {
 }
 
 impl<'tcx> LayoutOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
-    type LayoutOfResult = TyAndLayout<'tcx>;
-
     #[inline]
     fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
         self.cx.handle_layout_err(err, span, ty)
@@ -102,8 +100,6 @@ impl<'tcx> LayoutOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
 }
 
 impl<'tcx> FnAbiOfHelpers<'tcx> for Builder<'_, '_, 'tcx> {
-    type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
-
     #[inline]
     fn handle_fn_abi_err(
         &self,
@@ -124,11 +120,7 @@ impl<'ll, 'tcx> Deref for Builder<'_, 'll, 'tcx> {
     }
 }
 
-impl<'ll, 'tcx> HasCodegen<'tcx> for Builder<'_, 'll, 'tcx> {
-    type CodegenCx = CodegenCx<'ll, 'tcx>;
-}
-
-macro_rules! builder_methods_for_value_instructions {
+macro_rules! math_builder_methods {
     ($($name:ident($($arg:ident),*) => $llvm_capi:ident),+ $(,)?) => {
         $(fn $name(&mut self, $($arg: &'ll Value),*) -> &'ll Value {
             unsafe {
@@ -138,7 +130,21 @@ macro_rules! builder_methods_for_value_instructions {
     }
 }
 
+macro_rules! set_math_builder_methods {
+    ($($name:ident($($arg:ident),*) => ($llvm_capi:ident, $llvm_set_math:ident)),+ $(,)?) => {
+        $(fn $name(&mut self, $($arg: &'ll Value),*) -> &'ll Value {
+            unsafe {
+                let instr = llvm::$llvm_capi(self.llbuilder, $($arg,)* UNNAMED);
+                llvm::$llvm_set_math(instr);
+                instr
+            }
+        })+
+    }
+}
+
 impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
+    type CodegenCx = CodegenCx<'ll, 'tcx>;
+
     fn build(cx: &'a CodegenCx<'ll, 'tcx>, llbb: &'ll BasicBlock) -> Self {
         let bx = Builder::with_cx(cx);
         unsafe {
@@ -273,7 +279,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         }
     }
 
-    builder_methods_for_value_instructions! {
+    math_builder_methods! {
         add(a, b) => LLVMBuildAdd,
         fadd(a, b) => LLVMBuildFAdd,
         sub(a, b) => LLVMBuildSub,
@@ -305,84 +311,17 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
         unchecked_umul(x, y) => LLVMBuildNUWMul,
     }
 
-    fn fadd_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
-        unsafe {
-            let instr = llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, UNNAMED);
-            llvm::LLVMRustSetFastMath(instr);
-            instr
-        }
-    }
-
-    fn fsub_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
-        unsafe {
-            let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, UNNAMED);
-            llvm::LLVMRustSetFastMath(instr);
-            instr
-        }
-    }
-
-    fn fmul_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
-        unsafe {
-            let instr = llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, UNNAMED);
-            llvm::LLVMRustSetFastMath(instr);
-            instr
-        }
-    }
-
-    fn fdiv_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
-        unsafe {
-            let instr = llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, UNNAMED);
-            llvm::LLVMRustSetFastMath(instr);
-            instr
-        }
-    }
-
-    fn frem_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
-        unsafe {
-            let instr = llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, UNNAMED);
-            llvm::LLVMRustSetFastMath(instr);
-            instr
-        }
-    }
-
-    fn fadd_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
-        unsafe {
-            let instr = llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, UNNAMED);
-            llvm::LLVMRustSetAlgebraicMath(instr);
-            instr
-        }
-    }
-
-    fn fsub_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
-        unsafe {
-            let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, UNNAMED);
-            llvm::LLVMRustSetAlgebraicMath(instr);
-            instr
-        }
-    }
-
-    fn fmul_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
-        unsafe {
-            let instr = llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, UNNAMED);
-            llvm::LLVMRustSetAlgebraicMath(instr);
-            instr
-        }
-    }
-
-    fn fdiv_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
-        unsafe {
-            let instr = llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, UNNAMED);
-            llvm::LLVMRustSetAlgebraicMath(instr);
-            instr
-        }
-    }
-
-    fn frem_algebraic(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
-        unsafe {
-            let instr = llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, UNNAMED);
-            llvm::LLVMRustSetAlgebraicMath(instr);
-            instr
-        }
+    set_math_builder_methods! {
+        fadd_fast(x, y) => (LLVMBuildFAdd, LLVMRustSetFastMath),
+        fsub_fast(x, y) => (LLVMBuildFSub, LLVMRustSetFastMath),
+        fmul_fast(x, y) => (LLVMBuildFMul, LLVMRustSetFastMath),
+        fdiv_fast(x, y) => (LLVMBuildFDiv, LLVMRustSetFastMath),
+        frem_fast(x, y) => (LLVMBuildFRem, LLVMRustSetFastMath),
+        fadd_algebraic(x, y) => (LLVMBuildFAdd, LLVMRustSetAlgebraicMath),
+        fsub_algebraic(x, y) => (LLVMBuildFSub, LLVMRustSetAlgebraicMath),
+        fmul_algebraic(x, y) => (LLVMBuildFMul, LLVMRustSetAlgebraicMath),
+        fdiv_algebraic(x, y) => (LLVMBuildFDiv, LLVMRustSetAlgebraicMath),
+        frem_algebraic(x, y) => (LLVMBuildFRem, LLVMRustSetAlgebraicMath),
     }
 
     fn checked_binop(
@@ -465,6 +404,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
             val
         }
     }
+
     fn to_immediate_scalar(&mut self, val: Self::Value, scalar: abi::Scalar) -> Self::Value {
         if scalar.is_bool() {
             return self.trunc(val, self.cx().type_i1());
@@ -733,11 +673,11 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
                 // for performance. LLVM doesn't seem to care about this, and will happily treat
                 // `!nontemporal` stores as-if they were normal stores (for reordering optimizations
                 // etc) even on x86, despite later lowering them to MOVNT which do *not* behave like
-                // regular stores but require special fences.
-                // So we keep a list of architectures where `!nontemporal` is known to be truly just
-                // a hint, and use regular stores everywhere else.
-                // (In the future, we could alternatively ensure that an sfence gets emitted after a sequence of movnt
-                // before any kind of synchronizing operation. But it's not clear how to do that with LLVM.)
+                // regular stores but require special fences. So we keep a list of architectures
+                // where `!nontemporal` is known to be truly just a hint, and use regular stores
+                // everywhere else. (In the future, we could alternatively ensure that an sfence
+                // gets emitted after a sequence of movnt before any kind of synchronizing
+                // operation. But it's not clear how to do that with LLVM.)
                 // For more context, see <https://github.com/rust-lang/rust/issues/114582> and
                 // <https://github.com/llvm/llvm-project/issues/64521>.
                 const WELL_BEHAVED_NONTEMPORAL_ARCHS: &[&str] =
@@ -1166,6 +1106,7 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
             (val, success)
         }
     }
+
     fn atomic_rmw(
         &mut self,
         op: rustc_codegen_ssa::common::AtomicRmwBinOp,
@@ -1317,15 +1258,9 @@ impl<'a, 'll, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
     }
 
     fn apply_attrs_to_cleanup_callsite(&mut self, llret: &'ll Value) {
-        if llvm_util::get_version() < (17, 0, 2) {
-            // Work around https://github.com/llvm/llvm-project/issues/66984.
-            let noinline = llvm::AttributeKind::NoInline.create_attr(self.llcx);
-            attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[noinline]);
-        } else {
-            // Cleanup is always the cold path.
-            let cold_inline = llvm::AttributeKind::Cold.create_attr(self.llcx);
-            attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[cold_inline]);
-        }
+        // Cleanup is always the cold path.
+        let cold_inline = llvm::AttributeKind::Cold.create_attr(self.llcx);
+        attributes::apply_to_callsite(llret, llvm::AttributePlace::Function, &[cold_inline]);
     }
 }
 
@@ -1767,8 +1702,6 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
     ) {
         debug!("mcdc_parameters() with args ({:?}, {:?}, {:?})", fn_name, hash, bitmap_bytes);
 
-        assert!(llvm_util::get_version() >= (18, 0, 0), "MCDC intrinsics require LLVM 18 or later");
-
         let llfn = unsafe { llvm::LLVMRustGetInstrProfMCDCParametersIntrinsic(self.cx().llmod) };
         let llty = self.cx.type_func(
             &[self.cx.type_ptr(), self.cx.type_i64(), self.cx.type_i32()],
@@ -1802,7 +1735,6 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
             "mcdc_tvbitmap_update() with args ({:?}, {:?}, {:?}, {:?}, {:?})",
             fn_name, hash, bitmap_bytes, bitmap_index, mcdc_temp
         );
-        assert!(llvm_util::get_version() >= (18, 0, 0), "MCDC intrinsics require LLVM 18 or later");
 
         let llfn =
             unsafe { llvm::LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(self.cx().llmod) };
@@ -1844,7 +1776,6 @@ impl<'a, 'll, 'tcx> Builder<'a, 'll, 'tcx> {
             "mcdc_condbitmap_update() with args ({:?}, {:?}, {:?}, {:?}, {:?})",
             fn_name, hash, cond_loc, mcdc_temp, bool_value
         );
-        assert!(llvm_util::get_version() >= (18, 0, 0), "MCDC intrinsics require LLVM 18 or later");
         let llfn = unsafe { llvm::LLVMRustGetInstrProfMCDCCondBitmapIntrinsic(self.cx().llmod) };
         let llty = self.cx.type_func(
             &[
diff --git a/compiler/rustc_codegen_llvm/src/callee.rs b/compiler/rustc_codegen_llvm/src/callee.rs
index 949fd1bc124..206a7069792 100644
--- a/compiler/rustc_codegen_llvm/src/callee.rs
+++ b/compiler/rustc_codegen_llvm/src/callee.rs
@@ -15,11 +15,6 @@ use crate::value::Value;
 
 /// Codegens a reference to a fn/method item, monomorphizing and
 /// inlining as it goes.
-///
-/// # Parameters
-///
-/// - `cx`: the crate context
-/// - `instance`: the instance to be instantiated
 pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) -> &'ll Value {
     let tcx = cx.tcx();
 
@@ -106,62 +101,42 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t
             let is_generic =
                 instance.args.non_erasable_generics(tcx, instance.def_id()).next().is_some();
 
-            if is_generic {
-                // This is a monomorphization. Its expected visibility depends
-                // on whether we are in share-generics mode.
-
-                if cx.tcx.sess.opts.share_generics() {
-                    // We are in share_generics mode.
-
+            let is_hidden = if is_generic {
+                // This is a monomorphization of a generic function.
+                if !cx.tcx.sess.opts.share_generics() {
+                    // When not sharing generics, all instances are in the same
+                    // crate and have hidden visibility.
+                    true
+                } else {
                     if let Some(instance_def_id) = instance_def_id.as_local() {
-                        // This is a definition from the current crate. If the
-                        // definition is unreachable for downstream crates or
-                        // the current crate does not re-export generics, the
-                        // definition of the instance will have been declared
-                        // as `hidden`.
-                        if cx.tcx.is_unreachable_local_definition(instance_def_id)
+                        // This is a monomorphization of a generic function
+                        // defined in the current crate. It is hidden if:
+                        // - the definition is unreachable for downstream
+                        //   crates, or
+                        // - the current crate does not re-export generics
+                        //   (because the crate is a C library or executable)
+                        cx.tcx.is_unreachable_local_definition(instance_def_id)
                             || !cx.tcx.local_crate_exports_generics()
-                        {
-                            llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
-                        }
                     } else {
                         // This is a monomorphization of a generic function
-                        // defined in an upstream crate.
-                        if instance.upstream_monomorphization(tcx).is_some() {
-                            // This is instantiated in another crate. It cannot
-                            // be `hidden`.
-                        } else {
-                            // This is a local instantiation of an upstream definition.
-                            // If the current crate does not re-export it
-                            // (because it is a C library or an executable), it
-                            // will have been declared `hidden`.
-                            if !cx.tcx.local_crate_exports_generics() {
-                                llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
-                            }
-                        }
+                        // defined in an upstream crate. It is hidden if:
+                        // - it is instantiated in this crate, and
+                        // - the current crate does not re-export generics
+                        instance.upstream_monomorphization(tcx).is_none()
+                            && !cx.tcx.local_crate_exports_generics()
                     }
-                } else {
-                    // When not sharing generics, all instances are in the same
-                    // crate and have hidden visibility
-                    llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
                 }
             } else {
-                // This is a non-generic function
-                if cx.tcx.is_codegened_item(instance_def_id) {
-                    // This is a function that is instantiated in the local crate
-
-                    if instance_def_id.is_local() {
-                        // This is function that is defined in the local crate.
-                        // If it is not reachable, it is hidden.
-                        if !cx.tcx.is_reachable_non_generic(instance_def_id) {
-                            llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
-                        }
-                    } else {
-                        // This is a function from an upstream crate that has
-                        // been instantiated here. These are always hidden.
-                        llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
-                    }
-                }
+                // This is a non-generic function. It is hidden if:
+                // - it is instantiated in the local crate, and
+                //   - it is defined an upstream crate (non-local), or
+                //   - it is not reachable
+                cx.tcx.is_codegened_item(instance_def_id)
+                    && (!instance_def_id.is_local()
+                        || !cx.tcx.is_reachable_non_generic(instance_def_id))
+            };
+            if is_hidden {
+                llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
             }
 
             // MinGW: For backward compatibility we rely on the linker to decide whether it
diff --git a/compiler/rustc_codegen_llvm/src/common.rs b/compiler/rustc_codegen_llvm/src/common.rs
index ef6560ecbe5..508c2d1a820 100644
--- a/compiler/rustc_codegen_llvm/src/common.rs
+++ b/compiler/rustc_codegen_llvm/src/common.rs
@@ -113,7 +113,7 @@ impl<'ll> CodegenCx<'ll, '_> {
     }
 }
 
-impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
+impl<'ll, 'tcx> ConstCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     fn const_null(&self, t: &'ll Type) -> &'ll Value {
         unsafe { llvm::LLVMConstNull(t) }
     }
@@ -126,25 +126,14 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         unsafe { llvm::LLVMGetPoison(t) }
     }
 
-    fn const_int(&self, t: &'ll Type, i: i64) -> &'ll Value {
-        unsafe { llvm::LLVMConstInt(t, i as u64, True) }
-    }
-
-    fn const_uint(&self, t: &'ll Type, i: u64) -> &'ll Value {
-        unsafe { llvm::LLVMConstInt(t, i, False) }
-    }
-
-    fn const_uint_big(&self, t: &'ll Type, u: u128) -> &'ll Value {
-        unsafe {
-            let words = [u as u64, (u >> 64) as u64];
-            llvm::LLVMConstIntOfArbitraryPrecision(t, 2, words.as_ptr())
-        }
-    }
-
     fn const_bool(&self, val: bool) -> &'ll Value {
         self.const_uint(self.type_i1(), val as u64)
     }
 
+    fn const_i8(&self, i: i8) -> &'ll Value {
+        self.const_int(self.type_i8(), i as i64)
+    }
+
     fn const_i16(&self, i: i16) -> &'ll Value {
         self.const_int(self.type_i16(), i as i64)
     }
@@ -153,8 +142,12 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         self.const_int(self.type_i32(), i as i64)
     }
 
-    fn const_i8(&self, i: i8) -> &'ll Value {
-        self.const_int(self.type_i8(), i as i64)
+    fn const_int(&self, t: &'ll Type, i: i64) -> &'ll Value {
+        unsafe { llvm::LLVMConstInt(t, i as u64, True) }
+    }
+
+    fn const_u8(&self, i: u8) -> &'ll Value {
+        self.const_uint(self.type_i8(), i as u64)
     }
 
     fn const_u32(&self, i: u32) -> &'ll Value {
@@ -179,8 +172,15 @@ impl<'ll, 'tcx> ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         self.const_uint(self.isize_ty, i)
     }
 
-    fn const_u8(&self, i: u8) -> &'ll Value {
-        self.const_uint(self.type_i8(), i as u64)
+    fn const_uint(&self, t: &'ll Type, i: u64) -> &'ll Value {
+        unsafe { llvm::LLVMConstInt(t, i, False) }
+    }
+
+    fn const_uint_big(&self, t: &'ll Type, u: u128) -> &'ll Value {
+        unsafe {
+            let words = [u as u64, (u >> 64) as u64];
+            llvm::LLVMConstIntOfArbitraryPrecision(t, 2, words.as_ptr())
+        }
     }
 
     fn const_real(&self, t: &'ll Type, val: f64) -> &'ll Value {
diff --git a/compiler/rustc_codegen_llvm/src/consts.rs b/compiler/rustc_codegen_llvm/src/consts.rs
index d60122fccee..33d3b5d4474 100644
--- a/compiler/rustc_codegen_llvm/src/consts.rs
+++ b/compiler/rustc_codegen_llvm/src/consts.rs
@@ -73,8 +73,8 @@ pub(crate) fn const_alloc_to_llvm<'ll>(
 
         // Generating partially-uninit consts is limited to small numbers of chunks,
         // to avoid the cost of generating large complex const expressions.
-        // For example, `[(u32, u8); 1024 * 1024]` contains uninit padding in each element,
-        // and would result in `{ [5 x i8] zeroinitializer, [3 x i8] undef, ...repeat 1M times... }`.
+        // For example, `[(u32, u8); 1024 * 1024]` contains uninit padding in each element, and
+        // would result in `{ [5 x i8] zeroinitializer, [3 x i8] undef, ...repeat 1M times... }`.
         let max = cx.sess().opts.unstable_opts.uninit_const_chunk_threshold;
         let allow_uninit_chunks = chunks.clone().take(max.saturating_add(1)).count() <= max;
 
@@ -249,8 +249,8 @@ impl<'ll> CodegenCx<'ll, '_> {
         trace!(?instance);
 
         let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() };
-        // Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure out
-        // the llvm type from the actual evaluated initializer.
+        // Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure
+        // out the llvm type from the actual evaluated initializer.
         let llty = if nested {
             self.type_i8()
         } else {
@@ -262,7 +262,7 @@ impl<'ll> CodegenCx<'ll, '_> {
     }
 
     #[instrument(level = "debug", skip(self, llty))]
-    pub(crate) fn get_static_inner(&self, def_id: DefId, llty: &'ll Type) -> &'ll Value {
+    fn get_static_inner(&self, def_id: DefId, llty: &'ll Type) -> &'ll Value {
         let instance = Instance::mono(self.tcx, def_id);
         if let Some(&g) = self.instances.borrow().get(&instance) {
             trace!("used cached value");
@@ -320,15 +320,16 @@ impl<'ll> CodegenCx<'ll, '_> {
         }
 
         if !def_id.is_local() {
-            let needs_dll_storage_attr = self.use_dll_storage_attrs && !self.tcx.is_foreign_item(def_id) &&
+            let needs_dll_storage_attr = self.use_dll_storage_attrs
+                && !self.tcx.is_foreign_item(def_id)
                 // Local definitions can never be imported, so we must not apply
                 // the DLLImport annotation.
-                !dso_local &&
+                && !dso_local
                 // ThinLTO can't handle this workaround in all cases, so we don't
                 // emit the attrs. Instead we make them unnecessary by disallowing
                 // dynamic linking when linker plugin based LTO is enabled.
-                !self.tcx.sess.opts.cg.linker_plugin_lto.enabled() &&
-                self.tcx.sess.lto() != Lto::Thin;
+                && !self.tcx.sess.opts.cg.linker_plugin_lto.enabled()
+                && self.tcx.sess.lto() != Lto::Thin;
 
             // If this assertion triggers, there's something wrong with commandline
             // argument validation.
@@ -442,58 +443,6 @@ impl<'ll> CodegenCx<'ll, '_> {
 
             if attrs.flags.contains(CodegenFnAttrFlags::THREAD_LOCAL) {
                 llvm::set_thread_local_mode(g, self.tls_model);
-
-                // Do not allow LLVM to change the alignment of a TLS on macOS.
-                //
-                // By default a global's alignment can be freely increased.
-                // This allows LLVM to generate more performant instructions
-                // e.g., using load-aligned into a SIMD register.
-                //
-                // However, on macOS 10.10 or below, the dynamic linker does not
-                // respect any alignment given on the TLS (radar 24221680).
-                // This will violate the alignment assumption, and causing segfault at runtime.
-                //
-                // This bug is very easy to trigger. In `println!` and `panic!`,
-                // the `LOCAL_STDOUT`/`LOCAL_STDERR` handles are stored in a TLS,
-                // which the values would be `mem::replace`d on initialization.
-                // The implementation of `mem::replace` will use SIMD
-                // whenever the size is 32 bytes or higher. LLVM notices SIMD is used
-                // and tries to align `LOCAL_STDOUT`/`LOCAL_STDERR` to a 32-byte boundary,
-                // which macOS's dyld disregarded and causing crashes
-                // (see issues #51794, #51758, #50867, #48866 and #44056).
-                //
-                // To workaround the bug, we trick LLVM into not increasing
-                // the global's alignment by explicitly assigning a section to it
-                // (equivalent to automatically generating a `#[link_section]` attribute).
-                // See the comment in the `GlobalValue::canIncreaseAlignment()` function
-                // of `lib/IR/Globals.cpp` for why this works.
-                //
-                // When the alignment is not increased, the optimized `mem::replace`
-                // will use load-unaligned instructions instead, and thus avoiding the crash.
-                //
-                // We could remove this hack whenever we decide to drop macOS 10.10 support.
-                if self.tcx.sess.target.is_like_osx {
-                    // The `inspect` method is okay here because we checked for provenance, and
-                    // because we are doing this access to inspect the final interpreter state
-                    // (not as part of the interpreter execution).
-                    //
-                    // FIXME: This check requires that the (arbitrary) value of undefined bytes
-                    // happens to be zero. Instead, we should only check the value of defined bytes
-                    // and set all undefined bytes to zero if this allocation is headed for the
-                    // BSS.
-                    let all_bytes_are_zero = alloc.provenance().ptrs().is_empty()
-                        && alloc
-                            .inspect_with_uninit_and_ptr_outside_interpreter(0..alloc.len())
-                            .iter()
-                            .all(|&byte| byte == 0);
-
-                    let sect_name = if all_bytes_are_zero {
-                        c"__DATA,__thread_bss"
-                    } else {
-                        c"__DATA,__thread_data"
-                    };
-                    llvm::LLVMSetSection(g, sect_name.as_ptr());
-                }
             }
 
             // Wasm statics with custom link sections get special treatment as they
@@ -551,8 +500,8 @@ impl<'ll> CodegenCx<'ll, '_> {
                 // `#[used(compiler)]` is explicitly requested. This is to avoid similar breakage
                 // on other targets, in particular MachO targets have *their* static constructor
                 // lists broken if `llvm.compiler.used` is emitted rather than `llvm.used`. However,
-                // that check happens when assigning the `CodegenFnAttrFlags` in `rustc_hir_analysis`,
-                // so we don't need to take care of it here.
+                // that check happens when assigning the `CodegenFnAttrFlags` in
+                // `rustc_hir_analysis`, so we don't need to take care of it here.
                 self.add_compiler_used_global(g);
             }
             if attrs.flags.contains(CodegenFnAttrFlags::USED_LINKER) {
@@ -565,7 +514,7 @@ impl<'ll> CodegenCx<'ll, '_> {
     }
 }
 
-impl<'ll> StaticMethods for CodegenCx<'ll, '_> {
+impl<'ll> StaticCodegenMethods for CodegenCx<'ll, '_> {
     fn static_addr_of(&self, cv: &'ll Value, align: Align, kind: Option<&str>) -> &'ll Value {
         if let Some(&gv) = self.const_globals.borrow().get(&cv) {
             unsafe {
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 73c2c15717f..1d5580fdd07 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -15,7 +15,6 @@ use rustc_middle::middle::codegen_fn_attrs::PatchableFunctionEntry;
 use rustc_middle::mir::mono::CodegenUnit;
 use rustc_middle::ty::layout::{
     FnAbiError, FnAbiOfHelpers, FnAbiRequest, HasParamEnv, LayoutError, LayoutOfHelpers,
-    TyAndLayout,
 };
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
 use rustc_middle::{bug, span_bug};
@@ -25,7 +24,6 @@ use rustc_session::config::{
 use rustc_session::Session;
 use rustc_span::source_map::Spanned;
 use rustc_span::{Span, DUMMY_SP};
-use rustc_target::abi::call::FnAbi;
 use rustc_target::abi::{HasDataLayout, TargetDataLayout, VariantIdx};
 use rustc_target::spec::{HasTargetSpec, RelocModel, SmallDataThresholdSupport, Target, TlsModel};
 use smallvec::SmallVec;
@@ -37,8 +35,8 @@ use crate::type_::Type;
 use crate::value::Value;
 use crate::{attributes, coverageinfo, debuginfo, llvm, llvm_util};
 
-/// There is one `CodegenCx` per compilation unit. Each one has its own LLVM
-/// `llvm::Context` so that several compilation units may be optimized in parallel.
+/// There is one `CodegenCx` per codegen unit. Each one has its own LLVM
+/// `llvm::Context` so that several codegen units may be processed in parallel.
 /// All other LLVM data structures in the `CodegenCx` are tied to that `llvm::Context`.
 pub(crate) struct CodegenCx<'ll, 'tcx> {
     pub tcx: TyCtxt<'tcx>,
@@ -122,14 +120,6 @@ pub(crate) unsafe fn create_module<'ll>(
 
     let mut target_data_layout = sess.target.data_layout.to_string();
     let llvm_version = llvm_util::get_version();
-    if llvm_version < (18, 0, 0) {
-        if sess.target.arch == "x86" || sess.target.arch == "x86_64" {
-            // LLVM 18 adjusts i128 to be 128-bit aligned on x86 variants.
-            // Earlier LLVMs leave this as default alignment, so remove it.
-            // See https://reviews.llvm.org/D86310
-            target_data_layout = target_data_layout.replace("-i128:128", "");
-        }
-    }
 
     if llvm_version < (19, 0, 0) {
         if sess.target.arch == "aarch64" || sess.target.arch.starts_with("arm64") {
@@ -241,7 +231,8 @@ pub(crate) unsafe fn create_module<'ll>(
         }
     }
 
-    // Enable LTO unit splitting if specified or if CFI is enabled. (See https://reviews.llvm.org/D53891.)
+    // Enable LTO unit splitting if specified or if CFI is enabled. (See
+    // https://reviews.llvm.org/D53891.)
     if sess.is_split_lto_unit_enabled() || sess.is_sanitizer_cfi_enabled() {
         let enable_split_lto_unit = c"EnableSplitLTOUnit".as_ptr();
         unsafe {
@@ -598,7 +589,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
     }
 }
 
-impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
+impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     fn vtables(
         &self,
     ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>
@@ -1158,8 +1149,6 @@ impl<'tcx, 'll> HasParamEnv<'tcx> for CodegenCx<'ll, 'tcx> {
 }
 
 impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
-    type LayoutOfResult = TyAndLayout<'tcx>;
-
     #[inline]
     fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
         if let LayoutError::SizeOverflow(_) | LayoutError::ReferencesError(_) = err {
@@ -1171,8 +1160,6 @@ impl<'tcx> LayoutOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
 }
 
 impl<'tcx> FnAbiOfHelpers<'tcx> for CodegenCx<'_, 'tcx> {
-    type FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>;
-
     #[inline]
     fn handle_fn_abi_err(
         &self,
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
index d7a4f105f3c..77821ca89bc 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/ffi.rs
@@ -121,7 +121,8 @@ mod mcdc {
         num_conditions: u16,
     }
 
-    // ConditionId in llvm is `unsigned int` at 18 while `int16_t` at [19](https://github.com/llvm/llvm-project/pull/81257)
+    // ConditionId in llvm is `unsigned int` at 18 while `int16_t` at
+    // [19](https://github.com/llvm/llvm-project/pull/81257).
     type LLVMConditionId = i16;
 
     /// Must match the layout of `LLVMRustMCDCBranchParameters`.
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index b5acfabfde2..a9f65ee8a93 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -1,5 +1,5 @@
 use itertools::Itertools as _;
-use rustc_codegen_ssa::traits::{BaseTypeMethods, ConstMethods};
+use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, ConstCodegenMethods};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_index::IndexVec;
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index 69babc7c9cf..c9d2a1c9b88 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -2,8 +2,8 @@ use std::cell::RefCell;
 
 use libc::c_uint;
 use rustc_codegen_ssa::traits::{
-    BaseTypeMethods, BuilderMethods, ConstMethods, CoverageInfoBuilderMethods, MiscMethods,
-    StaticMethods,
+    BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods, CoverageInfoBuilderMethods,
+    MiscCodegenMethods, StaticCodegenMethods,
 };
 use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
 use rustc_llvm::RustString;
@@ -48,11 +48,10 @@ impl<'ll, 'tcx> CrateCoverageContext<'ll, 'tcx> {
         self.function_coverage_map.replace(FxIndexMap::default())
     }
 
-    /// LLVM use a temp value to record evaluated mcdc test vector of each decision, which is called condition bitmap.
-    /// In order to handle nested decisions, several condition bitmaps can be
-    /// allocated for a function body.
-    /// These values are named `mcdc.addr.{i}` and are a 32-bit integers.
-    /// They respectively hold the condition bitmaps for decisions with a depth of `i`.
+    /// LLVM use a temp value to record evaluated mcdc test vector of each decision, which is
+    /// called condition bitmap. In order to handle nested decisions, several condition bitmaps can
+    /// be allocated for a function body. These values are named `mcdc.addr.{i}` and are a 32-bit
+    /// integers. They respectively hold the condition bitmaps for decisions with a depth of `i`.
     fn try_get_mcdc_condition_bitmap(
         &self,
         instance: &Instance<'tcx>,
@@ -157,8 +156,8 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
             ),
             CoverageKind::CounterIncrement { id } => {
                 func_coverage.mark_counter_id_seen(id);
-                // We need to explicitly drop the `RefMut` before calling into `instrprof_increment`,
-                // as that needs an exclusive borrow.
+                // We need to explicitly drop the `RefMut` before calling into
+                // `instrprof_increment`, as that needs an exclusive borrow.
                 drop(coverage_map);
 
                 // The number of counters passed to `llvm.instrprof.increment` might
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
index dc228e94811..f93d3e40b20 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/gdb.rs
@@ -44,7 +44,8 @@ pub(crate) fn get_or_insert_gdb_debug_scripts_section_global<'ll>(
         // Add the pretty printers for the standard library first.
         section_contents.extend_from_slice(b"\x01gdb_load_rust_pretty_printers.py\0");
 
-        // Next, add the pretty printers that were specified via the `#[debugger_visualizer]` attribute.
+        // Next, add the pretty printers that were specified via the `#[debugger_visualizer]`
+        // attribute.
         let visualizers = collect_debugger_visualizers_transitive(
             cx.tcx,
             DebuggerVisualizerType::GdbPrettyPrinter,
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index d231b103964..57e396415cc 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -125,7 +125,9 @@ fn build_fixed_size_array_di_node<'ll, 'tcx>(
 
     let (size, align) = cx.size_and_align_of(array_type);
 
-    let upper_bound = len.eval_target_usize(cx.tcx, ty::ParamEnv::reveal_all()) as c_longlong;
+    let upper_bound = len
+        .try_to_target_usize(cx.tcx)
+        .expect("expected monomorphic const in codegen") as c_longlong;
 
     let subrange =
         unsafe { Some(llvm::LLVMRustDIBuilderGetOrCreateSubrange(DIB(cx), 0, upper_bound)) };
@@ -216,8 +218,9 @@ fn build_pointer_or_reference_di_node<'ll, 'tcx>(
                     //        need to make sure that we don't break existing debuginfo consumers
                     //        by doing that (at least not without a warning period).
                     let layout_type = if ptr_type.is_box() {
-                        // The assertion at the start of this function ensures we have a ZST allocator.
-                        // We'll make debuginfo "skip" all ZST allocators, not just the default allocator.
+                        // The assertion at the start of this function ensures we have a ZST
+                        // allocator. We'll make debuginfo "skip" all ZST allocators, not just the
+                        // default allocator.
                         Ty::new_mut_ptr(cx.tcx, pointee_type)
                     } else {
                         ptr_type
@@ -280,8 +283,7 @@ fn build_subroutine_type_di_node<'ll, 'tcx>(
     cx: &CodegenCx<'ll, 'tcx>,
     unique_type_id: UniqueTypeId<'tcx>,
 ) -> DINodeCreationResult<'ll> {
-    // It's possible to create a self-referential
-    // type in Rust by using 'impl trait':
+    // It's possible to create a self-referential type in Rust by using 'impl trait':
     //
     // fn foo() -> impl Copy { foo }
     //
@@ -573,14 +575,14 @@ pub(crate) fn file_metadata<'ll>(cx: &CodegenCx<'ll, '_>, source_file: &SourceFi
                     {
                         // If the compiler's working directory (which also is the DW_AT_comp_dir of
                         // the compilation unit) is a prefix of the path we are about to emit, then
-                        // only emit the part relative to the working directory.
-                        // Because of path remapping we sometimes see strange things here: `abs_path`
-                        // might actually look like a relative path
-                        // (e.g. `<crate-name-and-version>/src/lib.rs`), so if we emit it without
-                        // taking the working directory into account, downstream tooling will
-                        // interpret it as `<working-directory>/<crate-name-and-version>/src/lib.rs`,
-                        // which makes no sense. Usually in such cases the working directory will also
-                        // be remapped to `<crate-name-and-version>` or some other prefix of the path
+                        // only emit the part relative to the working directory. Because of path
+                        // remapping we sometimes see strange things here: `abs_path` might
+                        // actually look like a relative path (e.g.
+                        // `<crate-name-and-version>/src/lib.rs`), so if we emit it without taking
+                        // the working directory into account, downstream tooling will interpret it
+                        // as `<working-directory>/<crate-name-and-version>/src/lib.rs`, which
+                        // makes no sense. Usually in such cases the working directory will also be
+                        // remapped to `<crate-name-and-version>` or some other prefix of the path
                         // we are remapping, so we end up with
                         // `<crate-name-and-version>/<crate-name-and-version>/src/lib.rs`.
                         // By moving the working directory portion into the `directory` part of the
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
index 181022087f3..8a132f89aa3 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/cpp_like.rs
@@ -3,7 +3,7 @@ use std::borrow::Cow;
 use libc::c_uint;
 use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name;
 use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo};
-use rustc_codegen_ssa::traits::ConstMethods;
+use rustc_codegen_ssa::traits::ConstCodegenMethods;
 use rustc_index::IndexVec;
 use rustc_middle::bug;
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
index 238fbad4dfd..0b3140cc91f 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata/enums/native.rs
@@ -3,7 +3,7 @@ use std::borrow::Cow;
 use libc::c_uint;
 use rustc_codegen_ssa::debuginfo::type_names::compute_debuginfo_type_name;
 use rustc_codegen_ssa::debuginfo::{tag_base_type, wants_c_like_enum_debuginfo};
-use rustc_codegen_ssa::traits::ConstMethods;
+use rustc_codegen_ssa::traits::ConstCodegenMethods;
 use rustc_middle::bug;
 use rustc_middle::ty::layout::{LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self};
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 842212ac05d..920c9e06be4 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -286,7 +286,7 @@ impl CodegenCx<'_, '_> {
     }
 }
 
-impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
+impl<'ll, 'tcx> DebugInfoCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     fn create_function_debug_context(
         &self,
         instance: Instance<'tcx>,
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs
index 83d7a82dadc..9674b1eb848 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/namespace.rs
@@ -13,8 +13,7 @@ pub(crate) fn mangled_name_of_instance<'a, 'tcx>(
     cx: &CodegenCx<'a, 'tcx>,
     instance: Instance<'tcx>,
 ) -> ty::SymbolName<'tcx> {
-    let tcx = cx.tcx;
-    tcx.symbol_name(instance)
+    cx.tcx.symbol_name(instance)
 }
 
 pub(crate) fn item_namespace<'ll>(cx: &CodegenCx<'ll, '_>, def_id: DefId) -> &'ll DIScope {
diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs
index 4e4500b6373..b0b29ca1280 100644
--- a/compiler/rustc_codegen_llvm/src/declare.rs
+++ b/compiler/rustc_codegen_llvm/src/declare.rs
@@ -12,7 +12,7 @@
 //! * When in doubt, define.
 
 use itertools::Itertools;
-use rustc_codegen_ssa::traits::TypeMembershipMethods;
+use rustc_codegen_ssa::traits::TypeMembershipCodegenMethods;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_middle::ty::{Instance, Ty};
 use rustc_sanitizers::{cfi, kcfi};
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 15c519dfcb4..307fb9c35b7 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -148,7 +148,7 @@ fn get_simple_intrinsic<'ll>(
     Some(cx.get_intrinsic(llvm_name))
 }
 
-impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
+impl<'ll, 'tcx> IntrinsicCallBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
     fn codegen_intrinsic_call(
         &mut self,
         instance: ty::Instance<'tcx>,
@@ -404,7 +404,8 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                             let llvm_name =
                                 &format!("llvm.fsh{}.i{}", if is_left { 'l' } else { 'r' }, width);
 
-                            // llvm expects shift to be the same type as the values, but rust always uses `u32`
+                            // llvm expects shift to be the same type as the values, but rust
+                            // always uses `u32`.
                             let raw_shift = self.intcast(raw_shift, self.val_ty(val), false);
 
                             self.call_intrinsic(llvm_name, &[val, val, raw_shift])
@@ -573,8 +574,8 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     span,
                 ) {
                     Ok(llval) => llval,
-                    // If there was an error, just skip this invocation... we'll abort compilation anyway,
-                    // but we can keep codegen'ing to find more errors.
+                    // If there was an error, just skip this invocation... we'll abort compilation
+                    // anyway, but we can keep codegen'ing to find more errors.
                     Err(()) => return Ok(()),
                 }
             }
@@ -1847,7 +1848,8 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         require!(
             matches!(
                 *pointer_ty.kind(),
-                ty::RawPtr(p_ty, p_mutbl) if p_ty == values_elem && p_ty.kind() == values_elem.kind() && p_mutbl.is_mut()
+                ty::RawPtr(p_ty, p_mutbl)
+                    if p_ty == values_elem && p_ty.kind() == values_elem.kind() && p_mutbl.is_mut()
             ),
             InvalidMonomorphization::ExpectedElementType {
                 span,
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index e84ab0aa538..a588f11b623 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -220,17 +220,18 @@ pub enum IntPredicate {
 
 impl IntPredicate {
     pub fn from_generic(intpre: rustc_codegen_ssa::common::IntPredicate) -> Self {
+        use rustc_codegen_ssa::common::IntPredicate as Common;
         match intpre {
-            rustc_codegen_ssa::common::IntPredicate::IntEQ => IntPredicate::IntEQ,
-            rustc_codegen_ssa::common::IntPredicate::IntNE => IntPredicate::IntNE,
-            rustc_codegen_ssa::common::IntPredicate::IntUGT => IntPredicate::IntUGT,
-            rustc_codegen_ssa::common::IntPredicate::IntUGE => IntPredicate::IntUGE,
-            rustc_codegen_ssa::common::IntPredicate::IntULT => IntPredicate::IntULT,
-            rustc_codegen_ssa::common::IntPredicate::IntULE => IntPredicate::IntULE,
-            rustc_codegen_ssa::common::IntPredicate::IntSGT => IntPredicate::IntSGT,
-            rustc_codegen_ssa::common::IntPredicate::IntSGE => IntPredicate::IntSGE,
-            rustc_codegen_ssa::common::IntPredicate::IntSLT => IntPredicate::IntSLT,
-            rustc_codegen_ssa::common::IntPredicate::IntSLE => IntPredicate::IntSLE,
+            Common::IntEQ => Self::IntEQ,
+            Common::IntNE => Self::IntNE,
+            Common::IntUGT => Self::IntUGT,
+            Common::IntUGE => Self::IntUGE,
+            Common::IntULT => Self::IntULT,
+            Common::IntULE => Self::IntULE,
+            Common::IntSGT => Self::IntSGT,
+            Common::IntSGE => Self::IntSGE,
+            Common::IntSLT => Self::IntSLT,
+            Common::IntSLE => Self::IntSLE,
         }
     }
 }
@@ -259,27 +260,24 @@ pub enum RealPredicate {
 
 impl RealPredicate {
     pub fn from_generic(realp: rustc_codegen_ssa::common::RealPredicate) -> Self {
+        use rustc_codegen_ssa::common::RealPredicate as Common;
         match realp {
-            rustc_codegen_ssa::common::RealPredicate::RealPredicateFalse => {
-                RealPredicate::RealPredicateFalse
-            }
-            rustc_codegen_ssa::common::RealPredicate::RealOEQ => RealPredicate::RealOEQ,
-            rustc_codegen_ssa::common::RealPredicate::RealOGT => RealPredicate::RealOGT,
-            rustc_codegen_ssa::common::RealPredicate::RealOGE => RealPredicate::RealOGE,
-            rustc_codegen_ssa::common::RealPredicate::RealOLT => RealPredicate::RealOLT,
-            rustc_codegen_ssa::common::RealPredicate::RealOLE => RealPredicate::RealOLE,
-            rustc_codegen_ssa::common::RealPredicate::RealONE => RealPredicate::RealONE,
-            rustc_codegen_ssa::common::RealPredicate::RealORD => RealPredicate::RealORD,
-            rustc_codegen_ssa::common::RealPredicate::RealUNO => RealPredicate::RealUNO,
-            rustc_codegen_ssa::common::RealPredicate::RealUEQ => RealPredicate::RealUEQ,
-            rustc_codegen_ssa::common::RealPredicate::RealUGT => RealPredicate::RealUGT,
-            rustc_codegen_ssa::common::RealPredicate::RealUGE => RealPredicate::RealUGE,
-            rustc_codegen_ssa::common::RealPredicate::RealULT => RealPredicate::RealULT,
-            rustc_codegen_ssa::common::RealPredicate::RealULE => RealPredicate::RealULE,
-            rustc_codegen_ssa::common::RealPredicate::RealUNE => RealPredicate::RealUNE,
-            rustc_codegen_ssa::common::RealPredicate::RealPredicateTrue => {
-                RealPredicate::RealPredicateTrue
-            }
+            Common::RealPredicateFalse => Self::RealPredicateFalse,
+            Common::RealOEQ => Self::RealOEQ,
+            Common::RealOGT => Self::RealOGT,
+            Common::RealOGE => Self::RealOGE,
+            Common::RealOLT => Self::RealOLT,
+            Common::RealOLE => Self::RealOLE,
+            Common::RealONE => Self::RealONE,
+            Common::RealORD => Self::RealORD,
+            Common::RealUNO => Self::RealUNO,
+            Common::RealUEQ => Self::RealUEQ,
+            Common::RealUGT => Self::RealUGT,
+            Common::RealUGE => Self::RealUGE,
+            Common::RealULT => Self::RealULT,
+            Common::RealULE => Self::RealULE,
+            Common::RealUNE => Self::RealUNE,
+            Common::RealPredicateTrue => Self::RealPredicateTrue,
         }
     }
 }
@@ -311,26 +309,27 @@ pub enum TypeKind {
 
 impl TypeKind {
     pub fn to_generic(self) -> rustc_codegen_ssa::common::TypeKind {
+        use rustc_codegen_ssa::common::TypeKind as Common;
         match self {
-            TypeKind::Void => rustc_codegen_ssa::common::TypeKind::Void,
-            TypeKind::Half => rustc_codegen_ssa::common::TypeKind::Half,
-            TypeKind::Float => rustc_codegen_ssa::common::TypeKind::Float,
-            TypeKind::Double => rustc_codegen_ssa::common::TypeKind::Double,
-            TypeKind::X86_FP80 => rustc_codegen_ssa::common::TypeKind::X86_FP80,
-            TypeKind::FP128 => rustc_codegen_ssa::common::TypeKind::FP128,
-            TypeKind::PPC_FP128 => rustc_codegen_ssa::common::TypeKind::PPC_FP128,
-            TypeKind::Label => rustc_codegen_ssa::common::TypeKind::Label,
-            TypeKind::Integer => rustc_codegen_ssa::common::TypeKind::Integer,
-            TypeKind::Function => rustc_codegen_ssa::common::TypeKind::Function,
-            TypeKind::Struct => rustc_codegen_ssa::common::TypeKind::Struct,
-            TypeKind::Array => rustc_codegen_ssa::common::TypeKind::Array,
-            TypeKind::Pointer => rustc_codegen_ssa::common::TypeKind::Pointer,
-            TypeKind::Vector => rustc_codegen_ssa::common::TypeKind::Vector,
-            TypeKind::Metadata => rustc_codegen_ssa::common::TypeKind::Metadata,
-            TypeKind::Token => rustc_codegen_ssa::common::TypeKind::Token,
-            TypeKind::ScalableVector => rustc_codegen_ssa::common::TypeKind::ScalableVector,
-            TypeKind::BFloat => rustc_codegen_ssa::common::TypeKind::BFloat,
-            TypeKind::X86_AMX => rustc_codegen_ssa::common::TypeKind::X86_AMX,
+            Self::Void => Common::Void,
+            Self::Half => Common::Half,
+            Self::Float => Common::Float,
+            Self::Double => Common::Double,
+            Self::X86_FP80 => Common::X86_FP80,
+            Self::FP128 => Common::FP128,
+            Self::PPC_FP128 => Common::PPC_FP128,
+            Self::Label => Common::Label,
+            Self::Integer => Common::Integer,
+            Self::Function => Common::Function,
+            Self::Struct => Common::Struct,
+            Self::Array => Common::Array,
+            Self::Pointer => Common::Pointer,
+            Self::Vector => Common::Vector,
+            Self::Metadata => Common::Metadata,
+            Self::Token => Common::Token,
+            Self::ScalableVector => Common::ScalableVector,
+            Self::BFloat => Common::BFloat,
+            Self::X86_AMX => Common::X86_AMX,
         }
     }
 }
@@ -354,18 +353,19 @@ pub enum AtomicRmwBinOp {
 
 impl AtomicRmwBinOp {
     pub fn from_generic(op: rustc_codegen_ssa::common::AtomicRmwBinOp) -> Self {
+        use rustc_codegen_ssa::common::AtomicRmwBinOp as Common;
         match op {
-            rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicXchg => AtomicRmwBinOp::AtomicXchg,
-            rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicAdd => AtomicRmwBinOp::AtomicAdd,
-            rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicSub => AtomicRmwBinOp::AtomicSub,
-            rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicAnd => AtomicRmwBinOp::AtomicAnd,
-            rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicNand => AtomicRmwBinOp::AtomicNand,
-            rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicOr => AtomicRmwBinOp::AtomicOr,
-            rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicXor => AtomicRmwBinOp::AtomicXor,
-            rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicMax => AtomicRmwBinOp::AtomicMax,
-            rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicMin => AtomicRmwBinOp::AtomicMin,
-            rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicUMax => AtomicRmwBinOp::AtomicUMax,
-            rustc_codegen_ssa::common::AtomicRmwBinOp::AtomicUMin => AtomicRmwBinOp::AtomicUMin,
+            Common::AtomicXchg => Self::AtomicXchg,
+            Common::AtomicAdd => Self::AtomicAdd,
+            Common::AtomicSub => Self::AtomicSub,
+            Common::AtomicAnd => Self::AtomicAnd,
+            Common::AtomicNand => Self::AtomicNand,
+            Common::AtomicOr => Self::AtomicOr,
+            Common::AtomicXor => Self::AtomicXor,
+            Common::AtomicMax => Self::AtomicMax,
+            Common::AtomicMin => Self::AtomicMin,
+            Common::AtomicUMax => Self::AtomicUMax,
+            Common::AtomicUMin => Self::AtomicUMin,
         }
     }
 }
@@ -387,17 +387,14 @@ pub enum AtomicOrdering {
 
 impl AtomicOrdering {
     pub fn from_generic(ao: rustc_codegen_ssa::common::AtomicOrdering) -> Self {
+        use rustc_codegen_ssa::common::AtomicOrdering as Common;
         match ao {
-            rustc_codegen_ssa::common::AtomicOrdering::Unordered => AtomicOrdering::Unordered,
-            rustc_codegen_ssa::common::AtomicOrdering::Relaxed => AtomicOrdering::Monotonic,
-            rustc_codegen_ssa::common::AtomicOrdering::Acquire => AtomicOrdering::Acquire,
-            rustc_codegen_ssa::common::AtomicOrdering::Release => AtomicOrdering::Release,
-            rustc_codegen_ssa::common::AtomicOrdering::AcquireRelease => {
-                AtomicOrdering::AcquireRelease
-            }
-            rustc_codegen_ssa::common::AtomicOrdering::SequentiallyConsistent => {
-                AtomicOrdering::SequentiallyConsistent
-            }
+            Common::Unordered => Self::Unordered,
+            Common::Relaxed => Self::Monotonic,
+            Common::Acquire => Self::Acquire,
+            Common::Release => Self::Release,
+            Common::AcquireRelease => Self::AcquireRelease,
+            Common::SequentiallyConsistent => Self::SequentiallyConsistent,
         }
     }
 }
@@ -563,13 +560,11 @@ pub enum ArchiveKind {
     K_AIXBIG,
 }
 
-// LLVMRustThinLTOData
 unsafe extern "C" {
+    // LLVMRustThinLTOData
     pub type ThinLTOData;
-}
 
-// LLVMRustThinLTOBuffer
-unsafe extern "C" {
+    // LLVMRustThinLTOBuffer
     pub type ThinLTOBuffer;
 }
 
@@ -633,26 +628,12 @@ struct InvariantOpaque<'a> {
 // Opaque pointer types
 unsafe extern "C" {
     pub type Module;
-}
-unsafe extern "C" {
     pub type Context;
-}
-unsafe extern "C" {
     pub type Type;
-}
-unsafe extern "C" {
     pub type Value;
-}
-unsafe extern "C" {
     pub type ConstantInt;
-}
-unsafe extern "C" {
     pub type Attribute;
-}
-unsafe extern "C" {
     pub type Metadata;
-}
-unsafe extern "C" {
     pub type BasicBlock;
 }
 #[repr(C)]
@@ -661,11 +642,7 @@ pub struct Builder<'a>(InvariantOpaque<'a>);
 pub struct PassManager<'a>(InvariantOpaque<'a>);
 unsafe extern "C" {
     pub type Pass;
-}
-unsafe extern "C" {
     pub type TargetMachine;
-}
-unsafe extern "C" {
     pub type Archive;
 }
 #[repr(C)]
@@ -674,11 +651,7 @@ pub struct ArchiveIterator<'a>(InvariantOpaque<'a>);
 pub struct ArchiveChild<'a>(InvariantOpaque<'a>);
 unsafe extern "C" {
     pub type Twine;
-}
-unsafe extern "C" {
     pub type DiagnosticInfo;
-}
-unsafe extern "C" {
     pub type SMDiagnostic;
 }
 #[repr(C)]
@@ -2177,7 +2150,8 @@ unsafe extern "C" {
 
     pub fn LLVMRustGetHostCPUName(len: *mut usize) -> *const c_char;
 
-    // This function makes copies of pointed to data, so the data's lifetime may end after this function returns
+    // This function makes copies of pointed to data, so the data's lifetime may end after this
+    // function returns.
     pub fn LLVMRustCreateTargetMachine(
         Triple: *const c_char,
         CPU: *const c_char,
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 29afe6f6bfc..fd8db4ad1d5 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -217,10 +217,10 @@ impl<'a> IntoIterator for LLVMFeature<'a> {
 // where `{ARCH}` is the architecture name. Look for instances of `SubtargetFeature`.
 //
 // Check the current rustc fork of LLVM in the repo at https://github.com/rust-lang/llvm-project/.
-// The commit in use can be found via the `llvm-project` submodule in https://github.com/rust-lang/rust/tree/master/src
-// Though note that Rust can also be build with an external precompiled version of LLVM
-// which might lead to failures if the oldest tested / supported LLVM version
-// doesn't yet support the relevant intrinsics
+// The commit in use can be found via the `llvm-project` submodule in
+// https://github.com/rust-lang/rust/tree/master/src Though note that Rust can also be build with
+// an external precompiled version of LLVM which might lead to failures if the oldest tested /
+// supported LLVM version doesn't yet support the relevant intrinsics.
 pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFeature<'a>> {
     let arch = if sess.target.arch == "x86_64" {
         "x86"
@@ -258,28 +258,14 @@ pub(crate) fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> Option<LLVMFea
         ("aarch64", "fhm") => Some(LLVMFeature::new("fp16fml")),
         ("aarch64", "fp16") => Some(LLVMFeature::new("fullfp16")),
         // Filter out features that are not supported by the current LLVM version
-        ("aarch64", "faminmax") if get_version().0 < 18 => None,
-        ("aarch64", "fp8") if get_version().0 < 18 => None,
-        ("aarch64", "fp8dot2") if get_version().0 < 18 => None,
-        ("aarch64", "fp8dot4") if get_version().0 < 18 => None,
-        ("aarch64", "fp8fma") if get_version().0 < 18 => None,
         ("aarch64", "fpmr") if get_version().0 != 18 => None,
-        ("aarch64", "lut") if get_version().0 < 18 => None,
-        ("aarch64", "sme-f8f16") if get_version().0 < 18 => None,
-        ("aarch64", "sme-f8f32") if get_version().0 < 18 => None,
-        ("aarch64", "sme-fa64") if get_version().0 < 18 => None,
-        ("aarch64", "sme-lutv2") if get_version().0 < 18 => None,
-        ("aarch64", "ssve-fp8dot2") if get_version().0 < 18 => None,
-        ("aarch64", "ssve-fp8dot4") if get_version().0 < 18 => None,
-        ("aarch64", "ssve-fp8fma") if get_version().0 < 18 => None,
-        ("aarch64", "v9.5a") if get_version().0 < 18 => None,
-        // In LLVM 18, `unaligned-scalar-mem` was merged with `unaligned-vector-mem` into a single feature called
-        // `fast-unaligned-access`. In LLVM 19, it was split back out.
+        // In LLVM 18, `unaligned-scalar-mem` was merged with `unaligned-vector-mem` into a single
+        // feature called `fast-unaligned-access`. In LLVM 19, it was split back out.
         ("riscv32" | "riscv64", "unaligned-scalar-mem") if get_version().0 == 18 => {
             Some(LLVMFeature::new("fast-unaligned-access"))
         }
-        // For LLVM 18, enable the evex512 target feature if a avx512 target feature is enabled.
-        ("x86", s) if get_version().0 >= 18 && s.starts_with("avx512") => {
+        // Enable the evex512 target feature if an avx512 target feature is enabled.
+        ("x86", s) if s.starts_with("avx512") => {
             Some(LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512")))
         }
         (_, s) => Some(LLVMFeature::new(s)),
@@ -420,7 +406,8 @@ fn print_target_features(out: &mut String, sess: &Session, tm: &llvm::TargetMach
         .supported_target_features()
         .iter()
         .filter_map(|(feature, _gate, _implied)| {
-            // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these strings.
+            // LLVM asserts that these are sorted. LLVM and Rust both use byte comparison for these
+            // strings.
             let llvm_feature = to_llvm_features(sess, *feature)?.llvm_feature_name;
             let desc =
                 match llvm_target_features.binary_search_by_key(&llvm_feature, |(f, _d)| f).ok() {
@@ -587,7 +574,6 @@ pub(crate) fn global_llvm_features(
     // -Ctarget-features
     if !only_base_features {
         let supported_features = sess.target.supported_target_features();
-        let (llvm_major, _, _) = get_version();
         let mut featsmap = FxHashMap::default();
 
         // insert implied features
@@ -664,12 +650,6 @@ pub(crate) fn global_llvm_features(
                     return None;
                 }
 
-                // if the target-feature is "backchain" and LLVM version is greater than 18
-                // then we also need to add "+backchain" to the target-features attribute.
-                // otherwise, we will only add the naked `backchain` attribute to the attribute-group.
-                if feature == "backchain" && llvm_major < 18 {
-                    return None;
-                }
                 // ... otherwise though we run through `to_llvm_features` when
                 // passing requests down to LLVM. This means that all in-language
                 // features also work on the command line instead of having two
diff --git a/compiler/rustc_codegen_llvm/src/mono_item.rs b/compiler/rustc_codegen_llvm/src/mono_item.rs
index f1ef359594b..02e1995620b 100644
--- a/compiler/rustc_codegen_llvm/src/mono_item.rs
+++ b/compiler/rustc_codegen_llvm/src/mono_item.rs
@@ -14,7 +14,7 @@ use crate::errors::SymbolAlreadyDefined;
 use crate::type_of::LayoutLlvmExt;
 use crate::{base, llvm};
 
-impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
+impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
     fn predefine_static(
         &self,
         def_id: DefId,
@@ -24,8 +24,8 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
     ) {
         let instance = Instance::mono(self.tcx, def_id);
         let DefKind::Static { nested, .. } = self.tcx.def_kind(def_id) else { bug!() };
-        // Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure out
-        // the llvm type from the actual evaluated initializer.
+        // Nested statics do not have a type, so pick a dummy type and let `codegen_static` figure
+        // out the llvm type from the actual evaluated initializer.
         let ty = if nested {
             self.tcx.types.unit
         } else {
diff --git a/compiler/rustc_codegen_llvm/src/type_.rs b/compiler/rustc_codegen_llvm/src/type_.rs
index ec1e2cb8094..2c2b9030b7c 100644
--- a/compiler/rustc_codegen_llvm/src/type_.rs
+++ b/compiler/rustc_codegen_llvm/src/type_.rs
@@ -141,7 +141,7 @@ impl<'ll> CodegenCx<'ll, '_> {
     }
 }
 
-impl<'ll, 'tcx> BaseTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
+impl<'ll, 'tcx> BaseTypeCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     fn type_i8(&self) -> &'ll Type {
         unsafe { llvm::LLVMInt8TypeInContext(self.llcx) }
     }
@@ -245,7 +245,7 @@ impl Type {
     }
 }
 
-impl<'ll, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
+impl<'ll, 'tcx> LayoutTypeCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     fn backend_type(&self, layout: TyAndLayout<'tcx>) -> &'ll Type {
         layout.llvm_type(self)
     }
@@ -280,7 +280,7 @@ impl<'ll, 'tcx> LayoutTypeMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     }
 }
 
-impl<'ll, 'tcx> TypeMembershipMethods<'tcx> for CodegenCx<'ll, 'tcx> {
+impl<'ll, 'tcx> TypeMembershipCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
     fn add_type_metadata(&self, function: &'ll Value, typeid: String) {
         let typeid_metadata = self.typeid_metadata(typeid).unwrap();
         let v = [self.const_usize(0), typeid_metadata];
diff --git a/compiler/rustc_codegen_llvm/src/va_arg.rs b/compiler/rustc_codegen_llvm/src/va_arg.rs
index 94e77c5bd70..781cee81180 100644
--- a/compiler/rustc_codegen_llvm/src/va_arg.rs
+++ b/compiler/rustc_codegen_llvm/src/va_arg.rs
@@ -1,6 +1,6 @@
 use rustc_codegen_ssa::common::IntPredicate;
 use rustc_codegen_ssa::mir::operand::OperandRef;
-use rustc_codegen_ssa::traits::{BaseTypeMethods, BuilderMethods, ConstMethods};
+use rustc_codegen_ssa::traits::{BaseTypeCodegenMethods, BuilderMethods, ConstCodegenMethods};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf};
 use rustc_middle::ty::Ty;
 use rustc_target::abi::{Align, Endian, HasDataLayout, Size};
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index 76a94de5433..a665f5c9306 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -157,7 +157,7 @@ pub trait ArchiveBuilderBuilder {
     }
 }
 
-pub fn create_mingw_dll_import_lib(
+fn create_mingw_dll_import_lib(
     sess: &Session,
     lib_name: &str,
     import_name_and_ordinal_vector: Vec<(String, Option<u16>)>,
diff --git a/compiler/rustc_codegen_ssa/src/back/command.rs b/compiler/rustc_codegen_ssa/src/back/command.rs
index 95c4af2e59e..b3c5b86ccf4 100644
--- a/compiler/rustc_codegen_ssa/src/back/command.rs
+++ b/compiler/rustc_codegen_ssa/src/back/command.rs
@@ -8,7 +8,7 @@ use std::{fmt, io, mem};
 use rustc_target::spec::LldFlavor;
 
 #[derive(Clone)]
-pub struct Command {
+pub(crate) struct Command {
     program: Program,
     args: Vec<OsString>,
     env: Vec<(OsString, OsString)>,
@@ -23,15 +23,15 @@ enum Program {
 }
 
 impl Command {
-    pub fn new<P: AsRef<OsStr>>(program: P) -> Command {
+    pub(crate) fn new<P: AsRef<OsStr>>(program: P) -> Command {
         Command::_new(Program::Normal(program.as_ref().to_owned()))
     }
 
-    pub fn bat_script<P: AsRef<OsStr>>(program: P) -> Command {
+    pub(crate) fn bat_script<P: AsRef<OsStr>>(program: P) -> Command {
         Command::_new(Program::CmdBatScript(program.as_ref().to_owned()))
     }
 
-    pub fn lld<P: AsRef<OsStr>>(program: P, flavor: LldFlavor) -> Command {
+    pub(crate) fn lld<P: AsRef<OsStr>>(program: P, flavor: LldFlavor) -> Command {
         Command::_new(Program::Lld(program.as_ref().to_owned(), flavor))
     }
 
@@ -39,12 +39,12 @@ impl Command {
         Command { program, args: Vec::new(), env: Vec::new(), env_remove: Vec::new() }
     }
 
-    pub fn arg<P: AsRef<OsStr>>(&mut self, arg: P) -> &mut Command {
+    pub(crate) fn arg<P: AsRef<OsStr>>(&mut self, arg: P) -> &mut Command {
         self._arg(arg.as_ref());
         self
     }
 
-    pub fn args<I>(&mut self, args: I) -> &mut Command
+    pub(crate) fn args<I>(&mut self, args: I) -> &mut Command
     where
         I: IntoIterator<Item: AsRef<OsStr>>,
     {
@@ -58,7 +58,7 @@ impl Command {
         self.args.push(arg.to_owned());
     }
 
-    pub fn env<K, V>(&mut self, key: K, value: V) -> &mut Command
+    pub(crate) fn env<K, V>(&mut self, key: K, value: V) -> &mut Command
     where
         K: AsRef<OsStr>,
         V: AsRef<OsStr>,
@@ -71,7 +71,7 @@ impl Command {
         self.env.push((key.to_owned(), value.to_owned()));
     }
 
-    pub fn env_remove<K>(&mut self, key: K) -> &mut Command
+    pub(crate) fn env_remove<K>(&mut self, key: K) -> &mut Command
     where
         K: AsRef<OsStr>,
     {
@@ -83,11 +83,11 @@ impl Command {
         self.env_remove.push(key.to_owned());
     }
 
-    pub fn output(&mut self) -> io::Result<Output> {
+    pub(crate) fn output(&mut self) -> io::Result<Output> {
         self.command().output()
     }
 
-    pub fn command(&self) -> process::Command {
+    pub(crate) fn command(&self) -> process::Command {
         let mut ret = match self.program {
             Program::Normal(ref p) => process::Command::new(p),
             Program::CmdBatScript(ref p) => {
@@ -111,17 +111,17 @@ impl Command {
 
     // extensions
 
-    pub fn get_args(&self) -> &[OsString] {
+    pub(crate) fn get_args(&self) -> &[OsString] {
         &self.args
     }
 
-    pub fn take_args(&mut self) -> Vec<OsString> {
+    pub(crate) fn take_args(&mut self) -> Vec<OsString> {
         mem::take(&mut self.args)
     }
 
     /// Returns a `true` if we're pretty sure that this'll blow OS spawn limits,
     /// or `false` if we should attempt to spawn and see what the OS says.
-    pub fn very_likely_to_exceed_some_spawn_limit(&self) -> bool {
+    pub(crate) fn very_likely_to_exceed_some_spawn_limit(&self) -> bool {
         // We mostly only care about Windows in this method, on Unix the limits
         // can be gargantuan anyway so we're pretty unlikely to hit them
         if cfg!(unix) {
diff --git a/compiler/rustc_codegen_ssa/src/back/linker.rs b/compiler/rustc_codegen_ssa/src/back/linker.rs
index bda22255705..06fc164893f 100644
--- a/compiler/rustc_codegen_ssa/src/back/linker.rs
+++ b/compiler/rustc_codegen_ssa/src/back/linker.rs
@@ -30,7 +30,7 @@ use crate::errors;
 /// and prevent inspection of linker output in case of errors, which we occasionally do.
 /// This should be acceptable because other messages from rustc are in English anyway,
 /// and may also be desirable to improve searchability of the linker diagnostics.
-pub fn disable_localization(linker: &mut Command) {
+pub(crate) fn disable_localization(linker: &mut Command) {
     // No harm in setting both env vars simultaneously.
     // Unix-style linkers.
     linker.env("LC_ALL", "C");
@@ -41,7 +41,7 @@ pub fn disable_localization(linker: &mut Command) {
 /// The third parameter is for env vars, used on windows to set up the
 /// path for MSVC to find its DLLs, and gcc to find its bundled
 /// toolchain
-pub fn get_linker<'a>(
+pub(crate) fn get_linker<'a>(
     sess: &'a Session,
     linker: &Path,
     flavor: LinkerFlavor,
@@ -215,28 +215,36 @@ fn link_or_cc_args<L: Linker + ?Sized>(
 macro_rules! generate_arg_methods {
     ($($ty:ty)*) => { $(
         impl $ty {
-            pub fn verbatim_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>>) -> &mut Self {
+            #[allow(unused)]
+            pub(crate) fn verbatim_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>>) -> &mut Self {
                 verbatim_args(self, args)
             }
-            pub fn verbatim_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
+            #[allow(unused)]
+            pub(crate) fn verbatim_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
                 verbatim_args(self, iter::once(arg))
             }
-            pub fn link_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>, IntoIter: ExactSizeIterator>) -> &mut Self {
+            #[allow(unused)]
+            pub(crate) fn link_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>, IntoIter: ExactSizeIterator>) -> &mut Self {
                 link_args(self, args)
             }
-            pub fn link_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
+            #[allow(unused)]
+            pub(crate) fn link_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
                 link_args(self, iter::once(arg))
             }
-            pub fn cc_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>>) -> &mut Self {
+            #[allow(unused)]
+            pub(crate) fn cc_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>>) -> &mut Self {
                 cc_args(self, args)
             }
-            pub fn cc_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
+            #[allow(unused)]
+            pub(crate) fn cc_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
                 cc_args(self, iter::once(arg))
             }
-            pub fn link_or_cc_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>>) -> &mut Self {
+            #[allow(unused)]
+            pub(crate) fn link_or_cc_args(&mut self, args: impl IntoIterator<Item: AsRef<OsStr>>) -> &mut Self {
                 link_or_cc_args(self, args)
             }
-            pub fn link_or_cc_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
+            #[allow(unused)]
+            pub(crate) fn link_or_cc_arg(&mut self, arg: impl AsRef<OsStr>) -> &mut Self {
                 link_or_cc_args(self, iter::once(arg))
             }
         }
@@ -263,7 +271,7 @@ generate_arg_methods! {
 /// represents the meaning of each option being passed down. This trait is then
 /// used to dispatch on whether a GNU-like linker (generally `ld.exe`) or an
 /// MSVC linker (e.g., `link.exe`) is being used.
-pub trait Linker {
+pub(crate) trait Linker {
     fn cmd(&mut self) -> &mut Command;
     fn is_cc(&self) -> bool {
         false
@@ -314,12 +322,12 @@ pub trait Linker {
 }
 
 impl dyn Linker + '_ {
-    pub fn take_cmd(&mut self) -> Command {
+    pub(crate) fn take_cmd(&mut self) -> Command {
         mem::replace(self.cmd(), Command::new(""))
     }
 }
 
-pub struct GccLinker<'a> {
+struct GccLinker<'a> {
     cmd: Command,
     sess: &'a Session,
     target_cpu: &'a str,
@@ -849,7 +857,7 @@ impl<'a> Linker for GccLinker<'a> {
     }
 }
 
-pub struct MsvcLinker<'a> {
+struct MsvcLinker<'a> {
     cmd: Command,
     sess: &'a Session,
 }
@@ -1103,7 +1111,7 @@ impl<'a> Linker for MsvcLinker<'a> {
     }
 }
 
-pub struct EmLinker<'a> {
+struct EmLinker<'a> {
     cmd: Command,
     sess: &'a Session,
 }
@@ -1220,7 +1228,7 @@ impl<'a> Linker for EmLinker<'a> {
     }
 }
 
-pub struct WasmLd<'a> {
+struct WasmLd<'a> {
     cmd: Command,
     sess: &'a Session,
 }
@@ -1404,7 +1412,7 @@ impl<'a> WasmLd<'a> {
 }
 
 /// Linker shepherd script for L4Re (Fiasco)
-pub struct L4Bender<'a> {
+struct L4Bender<'a> {
     cmd: Command,
     sess: &'a Session,
     hinted_static: bool,
@@ -1510,7 +1518,7 @@ impl<'a> Linker for L4Bender<'a> {
 }
 
 impl<'a> L4Bender<'a> {
-    pub fn new(cmd: Command, sess: &'a Session) -> L4Bender<'a> {
+    fn new(cmd: Command, sess: &'a Session) -> L4Bender<'a> {
         L4Bender { cmd, sess, hinted_static: false }
     }
 
@@ -1523,14 +1531,14 @@ impl<'a> L4Bender<'a> {
 }
 
 /// Linker for AIX.
-pub struct AixLinker<'a> {
+struct AixLinker<'a> {
     cmd: Command,
     sess: &'a Session,
     hinted_static: Option<bool>,
 }
 
 impl<'a> AixLinker<'a> {
-    pub fn new(cmd: Command, sess: &'a Session) -> AixLinker<'a> {
+    fn new(cmd: Command, sess: &'a Session) -> AixLinker<'a> {
         AixLinker { cmd, sess, hinted_static: None }
     }
 
@@ -1758,7 +1766,7 @@ pub(crate) fn linked_symbols(
 
 /// Much simplified and explicit CLI for the NVPTX linker. The linker operates
 /// with bitcode and uses LLVM backend to generate a PTX assembly.
-pub struct PtxLinker<'a> {
+struct PtxLinker<'a> {
     cmd: Command,
     sess: &'a Session,
 }
@@ -1824,7 +1832,7 @@ impl<'a> Linker for PtxLinker<'a> {
 }
 
 /// The `self-contained` LLVM bitcode linker
-pub struct LlbcLinker<'a> {
+struct LlbcLinker<'a> {
     cmd: Command,
     sess: &'a Session,
 }
@@ -1895,7 +1903,7 @@ impl<'a> Linker for LlbcLinker<'a> {
     fn linker_plugin_lto(&mut self) {}
 }
 
-pub struct BpfLinker<'a> {
+struct BpfLinker<'a> {
     cmd: Command,
     sess: &'a Session,
 }
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 6215616e510..ff87f7f1ea4 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -32,7 +32,7 @@ use rustc_target::spec::{ef_avr_arch, RelocModel, Target};
 /// <dd>The metadata can be found in the `.rustc` section of the shared library.</dd>
 /// </dl>
 #[derive(Debug)]
-pub struct DefaultMetadataLoader;
+pub(crate) struct DefaultMetadataLoader;
 
 static AIX_METADATA_SYMBOL_NAME: &'static str = "__aix_rust_metadata";
 
@@ -416,7 +416,7 @@ fn macho_is_arm64e(target: &Target) -> bool {
     target.llvm_target.starts_with("arm64e")
 }
 
-pub enum MetadataPosition {
+pub(crate) enum MetadataPosition {
     First,
     Last,
 }
@@ -452,7 +452,7 @@ pub enum MetadataPosition {
 /// * ELF - All other targets are similar to Windows in that there's a
 ///   `SHF_EXCLUDE` flag we can set on sections in an object file to get
 ///   automatically removed from the final output.
-pub fn create_wrapper_file(
+pub(crate) fn create_wrapper_file(
     sess: &Session,
     section_name: String,
     data: &[u8],
diff --git a/compiler/rustc_codegen_ssa/src/back/mod.rs b/compiler/rustc_codegen_ssa/src/back/mod.rs
index d11ed54eb20..2b3a2e3a369 100644
--- a/compiler/rustc_codegen_ssa/src/back/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/back/mod.rs
@@ -1,9 +1,9 @@
 pub mod archive;
-pub mod command;
+pub(crate) mod command;
 pub mod link;
-pub mod linker;
+pub(crate) mod linker;
 pub mod lto;
 pub mod metadata;
-pub mod rpath;
+pub(crate) mod rpath;
 pub mod symbol_export;
 pub mod write;
diff --git a/compiler/rustc_codegen_ssa/src/back/rpath.rs b/compiler/rustc_codegen_ssa/src/back/rpath.rs
index 42f8c3114ff..56a808df6b0 100644
--- a/compiler/rustc_codegen_ssa/src/back/rpath.rs
+++ b/compiler/rustc_codegen_ssa/src/back/rpath.rs
@@ -6,14 +6,14 @@ use rustc_data_structures::fx::FxHashSet;
 use rustc_fs_util::try_canonicalize;
 use tracing::debug;
 
-pub struct RPathConfig<'a> {
+pub(super) struct RPathConfig<'a> {
     pub libs: &'a [&'a Path],
     pub out_filename: PathBuf,
     pub is_like_osx: bool,
     pub linker_is_gnu: bool,
 }
 
-pub fn get_rpath_flags(config: &RPathConfig<'_>) -> Vec<OsString> {
+pub(super) fn get_rpath_flags(config: &RPathConfig<'_>) -> Vec<OsString> {
     debug!("preparing the RPATH!");
 
     let rpaths = get_rpaths(config);
diff --git a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
index d2f11d48140..257e2dfac00 100644
--- a/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
+++ b/compiler/rustc_codegen_ssa/src/back/symbol_export.rs
@@ -18,7 +18,7 @@ use tracing::debug;
 
 use crate::base::allocator_kind_for_codegen;
 
-pub fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
+fn threshold(tcx: TyCtxt<'_>) -> SymbolExportLevel {
     crates_export_threshold(tcx.crate_types())
 }
 
@@ -484,7 +484,7 @@ fn is_unreachable_local_definition_provider(tcx: TyCtxt<'_>, def_id: LocalDefId)
     !tcx.reachable_set(()).contains(&def_id)
 }
 
-pub fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers) {
     providers.reachable_non_generics = reachable_non_generics_provider;
     providers.is_reachable_non_generic = is_reachable_non_generic_provider_local;
     providers.exported_symbols = exported_symbols_provider_local;
@@ -525,7 +525,7 @@ fn symbol_export_level(tcx: TyCtxt<'_>, sym_def_id: DefId) -> SymbolExportLevel
 }
 
 /// This is the symbol name of the given instance instantiated in a specific crate.
-pub fn symbol_name_for_instance_in_crate<'tcx>(
+pub(crate) fn symbol_name_for_instance_in_crate<'tcx>(
     tcx: TyCtxt<'tcx>,
     symbol: ExportedSymbol<'tcx>,
     instantiating_crate: CrateNum,
@@ -582,7 +582,7 @@ pub fn symbol_name_for_instance_in_crate<'tcx>(
 /// This is the symbol name of the given instance as seen by the linker.
 ///
 /// On 32-bit Windows symbols are decorated according to their calling conventions.
-pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
+pub(crate) fn linking_symbol_name_for_instance_in_crate<'tcx>(
     tcx: TyCtxt<'tcx>,
     symbol: ExportedSymbol<'tcx>,
     instantiating_crate: CrateNum,
@@ -661,7 +661,7 @@ pub fn linking_symbol_name_for_instance_in_crate<'tcx>(
     format!("{prefix}{undecorated}{suffix}{args_in_bytes}")
 }
 
-pub fn exporting_symbol_name_for_instance_in_crate<'tcx>(
+pub(crate) fn exporting_symbol_name_for_instance_in_crate<'tcx>(
     tcx: TyCtxt<'tcx>,
     symbol: ExportedSymbol<'tcx>,
     cnum: CrateNum,
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index feb27c148a1..c170cd41ec4 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -16,7 +16,7 @@ use rustc_errors::emitter::Emitter;
 use rustc_errors::translation::Translate;
 use rustc_errors::{
     Diag, DiagArgMap, DiagCtxt, DiagMessage, ErrCode, FatalError, FluentBundle, Level, MultiSpan,
-    Style,
+    Style, Suggestions,
 };
 use rustc_fs_util::link_or_copy;
 use rustc_hir::def_id::{CrateNum, LOCAL_CRATE};
@@ -335,7 +335,7 @@ pub type TargetMachineFactoryFn<B> = Arc<
         + Sync,
 >;
 
-pub type ExportedSymbols = FxHashMap<CrateNum, Arc<Vec<(String, SymbolExportInfo)>>>;
+type ExportedSymbols = FxHashMap<CrateNum, Arc<Vec<(String, SymbolExportInfo)>>>;
 
 /// Additional resources used by optimize_and_codegen (not module specific)
 #[derive(Clone)]
@@ -437,9 +437,9 @@ fn generate_lto_work<B: ExtraBackendMethods>(
     }
 }
 
-pub struct CompiledModules {
-    pub modules: Vec<CompiledModule>,
-    pub allocator_module: Option<CompiledModule>,
+struct CompiledModules {
+    modules: Vec<CompiledModule>,
+    allocator_module: Option<CompiledModule>,
 }
 
 fn need_bitcode_in_object(tcx: TyCtxt<'_>) -> bool {
@@ -462,7 +462,7 @@ fn need_pre_lto_bitcode_for_incr_comp(sess: &Session) -> bool {
     }
 }
 
-pub fn start_async_codegen<B: ExtraBackendMethods>(
+pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
     backend: B,
     tcx: TyCtxt<'_>,
     target_cpu: String,
@@ -836,13 +836,13 @@ pub enum FatLtoInput<B: WriteBackendMethods> {
 }
 
 /// Actual LTO type we end up choosing based on multiple factors.
-pub enum ComputedLtoType {
+pub(crate) enum ComputedLtoType {
     No,
     Thin,
     Fat,
 }
 
-pub fn compute_per_cgu_lto_type(
+pub(crate) fn compute_per_cgu_lto_type(
     sess_lto: &Lto,
     opts: &config::Options,
     sess_crate_types: &[CrateType],
@@ -1087,7 +1087,7 @@ struct Diagnostic {
 // A cut-down version of `rustc_errors::Subdiag` that impls `Send`. It's
 // missing the following fields from `rustc_errors::Subdiag`.
 // - `span`: it doesn't impl `Send`.
-pub struct Subdiagnostic {
+pub(crate) struct Subdiagnostic {
     level: Level,
     messages: Vec<(DiagMessage, Style)>,
 }
@@ -1779,7 +1779,7 @@ fn start_executing_work<B: ExtraBackendMethods>(
 
 /// `FatalError` is explicitly not `Send`.
 #[must_use]
-pub struct WorkerFatalError;
+pub(crate) struct WorkerFatalError;
 
 fn spawn_work<'a, B: ExtraBackendMethods>(
     cgcx: &'a CodegenContext<B>,
@@ -1867,7 +1867,7 @@ pub struct SharedEmitterMain {
 }
 
 impl SharedEmitter {
-    pub fn new() -> (SharedEmitter, SharedEmitterMain) {
+    fn new() -> (SharedEmitter, SharedEmitterMain) {
         let (sender, receiver) = channel();
 
         (SharedEmitter { sender }, SharedEmitterMain { receiver })
@@ -1883,7 +1883,7 @@ impl SharedEmitter {
         drop(self.sender.send(SharedEmitterMessage::InlineAsmError(cookie, msg, level, source)));
     }
 
-    pub fn fatal(&self, msg: &str) {
+    fn fatal(&self, msg: &str) {
         drop(self.sender.send(SharedEmitterMessage::Fatal(msg.to_string())));
     }
 }
@@ -1903,7 +1903,7 @@ impl Emitter for SharedEmitter {
         // Check that we aren't missing anything interesting when converting to
         // the cut-down local `DiagInner`.
         assert_eq!(diag.span, MultiSpan::new());
-        assert_eq!(diag.suggestions, Ok(vec![]));
+        assert_eq!(diag.suggestions, Suggestions::Enabled(vec![]));
         assert_eq!(diag.sort_span, rustc_span::DUMMY_SP);
         assert_eq!(diag.is_lint, None);
         // No sensible check for `diag.emitted_at`.
@@ -1930,7 +1930,7 @@ impl Emitter for SharedEmitter {
 }
 
 impl SharedEmitterMain {
-    pub fn check(&self, sess: &Session, blocking: bool) {
+    fn check(&self, sess: &Session, blocking: bool) {
         loop {
             let message = if blocking {
                 match self.receiver.recv() {
@@ -2087,17 +2087,17 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
         )
     }
 
-    pub fn codegen_finished(&self, tcx: TyCtxt<'_>) {
+    pub(crate) fn codegen_finished(&self, tcx: TyCtxt<'_>) {
         self.wait_for_signal_to_codegen_item();
         self.check_for_errors(tcx.sess);
         drop(self.coordinator.sender.send(Box::new(Message::CodegenComplete::<B>)));
     }
 
-    pub fn check_for_errors(&self, sess: &Session) {
+    pub(crate) fn check_for_errors(&self, sess: &Session) {
         self.shared_emitter_main.check(sess, false);
     }
 
-    pub fn wait_for_signal_to_codegen_item(&self) {
+    pub(crate) fn wait_for_signal_to_codegen_item(&self) {
         match self.codegen_worker_receive.recv() {
             Ok(CguMessage) => {
                 // Ok to proceed.
@@ -2110,7 +2110,7 @@ impl<B: ExtraBackendMethods> OngoingCodegen<B> {
     }
 }
 
-pub fn submit_codegened_module_to_llvm<B: ExtraBackendMethods>(
+pub(crate) fn submit_codegened_module_to_llvm<B: ExtraBackendMethods>(
     _backend: &B,
     tx_to_llvm_workers: &Sender<Box<dyn Any + Send>>,
     module: ModuleCodegen<B::Module>,
@@ -2120,7 +2120,7 @@ pub fn submit_codegened_module_to_llvm<B: ExtraBackendMethods>(
     drop(tx_to_llvm_workers.send(Box::new(Message::CodegenDone::<B> { llvm_work_item, cost })));
 }
 
-pub fn submit_post_lto_module_to_llvm<B: ExtraBackendMethods>(
+pub(crate) fn submit_post_lto_module_to_llvm<B: ExtraBackendMethods>(
     _backend: &B,
     tx_to_llvm_workers: &Sender<Box<dyn Any + Send>>,
     module: CachedModuleCodegen,
@@ -2129,7 +2129,7 @@ pub fn submit_post_lto_module_to_llvm<B: ExtraBackendMethods>(
     drop(tx_to_llvm_workers.send(Box::new(Message::CodegenDone::<B> { llvm_work_item, cost: 0 })));
 }
 
-pub fn submit_pre_lto_module_to_llvm<B: ExtraBackendMethods>(
+pub(crate) fn submit_pre_lto_module_to_llvm<B: ExtraBackendMethods>(
     _backend: &B,
     tcx: TyCtxt<'_>,
     tx_to_llvm_workers: &Sender<Box<dyn Any + Send>>,
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index f1e7f87f567..3d1007a4673 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -44,47 +44,23 @@ use crate::{
     errors, meth, mir, CachedModuleCodegen, CompiledModule, CrateInfo, ModuleCodegen, ModuleKind,
 };
 
-pub fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate {
-    match op {
-        BinOp::Eq => IntPredicate::IntEQ,
-        BinOp::Ne => IntPredicate::IntNE,
-        BinOp::Lt => {
-            if signed {
-                IntPredicate::IntSLT
-            } else {
-                IntPredicate::IntULT
-            }
-        }
-        BinOp::Le => {
-            if signed {
-                IntPredicate::IntSLE
-            } else {
-                IntPredicate::IntULE
-            }
-        }
-        BinOp::Gt => {
-            if signed {
-                IntPredicate::IntSGT
-            } else {
-                IntPredicate::IntUGT
-            }
-        }
-        BinOp::Ge => {
-            if signed {
-                IntPredicate::IntSGE
-            } else {
-                IntPredicate::IntUGE
-            }
-        }
-        op => bug!(
-            "comparison_op_to_icmp_predicate: expected comparison operator, \
-             found {:?}",
-            op
-        ),
+pub(crate) fn bin_op_to_icmp_predicate(op: BinOp, signed: bool) -> IntPredicate {
+    match (op, signed) {
+        (BinOp::Eq, _) => IntPredicate::IntEQ,
+        (BinOp::Ne, _) => IntPredicate::IntNE,
+        (BinOp::Lt, true) => IntPredicate::IntSLT,
+        (BinOp::Lt, false) => IntPredicate::IntULT,
+        (BinOp::Le, true) => IntPredicate::IntSLE,
+        (BinOp::Le, false) => IntPredicate::IntULE,
+        (BinOp::Gt, true) => IntPredicate::IntSGT,
+        (BinOp::Gt, false) => IntPredicate::IntUGT,
+        (BinOp::Ge, true) => IntPredicate::IntSGE,
+        (BinOp::Ge, false) => IntPredicate::IntUGE,
+        op => bug!("bin_op_to_icmp_predicate: expected comparison operator, found {:?}", op),
     }
 }
 
-pub fn bin_op_to_fcmp_predicate(op: BinOp) -> RealPredicate {
+pub(crate) fn bin_op_to_fcmp_predicate(op: BinOp) -> RealPredicate {
     match op {
         BinOp::Eq => RealPredicate::RealOEQ,
         BinOp::Ne => RealPredicate::RealUNE,
@@ -92,13 +68,7 @@ pub fn bin_op_to_fcmp_predicate(op: BinOp) -> RealPredicate {
         BinOp::Le => RealPredicate::RealOLE,
         BinOp::Gt => RealPredicate::RealOGT,
         BinOp::Ge => RealPredicate::RealOGE,
-        op => {
-            bug!(
-                "comparison_op_to_fcmp_predicate: expected comparison operator, \
-                 found {:?}",
-                op
-            );
-        }
+        op => bug!("bin_op_to_fcmp_predicate: expected comparison operator, found {:?}", op),
     }
 }
 
@@ -135,7 +105,7 @@ pub fn compare_simd_types<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 ///
 /// The `old_info` argument is a bit odd. It is intended for use in an upcast,
 /// where the new vtable for an object will be derived from the old one.
-pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
+fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
     source: Ty<'tcx>,
     target: Ty<'tcx>,
@@ -145,16 +115,17 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     let (source, target) =
         cx.tcx().struct_lockstep_tails_for_codegen(source, target, bx.param_env());
     match (source.kind(), target.kind()) {
-        (&ty::Array(_, len), &ty::Slice(_)) => {
-            cx.const_usize(len.eval_target_usize(cx.tcx(), ty::ParamEnv::reveal_all()))
-        }
+        (&ty::Array(_, len), &ty::Slice(_)) => cx.const_usize(
+            len.try_to_target_usize(cx.tcx()).expect("expected monomorphic const in codegen"),
+        ),
         (&ty::Dynamic(data_a, _, src_dyn_kind), &ty::Dynamic(data_b, _, target_dyn_kind))
             if src_dyn_kind == target_dyn_kind =>
         {
             let old_info =
                 old_info.expect("unsized_info: missing old info for trait upcasting coercion");
             if data_a.principal_def_id() == data_b.principal_def_id() {
-                // A NOP cast that doesn't actually change anything, should be allowed even with invalid vtables.
+                // A NOP cast that doesn't actually change anything, should be allowed even with
+                // invalid vtables.
                 return old_info;
             }
 
@@ -182,7 +153,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 }
 
 /// Coerces `src` to `dst_ty`. `src_ty` must be a pointer.
-pub fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
+pub(crate) fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
     src: Bx::Value,
     src_ty: Ty<'tcx>,
@@ -227,7 +198,7 @@ pub fn unsize_ptr<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 }
 
 /// Coerces `src` to `dst_ty` which is guaranteed to be a `dyn*` type.
-pub fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
+pub(crate) fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
     src: Bx::Value,
     src_ty_and_layout: TyAndLayout<'tcx>,
@@ -250,7 +221,7 @@ pub fn cast_to_dyn_star<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
 /// Coerces `src`, which is a reference to a value of type `src_ty`,
 /// to a value of type `dst_ty`, and stores the result in `dst`.
-pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
+pub(crate) fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
     src: PlaceRef<'tcx, Bx::Value>,
     dst: PlaceRef<'tcx, Bx::Value>,
@@ -305,7 +276,7 @@ pub fn coerce_unsized_into<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 ///
 /// If `is_unchecked` is true, this does no masking, and adds sufficient `assume`
 /// calls or operation flags to preserve as much freedom to optimize as possible.
-pub fn build_shift_expr_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
+pub(crate) fn build_shift_expr_rhs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
     lhs: Bx::Value,
     mut rhs: Bx::Value,
@@ -369,11 +340,11 @@ pub fn wants_msvc_seh(sess: &Session) -> bool {
 /// Returns `true` if this session's target requires the new exception
 /// handling LLVM IR instructions (catchpad / cleanuppad / ... instead
 /// of landingpad)
-pub fn wants_new_eh_instructions(sess: &Session) -> bool {
+pub(crate) fn wants_new_eh_instructions(sess: &Session) -> bool {
     wants_wasm_eh(sess) || wants_msvc_seh(sess)
 }
 
-pub fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
+pub(crate) fn codegen_instance<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>>(
     cx: &'a Bx::CodegenCx,
     instance: Instance<'tcx>,
 ) {
@@ -454,7 +425,7 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 
         let isize_ty = cx.type_isize();
         let ptr_ty = cx.type_ptr();
-        let (arg_argc, arg_argv) = get_argc_argv(cx, &mut bx);
+        let (arg_argc, arg_argv) = get_argc_argv(&mut bx);
 
         let (start_fn, start_ty, args, instance) = if let EntryFnType::Main { sigpipe } = entry_type
         {
@@ -497,33 +468,30 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
 }
 
 /// Obtain the `argc` and `argv` values to pass to the rust start function.
-fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
-    cx: &'a Bx::CodegenCx,
-    bx: &mut Bx,
-) -> (Bx::Value, Bx::Value) {
-    if cx.sess().target.os.contains("uefi") {
+fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(bx: &mut Bx) -> (Bx::Value, Bx::Value) {
+    if bx.cx().sess().target.os.contains("uefi") {
         // Params for UEFI
         let param_handle = bx.get_param(0);
         let param_system_table = bx.get_param(1);
         let ptr_size = bx.tcx().data_layout.pointer_size;
         let ptr_align = bx.tcx().data_layout.pointer_align.abi;
-        let arg_argc = bx.const_int(cx.type_isize(), 2);
+        let arg_argc = bx.const_int(bx.cx().type_isize(), 2);
         let arg_argv = bx.alloca(2 * ptr_size, ptr_align);
         bx.store(param_handle, arg_argv, ptr_align);
         let arg_argv_el1 = bx.inbounds_ptradd(arg_argv, bx.const_usize(ptr_size.bytes()));
         bx.store(param_system_table, arg_argv_el1, ptr_align);
         (arg_argc, arg_argv)
-    } else if cx.sess().target.main_needs_argc_argv {
+    } else if bx.cx().sess().target.main_needs_argc_argv {
         // Params from native `main()` used as args for rust start function
         let param_argc = bx.get_param(0);
         let param_argv = bx.get_param(1);
-        let arg_argc = bx.intcast(param_argc, cx.type_isize(), true);
+        let arg_argc = bx.intcast(param_argc, bx.cx().type_isize(), true);
         let arg_argv = param_argv;
         (arg_argc, arg_argv)
     } else {
         // The Rust start function doesn't need `argc` and `argv`, so just pass zeros.
-        let arg_argc = bx.const_int(cx.type_int(), 0);
-        let arg_argv = bx.const_null(cx.type_ptr());
+        let arg_argc = bx.const_int(bx.cx().type_int(), 0);
+        let arg_argv = bx.const_null(bx.cx().type_ptr());
         (arg_argc, arg_argv)
     }
 }
@@ -985,7 +953,8 @@ impl CrateInfo {
                 false
             }
             CrateType::Staticlib | CrateType::Rlib => {
-                // We don't invoke the linker for these, so we don't need to collect the NatVis for them.
+                // We don't invoke the linker for these, so we don't need to collect the NatVis for
+                // them.
                 false
             }
         });
@@ -999,7 +968,7 @@ impl CrateInfo {
     }
 }
 
-pub fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers) {
     providers.backend_optimization_level = |tcx, cratenum| {
         let for_speed = match tcx.sess.opts.optimize {
             // If globally no optimisation is done, #[optimize] has no effect.
diff --git a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
index 9149c602296..137e481f08c 100644
--- a/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
+++ b/compiler/rustc_codegen_ssa/src/codegen_attrs.rs
@@ -317,9 +317,9 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
                                 "extern mutable statics are not allowed with `#[linkage]`",
                             );
                             diag.note(
-                                "marking the extern static mutable would allow changing which symbol \
-                                 the static references rather than make the target of the symbol \
-                                 mutable",
+                                "marking the extern static mutable would allow changing which \
+                                 symbol the static references rather than make the target of the \
+                                 symbol mutable",
                             );
                             diag.emit();
                         }
@@ -711,18 +711,19 @@ fn check_link_ordinal(tcx: TyCtxt<'_>, attr: &ast::Attribute) -> Option<u16> {
     if let Some(MetaItemLit { kind: LitKind::Int(ordinal, LitIntType::Unsuffixed), .. }) =
         sole_meta_list
     {
-        // According to the table at https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header,
-        // the ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
-        // in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import information
-        // to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t.
+        // According to the table at
+        // https://docs.microsoft.com/en-us/windows/win32/debug/pe-format#import-header, the
+        // ordinal must fit into 16 bits. Similarly, the Ordinal field in COFFShortExport (defined
+        // in llvm/include/llvm/Object/COFFImportFile.h), which we use to communicate import
+        // information to LLVM for `#[link(kind = "raw-dylib"_])`, is also defined to be uint16_t.
         //
-        // FIXME: should we allow an ordinal of 0?  The MSVC toolchain has inconsistent support for this:
-        // both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that specifies
-        // a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import library
-        // for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an import
-        // library produced by LLVM with an ordinal of 0, and it generates an .EXE.  (I don't know yet
-        // if the resulting EXE runs, as I haven't yet built the necessary DLL -- see earlier comment
-        // about LINK.EXE failing.)
+        // FIXME: should we allow an ordinal of 0?  The MSVC toolchain has inconsistent support for
+        // this: both LINK.EXE and LIB.EXE signal errors and abort when given a .DEF file that
+        // specifies a zero ordinal. However, llvm-dlltool is perfectly happy to generate an import
+        // library for such a .DEF file, and MSVC's LINK.EXE is also perfectly happy to consume an
+        // import library produced by LLVM with an ordinal of 0, and it generates an .EXE.  (I
+        // don't know yet if the resulting EXE runs, as I haven't yet built the necessary DLL --
+        // see earlier comment about LINK.EXE failing.)
         if *ordinal <= u16::MAX as u128 {
             Some(ordinal.get() as u16)
         } else {
@@ -755,6 +756,6 @@ fn check_link_name_xor_ordinal(
     }
 }
 
-pub fn provide(providers: &mut Providers) {
+pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { codegen_fn_attrs, should_inherit_track_caller, ..*providers };
 }
diff --git a/compiler/rustc_codegen_ssa/src/common.rs b/compiler/rustc_codegen_ssa/src/common.rs
index bfb1d217eae..582a2a87e48 100644
--- a/compiler/rustc_codegen_ssa/src/common.rs
+++ b/compiler/rustc_codegen_ssa/src/common.rs
@@ -118,7 +118,7 @@ mod temp_stable_hash_impls {
     }
 }
 
-pub fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
+pub(crate) fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &Bx,
     span: Option<Span>,
     li: LangItem,
@@ -129,7 +129,7 @@ pub fn build_langcall<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     (bx.fn_abi_of_instance(instance, ty::List::empty()), bx.get_fn_addr(instance), instance)
 }
 
-pub fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
+pub(crate) fn shift_mask_val<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     bx: &mut Bx,
     llty: Bx::Type,
     mask_llty: Bx::Type,
@@ -200,7 +200,8 @@ pub fn i686_decorated_name(
     let mut decorated_name = String::with_capacity(name.len() + 6);
 
     if disable_name_mangling {
-        // LLVM uses a binary 1 ('\x01') prefix to a name to indicate that mangling needs to be disabled.
+        // LLVM uses a binary 1 ('\x01') prefix to a name to indicate that mangling needs to be
+        // disabled.
         decorated_name.push('\x01');
     }
 
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs b/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs
index 0918660e6be..bfd1b94c790 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/mod.rs
@@ -54,7 +54,7 @@ pub fn tag_base_type<'tcx>(tcx: TyCtxt<'tcx>, enum_type_and_layout: TyAndLayout<
     })
 }
 
-pub fn tag_base_type_opt<'tcx>(
+fn tag_base_type_opt<'tcx>(
     tcx: TyCtxt<'tcx>,
     enum_type_and_layout: TyAndLayout<'tcx>,
 ) -> Option<Ty<'tcx>> {
@@ -76,9 +76,9 @@ pub fn tag_base_type_opt<'tcx>(
                     Primitive::Float(f) => Integer::from_size(f.size()).unwrap(),
                     // FIXME(erikdesjardins): handle non-default addrspace ptr sizes
                     Primitive::Pointer(_) => {
-                        // If the niche is the NULL value of a reference, then `discr_enum_ty` will be
-                        // a RawPtr. CodeView doesn't know what to do with enums whose base type is a
-                        // pointer so we fix this up to just be `usize`.
+                        // If the niche is the NULL value of a reference, then `discr_enum_ty` will
+                        // be a RawPtr. CodeView doesn't know what to do with enums whose base type
+                        // is a pointer so we fix this up to just be `usize`.
                         // DWARF might be able to deal with this but with an integer type we are on
                         // the safe side there too.
                         tcx.data_layout.ptr_sized_integer()
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index e34fbfe3f76..369ab387bea 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -95,7 +95,8 @@ fn push_debuginfo_type_name<'tcx>(
                     }
                     Err(e) => {
                         // Computing the layout can still fail here, e.g. if the target architecture
-                        // cannot represent the type. See https://github.com/rust-lang/rust/issues/94961.
+                        // cannot represent the type. See
+                        // https://github.com/rust-lang/rust/issues/94961.
                         tcx.dcx().emit_fatal(e.into_diagnostic());
                     }
                 }
@@ -187,7 +188,8 @@ fn push_debuginfo_type_name<'tcx>(
                     _ => write!(
                         output,
                         ",{}>",
-                        len.eval_target_usize(tcx, ty::ParamEnv::reveal_all())
+                        len.try_to_target_usize(tcx)
+                            .expect("expected monomorphic const in codegen")
                     )
                     .unwrap(),
                 }
@@ -199,7 +201,8 @@ fn push_debuginfo_type_name<'tcx>(
                     _ => write!(
                         output,
                         "; {}]",
-                        len.eval_target_usize(tcx, ty::ParamEnv::reveal_all())
+                        len.try_to_target_usize(tcx)
+                            .expect("expected monomorphic const in codegen")
                     )
                     .unwrap(),
                 }
@@ -575,33 +578,20 @@ pub fn push_item_name(tcx: TyCtxt<'_>, def_id: DefId, qualified: bool, output: &
 }
 
 fn coroutine_kind_label(coroutine_kind: Option<CoroutineKind>) -> &'static str {
+    use CoroutineDesugaring::*;
+    use CoroutineKind::*;
+    use CoroutineSource::*;
     match coroutine_kind {
-        Some(CoroutineKind::Desugared(CoroutineDesugaring::Gen, CoroutineSource::Block)) => {
-            "gen_block"
-        }
-        Some(CoroutineKind::Desugared(CoroutineDesugaring::Gen, CoroutineSource::Closure)) => {
-            "gen_closure"
-        }
-        Some(CoroutineKind::Desugared(CoroutineDesugaring::Gen, CoroutineSource::Fn)) => "gen_fn",
-        Some(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Block)) => {
-            "async_block"
-        }
-        Some(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure)) => {
-            "async_closure"
-        }
-        Some(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Fn)) => {
-            "async_fn"
-        }
-        Some(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, CoroutineSource::Block)) => {
-            "async_gen_block"
-        }
-        Some(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, CoroutineSource::Closure)) => {
-            "async_gen_closure"
-        }
-        Some(CoroutineKind::Desugared(CoroutineDesugaring::AsyncGen, CoroutineSource::Fn)) => {
-            "async_gen_fn"
-        }
-        Some(CoroutineKind::Coroutine(_)) => "coroutine",
+        Some(Desugared(Gen, Block)) => "gen_block",
+        Some(Desugared(Gen, Closure)) => "gen_closure",
+        Some(Desugared(Gen, Fn)) => "gen_fn",
+        Some(Desugared(Async, Block)) => "async_block",
+        Some(Desugared(Async, Closure)) => "async_closure",
+        Some(Desugared(Async, Fn)) => "async_fn",
+        Some(Desugared(AsyncGen, Block)) => "async_gen_block",
+        Some(Desugared(AsyncGen, Closure)) => "async_gen_closure",
+        Some(Desugared(AsyncGen, Fn)) => "async_gen_fn",
+        Some(Coroutine(_)) => "coroutine",
         None => "closure",
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index 573a8cf7cbe..58877379e26 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -21,7 +21,7 @@ use crate::fluent_generated as fluent;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_incorrect_cgu_reuse_type)]
-pub struct IncorrectCguReuseType<'a> {
+pub(crate) struct IncorrectCguReuseType<'a> {
     #[primary_span]
     pub span: Span,
     pub cgu_user_name: &'a str,
@@ -32,14 +32,14 @@ pub struct IncorrectCguReuseType<'a> {
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_cgu_not_recorded)]
-pub struct CguNotRecorded<'a> {
+pub(crate) struct CguNotRecorded<'a> {
     pub cgu_user_name: &'a str,
     pub cgu_name: &'a str,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_unknown_reuse_kind)]
-pub struct UnknownReuseKind {
+pub(crate) struct UnknownReuseKind {
     #[primary_span]
     pub span: Span,
     pub kind: Symbol,
@@ -47,14 +47,14 @@ pub struct UnknownReuseKind {
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_missing_query_depgraph)]
-pub struct MissingQueryDepGraph {
+pub(crate) struct MissingQueryDepGraph {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_malformed_cgu_name)]
-pub struct MalformedCguName {
+pub(crate) struct MalformedCguName {
     #[primary_span]
     pub span: Span,
     pub user_path: String,
@@ -63,7 +63,7 @@ pub struct MalformedCguName {
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_no_module_named)]
-pub struct NoModuleNamed<'a> {
+pub(crate) struct NoModuleNamed<'a> {
     #[primary_span]
     pub span: Span,
     pub user_path: &'a str,
@@ -73,7 +73,7 @@ pub struct NoModuleNamed<'a> {
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_field_associated_value_expected)]
-pub struct FieldAssociatedValueExpected {
+pub(crate) struct FieldAssociatedValueExpected {
     #[primary_span]
     pub span: Span,
     pub name: Symbol,
@@ -81,7 +81,7 @@ pub struct FieldAssociatedValueExpected {
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_no_field)]
-pub struct NoField {
+pub(crate) struct NoField {
     #[primary_span]
     pub span: Span,
     pub name: Symbol,
@@ -89,49 +89,49 @@ pub struct NoField {
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_lib_def_write_failure)]
-pub struct LibDefWriteFailure {
+pub(crate) struct LibDefWriteFailure {
     pub error: Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_version_script_write_failure)]
-pub struct VersionScriptWriteFailure {
+pub(crate) struct VersionScriptWriteFailure {
     pub error: Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_symbol_file_write_failure)]
-pub struct SymbolFileWriteFailure {
+pub(crate) struct SymbolFileWriteFailure {
     pub error: Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_ld64_unimplemented_modifier)]
-pub struct Ld64UnimplementedModifier;
+pub(crate) struct Ld64UnimplementedModifier;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_linker_unsupported_modifier)]
-pub struct LinkerUnsupportedModifier;
+pub(crate) struct LinkerUnsupportedModifier;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_L4Bender_exporting_symbols_unimplemented)]
-pub struct L4BenderExportingSymbolsUnimplemented;
+pub(crate) struct L4BenderExportingSymbolsUnimplemented;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_no_natvis_directory)]
-pub struct NoNatvisDirectory {
+pub(crate) struct NoNatvisDirectory {
     pub error: Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_no_saved_object_file)]
-pub struct NoSavedObjectFile<'a> {
+pub(crate) struct NoSavedObjectFile<'a> {
     pub cgu_name: &'a str,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_copy_path_buf)]
-pub struct CopyPathBuf {
+pub(crate) struct CopyPathBuf {
     pub source_file: PathBuf,
     pub output_path: PathBuf,
     pub error: Error,
@@ -180,20 +180,20 @@ pub struct IgnoringOutput {
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_create_temp_dir)]
-pub struct CreateTempDir {
+pub(crate) struct CreateTempDir {
     pub error: Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_add_native_library)]
-pub struct AddNativeLibrary {
+pub(crate) struct AddNativeLibrary {
     pub library_path: PathBuf,
     pub error: Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_multiple_external_func_decl)]
-pub struct MultipleExternalFuncDecl<'a> {
+pub(crate) struct MultipleExternalFuncDecl<'a> {
     #[primary_span]
     pub span: Span,
     pub function: Symbol,
@@ -215,7 +215,7 @@ pub enum LinkRlibError {
     IncompatibleDependencyFormats { ty1: String, ty2: String, list1: String, list2: String },
 }
 
-pub struct ThorinErrorWrapper(pub thorin::Error);
+pub(crate) struct ThorinErrorWrapper(pub thorin::Error);
 
 impl<G: EmissionGuarantee> Diagnostic<'_, G> for ThorinErrorWrapper {
     fn into_diag(self, dcx: DiagCtxtHandle<'_>, level: Level) -> Diag<'_, G> {
@@ -343,7 +343,7 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for ThorinErrorWrapper {
     }
 }
 
-pub struct LinkingFailed<'a> {
+pub(crate) struct LinkingFailed<'a> {
     pub linker_path: &'a PathBuf,
     pub exit_status: ExitStatus,
     pub command: &'a Command,
@@ -376,28 +376,28 @@ impl<G: EmissionGuarantee> Diagnostic<'_, G> for LinkingFailed<'_> {
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_link_exe_unexpected_error)]
-pub struct LinkExeUnexpectedError;
+pub(crate) struct LinkExeUnexpectedError;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_repair_vs_build_tools)]
-pub struct RepairVSBuildTools;
+pub(crate) struct RepairVSBuildTools;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_missing_cpp_build_tool_component)]
-pub struct MissingCppBuildToolComponent;
+pub(crate) struct MissingCppBuildToolComponent;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_select_cpp_build_tool_workload)]
-pub struct SelectCppBuildToolWorkload;
+pub(crate) struct SelectCppBuildToolWorkload;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_visual_studio_not_installed)]
-pub struct VisualStudioNotInstalled;
+pub(crate) struct VisualStudioNotInstalled;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_linker_not_found)]
 #[note]
-pub struct LinkerNotFound {
+pub(crate) struct LinkerNotFound {
     pub linker_path: PathBuf,
     pub error: Error,
 }
@@ -406,7 +406,7 @@ pub struct LinkerNotFound {
 #[diag(codegen_ssa_unable_to_exe_linker)]
 #[note]
 #[note(codegen_ssa_command_note)]
-pub struct UnableToExeLinker {
+pub(crate) struct UnableToExeLinker {
     pub linker_path: PathBuf,
     pub error: Error,
     pub command_formatted: String,
@@ -414,38 +414,38 @@ pub struct UnableToExeLinker {
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_msvc_missing_linker)]
-pub struct MsvcMissingLinker;
+pub(crate) struct MsvcMissingLinker;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_self_contained_linker_missing)]
-pub struct SelfContainedLinkerMissing;
+pub(crate) struct SelfContainedLinkerMissing;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_check_installed_visual_studio)]
-pub struct CheckInstalledVisualStudio;
+pub(crate) struct CheckInstalledVisualStudio;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_insufficient_vs_code_product)]
-pub struct InsufficientVSCodeProduct;
+pub(crate) struct InsufficientVSCodeProduct;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_processing_dymutil_failed)]
 #[note]
-pub struct ProcessingDymutilFailed {
+pub(crate) struct ProcessingDymutilFailed {
     pub status: ExitStatus,
     pub output: String,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_unable_to_run_dsymutil)]
-pub struct UnableToRunDsymutil {
+pub(crate) struct UnableToRunDsymutil {
     pub error: Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_stripping_debug_info_failed)]
 #[note]
-pub struct StrippingDebugInfoFailed<'a> {
+pub(crate) struct StrippingDebugInfoFailed<'a> {
     pub util: &'a str,
     pub status: ExitStatus,
     pub output: String,
@@ -453,58 +453,59 @@ pub struct StrippingDebugInfoFailed<'a> {
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_unable_to_run)]
-pub struct UnableToRun<'a> {
+pub(crate) struct UnableToRun<'a> {
     pub util: &'a str,
     pub error: Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_linker_file_stem)]
-pub struct LinkerFileStem;
+pub(crate) struct LinkerFileStem;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_static_library_native_artifacts)]
-pub struct StaticLibraryNativeArtifacts;
+pub(crate) struct StaticLibraryNativeArtifacts;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_static_library_native_artifacts_to_file)]
-pub struct StaticLibraryNativeArtifactsToFile<'a> {
+pub(crate) struct StaticLibraryNativeArtifactsToFile<'a> {
     pub path: &'a Path,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_link_script_unavailable)]
-pub struct LinkScriptUnavailable;
+pub(crate) struct LinkScriptUnavailable;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_link_script_write_failure)]
-pub struct LinkScriptWriteFailure {
+pub(crate) struct LinkScriptWriteFailure {
     pub path: PathBuf,
     pub error: Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_failed_to_write)]
-pub struct FailedToWrite {
+pub(crate) struct FailedToWrite {
     pub path: PathBuf,
     pub error: Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_unable_to_write_debugger_visualizer)]
-pub struct UnableToWriteDebuggerVisualizer {
+pub(crate) struct UnableToWriteDebuggerVisualizer {
     pub path: PathBuf,
     pub error: Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_rlib_archive_build_failure)]
-pub struct RlibArchiveBuildFailure {
+pub(crate) struct RlibArchiveBuildFailure {
     pub path: PathBuf,
     pub error: Error,
 }
 
 #[derive(Diagnostic)]
+// Public for rustc_codegen_llvm::back::archive
 pub enum ExtractBundledLibsError<'a> {
     #[diag(codegen_ssa_extract_bundled_libs_open_file)]
     OpenFile { rlib: &'a Path, error: Box<dyn std::error::Error> },
@@ -533,26 +534,26 @@ pub enum ExtractBundledLibsError<'a> {
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_unsupported_arch)]
-pub struct UnsupportedArch<'a> {
+pub(crate) struct UnsupportedArch<'a> {
     pub arch: &'a str,
     pub os: &'a str,
 }
 
 #[derive(Diagnostic)]
-pub enum AppleSdkRootError<'a> {
+pub(crate) enum AppleSdkRootError<'a> {
     #[diag(codegen_ssa_apple_sdk_error_sdk_path)]
     SdkPath { sdk_name: &'a str, error: Error },
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_read_file)]
-pub struct ReadFileError {
+pub(crate) struct ReadFileError {
     pub message: std::io::Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_unsupported_link_self_contained)]
-pub struct UnsupportedLinkSelfContained;
+pub(crate) struct UnsupportedLinkSelfContained;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_archive_build_failure)]
@@ -571,7 +572,7 @@ pub struct UnknownArchiveKind<'a> {
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_expected_used_symbol)]
-pub struct ExpectedUsedSymbol {
+pub(crate) struct ExpectedUsedSymbol {
     #[primary_span]
     pub span: Span,
 }
@@ -579,45 +580,45 @@ pub struct ExpectedUsedSymbol {
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_multiple_main_functions)]
 #[help]
-pub struct MultipleMainFunctions {
+pub(crate) struct MultipleMainFunctions {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_metadata_object_file_write)]
-pub struct MetadataObjectFileWrite {
+pub(crate) struct MetadataObjectFileWrite {
     pub error: Error,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_invalid_windows_subsystem)]
-pub struct InvalidWindowsSubsystem {
+pub(crate) struct InvalidWindowsSubsystem {
     pub subsystem: Symbol,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_shuffle_indices_evaluation)]
-pub struct ShuffleIndicesEvaluation {
+pub(crate) struct ShuffleIndicesEvaluation {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_missing_memory_ordering)]
-pub struct MissingMemoryOrdering;
+pub(crate) struct MissingMemoryOrdering;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_unknown_atomic_ordering)]
-pub struct UnknownAtomicOrdering;
+pub(crate) struct UnknownAtomicOrdering;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_atomic_compare_exchange)]
-pub struct AtomicCompareExchange;
+pub(crate) struct AtomicCompareExchange;
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_unknown_atomic_operation)]
-pub struct UnknownAtomicOperation;
+pub(crate) struct UnknownAtomicOperation;
 
 #[derive(Diagnostic)]
 pub enum InvalidMonomorphization<'tcx> {
@@ -986,7 +987,7 @@ impl IntoDiagArg for ExpectedPointerMutability {
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_invalid_no_sanitize)]
 #[note]
-pub struct InvalidNoSanitize {
+pub(crate) struct InvalidNoSanitize {
     #[primary_span]
     pub span: Span,
 }
@@ -994,7 +995,7 @@ pub struct InvalidNoSanitize {
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_invalid_link_ordinal_nargs)]
 #[note]
-pub struct InvalidLinkOrdinalNargs {
+pub(crate) struct InvalidLinkOrdinalNargs {
     #[primary_span]
     pub span: Span,
 }
@@ -1002,14 +1003,14 @@ pub struct InvalidLinkOrdinalNargs {
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_illegal_link_ordinal_format)]
 #[note]
-pub struct InvalidLinkOrdinalFormat {
+pub(crate) struct InvalidLinkOrdinalFormat {
     #[primary_span]
     pub span: Span,
 }
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_target_feature_safe_trait)]
-pub struct TargetFeatureSafeTrait {
+pub(crate) struct TargetFeatureSafeTrait {
     #[primary_span]
     #[label]
     pub span: Span,
@@ -1050,7 +1051,7 @@ pub(crate) struct ErrorCallingDllTool<'a> {
 
 #[derive(Diagnostic)]
 #[diag(codegen_ssa_error_creating_remark_dir)]
-pub struct ErrorCreatingRemarkDir {
+pub(crate) struct ErrorCreatingRemarkDir {
     pub error: std::io::Error,
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index c89bfca6687..26d4d0acac5 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -11,6 +11,7 @@
 #![feature(negative_impls)]
 #![feature(rustdoc_internals)]
 #![feature(strict_provenance)]
+#![feature(trait_alias)]
 #![feature(try_blocks)]
 #![warn(unreachable_pub)]
 // tidy-alphabetical-end
@@ -128,7 +129,7 @@ impl CompiledModule {
     }
 }
 
-pub struct CachedModuleCodegen {
+pub(crate) struct CachedModuleCodegen {
     pub name: String,
     pub source: WorkProduct,
 }
diff --git a/compiler/rustc_codegen_ssa/src/meth.rs b/compiler/rustc_codegen_ssa/src/meth.rs
index c9602d9cdae..ecc3b2b24f1 100644
--- a/compiler/rustc_codegen_ssa/src/meth.rs
+++ b/compiler/rustc_codegen_ssa/src/meth.rs
@@ -8,10 +8,10 @@ use tracing::{debug, instrument};
 use crate::traits::*;
 
 #[derive(Copy, Clone, Debug)]
-pub struct VirtualIndex(u64);
+pub(crate) struct VirtualIndex(u64);
 
 impl<'a, 'tcx> VirtualIndex {
-    pub fn from_index(index: usize) -> Self {
+    pub(crate) fn from_index(index: usize) -> Self {
         VirtualIndex(index as u64)
     }
 
@@ -51,7 +51,7 @@ impl<'a, 'tcx> VirtualIndex {
         }
     }
 
-    pub fn get_optional_fn<Bx: BuilderMethods<'a, 'tcx>>(
+    pub(crate) fn get_optional_fn<Bx: BuilderMethods<'a, 'tcx>>(
         self,
         bx: &mut Bx,
         llvtable: Bx::Value,
@@ -61,7 +61,7 @@ impl<'a, 'tcx> VirtualIndex {
         self.get_fn_inner(bx, llvtable, ty, fn_abi, false)
     }
 
-    pub fn get_fn<Bx: BuilderMethods<'a, 'tcx>>(
+    pub(crate) fn get_fn<Bx: BuilderMethods<'a, 'tcx>>(
         self,
         bx: &mut Bx,
         llvtable: Bx::Value,
@@ -71,7 +71,7 @@ impl<'a, 'tcx> VirtualIndex {
         self.get_fn_inner(bx, llvtable, ty, fn_abi, true)
     }
 
-    pub fn get_usize<Bx: BuilderMethods<'a, 'tcx>>(
+    pub(crate) fn get_usize<Bx: BuilderMethods<'a, 'tcx>>(
         self,
         bx: &mut Bx,
         llvtable: Bx::Value,
@@ -115,7 +115,7 @@ fn expect_dyn_trait_in_self(ty: Ty<'_>) -> ty::PolyExistentialTraitRef<'_> {
 /// making an object `Foo<dyn Trait>` from a value of type `Foo<T>`, then
 /// `trait_ref` would map `T: Trait`.
 #[instrument(level = "debug", skip(cx))]
-pub fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
+pub(crate) fn get_vtable<'tcx, Cx: CodegenMethods<'tcx>>(
     cx: &Cx,
     ty: Ty<'tcx>,
     trait_ref: Option<ty::PolyExistentialTraitRef<'tcx>>,
diff --git a/compiler/rustc_codegen_ssa/src/mir/analyze.rs b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
index 386e1f91e7f..f13c46e8bef 100644
--- a/compiler/rustc_codegen_ssa/src/mir/analyze.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/analyze.rs
@@ -69,13 +69,13 @@ enum LocalKind {
     SSA(DefLocation),
 }
 
-struct LocalAnalyzer<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> {
-    fx: &'mir FunctionCx<'a, 'tcx, Bx>,
-    dominators: &'mir Dominators<mir::BasicBlock>,
+struct LocalAnalyzer<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> {
+    fx: &'a FunctionCx<'b, 'tcx, Bx>,
+    dominators: &'a Dominators<mir::BasicBlock>,
     locals: IndexVec<mir::Local, LocalKind>,
 }
 
-impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx, Bx> {
+impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> LocalAnalyzer<'a, 'b, 'tcx, Bx> {
     fn define(&mut self, local: mir::Local, location: DefLocation) {
         let kind = &mut self.locals[local];
         match *kind {
@@ -152,9 +152,7 @@ impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> LocalAnalyzer<'mir, 'a, 'tcx,
     }
 }
 
-impl<'mir, 'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> Visitor<'tcx>
-    for LocalAnalyzer<'mir, 'a, 'tcx, Bx>
-{
+impl<'a, 'b, 'tcx, Bx: BuilderMethods<'b, 'tcx>> Visitor<'tcx> for LocalAnalyzer<'a, 'b, 'tcx, Bx> {
     fn visit_assign(
         &mut self,
         place: &mir::Place<'tcx>,
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index 8f96c462240..f23ae7abafd 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -996,7 +996,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         // To get a `*mut RcBox<Self>`, we just keep unwrapping newtypes until
                         // we get a value of a built-in pointer type.
                         //
-                        // This is also relevant for `Pin<&mut Self>`, where we need to peel the `Pin`.
+                        // This is also relevant for `Pin<&mut Self>`, where we need to peel the
+                        // `Pin`.
                         while !op.layout.ty.is_unsafe_ptr() && !op.layout.ty.is_ref() {
                             let (idx, _) = op.layout.non_1zst_field(bx).expect(
                                 "not exactly one non-1-ZST field in a `DispatchFromDyn` type",
@@ -1004,9 +1005,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             op = op.extract_field(bx, idx);
                         }
 
-                        // now that we have `*dyn Trait` or `&dyn Trait`, split it up into its
+                        // Now that we have `*dyn Trait` or `&dyn Trait`, split it up into its
                         // data pointer and vtable. Look up the method in the vtable, and pass
-                        // the data pointer as the first argument
+                        // the data pointer as the first argument.
                         llfn = Some(meth::VirtualIndex::from_index(idx).get_fn(
                             bx,
                             meta,
@@ -1212,10 +1213,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             mergeable_succ,
         )
     }
-}
 
-impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
-    pub fn codegen_block(&mut self, mut bb: mir::BasicBlock) {
+    pub(crate) fn codegen_block(&mut self, mut bb: mir::BasicBlock) {
         let llbb = match self.try_llbb(bb) {
             Some(llbb) => llbb,
             None => return,
@@ -1255,7 +1254,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
     }
 
-    pub fn codegen_block_as_unreachable(&mut self, bb: mir::BasicBlock) {
+    pub(crate) fn codegen_block_as_unreachable(&mut self, bb: mir::BasicBlock) {
         let llbb = match self.try_llbb(bb) {
             Some(llbb) => llbb,
             None => return,
@@ -1440,8 +1439,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let (mut llval, align, by_ref) = match op.val {
             Immediate(_) | Pair(..) => match arg.mode {
                 PassMode::Indirect { attrs, .. } => {
-                    // Indirect argument may have higher alignment requirements than the type's alignment.
-                    // This can happen, e.g. when passing types with <4 byte alignment on the stack on x86.
+                    // Indirect argument may have higher alignment requirements than the type's
+                    // alignment. This can happen, e.g. when passing types with <4 byte alignment
+                    // on the stack on x86.
                     let required_align = match attrs.pointee_align {
                         Some(pointee_align) => cmp::max(pointee_align, arg.layout.align.abi),
                         None => arg.layout.align.abi,
@@ -1740,7 +1740,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     }
 
     /// Like `llbb`, but may fail if the basic block should be skipped.
-    pub fn try_llbb(&mut self, bb: mir::BasicBlock) -> Option<Bx::BasicBlock> {
+    pub(crate) fn try_llbb(&mut self, bb: mir::BasicBlock) -> Option<Bx::BasicBlock> {
         match self.cached_llbbs[bb] {
             CachedLlbb::None => {
                 let llbb = Bx::append_block(self.cx, self.llfn, &format!("{bb:?}"));
diff --git a/compiler/rustc_codegen_ssa/src/mir/constant.rs b/compiler/rustc_codegen_ssa/src/mir/constant.rs
index 8254fb3d866..15f45b226f5 100644
--- a/compiler/rustc_codegen_ssa/src/mir/constant.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/constant.rs
@@ -10,7 +10,7 @@ use crate::mir::operand::OperandRef;
 use crate::traits::*;
 
 impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
-    pub fn eval_mir_constant_to_operand(
+    pub(crate) fn eval_mir_constant_to_operand(
         &self,
         bx: &mut Bx,
         constant: &mir::ConstOperand<'tcx>,
@@ -32,27 +32,28 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     /// that the given `constant` is an `Const::Unevaluated` and must be convertible to
     /// a `ValTree`. If you want a more general version of this, talk to `wg-const-eval` on zulip.
     ///
-    /// Note that this function is cursed, since usually MIR consts should not be evaluated to valtrees!
-    pub fn eval_unevaluated_mir_constant_to_valtree(
+    /// Note that this function is cursed, since usually MIR consts should not be evaluated to
+    /// valtrees!
+    fn eval_unevaluated_mir_constant_to_valtree(
         &self,
         constant: &mir::ConstOperand<'tcx>,
     ) -> Result<Result<ty::ValTree<'tcx>, Ty<'tcx>>, ErrorHandled> {
         let uv = match self.monomorphize(constant.const_) {
             mir::Const::Unevaluated(uv, _) => uv.shrink(),
             mir::Const::Ty(_, c) => match c.kind() {
-                // A constant that came from a const generic but was then used as an argument to old-style
-                // simd_shuffle (passing as argument instead of as a generic param).
+                // A constant that came from a const generic but was then used as an argument to
+                // old-style simd_shuffle (passing as argument instead of as a generic param).
                 rustc_type_ir::ConstKind::Value(_, valtree) => return Ok(Ok(valtree)),
                 other => span_bug!(constant.span, "{other:#?}"),
             },
             // We should never encounter `Const::Val` unless MIR opts (like const prop) evaluate
-            // a constant and write that value back into `Operand`s. This could happen, but is unlikely.
-            // Also: all users of `simd_shuffle` are on unstable and already need to take a lot of care
-            // around intrinsics. For an issue to happen here, it would require a macro expanding to a
-            // `simd_shuffle` call without wrapping the constant argument in a `const {}` block, but
-            // the user pass through arbitrary expressions.
-            // FIXME(oli-obk): replace the magic const generic argument of `simd_shuffle` with a real
-            // const generic, and get rid of this entire function.
+            // a constant and write that value back into `Operand`s. This could happen, but is
+            // unlikely. Also: all users of `simd_shuffle` are on unstable and already need to take
+            // a lot of care around intrinsics. For an issue to happen here, it would require a
+            // macro expanding to a `simd_shuffle` call without wrapping the constant argument in a
+            // `const {}` block, but the user pass through arbitrary expressions.
+            // FIXME(oli-obk): replace the magic const generic argument of `simd_shuffle` with a
+            // real const generic, and get rid of this entire function.
             other => span_bug!(constant.span, "{other:#?}"),
         };
         let uv = self.monomorphize(uv);
diff --git a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs
index 67f1ef5d944..52e749f4fb7 100644
--- a/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/coverageinfo.rs
@@ -5,7 +5,7 @@ use super::FunctionCx;
 use crate::traits::*;
 
 impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
-    pub fn codegen_coverage(&self, bx: &mut Bx, kind: &CoverageKind, scope: SourceScope) {
+    pub(crate) fn codegen_coverage(&self, bx: &mut Bx, kind: &CoverageKind, scope: SourceScope) {
         // Determine the instance that coverage data was originally generated for.
         let instance = if let Some(inlined) = scope.inlined_instance(&self.mir.source_scopes) {
             self.monomorphize(inlined)
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index ab08ef72a69..5b36a11aa25 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -24,6 +24,7 @@ pub struct FunctionDebugContext<'tcx, S, L> {
     /// Maps from an inlined function to its debug info declaration.
     pub inlined_function_scopes: FxHashMap<Instance<'tcx>, S>,
 }
+
 #[derive(Copy, Clone)]
 pub enum VariableKind {
     ArgumentVariable(usize /*index*/),
@@ -243,7 +244,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
     /// Apply debuginfo and/or name, after creating the `alloca` for a local,
     /// or initializing the local with an operand (whichever applies).
-    pub fn debug_introduce_local(&self, bx: &mut Bx, local: mir::Local) {
+    pub(crate) fn debug_introduce_local(&self, bx: &mut Bx, local: mir::Local) {
         let full_debug_info = bx.sess().opts.debuginfo == DebugInfo::Full;
 
         let vars = match &self.per_local_var_debug_info {
@@ -426,7 +427,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
     }
 
-    pub fn debug_introduce_locals(&self, bx: &mut Bx) {
+    pub(crate) fn debug_introduce_locals(&self, bx: &mut Bx) {
         if bx.sess().opts.debuginfo == DebugInfo::Full || !bx.sess().fewer_names() {
             for local in self.locals.indices() {
                 self.debug_introduce_local(bx, local);
@@ -435,7 +436,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     }
 
     /// Partition all `VarDebugInfo` in `self.mir`, by their base `Local`.
-    pub fn compute_per_local_var_debug_info(
+    pub(crate) fn compute_per_local_var_debug_info(
         &self,
         bx: &mut Bx,
     ) -> Option<IndexVec<mir::Local, Vec<PerLocalVarDebugInfo<'tcx, Bx::DIVariable>>>> {
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index de94d87bcea..61e9b9bd774 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -15,8 +15,8 @@ use crate::traits::*;
 
 mod analyze;
 mod block;
-pub mod constant;
-pub mod coverageinfo;
+mod constant;
+mod coverageinfo;
 pub mod debuginfo;
 mod intrinsic;
 mod locals;
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 1891de8c0eb..ee32b4f23c9 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -27,32 +27,32 @@ pub enum OperandValue<V> {
     /// which indicates that it refers to an unsized rvalue.
     ///
     /// An `OperandValue` *must* be this variant for any type for which
-    /// [`LayoutTypeMethods::is_backend_ref`] returns `true`.
+    /// [`LayoutTypeCodegenMethods::is_backend_ref`] returns `true`.
     /// (That basically amounts to "isn't one of the other variants".)
     ///
     /// This holds a [`PlaceValue`] (like a [`PlaceRef`] does) with a pointer
     /// to the location holding the value. The type behind that pointer is the
-    /// one returned by [`LayoutTypeMethods::backend_type`].
+    /// one returned by [`LayoutTypeCodegenMethods::backend_type`].
     Ref(PlaceValue<V>),
     /// A single LLVM immediate value.
     ///
     /// An `OperandValue` *must* be this variant for any type for which
-    /// [`LayoutTypeMethods::is_backend_immediate`] returns `true`.
+    /// [`LayoutTypeCodegenMethods::is_backend_immediate`] returns `true`.
     /// The backend value in this variant must be the *immediate* backend type,
-    /// as returned by [`LayoutTypeMethods::immediate_backend_type`].
+    /// as returned by [`LayoutTypeCodegenMethods::immediate_backend_type`].
     Immediate(V),
     /// A pair of immediate LLVM values. Used by fat pointers too.
     ///
     /// An `OperandValue` *must* be this variant for any type for which
-    /// [`LayoutTypeMethods::is_backend_scalar_pair`] returns `true`.
+    /// [`LayoutTypeCodegenMethods::is_backend_scalar_pair`] returns `true`.
     /// The backend values in this variant must be the *immediate* backend types,
-    /// as returned by [`LayoutTypeMethods::scalar_pair_element_backend_type`]
+    /// as returned by [`LayoutTypeCodegenMethods::scalar_pair_element_backend_type`]
     /// with `immediate: true`.
     Pair(V, V),
     /// A value taking no bytes, and which therefore needs no LLVM value at all.
     ///
     /// If you ever need a `V` to pass to something, get a fresh poison value
-    /// from [`ConstMethods::const_poison`].
+    /// from [`ConstCodegenMethods::const_poison`].
     ///
     /// An `OperandValue` *must* be this variant for any type for which
     /// `is_zst` on its `Layout` returns `true`. Note however that
@@ -64,7 +64,7 @@ impl<V: CodegenObject> OperandValue<V> {
     /// If this is ZeroSized/Immediate/Pair, return an array of the 0/1/2 values.
     /// If this is Ref, return the place.
     #[inline]
-    pub fn immediates_or_place(self) -> Either<ArrayVec<V, 2>, PlaceValue<V>> {
+    pub(crate) fn immediates_or_place(self) -> Either<ArrayVec<V, 2>, PlaceValue<V>> {
         match self {
             OperandValue::ZeroSized => Either::Left(ArrayVec::new()),
             OperandValue::Immediate(a) => Either::Left(ArrayVec::from_iter([a])),
@@ -75,7 +75,7 @@ impl<V: CodegenObject> OperandValue<V> {
 
     /// Given an array of 0/1/2 immediate values, return ZeroSized/Immediate/Pair.
     #[inline]
-    pub fn from_immediates(immediates: ArrayVec<V, 2>) -> Self {
+    pub(crate) fn from_immediates(immediates: ArrayVec<V, 2>) -> Self {
         let mut it = immediates.into_iter();
         let Some(a) = it.next() else {
             return OperandValue::ZeroSized;
@@ -90,7 +90,7 @@ impl<V: CodegenObject> OperandValue<V> {
     /// optional metadata as backend values.
     ///
     /// If you're making a place, use [`Self::deref`] instead.
-    pub fn pointer_parts(self) -> (V, Option<V>) {
+    pub(crate) fn pointer_parts(self) -> (V, Option<V>) {
         match self {
             OperandValue::Immediate(llptr) => (llptr, None),
             OperandValue::Pair(llptr, llextra) => (llptr, Some(llextra)),
@@ -105,12 +105,12 @@ impl<V: CodegenObject> OperandValue<V> {
     /// alignment, then maybe you want [`OperandRef::deref`] instead.
     ///
     /// This is the inverse of [`PlaceValue::address`].
-    pub fn deref(self, align: Align) -> PlaceValue<V> {
+    pub(crate) fn deref(self, align: Align) -> PlaceValue<V> {
         let (llval, llextra) = self.pointer_parts();
         PlaceValue { llval, llextra, align }
     }
 
-    pub(crate) fn is_expected_variant_for_type<'tcx, Cx: LayoutTypeMethods<'tcx>>(
+    pub(crate) fn is_expected_variant_for_type<'tcx, Cx: LayoutTypeCodegenMethods<'tcx>>(
         &self,
         cx: &Cx,
         ty: TyAndLayout<'tcx>,
@@ -153,7 +153,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
         OperandRef { val: OperandValue::ZeroSized, layout }
     }
 
-    pub fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
+    pub(crate) fn from_const<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         bx: &mut Bx,
         val: mir::ConstValue<'tcx>,
         ty: Ty<'tcx>,
@@ -280,7 +280,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
     ///
     /// If you don't need the type, see [`OperandValue::pointer_parts`]
     /// or [`OperandValue::deref`].
-    pub fn deref<Cx: LayoutTypeMethods<'tcx>>(self, cx: &Cx) -> PlaceRef<'tcx, V> {
+    pub fn deref<Cx: CodegenMethods<'tcx>>(self, cx: &Cx) -> PlaceRef<'tcx, V> {
         if self.layout.ty.is_box() {
             // Derefer should have removed all Box derefs
             bug!("dereferencing {:?} in codegen", self.layout.ty);
@@ -334,7 +334,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
         OperandRef { val, layout }
     }
 
-    pub fn extract_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
+    pub(crate) fn extract_field<Bx: BuilderMethods<'a, 'tcx, Value = V>>(
         &self,
         bx: &mut Bx,
         i: usize,
@@ -478,8 +478,8 @@ impl<'a, 'tcx, V: CodegenObject> OperandValue<V> {
         debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest);
         match self {
             OperandValue::ZeroSized => {
-                // Avoid generating stores of zero-sized values, because the only way to have a zero-sized
-                // value is through `undef`/`poison`, and the store itself is useless.
+                // Avoid generating stores of zero-sized values, because the only way to have a
+                // zero-sized value is through `undef`/`poison`, and the store itself is useless.
             }
             OperandValue::Ref(val) => {
                 assert!(dest.layout.is_sized(), "cannot directly store unsized values");
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index 0fad4d169ed..eba150c6eac 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -133,7 +133,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         Self::alloca(bx, ptr_layout)
     }
 
-    pub fn len<Cx: ConstMethods<'tcx, Value = V>>(&self, cx: &Cx) -> V {
+    pub fn len<Cx: ConstCodegenMethods<'tcx, Value = V>>(&self, cx: &Cx) -> V {
         if let FieldsShape::Array { count, .. } = self.layout.fields {
             if self.layout.is_unsized() {
                 assert_eq!(count, 0);
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 91fd9905f63..6bf75293fce 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -19,7 +19,7 @@ use crate::{base, MemFlags};
 
 impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     #[instrument(level = "trace", skip(self, bx))]
-    pub fn codegen_rvalue(
+    pub(crate) fn codegen_rvalue(
         &mut self,
         bx: &mut Bx,
         dest: PlaceRef<'tcx, Bx::Value>,
@@ -114,7 +114,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
                 let count = self
                     .monomorphize(count)
-                    .eval_target_usize(bx.cx().tcx(), ty::ParamEnv::reveal_all());
+                    .try_to_target_usize(bx.tcx())
+                    .expect("expected monomorphic const in codegen");
 
                 bx.write_operand_repeatedly(cg_elem, count, dest);
             }
@@ -419,7 +420,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
     }
 
-    pub fn codegen_rvalue_unsized(
+    pub(crate) fn codegen_rvalue_unsized(
         &mut self,
         bx: &mut Bx,
         indirect_dest: PlaceRef<'tcx, Bx::Value>,
@@ -440,7 +441,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
     }
 
-    pub fn codegen_rvalue_operand(
+    pub(crate) fn codegen_rvalue_operand(
         &mut self,
         bx: &mut Bx,
         rvalue: &mir::Rvalue<'tcx>,
@@ -803,7 +804,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         if let Some(index) = place.as_local() {
             if let LocalRef::Operand(op) = self.locals[index] {
                 if let ty::Array(_, n) = op.layout.ty.kind() {
-                    let n = n.eval_target_usize(bx.cx().tcx(), ty::ParamEnv::reveal_all());
+                    let n = n
+                        .try_to_target_usize(bx.tcx())
+                        .expect("expected monomorphic const in codegen");
                     return bx.cx().const_usize(n);
                 }
             }
@@ -836,7 +839,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         OperandRef { val, layout: self.cx.layout_of(mk_ptr_ty(self.cx.tcx(), ty)) }
     }
 
-    pub fn codegen_scalar_binop(
+    fn codegen_scalar_binop(
         &mut self,
         bx: &mut Bx,
         op: mir::BinOp,
@@ -981,7 +984,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
     }
 
-    pub fn codegen_fat_ptr_binop(
+    fn codegen_fat_ptr_binop(
         &mut self,
         bx: &mut Bx,
         op: mir::BinOp,
@@ -1023,7 +1026,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         }
     }
 
-    pub fn codegen_scalar_checked_binop(
+    fn codegen_scalar_checked_binop(
         &mut self,
         bx: &mut Bx,
         op: mir::BinOp,
@@ -1047,10 +1050,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         OperandValue::Pair(val, of)
     }
-}
 
-impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
-    pub fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) -> bool {
+    pub(crate) fn rvalue_creates_operand(&self, rvalue: &mir::Rvalue<'tcx>, span: Span) -> bool {
         match *rvalue {
             mir::Rvalue::Cast(mir::CastKind::Transmute, ref operand, cast_ty) => {
                 let operand_ty = operand.ty(self.mir, self.cx.tcx());
diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs
index 73283cafb49..6338d16c897 100644
--- a/compiler/rustc_codegen_ssa/src/mir/statement.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs
@@ -7,7 +7,7 @@ use crate::traits::*;
 
 impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
     #[instrument(level = "debug", skip(self, bx))]
-    pub fn codegen_statement(&mut self, bx: &mut Bx, statement: &mir::Statement<'tcx>) {
+    pub(crate) fn codegen_statement(&mut self, bx: &mut Bx, statement: &mir::Statement<'tcx>) {
         self.set_debug_loc(bx, statement.source_info);
         match statement.kind {
             mir::StatementKind::Assign(box (ref place, ref rvalue)) => {
diff --git a/compiler/rustc_codegen_ssa/src/size_of_val.rs b/compiler/rustc_codegen_ssa/src/size_of_val.rs
index 933904f9845..3f3ae21035d 100644
--- a/compiler/rustc_codegen_ssa/src/size_of_val.rs
+++ b/compiler/rustc_codegen_ssa/src/size_of_val.rs
@@ -45,11 +45,13 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             // The info in this case is the length of the str, so the size is that
             // times the unit size.
             (
-                // All slice sizes must fit into `isize`, so this multiplication cannot (signed) wrap.
+                // All slice sizes must fit into `isize`, so this multiplication cannot (signed)
+                // wrap.
                 // NOTE: ideally, we want the effects of both `unchecked_smul` and `unchecked_umul`
                 // (resulting in `mul nsw nuw` in LLVM IR), since we know that the multiplication
-                // cannot signed wrap, and that both operands are non-negative. But at the time of writing,
-                // the `LLVM-C` binding can't do this, and it doesn't seem to enable any further optimizations.
+                // cannot signed wrap, and that both operands are non-negative. But at the time of
+                // writing, the `LLVM-C` binding can't do this, and it doesn't seem to enable any
+                // further optimizations.
                 bx.unchecked_smul(info.unwrap(), bx.const_usize(unit.size.bytes())),
                 bx.const_usize(unit.align.abi.bytes()),
             )
@@ -67,9 +69,9 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             let (fn_abi, llfn, _instance) =
                 common::build_langcall(bx, None, LangItem::PanicNounwind);
 
-            // Generate the call.
-            // Cannot use `do_call` since we don't have a MIR terminator so we can't create a `TerminationCodegenHelper`.
-            // (But we are in good company, this code is duplicated plenty of times.)
+            // Generate the call. Cannot use `do_call` since we don't have a MIR terminator so we
+            // can't create a `TerminationCodegenHelper`. (But we are in good company, this code is
+            // duplicated plenty of times.)
             let fn_ty = bx.fn_decl_backend_type(fn_abi);
 
             bx.call(
@@ -148,9 +150,14 @@ pub fn size_and_align_of_dst<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             // The full formula for the size would be:
             // let unsized_offset_adjusted = unsized_offset_unadjusted.align_to(unsized_align);
             // let full_size = (unsized_offset_adjusted + unsized_size).align_to(full_align);
-            // However, `unsized_size` is a multiple of `unsized_align`.
-            // Therefore, we can equivalently do the `align_to(unsized_align)` *after* adding `unsized_size`:
-            // let full_size = (unsized_offset_unadjusted + unsized_size).align_to(unsized_align).align_to(full_align);
+            // However, `unsized_size` is a multiple of `unsized_align`. Therefore, we can
+            // equivalently do the `align_to(unsized_align)` *after* adding `unsized_size`:
+            //
+            // let full_size =
+            //     (unsized_offset_unadjusted + unsized_size)
+            //     .align_to(unsized_align)
+            //     .align_to(full_align);
+            //
             // Furthermore, `align >= unsized_align`, and therefore we only need to do:
             // let full_size = (unsized_offset_unadjusted + unsized_size).align_to(full_align);
 
diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs
index cf8f7fa25d8..0349d5817b4 100644
--- a/compiler/rustc_codegen_ssa/src/target_features.rs
+++ b/compiler/rustc_codegen_ssa/src/target_features.rs
@@ -15,7 +15,7 @@ use rustc_span::Span;
 
 use crate::errors;
 
-pub fn from_target_feature(
+pub(crate) fn from_target_feature(
     tcx: TyCtxt<'_>,
     attr: &ast::Attribute,
     supported_target_features: &UnordMap<String, Option<Symbol>>,
@@ -146,7 +146,7 @@ fn asm_target_features(tcx: TyCtxt<'_>, did: DefId) -> &FxIndexSet<Symbol> {
 
 /// Checks the function annotated with `#[target_feature]` is not a safe
 /// trait method implementation, reporting an error if it is.
-pub fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_span: Span) {
+pub(crate) fn check_target_feature_trait_unsafe(tcx: TyCtxt<'_>, id: LocalDefId, attr_span: Span) {
     if let DefKind::AssocFn = tcx.def_kind(id) {
         let parent_id = tcx.local_parent(id);
         if let DefKind::Trait | DefKind::Impl { of_trait: true } = tcx.def_kind(parent_id) {
diff --git a/compiler/rustc_codegen_ssa/src/traits/asm.rs b/compiler/rustc_codegen_ssa/src/traits/asm.rs
index 162141a106b..f4853da1156 100644
--- a/compiler/rustc_codegen_ssa/src/traits/asm.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/asm.rs
@@ -60,7 +60,7 @@ pub trait AsmBuilderMethods<'tcx>: BackendTypes {
     );
 }
 
-pub trait AsmMethods<'tcx> {
+pub trait AsmCodegenMethods<'tcx> {
     fn codegen_global_asm(
         &self,
         template: &[InlineAsmTemplatePiece],
diff --git a/compiler/rustc_codegen_ssa/src/traits/backend.rs b/compiler/rustc_codegen_ssa/src/traits/backend.rs
index c5e2d55be83..e45af1cd153 100644
--- a/compiler/rustc_codegen_ssa/src/traits/backend.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/backend.rs
@@ -8,13 +8,11 @@ use rustc_errors::ErrorGuaranteed;
 use rustc_metadata::creader::MetadataLoaderDyn;
 use rustc_metadata::EncodedMetadata;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
-use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf, TyAndLayout};
-use rustc_middle::ty::{Ty, TyCtxt};
+use rustc_middle::ty::TyCtxt;
 use rustc_middle::util::Providers;
 use rustc_session::config::{self, OutputFilenames, PrintRequest};
 use rustc_session::Session;
 use rustc_span::symbol::Symbol;
-use rustc_target::abi::call::FnAbi;
 
 use super::write::WriteBackendMethods;
 use super::CodegenObject;
@@ -36,34 +34,21 @@ pub trait BackendTypes {
     type DIVariable: Copy;
 }
 
-pub trait Backend<'tcx>:
-    Sized
-    + BackendTypes
-    + HasTyCtxt<'tcx>
-    + LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
-    + FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>>
-{
-}
-
-impl<'tcx, T> Backend<'tcx> for T where
-    Self: BackendTypes
-        + HasTyCtxt<'tcx>
-        + LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
-        + FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>>
-{
-}
-
 pub trait CodegenBackend {
     /// Locale resources for diagnostic messages - a string the content of the Fluent resource.
     /// Called before `init` so that all other functions are able to emit translatable diagnostics.
     fn locale_resource(&self) -> &'static str;
 
     fn init(&self, _sess: &Session) {}
+
     fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {}
+
     fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> {
         vec![]
     }
+
     fn print_passes(&self) {}
+
     fn print_version(&self) {}
 
     /// The metadata loader used to load rlib and dylib metadata.
@@ -75,6 +60,7 @@ pub trait CodegenBackend {
     }
 
     fn provide(&self, _providers: &mut Providers) {}
+
     fn codegen_crate<'tcx>(
         &self,
         tcx: TyCtxt<'tcx>,
@@ -120,6 +106,7 @@ pub trait ExtraBackendMethods:
         kind: AllocatorKind,
         alloc_error_handler_kind: AllocatorKind,
     ) -> Self::Module;
+
     /// This generates the codegen unit and returns it along with
     /// a `u64` giving an estimate of the unit's processing cost.
     fn compile_codegen_unit(
@@ -127,6 +114,7 @@ pub trait ExtraBackendMethods:
         tcx: TyCtxt<'_>,
         cgu_name: Symbol,
     ) -> (ModuleCodegen<Self::Module>, u64);
+
     fn target_machine_factory(
         &self,
         sess: &Session,
diff --git a/compiler/rustc_codegen_ssa/src/traits/builder.rs b/compiler/rustc_codegen_ssa/src/traits/builder.rs
index 6cf84a012f0..5af0457bebd 100644
--- a/compiler/rustc_codegen_ssa/src/traits/builder.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/builder.rs
@@ -1,23 +1,23 @@
 use std::assert_matches::assert_matches;
+use std::ops::Deref;
 
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrs;
-use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout};
+use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{Instance, Ty};
 use rustc_session::config::OptLevel;
 use rustc_span::Span;
 use rustc_target::abi::call::FnAbi;
 use rustc_target::abi::{Abi, Align, Scalar, Size, WrappingRange};
-use rustc_target::spec::HasTargetSpec;
 
 use super::abi::AbiBuilderMethods;
 use super::asm::AsmBuilderMethods;
-use super::consts::ConstMethods;
+use super::consts::ConstCodegenMethods;
 use super::coverageinfo::CoverageInfoBuilderMethods;
 use super::debuginfo::DebugInfoBuilderMethods;
-use super::intrinsic::IntrinsicCallMethods;
-use super::misc::MiscMethods;
-use super::type_::{ArgAbiMethods, BaseTypeMethods, LayoutTypeMethods};
-use super::{HasCodegen, StaticBuilderMethods};
+use super::intrinsic::IntrinsicCallBuilderMethods;
+use super::misc::MiscCodegenMethods;
+use super::type_::{ArgAbiBuilderMethods, BaseTypeCodegenMethods, LayoutTypeCodegenMethods};
+use super::{CodegenMethods, StaticBuilderMethods};
 use crate::common::{
     AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind,
 };
@@ -33,17 +33,33 @@ pub enum OverflowOp {
 }
 
 pub trait BuilderMethods<'a, 'tcx>:
-    HasCodegen<'tcx>
+    Sized
+    + LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
+    + FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>>
+    + Deref<Target = Self::CodegenCx>
     + CoverageInfoBuilderMethods<'tcx>
     + DebugInfoBuilderMethods
-    + ArgAbiMethods<'tcx>
+    + ArgAbiBuilderMethods<'tcx>
     + AbiBuilderMethods<'tcx>
-    + IntrinsicCallMethods<'tcx>
+    + IntrinsicCallBuilderMethods<'tcx>
     + AsmBuilderMethods<'tcx>
     + StaticBuilderMethods
-    + HasParamEnv<'tcx>
-    + HasTargetSpec
 {
+    // `BackendTypes` is a supertrait of both `CodegenMethods` and
+    // `BuilderMethods`. This bound ensures all impls agree on the associated
+    // types within.
+    type CodegenCx: CodegenMethods<
+            'tcx,
+            Value = Self::Value,
+            Function = Self::Function,
+            BasicBlock = Self::BasicBlock,
+            Type = Self::Type,
+            Funclet = Self::Funclet,
+            DIScope = Self::DIScope,
+            DILocation = Self::DILocation,
+            DIVariable = Self::DIVariable,
+        >;
+
     fn build(cx: &'a Self::CodegenCx, llbb: Self::BasicBlock) -> Self;
 
     fn cx(&self) -> &Self::CodegenCx;
diff --git a/compiler/rustc_codegen_ssa/src/traits/consts.rs b/compiler/rustc_codegen_ssa/src/traits/consts.rs
index c15f1fa8e56..9af463a691a 100644
--- a/compiler/rustc_codegen_ssa/src/traits/consts.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/consts.rs
@@ -3,7 +3,7 @@ use rustc_target::abi;
 
 use super::BackendTypes;
 
-pub trait ConstMethods<'tcx>: BackendTypes {
+pub trait ConstCodegenMethods<'tcx>: BackendTypes {
     // Constant constructors
     fn const_null(&self, t: Self::Type) -> Self::Value;
     /// Generate an uninitialized value (matching uninitialized memory in MIR).
@@ -14,18 +14,20 @@ pub trait ConstMethods<'tcx>: BackendTypes {
     /// (including code that e.g. copies uninit memory with `MaybeUninit`) can never encounter a
     /// poison value.
     fn const_poison(&self, t: Self::Type) -> Self::Value;
-    fn const_int(&self, t: Self::Type, i: i64) -> Self::Value;
-    fn const_uint(&self, t: Self::Type, i: u64) -> Self::Value;
-    fn const_uint_big(&self, t: Self::Type, u: u128) -> Self::Value;
+
     fn const_bool(&self, val: bool) -> Self::Value;
+
+    fn const_i8(&self, i: i8) -> Self::Value;
     fn const_i16(&self, i: i16) -> Self::Value;
     fn const_i32(&self, i: i32) -> Self::Value;
-    fn const_i8(&self, i: i8) -> Self::Value;
+    fn const_int(&self, t: Self::Type, i: i64) -> Self::Value;
+    fn const_u8(&self, i: u8) -> Self::Value;
     fn const_u32(&self, i: u32) -> Self::Value;
     fn const_u64(&self, i: u64) -> Self::Value;
     fn const_u128(&self, i: u128) -> Self::Value;
     fn const_usize(&self, i: u64) -> Self::Value;
-    fn const_u8(&self, i: u8) -> Self::Value;
+    fn const_uint(&self, t: Self::Type, i: u64) -> Self::Value;
+    fn const_uint_big(&self, t: Self::Type, u: u128) -> Self::Value;
     fn const_real(&self, t: Self::Type, val: f64) -> Self::Value;
 
     fn const_str(&self, s: &str) -> (Self::Value, Self::Value);
diff --git a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs
index 0b1645c66ed..0b513dac503 100644
--- a/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/coverageinfo.rs
@@ -1,9 +1,7 @@
 use rustc_middle::mir::coverage::CoverageKind;
 use rustc_middle::ty::Instance;
 
-use super::BackendTypes;
-
-pub trait CoverageInfoBuilderMethods<'tcx>: BackendTypes {
+pub trait CoverageInfoBuilderMethods<'tcx> {
     /// Performs any start-of-function codegen needed for coverage instrumentation.
     ///
     /// Can be a no-op in backends that don't support coverage instrumentation.
diff --git a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
index 5fbe97214fb..7526c221b05 100644
--- a/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/debuginfo.rs
@@ -9,7 +9,7 @@ use rustc_target::abi::Size;
 use super::BackendTypes;
 use crate::mir::debuginfo::{FunctionDebugContext, VariableKind};
 
-pub trait DebugInfoMethods<'tcx>: BackendTypes {
+pub trait DebugInfoCodegenMethods<'tcx>: BackendTypes {
     fn create_vtable_debuginfo(
         &self,
         ty: Ty<'tcx>,
diff --git a/compiler/rustc_codegen_ssa/src/traits/declare.rs b/compiler/rustc_codegen_ssa/src/traits/declare.rs
index 792d2b04ed6..c1edeac31b0 100644
--- a/compiler/rustc_codegen_ssa/src/traits/declare.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/declare.rs
@@ -2,9 +2,7 @@ use rustc_hir::def_id::DefId;
 use rustc_middle::mir::mono::{Linkage, Visibility};
 use rustc_middle::ty::Instance;
 
-use super::BackendTypes;
-
-pub trait PreDefineMethods<'tcx>: BackendTypes {
+pub trait PreDefineCodegenMethods<'tcx> {
     fn predefine_static(
         &self,
         def_id: DefId,
diff --git a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
index 172004a9cc7..e721cfb7134 100644
--- a/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/intrinsic.rs
@@ -5,7 +5,7 @@ use rustc_target::abi::call::FnAbi;
 use super::BackendTypes;
 use crate::mir::operand::OperandRef;
 
-pub trait IntrinsicCallMethods<'tcx>: BackendTypes {
+pub trait IntrinsicCallBuilderMethods<'tcx>: BackendTypes {
     /// Remember to add all intrinsics here, in `compiler/rustc_hir_analysis/src/check/mod.rs`,
     /// and in `library/core/src/intrinsics.rs`; if you need access to any LLVM intrinsics,
     /// add them to `compiler/rustc_codegen_llvm/src/context.rs`.
diff --git a/compiler/rustc_codegen_ssa/src/traits/misc.rs b/compiler/rustc_codegen_ssa/src/traits/misc.rs
index 40a49b3e1b5..5b33fd7ab10 100644
--- a/compiler/rustc_codegen_ssa/src/traits/misc.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/misc.rs
@@ -7,7 +7,7 @@ use rustc_session::Session;
 
 use super::BackendTypes;
 
-pub trait MiscMethods<'tcx>: BackendTypes {
+pub trait MiscCodegenMethods<'tcx>: BackendTypes {
     fn vtables(
         &self,
     ) -> &RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), Self::Value>>;
@@ -25,6 +25,7 @@ pub trait MiscMethods<'tcx>: BackendTypes {
     fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx>;
     fn set_frame_pointer_type(&self, llfn: Self::Function);
     fn apply_target_cpu_attr(&self, llfn: Self::Function);
-    /// Declares the extern "C" main function for the entry point. Returns None if the symbol already exists.
+    /// Declares the extern "C" main function for the entry point. Returns None if the symbol
+    /// already exists.
     fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function>;
 }
diff --git a/compiler/rustc_codegen_ssa/src/traits/mod.rs b/compiler/rustc_codegen_ssa/src/traits/mod.rs
index 9ac923bef88..2196bc996d9 100644
--- a/compiler/rustc_codegen_ssa/src/traits/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/mod.rs
@@ -8,9 +8,6 @@
 //! actual codegen, while the builder stores the information about the function during codegen and
 //! is used to produce the instructions of the backend IR.
 //!
-//! Finally, a third `Backend` structure has to implement methods related to how codegen information
-//! is passed to the backend, especially for asynchronous compilation.
-//!
 //! The traits contain associated types that are backend-specific, such as the backend's value or
 //! basic blocks.
 
@@ -30,71 +27,36 @@ mod write;
 
 use std::fmt;
 
-use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt};
-use rustc_target::spec::HasTargetSpec;
+use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, TyAndLayout};
+use rustc_middle::ty::Ty;
+use rustc_target::abi::call::FnAbi;
 
 pub use self::abi::AbiBuilderMethods;
-pub use self::asm::{AsmBuilderMethods, AsmMethods, GlobalAsmOperandRef, InlineAsmOperandRef};
-pub use self::backend::{Backend, BackendTypes, CodegenBackend, ExtraBackendMethods};
+pub use self::asm::{
+    AsmBuilderMethods, AsmCodegenMethods, GlobalAsmOperandRef, InlineAsmOperandRef,
+};
+pub use self::backend::{BackendTypes, CodegenBackend, ExtraBackendMethods};
 pub use self::builder::{BuilderMethods, OverflowOp};
-pub use self::consts::ConstMethods;
+pub use self::consts::ConstCodegenMethods;
 pub use self::coverageinfo::CoverageInfoBuilderMethods;
-pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoMethods};
-pub use self::declare::PreDefineMethods;
-pub use self::intrinsic::IntrinsicCallMethods;
-pub use self::misc::MiscMethods;
-pub use self::statics::{StaticBuilderMethods, StaticMethods};
+pub use self::debuginfo::{DebugInfoBuilderMethods, DebugInfoCodegenMethods};
+pub use self::declare::PreDefineCodegenMethods;
+pub use self::intrinsic::IntrinsicCallBuilderMethods;
+pub use self::misc::MiscCodegenMethods;
+pub use self::statics::{StaticBuilderMethods, StaticCodegenMethods};
 pub use self::type_::{
-    ArgAbiMethods, BaseTypeMethods, DerivedTypeMethods, LayoutTypeMethods, TypeMembershipMethods,
-    TypeMethods,
+    ArgAbiBuilderMethods, BaseTypeCodegenMethods, DerivedTypeCodegenMethods,
+    LayoutTypeCodegenMethods, TypeCodegenMethods, TypeMembershipCodegenMethods,
 };
 pub use self::write::{ModuleBufferMethods, ThinBufferMethods, WriteBackendMethods};
 
-pub trait CodegenObject: Copy + PartialEq + fmt::Debug {}
-impl<T: Copy + PartialEq + fmt::Debug> CodegenObject for T {}
-
-pub trait CodegenMethods<'tcx>:
-    Backend<'tcx>
-    + TypeMethods<'tcx>
-    + MiscMethods<'tcx>
-    + ConstMethods<'tcx>
-    + StaticMethods
-    + DebugInfoMethods<'tcx>
-    + AsmMethods<'tcx>
-    + PreDefineMethods<'tcx>
-    + HasParamEnv<'tcx>
-    + HasTyCtxt<'tcx>
-    + HasTargetSpec
-{
-}
-
-impl<'tcx, T> CodegenMethods<'tcx> for T where
-    Self: Backend<'tcx>
-        + TypeMethods<'tcx>
-        + MiscMethods<'tcx>
-        + ConstMethods<'tcx>
-        + StaticMethods
-        + DebugInfoMethods<'tcx>
-        + AsmMethods<'tcx>
-        + PreDefineMethods<'tcx>
-        + HasParamEnv<'tcx>
-        + HasTyCtxt<'tcx>
-        + HasTargetSpec
-{
-}
+pub trait CodegenObject = Copy + PartialEq + fmt::Debug;
 
-pub trait HasCodegen<'tcx>:
-    Backend<'tcx> + std::ops::Deref<Target = <Self as HasCodegen<'tcx>>::CodegenCx>
-{
-    type CodegenCx: CodegenMethods<'tcx>
-        + BackendTypes<
-            Value = Self::Value,
-            Function = Self::Function,
-            BasicBlock = Self::BasicBlock,
-            Type = Self::Type,
-            Funclet = Self::Funclet,
-            DIScope = Self::DIScope,
-            DILocation = Self::DILocation,
-            DIVariable = Self::DIVariable,
-        >;
-}
+pub trait CodegenMethods<'tcx> = LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
+    + FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>>
+    + TypeCodegenMethods<'tcx>
+    + ConstCodegenMethods<'tcx>
+    + StaticCodegenMethods
+    + DebugInfoCodegenMethods<'tcx>
+    + AsmCodegenMethods<'tcx>
+    + PreDefineCodegenMethods<'tcx>;
diff --git a/compiler/rustc_codegen_ssa/src/traits/statics.rs b/compiler/rustc_codegen_ssa/src/traits/statics.rs
index b418199e616..c10733fb0ed 100644
--- a/compiler/rustc_codegen_ssa/src/traits/statics.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/statics.rs
@@ -3,7 +3,7 @@ use rustc_target::abi::Align;
 
 use super::BackendTypes;
 
-pub trait StaticMethods: BackendTypes {
+pub trait StaticCodegenMethods: BackendTypes {
     fn static_addr_of(&self, cv: Self::Value, align: Align, kind: Option<&str>) -> Self::Value;
     fn codegen_static(&self, def_id: DefId);
 
diff --git a/compiler/rustc_codegen_ssa/src/traits/type_.rs b/compiler/rustc_codegen_ssa/src/traits/type_.rs
index 7c042c0c621..f6f309287fe 100644
--- a/compiler/rustc_codegen_ssa/src/traits/type_.rs
+++ b/compiler/rustc_codegen_ssa/src/traits/type_.rs
@@ -1,17 +1,15 @@
 use rustc_middle::bug;
-use rustc_middle::ty::layout::TyAndLayout;
+use rustc_middle::ty::layout::{HasTyCtxt, TyAndLayout};
 use rustc_middle::ty::{self, Ty};
 use rustc_target::abi::call::{ArgAbi, CastTarget, FnAbi, Reg};
 use rustc_target::abi::{AddressSpace, Float, Integer};
 
-use super::misc::MiscMethods;
-use super::{Backend, HasCodegen};
+use super::misc::MiscCodegenMethods;
+use super::BackendTypes;
 use crate::common::TypeKind;
 use crate::mir::place::PlaceRef;
 
-// This depends on `Backend` and not `BackendTypes`, because consumers will probably want to use
-// `LayoutOf` or `HasTyCtxt`. This way, they don't have to add a constraint on it themselves.
-pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
+pub trait BaseTypeCodegenMethods<'tcx>: BackendTypes {
     fn type_i8(&self) -> Self::Type;
     fn type_i16(&self) -> Self::Type;
     fn type_i32(&self) -> Self::Type;
@@ -42,7 +40,9 @@ pub trait BaseTypeMethods<'tcx>: Backend<'tcx> {
     fn val_ty(&self, v: Self::Value) -> Self::Type;
 }
 
-pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
+pub trait DerivedTypeCodegenMethods<'tcx>:
+    BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx>
+{
     fn type_int(&self) -> Self::Type {
         match &self.sess().target.c_int_width[..] {
             "16" => self.type_i16(),
@@ -100,9 +100,12 @@ pub trait DerivedTypeMethods<'tcx>: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {
     }
 }
 
-impl<'tcx, T> DerivedTypeMethods<'tcx> for T where Self: BaseTypeMethods<'tcx> + MiscMethods<'tcx> {}
+impl<'tcx, T> DerivedTypeCodegenMethods<'tcx> for T where
+    Self: BaseTypeCodegenMethods<'tcx> + MiscCodegenMethods<'tcx> + HasTyCtxt<'tcx>
+{
+}
 
-pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
+pub trait LayoutTypeCodegenMethods<'tcx>: BackendTypes {
     /// The backend type used for a rust type when it's in memory,
     /// such as when it's stack-allocated or when it's being loaded or stored.
     fn backend_type(&self, layout: TyAndLayout<'tcx>) -> Self::Type;
@@ -114,7 +117,7 @@ pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
     ///
     /// For nearly all types this is the same as the [`Self::backend_type`], however
     /// `bool` (and other `0`-or-`1` values) are kept as `i1` in registers but as
-    /// [`BaseTypeMethods::type_i8`] in memory.
+    /// [`BaseTypeCodegenMethods::type_i8`] in memory.
     ///
     /// Converting values between the two different backend types is done using
     /// [`from_immediate`](super::BuilderMethods::from_immediate) and
@@ -146,7 +149,7 @@ pub trait LayoutTypeMethods<'tcx>: Backend<'tcx> {
 
 // For backends that support CFI using type membership (i.e., testing whether a given pointer is
 // associated with a type identifier).
-pub trait TypeMembershipMethods<'tcx>: Backend<'tcx> {
+pub trait TypeMembershipCodegenMethods<'tcx>: BackendTypes {
     fn add_type_metadata(&self, _function: Self::Function, _typeid: String) {}
     fn set_type_metadata(&self, _function: Self::Function, _typeid: String) {}
     fn typeid_metadata(&self, _typeid: String) -> Option<Self::Value> {
@@ -156,7 +159,7 @@ pub trait TypeMembershipMethods<'tcx>: Backend<'tcx> {
     fn set_kcfi_type_metadata(&self, _function: Self::Function, _typeid: u32) {}
 }
 
-pub trait ArgAbiMethods<'tcx>: HasCodegen<'tcx> {
+pub trait ArgAbiBuilderMethods<'tcx>: BackendTypes {
     fn store_fn_arg(
         &mut self,
         arg_abi: &ArgAbi<'tcx, Ty<'tcx>>,
@@ -172,12 +175,6 @@ pub trait ArgAbiMethods<'tcx>: HasCodegen<'tcx> {
     fn arg_memory_ty(&self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> Self::Type;
 }
 
-pub trait TypeMethods<'tcx>:
-    DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx> + TypeMembershipMethods<'tcx>
-{
-}
-
-impl<'tcx, T> TypeMethods<'tcx> for T where
-    Self: DerivedTypeMethods<'tcx> + LayoutTypeMethods<'tcx> + TypeMembershipMethods<'tcx>
-{
-}
+pub trait TypeCodegenMethods<'tcx> = DerivedTypeCodegenMethods<'tcx>
+    + LayoutTypeCodegenMethods<'tcx>
+    + TypeMembershipCodegenMethods<'tcx>;
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index 9d4061d16a1..44a6b03177e 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -320,7 +320,7 @@ fn run_compiler(
         output_dir: odir,
         ice_file,
         file_loader,
-        locale_resources: DEFAULT_LOCALE_RESOURCES,
+        locale_resources: DEFAULT_LOCALE_RESOURCES.to_vec(),
         lint_caps: Default::default(),
         psess_created: None,
         hash_untracked_state: None,
@@ -1218,17 +1218,30 @@ pub fn handle_options(early_dcx: &EarlyDiagCtxt, args: &[String]) -> Option<geto
     // Parse with *all* options defined in the compiler, we don't worry about
     // option stability here we just want to parse as much as possible.
     let mut options = getopts::Options::new();
-    for option in config::rustc_optgroups() {
+    let optgroups = config::rustc_optgroups();
+    for option in &optgroups {
         (option.apply)(&mut options);
     }
     let matches = options.parse(args).unwrap_or_else(|e| {
-        let msg = match e {
+        let msg: Option<String> = match e {
             getopts::Fail::UnrecognizedOption(ref opt) => CG_OPTIONS
                 .iter()
                 .map(|&(name, ..)| ('C', name))
                 .chain(Z_OPTIONS.iter().map(|&(name, ..)| ('Z', name)))
                 .find(|&(_, name)| *opt == name.replace('_', "-"))
                 .map(|(flag, _)| format!("{e}. Did you mean `-{flag} {opt}`?")),
+            getopts::Fail::ArgumentMissing(ref opt) => {
+                optgroups.iter().find(|option| option.name == opt).map(|option| {
+                    // Print the help just for the option in question.
+                    let mut options = getopts::Options::new();
+                    (option.apply)(&mut options);
+                    // getopt requires us to pass a function for joining an iterator of
+                    // strings, even though in this case we expect exactly one string.
+                    options.usage_with_format(|it| {
+                        it.fold(format!("{e}\nUsage:"), |a, b| a + "\n" + &b)
+                    })
+                })
+            }
             _ => None,
         };
         early_dcx.early_fatal(msg.unwrap_or_else(|| e.to_string()));
diff --git a/compiler/rustc_driver_impl/src/signal_handler.rs b/compiler/rustc_driver_impl/src/signal_handler.rs
index e1f868c2522..411661824f0 100644
--- a/compiler/rustc_driver_impl/src/signal_handler.rs
+++ b/compiler/rustc_driver_impl/src/signal_handler.rs
@@ -35,6 +35,8 @@ macro raw_errln($tokens:tt) {
 }
 
 /// Signal handler installed for SIGSEGV
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#[allow(static_mut_refs)]
 extern "C" fn print_stack_trace(_: libc::c_int) {
     const MAX_FRAMES: usize = 256;
     // Reserve data segment so we don't have to malloc in a signal handler, which might fail
diff --git a/compiler/rustc_error_codes/src/error_codes/E0796.md b/compiler/rustc_error_codes/src/error_codes/E0796.md
index 7ac429e5215..ced163e98f7 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0796.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0796.md
@@ -1,14 +1,14 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 You have created a reference to a mutable static.
 
 Erroneous code example:
 
-```compile_fail,edition2024,E0796
+```
 static mut X: i32 = 23;
-
 fn work() {
   let _val = unsafe { X };
 }
-
 let x_ref = unsafe { &mut X };
 work();
 // The next line has Undefined Behavior!
diff --git a/compiler/rustc_error_codes/src/lib.rs b/compiler/rustc_error_codes/src/lib.rs
index d6f0206b0de..11cad0b8f97 100644
--- a/compiler/rustc_error_codes/src/lib.rs
+++ b/compiler/rustc_error_codes/src/lib.rs
@@ -681,3 +681,4 @@ E0800: 0800,
 //  E0723, // unstable feature in `const` context
 //  E0738, // Removed; errored on `#[track_caller] fn`s in `extern "Rust" { ... }`.
 //  E0744, // merged into E0728
+//  E0796, // unused error code. We use `static_mut_refs` lint instead.
diff --git a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
index d71ae9d210d..556e6d46f89 100644
--- a/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
+++ b/compiler/rustc_errors/src/annotate_snippet_emitter_writer.rs
@@ -48,7 +48,7 @@ impl Emitter for AnnotateSnippetEmitter {
     fn emit_diagnostic(&mut self, mut diag: DiagInner) {
         let fluent_args = to_fluent_args(diag.args.iter());
 
-        let mut suggestions = diag.suggestions.unwrap_or(vec![]);
+        let mut suggestions = diag.suggestions.unwrap_tag();
         self.primary_span_formatted(&mut diag.span, &mut suggestions, &fluent_args);
 
         self.fix_multispans_in_extern_macros_and_render_macro_backtrace(
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index 7a4d8dba179..6b756cff225 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -19,13 +19,9 @@ use crate::snippet::Style;
 use crate::{
     CodeSuggestion, DiagCtxtHandle, DiagMessage, ErrCode, ErrorGuaranteed, ExplicitBug, Level,
     MultiSpan, StashKey, SubdiagMessage, Substitution, SubstitutionPart, SuggestionStyle,
+    Suggestions,
 };
 
-/// Error type for `DiagInner`'s `suggestions` field, indicating that
-/// `.disable_suggestions()` was called on the `DiagInner`.
-#[derive(Clone, Debug, PartialEq, Eq, Hash, Encodable, Decodable)]
-pub struct SuggestionsDisabled;
-
 /// Simplified version of `FluentArg` that can implement `Encodable` and `Decodable`. Collection of
 /// `DiagArg` are converted to `FluentArgs` (consuming the collection) at the start of diagnostic
 /// emission.
@@ -296,7 +292,7 @@ pub struct DiagInner {
     pub code: Option<ErrCode>,
     pub span: MultiSpan,
     pub children: Vec<Subdiag>,
-    pub suggestions: Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
+    pub suggestions: Suggestions,
     pub args: DiagArgMap,
 
     /// This is not used for highlighting or rendering any error message. Rather, it can be used
@@ -325,7 +321,7 @@ impl DiagInner {
             code: None,
             span: MultiSpan::new(),
             children: vec![],
-            suggestions: Ok(vec![]),
+            suggestions: Suggestions::Enabled(vec![]),
             args: Default::default(),
             sort_span: DUMMY_SP,
             is_lint: None,
@@ -409,7 +405,7 @@ impl DiagInner {
         &Option<ErrCode>,
         &MultiSpan,
         &[Subdiag],
-        &Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
+        &Suggestions,
         Vec<(&DiagArgName, &DiagArgValue)>,
         &Option<IsLint>,
     ) {
@@ -823,16 +819,32 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
         self
     }
 
-    /// Disallow attaching suggestions this diagnostic.
+    /// Disallow attaching suggestions to this diagnostic.
     /// Any suggestions attached e.g. with the `span_suggestion_*` methods
     /// (before and after the call to `disable_suggestions`) will be ignored.
     #[rustc_lint_diagnostics]
     pub fn disable_suggestions(&mut self) -> &mut Self {
-        self.suggestions = Err(SuggestionsDisabled);
+        self.suggestions = Suggestions::Disabled;
         self
     }
 
-    /// Helper for pushing to `self.suggestions`, if available (not disable).
+    /// Prevent new suggestions from being added to this diagnostic.
+    ///
+    /// Suggestions added before the call to `.seal_suggestions()` will be preserved
+    /// and new suggestions will be ignored.
+    #[rustc_lint_diagnostics]
+    pub fn seal_suggestions(&mut self) -> &mut Self {
+        if let Suggestions::Enabled(suggestions) = &mut self.suggestions {
+            let suggestions_slice = std::mem::take(suggestions).into_boxed_slice();
+            self.suggestions = Suggestions::Sealed(suggestions_slice);
+        }
+        self
+    }
+
+    /// Helper for pushing to `self.suggestions`.
+    ///
+    /// A new suggestion is added if suggestions are enabled for this diagnostic.
+    /// Otherwise, they are ignored.
     #[rustc_lint_diagnostics]
     fn push_suggestion(&mut self, suggestion: CodeSuggestion) {
         for subst in &suggestion.substitutions {
@@ -846,7 +858,7 @@ impl<'a, G: EmissionGuarantee> Diag<'a, G> {
             }
         }
 
-        if let Ok(suggestions) = &mut self.suggestions {
+        if let Suggestions::Enabled(suggestions) = &mut self.suggestions {
             suggestions.push(suggestion);
         }
     }
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 2b135df91a4..3ab371b8057 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -498,7 +498,7 @@ impl Emitter for HumanEmitter {
     fn emit_diagnostic(&mut self, mut diag: DiagInner) {
         let fluent_args = to_fluent_args(diag.args.iter());
 
-        let mut suggestions = diag.suggestions.unwrap_or(vec![]);
+        let mut suggestions = diag.suggestions.unwrap_tag();
         self.primary_span_formatted(&mut diag.span, &mut suggestions, &fluent_args);
 
         self.fix_multispans_in_extern_macros_and_render_macro_backtrace(
diff --git a/compiler/rustc_errors/src/json.rs b/compiler/rustc_errors/src/json.rs
index 32e59f9ab03..6a2ecf13f7b 100644
--- a/compiler/rustc_errors/src/json.rs
+++ b/compiler/rustc_errors/src/json.rs
@@ -33,7 +33,8 @@ use crate::emitter::{
 use crate::registry::Registry;
 use crate::translation::{to_fluent_args, Translate};
 use crate::{
-    CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel, Subdiag, TerminalUrl,
+    CodeSuggestion, FluentBundle, LazyFallbackBundle, MultiSpan, SpanLabel, Subdiag, Suggestions,
+    TerminalUrl,
 };
 
 #[cfg(test)]
@@ -292,7 +293,7 @@ impl Diagnostic {
     /// Converts from `rustc_errors::DiagInner` to `Diagnostic`.
     fn from_errors_diagnostic(diag: crate::DiagInner, je: &JsonEmitter) -> Diagnostic {
         let args = to_fluent_args(diag.args.iter());
-        let sugg = diag.suggestions.iter().flatten().map(|sugg| {
+        let sugg_to_diag = |sugg: &CodeSuggestion| {
             let translated_message =
                 je.translate_message(&sugg.msg, &args).map_err(Report::new).unwrap();
             Diagnostic {
@@ -303,7 +304,12 @@ impl Diagnostic {
                 children: vec![],
                 rendered: None,
             }
-        });
+        };
+        let sugg = match &diag.suggestions {
+            Suggestions::Enabled(suggestions) => suggestions.iter().map(sugg_to_diag),
+            Suggestions::Sealed(suggestions) => suggestions.iter().map(sugg_to_diag),
+            Suggestions::Disabled => [].iter().map(sugg_to_diag),
+        };
 
         // generate regular command line output and store it in the json
 
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 13da1721a4a..59866012069 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -126,6 +126,41 @@ impl SuggestionStyle {
     }
 }
 
+/// Represents the help messages seen on a diagnostic.
+#[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
+pub enum Suggestions {
+    /// Indicates that new suggestions can be added or removed from this diagnostic.
+    ///
+    /// `DiagInner`'s new_* methods initialize the `suggestions` field with
+    /// this variant. Also, this is the default variant for `Suggestions`.
+    Enabled(Vec<CodeSuggestion>),
+    /// Indicates that suggestions cannot be added or removed from this diagnostic.
+    ///
+    /// Gets toggled when `.seal_suggestions()` is called on the `DiagInner`.
+    Sealed(Box<[CodeSuggestion]>),
+    /// Indicates that no suggestion is available for this diagnostic.
+    ///
+    /// Gets toggled when `.disable_suggestions()` is called on the `DiagInner`.
+    Disabled,
+}
+
+impl Suggestions {
+    /// Returns the underlying list of suggestions.
+    pub fn unwrap_tag(self) -> Vec<CodeSuggestion> {
+        match self {
+            Suggestions::Enabled(suggestions) => suggestions,
+            Suggestions::Sealed(suggestions) => suggestions.into_vec(),
+            Suggestions::Disabled => Vec::new(),
+        }
+    }
+}
+
+impl Default for Suggestions {
+    fn default() -> Self {
+        Self::Enabled(vec![])
+    }
+}
+
 #[derive(Clone, Debug, PartialEq, Hash, Encodable, Decodable)]
 pub struct CodeSuggestion {
     /// Each substitute can have multiple variants due to multiple
@@ -536,6 +571,8 @@ pub enum StashKey {
     /// Query cycle detected, stashing in favor of a better error.
     Cycle,
     UndeterminedMacroResolution,
+    /// Used by `Parser::maybe_recover_trailing_expr`
+    ExprInPat,
 }
 
 fn default_track_diagnostic<R>(diag: DiagInner, f: &mut dyn FnMut(DiagInner) -> R) -> R {
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index d0c0460ddfe..40333c3953a 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -204,7 +204,7 @@ declare_features! (
     /// Changes `impl Trait` to capture all lifetimes in scope.
     (unstable, lifetime_capture_rules_2024, "1.76.0", None),
     /// Allows `#[link(..., cfg(..))]`; perma-unstable per #37406
-    (unstable, link_cfg, "1.14.0", None),
+    (internal, link_cfg, "1.14.0", None),
     /// Allows using `?Trait` trait bounds in more contexts.
     (internal, more_maybe_bounds, "1.82.0", None),
     /// Allows the `multiple_supertrait_upcastable` lint.
@@ -558,6 +558,8 @@ declare_features! (
     (unstable, optimize_attribute, "1.34.0", Some(54882)),
     /// Allows specifying nop padding on functions for dynamic patching.
     (unstable, patchable_function_entry, "1.81.0", Some(123115)),
+    /// Experimental features that make `Pin` more ergonomic.
+    (incomplete, pin_ergonomics, "CURRENT_RUSTC_VERSION", Some(130494)),
     /// Allows postfix match `expr.match { ... }`
     (unstable, postfix_match, "1.79.0", Some(121618)),
     /// Allows macro attributes on expressions, statements and non-inline modules.
diff --git a/compiler/rustc_fluent_macro/src/fluent.rs b/compiler/rustc_fluent_macro/src/fluent.rs
index ca8bace28f3..37e610a85a6 100644
--- a/compiler/rustc_fluent_macro/src/fluent.rs
+++ b/compiler/rustc_fluent_macro/src/fluent.rs
@@ -138,25 +138,8 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok
                 // with a lowercase as rustc errors do.
                 err.replace_range(0..1, &err.chars().next().unwrap().to_lowercase().to_string());
 
-                let line_starts: Vec<usize> = std::iter::once(0)
-                    .chain(
-                        this.source()
-                            .char_indices()
-                            .filter_map(|(i, c)| Some(i + 1).filter(|_| c == '\n')),
-                    )
-                    .collect();
-                let line_start = line_starts
-                    .iter()
-                    .enumerate()
-                    .map(|(line, idx)| (line + 1, idx))
-                    .filter(|(_, idx)| **idx <= pos.start)
-                    .last()
-                    .unwrap()
-                    .0;
-
                 let message = annotate_snippets::Level::Error.title(&err).snippet(
                     Snippet::source(this.source())
-                        .line_start(line_start)
                         .origin(&relative_ftl_path)
                         .fold(true)
                         .annotation(annotate_snippets::Level::Error.span(pos.start..pos.end - 1)),
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index bd55617d84e..9b4174013a6 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -287,7 +287,10 @@ impl DefKind {
 
     #[inline]
     pub fn is_fn_like(self) -> bool {
-        matches!(self, DefKind::Fn | DefKind::AssocFn | DefKind::Closure)
+        matches!(
+            self,
+            DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::SyntheticCoroutineBody
+        )
     }
 
     /// Whether `query get_codegen_attrs` should be used with this definition.
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index ee03f780e16..f92c6650355 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -1378,7 +1378,8 @@ pub struct LetStmt<'hir> {
     pub hir_id: HirId,
     pub span: Span,
     /// Can be `ForLoopDesugar` if the `let` statement is part of a `for` loop
-    /// desugaring. Otherwise will be `Normal`.
+    /// desugaring, or `AssignDesugar` if it is the result of a complex
+    /// assignment desugaring. Otherwise will be `Normal`.
     pub source: LocalSource,
 }
 
@@ -1726,7 +1727,7 @@ impl Expr<'_> {
             ExprKind::Binary(op, ..) => ExprPrecedence::Binary(op.node),
             ExprKind::Unary(..) => ExprPrecedence::Unary,
             ExprKind::Lit(_) => ExprPrecedence::Lit,
-            ExprKind::Type(..) | ExprKind::Cast(..) => ExprPrecedence::Cast,
+            ExprKind::Cast(..) => ExprPrecedence::Cast,
             ExprKind::DropTemps(ref expr, ..) => expr.precedence(),
             ExprKind::If(..) => ExprPrecedence::If,
             ExprKind::Let(..) => ExprPrecedence::Let,
@@ -1744,11 +1745,12 @@ impl Expr<'_> {
             ExprKind::Continue(..) => ExprPrecedence::Continue,
             ExprKind::Ret(..) => ExprPrecedence::Ret,
             ExprKind::Become(..) => ExprPrecedence::Become,
-            ExprKind::InlineAsm(..) => ExprPrecedence::InlineAsm,
-            ExprKind::OffsetOf(..) => ExprPrecedence::OffsetOf,
             ExprKind::Struct(..) => ExprPrecedence::Struct,
             ExprKind::Repeat(..) => ExprPrecedence::Repeat,
             ExprKind::Yield(..) => ExprPrecedence::Yield,
+            ExprKind::Type(..) | ExprKind::InlineAsm(..) | ExprKind::OffsetOf(..) => {
+                ExprPrecedence::Mac
+            }
             ExprKind::Err(_) => ExprPrecedence::Err,
         }
     }
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index e7398fd2226..c148dc7f53b 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -45,7 +45,16 @@ impl LanguageItems {
 
     pub fn set(&mut self, item: LangItem, def_id: DefId) {
         self.items[item as usize] = Some(def_id);
-        self.reverse_items.insert(def_id, item);
+        let preexisting = self.reverse_items.insert(def_id, item);
+
+        // This needs to be a bijection.
+        if let Some(preexisting) = preexisting {
+            panic!(
+                "For the bijection of LangItem <=> DefId to work,\
+                one item DefId may only be assigned one LangItem. \
+                Separate the LangItem definitions for {item:?} and {preexisting:?}."
+            );
+        }
     }
 
     pub fn from_def_id(&self, def_id: DefId) -> Option<LangItem> {
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index bde94be6f51..633ccacedfc 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -467,25 +467,6 @@ hir_analysis_start_not_target_feature = `#[start]` function is not allowed to ha
 hir_analysis_start_not_track_caller = `#[start]` function is not allowed to be `#[track_caller]`
     .label = `#[start]` function is not allowed to be `#[track_caller]`
 
-hir_analysis_static_mut_ref = creating a {$shared} reference to a mutable static
-    .label = {$shared} reference to mutable static
-    .note = {$shared ->
-        [shared] this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-        *[mutable] this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
-    }
-    .suggestion = use `addr_of!` instead to create a raw pointer
-    .suggestion_mut = use `addr_of_mut!` instead to create a raw pointer
-
-hir_analysis_static_mut_refs_lint = creating a {$shared} reference to mutable static is discouraged
-    .label = {$shared} reference to mutable static
-    .suggestion = use `addr_of!` instead to create a raw pointer
-    .suggestion_mut = use `addr_of_mut!` instead to create a raw pointer
-    .note = this will be a hard error in the 2024 edition
-    .why_note = {$shared ->
-        [shared] this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-        *[mutable] this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
-    }
-
 hir_analysis_static_specialize = cannot specialize on `'static` lifetime
 
 hir_analysis_tait_forward_compat = item constrains opaque type that is not in its signature
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index dbdad2eb41d..3a7366ef78a 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -66,7 +66,6 @@ mod check;
 mod compare_impl_item;
 pub mod dropck;
 mod entry;
-mod errs;
 pub mod intrinsic;
 pub mod intrinsicck;
 mod region;
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index 33e58a92e37..1a5f4659812 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -20,8 +20,6 @@ use rustc_middle::ty::TyCtxt;
 use rustc_span::source_map;
 use tracing::debug;
 
-use super::errs::{maybe_expr_static_mut, maybe_stmt_static_mut};
-
 #[derive(Debug, Copy, Clone)]
 struct Context {
     /// The scope that contains any new variables declared, plus its depth in
@@ -229,8 +227,6 @@ fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx h
     let stmt_id = stmt.hir_id.local_id;
     debug!("resolve_stmt(stmt.id={:?})", stmt_id);
 
-    maybe_stmt_static_mut(visitor.tcx, *stmt);
-
     // Every statement will clean up the temporaries created during
     // execution of that statement. Therefore each statement has an
     // associated destruction scope that represents the scope of the
@@ -249,8 +245,6 @@ fn resolve_stmt<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, stmt: &'tcx h
 fn resolve_expr<'tcx>(visitor: &mut RegionResolutionVisitor<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
     debug!("resolve_expr - pre-increment {} expr = {:?}", visitor.expr_and_pat_count, expr);
 
-    maybe_expr_static_mut(visitor.tcx, *expr);
-
     let prev_cx = visitor.cx;
     visitor.enter_node_scope_with_dtor(expr.hir_id.local_id);
 
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 5cb90e97eef..b877cacd998 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -1,6 +1,6 @@
 use core::ops::ControlFlow;
 
-use rustc_errors::{Applicability, StashKey};
+use rustc_errors::{Applicability, StashKey, Suggestions};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::HirId;
@@ -670,7 +670,7 @@ fn infer_placeholder_type<'tcx>(
 
                 // The parser provided a sub-optimal `HasPlaceholders` suggestion for the type.
                 // We are typeck and have the real type, so remove that and suggest the actual type.
-                if let Ok(suggestions) = &mut err.suggestions {
+                if let Suggestions::Enabled(suggestions) = &mut err.suggestions {
                     suggestions.clear();
                 }
 
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 39df18ff658..e4e5f76ae32 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1523,57 +1523,6 @@ pub(crate) struct OnlyCurrentTraitsPointerSugg<'a> {
 }
 
 #[derive(Diagnostic)]
-#[diag(hir_analysis_static_mut_ref, code = E0796)]
-#[note]
-pub(crate) struct StaticMutRef<'a> {
-    #[primary_span]
-    #[label]
-    pub span: Span,
-    #[subdiagnostic]
-    pub sugg: MutRefSugg,
-    pub shared: &'a str,
-}
-
-#[derive(Subdiagnostic)]
-pub(crate) enum MutRefSugg {
-    #[multipart_suggestion(
-        hir_analysis_suggestion,
-        style = "verbose",
-        applicability = "maybe-incorrect"
-    )]
-    Shared {
-        #[suggestion_part(code = "addr_of!(")]
-        lo: Span,
-        #[suggestion_part(code = ")")]
-        hi: Span,
-    },
-    #[multipart_suggestion(
-        hir_analysis_suggestion_mut,
-        style = "verbose",
-        applicability = "maybe-incorrect"
-    )]
-    Mut {
-        #[suggestion_part(code = "addr_of_mut!(")]
-        lo: Span,
-        #[suggestion_part(code = ")")]
-        hi: Span,
-    },
-}
-
-// STATIC_MUT_REF lint
-#[derive(LintDiagnostic)]
-#[diag(hir_analysis_static_mut_refs_lint)]
-#[note]
-#[note(hir_analysis_why_note)]
-pub(crate) struct RefOfMutStatic<'a> {
-    #[label]
-    pub span: Span,
-    #[subdiagnostic]
-    pub sugg: MutRefSugg,
-    pub shared: &'a str,
-}
-
-#[derive(Diagnostic)]
 #[diag(hir_analysis_not_supported_delegation)]
 pub(crate) struct UnsupportedDelegation<'a> {
     #[primary_span]
diff --git a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs
index 97402dd1109..236543007fc 100644
--- a/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs
+++ b/compiler/rustc_hir_analysis/src/errors/wrong_number_of_generic_args.rs
@@ -1048,7 +1048,18 @@ impl<'a, 'tcx> WrongNumberOfGenericArgs<'a, 'tcx> {
                 },
             );
 
-            err.span_suggestion(span, msg, "", Applicability::MaybeIncorrect);
+            if span.is_empty() {
+                // HACK: Avoid ICE when types with the same name with `derive`s are in the same scope:
+                //     struct NotSM;
+                //     #[derive(PartialEq, Eq)]
+                //     struct NotSM<T>(T);
+                // With the above code, the suggestion would be to remove the generics of the first
+                // `NotSM`, which doesn't *have* generics, so we would suggest to remove no code with
+                // no code, which would trigger an `assert!` later. Ideally, we would do something a
+                // bit more principled. See closed PR #109082.
+            } else {
+                err.span_suggestion(span, msg, "", Applicability::MaybeIncorrect);
+            }
         } else if redundant_lifetime_args && redundant_type_or_const_args {
             remove_lifetime_args(err);
             remove_type_or_const_args(err);
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index fca7babea30..26c9b8dfdc3 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -214,6 +214,12 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             ty::Dynamic(predicates, region, ty::DynStar) if self.tcx.features().dyn_star => {
                 return self.coerce_dyn_star(a, b, predicates, region);
             }
+            ty::Adt(pin, _)
+                if self.tcx.features().pin_ergonomics
+                    && self.tcx.is_lang_item(pin.did(), hir::LangItem::Pin) =>
+            {
+                return self.coerce_pin(a, b);
+            }
             _ => {}
         }
 
@@ -774,6 +780,62 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         })
     }
 
+    /// Applies reborrowing for `Pin`
+    ///
+    /// We currently only support reborrowing `Pin<&mut T>` as `Pin<&mut T>`. This is accomplished
+    /// by inserting a call to `Pin::as_mut` during MIR building.
+    ///
+    /// In the future we might want to support other reborrowing coercions, such as:
+    /// - `Pin<&mut T>` as `Pin<&T>`
+    /// - `Pin<&T>` as `Pin<&T>`
+    /// - `Pin<Box<T>>` as `Pin<&T>`
+    /// - `Pin<Box<T>>` as `Pin<&mut T>`
+    #[instrument(skip(self), level = "trace")]
+    fn coerce_pin(&self, a: Ty<'tcx>, b: Ty<'tcx>) -> CoerceResult<'tcx> {
+        // We need to make sure the two types are compatible for coercion.
+        // Then we will build a ReborrowPin adjustment and return that as an InferOk.
+
+        // Right now we can only reborrow if this is a `Pin<&mut T>`.
+        let extract_pin_mut = |ty: Ty<'tcx>| {
+            // Get the T out of Pin<T>
+            let (pin, ty) = match ty.kind() {
+                ty::Adt(pin, args) if self.tcx.is_lang_item(pin.did(), hir::LangItem::Pin) => {
+                    (*pin, args[0].expect_ty())
+                }
+                _ => {
+                    debug!("can't reborrow {:?} as pinned", ty);
+                    return Err(TypeError::Mismatch);
+                }
+            };
+            // Make sure the T is something we understand (just `&mut U` for now)
+            match ty.kind() {
+                ty::Ref(region, ty, mutbl) => Ok((pin, *region, *ty, *mutbl)),
+                _ => {
+                    debug!("can't reborrow pin of inner type {:?}", ty);
+                    Err(TypeError::Mismatch)
+                }
+            }
+        };
+
+        let (pin, a_region, a_ty, mut_a) = extract_pin_mut(a)?;
+        let (_, b_region, _b_ty, mut_b) = extract_pin_mut(b)?;
+
+        coerce_mutbls(mut_a, mut_b)?;
+
+        // update a with b's mutability since we'll be coercing mutability
+        let a = Ty::new_adt(
+            self.tcx,
+            pin,
+            self.tcx.mk_args(&[Ty::new_ref(self.tcx, a_region, a_ty, mut_b).into()]),
+        );
+
+        // To complete the reborrow, we need to make sure we can unify the inner types, and if so we
+        // add the adjustments.
+        self.unify_and(a, b, |_inner_ty| {
+            vec![Adjustment { kind: Adjust::ReborrowPin(b_region, mut_b), target: b }]
+        })
+    }
+
     fn coerce_from_safe_fn<F, G>(
         &self,
         a: Ty<'tcx>,
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index da8c0ad3a30..3b2ddf659a1 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -780,6 +780,16 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                 adjustment::Adjust::Borrow(ref autoref) => {
                     self.walk_autoref(expr, &place_with_id, autoref);
                 }
+
+                adjustment::Adjust::ReborrowPin(_, mutbl) => {
+                    // Reborrowing a Pin is like a combinations of a deref and a borrow, so we do
+                    // both.
+                    let bk = match mutbl {
+                        ty::Mutability::Not => ty::BorrowKind::ImmBorrow,
+                        ty::Mutability::Mut => ty::BorrowKind::MutBorrow,
+                    };
+                    self.delegate.borrow_mut().borrow(&place_with_id, place_with_id.hir_id, bk);
+                }
             }
             place_with_id = self.cat_expr_adjusted(expr, place_with_id, adjustment)?;
         }
@@ -1284,6 +1294,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
             adjustment::Adjust::NeverToAny
             | adjustment::Adjust::Pointer(_)
             | adjustment::Adjust::Borrow(_)
+            | adjustment::Adjust::ReborrowPin(..)
             | adjustment::Adjust::DynStar => {
                 // Result is an rvalue.
                 Ok(self.cat_rvalue(expr.hir_id, target))
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 7318d02d24c..61898b06476 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1388,10 +1388,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // This also occurs for an enum variant on a type alias.
             let impl_ty = self.normalize(span, tcx.type_of(impl_def_id).instantiate(tcx, args));
             let self_ty = self.normalize(span, self_ty);
-            match self.at(&self.misc(span), self.param_env).sub(
+            match self.at(&self.misc(span), self.param_env).eq(
                 DefineOpaqueTypes::Yes,
-                self_ty,
                 impl_ty,
+                self_ty,
             ) {
                 Ok(ok) => self.register_infer_ok_obligations(ok),
                 Err(_) => {
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 5dc341653e5..17aa43ae7c0 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -621,6 +621,16 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         self.unsatisfied_predicates.borrow_mut().clear();
     }
 
+    /// When we're looking up a method by path (UFCS), we relate the receiver
+    /// types invariantly. When we are looking up a method by the `.` operator,
+    /// we relate them covariantly.
+    fn variance(&self) -> ty::Variance {
+        match self.mode {
+            Mode::MethodCall => ty::Covariant,
+            Mode::Path => ty::Invariant,
+        }
+    }
+
     ///////////////////////////////////////////////////////////////////////////
     // CANDIDATE ASSEMBLY
 
@@ -1443,7 +1453,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     (xform_self_ty, xform_ret_ty) =
                         self.xform_self_ty(probe.item, impl_ty, impl_args);
                     xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty);
-                    match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) {
+                    match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty)
+                    {
                         Ok(()) => {}
                         Err(err) => {
                             debug!("--> cannot relate self-types {:?}", err);
@@ -1514,7 +1525,13 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                         {
                             return ProbeResult::NoMatch;
                         }
-                        _ => match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) {
+                        _ => match ocx.relate(
+                            cause,
+                            self.param_env,
+                            self.variance(),
+                            self_ty,
+                            xform_self_ty,
+                        ) {
                             Ok(()) => {}
                             Err(err) => {
                                 debug!("--> cannot relate self-types {:?}", err);
@@ -1560,7 +1577,8 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                     (xform_self_ty, xform_ret_ty) =
                         self.xform_self_ty(probe.item, trait_ref.self_ty(), trait_ref.args);
                     xform_self_ty = ocx.normalize(cause, self.param_env, xform_self_ty);
-                    match ocx.sup(cause, self.param_env, xform_self_ty, self_ty) {
+                    match ocx.relate(cause, self.param_env, self.variance(), self_ty, xform_self_ty)
+                    {
                         Ok(()) => {}
                         Err(err) => {
                             debug!("--> cannot relate self-types {:?}", err);
@@ -1603,7 +1621,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
                 }
 
                 debug!("comparing return_ty {:?} with xform ret ty {:?}", return_ty, xform_ret_ty);
-                match ocx.sup(cause, self.param_env, return_ty, xform_ret_ty) {
+                match ocx.relate(cause, self.param_env, self.variance(), xform_ret_ty, return_ty) {
                     Ok(()) => {}
                     Err(_) => {
                         result = ProbeResult::BadReturnType;
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 45a6efc7a6a..7dd6deb4fe6 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -11,7 +11,6 @@ use rustc_hir::def::{CtorKind, DefKind, Res};
 use rustc_hir::pat_util::EnumerateAndAdjustIterator;
 use rustc_hir::{self as hir, BindingMode, ByRef, HirId, LangItem, Mutability, Pat, PatKind};
 use rustc_infer::infer;
-use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint::builtin::NON_EXHAUSTIVE_OMITTED_PATTERNS;
@@ -2413,17 +2412,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         len: ty::Const<'tcx>,
         min_len: u64,
     ) -> (Option<Ty<'tcx>>, Ty<'tcx>) {
-        let len = match len.eval(self.tcx, self.param_env, span) {
-            Ok((_, val)) => val
-                .try_to_scalar()
-                .and_then(|scalar| scalar.try_to_scalar_int().ok())
-                .map(|int| int.to_target_usize(self.tcx)),
-            Err(ErrorHandled::Reported(..)) => {
-                let guar = self.error_scrutinee_unfixed_length(span);
-                return (Some(Ty::new_error(self.tcx, guar)), arr_ty);
-            }
-            Err(ErrorHandled::TooGeneric(..)) => None,
-        };
+        let len = len.try_eval_target_usize(self.tcx, self.param_env);
 
         let guar = if let Some(len) = len {
             // Now we know the length...
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index c2555d2bb47..2fbbc3200e1 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -803,7 +803,7 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
         // We must deeply normalize in the new solver, since later lints
         // expect that types that show up in the typeck are fully
         // normalized.
-        let value = if self.should_normalize {
+        let mut value = if self.should_normalize {
             let body_id = tcx.hir().body_owner_def_id(self.body.id());
             let cause = ObligationCause::misc(self.span.to_span(tcx), body_id);
             let at = self.fcx.at(&cause, self.fcx.param_env);
@@ -818,12 +818,27 @@ impl<'cx, 'tcx> Resolver<'cx, 'tcx> {
             value
         };
 
+        // Bail if there are any non-region infer.
         if value.has_non_region_infer() {
             let guar = self.report_error(value);
-            new_err(tcx, guar)
-        } else {
-            tcx.fold_regions(value, |_, _| tcx.lifetimes.re_erased)
+            value = new_err(tcx, guar);
+        }
+
+        // Erase the regions from the ty, since it's not really meaningful what
+        // these region values are; there's not a trivial correspondence between
+        // regions in the HIR and MIR, so when we turn the body into MIR, there's
+        // no reason to keep regions around. They will be repopulated during MIR
+        // borrowck, and specifically region constraints will be populated during
+        // MIR typeck which is run on the new body.
+        value = tcx.fold_regions(value, |_, _| tcx.lifetimes.re_erased);
+
+        // Normalize consts in writeback, because GCE doesn't normalize eagerly.
+        if tcx.features().generic_const_exprs {
+            value =
+                value.fold_with(&mut EagerlyNormalizeConsts { tcx, param_env: self.fcx.param_env });
         }
+
+        value
     }
 }
 
@@ -858,3 +873,17 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Resolver<'cx, 'tcx> {
         predicate
     }
 }
+
+struct EagerlyNormalizeConsts<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+}
+impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EagerlyNormalizeConsts<'tcx> {
+    fn cx(&self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
+        self.tcx.try_normalize_erasing_regions(self.param_env, ct).unwrap_or(ct)
+    }
+}
diff --git a/compiler/rustc_interface/src/interface.rs b/compiler/rustc_interface/src/interface.rs
index 04e2b7d45dc..347dc185043 100644
--- a/compiler/rustc_interface/src/interface.rs
+++ b/compiler/rustc_interface/src/interface.rs
@@ -311,7 +311,9 @@ pub struct Config {
     pub output_file: Option<OutFileName>,
     pub ice_file: Option<PathBuf>,
     pub file_loader: Option<Box<dyn FileLoader + Send + Sync>>,
-    pub locale_resources: &'static [&'static str],
+    /// The list of fluent resources, used for lints declared with
+    /// [`Diagnostic`](rustc_errors::Diagnostic) and [`LintDiagnostic`](rustc_errors::LintDiagnostic).
+    pub locale_resources: Vec<&'static str>,
 
     pub lint_caps: FxHashMap<lint::LintId, lint::Level>,
 
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 4aa86944a0b..e71c5676ce4 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -395,6 +395,8 @@ lint_improper_ctypes_opaque = opaque types have no C equivalent
 lint_improper_ctypes_pat_help = consider using the base type instead
 
 lint_improper_ctypes_pat_reason = pattern types have no C equivalent
+
+lint_improper_ctypes_recursion_limit_reached = type is infinitely recursive
 lint_improper_ctypes_slice_help = consider using a raw pointer instead
 
 lint_improper_ctypes_slice_reason = slices have no C equivalent
@@ -769,6 +771,13 @@ lint_single_use_lifetime = lifetime parameter `{$ident}` only used once
 
 lint_span_use_eq_ctxt = use `.eq_ctxt()` instead of `.ctxt() == .ctxt()`
 
+lint_static_mut_refs_lint = creating a {$shared_label}reference to mutable static is discouraged
+    .label = {$shared_label}reference to mutable static
+    .suggestion = use `&raw const` instead to create a raw pointer
+    .suggestion_mut = use `&raw mut` instead to create a raw pointer
+    .shared_note = shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+    .mut_note = mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
+
 lint_supertrait_as_deref_target = this `Deref` implementation is covered by an implicit supertrait coercion
     .label = `{$self_ty}` implements `Deref<Target = dyn {$target_principal}>` which conflicts with supertrait `{$supertrait_principal}`
     .label2 = target type is a supertrait of `{$self_ty}`
diff --git a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
index ddaa819df14..38c4e48928f 100644
--- a/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
+++ b/compiler/rustc_lint/src/context/diagnostics/check_cfg.rs
@@ -2,6 +2,7 @@ use rustc_middle::bug;
 use rustc_session::config::ExpectedValues;
 use rustc_session::Session;
 use rustc_span::edit_distance::find_best_match_for_name;
+use rustc_span::symbol::Ident;
 use rustc_span::{sym, Span, Symbol};
 
 use crate::lints;
@@ -30,7 +31,7 @@ enum EscapeQuotes {
     No,
 }
 
-fn to_check_cfg_arg(name: Symbol, value: Option<Symbol>, quotes: EscapeQuotes) -> String {
+fn to_check_cfg_arg(name: Ident, value: Option<Symbol>, quotes: EscapeQuotes) -> String {
     if let Some(value) = value {
         let value = str::escape_debug(value.as_str()).to_string();
         let values = match quotes {
@@ -110,6 +111,7 @@ pub(super) fn unexpected_cfg_name(
                 }
             };
 
+            let best_match = Ident::new(best_match, name_span);
             if let Some((value, value_span)) = value {
                 if best_match_values.contains(&Some(value)) {
                     lints::unexpected_cfg_name::CodeSuggestion::SimilarNameAndValue {
@@ -163,6 +165,8 @@ pub(super) fn unexpected_cfg_name(
         };
         let expected_names = if !possibilities.is_empty() {
             let (possibilities, and_more) = sort_and_truncate_possibilities(sess, possibilities);
+            let possibilities: Vec<_> =
+                possibilities.into_iter().map(|s| Ident::new(s, name_span)).collect();
             Some(lints::unexpected_cfg_name::ExpectedNames {
                 possibilities: possibilities.into(),
                 and_more,
@@ -176,7 +180,9 @@ pub(super) fn unexpected_cfg_name(
         }
     };
 
-    let inst = |escape_quotes| to_check_cfg_arg(name, value.map(|(v, _s)| v), escape_quotes);
+    let inst = |escape_quotes| {
+        to_check_cfg_arg(Ident::new(name, name_span), value.map(|(v, _s)| v), escape_quotes)
+    };
 
     let invocation_help = if is_from_cargo {
         let sub = if !is_feature_cfg { Some(cargo_help_sub(sess, &inst)) } else { None };
@@ -273,7 +279,9 @@ pub(super) fn unexpected_cfg_value(
         || (matches!(sess.psess.unstable_features, rustc_feature::UnstableFeatures::Cheat)
             && !sess.opts.unstable_opts.ui_testing);
 
-    let inst = |escape_quotes| to_check_cfg_arg(name, value.map(|(v, _s)| v), escape_quotes);
+    let inst = |escape_quotes| {
+        to_check_cfg_arg(Ident::new(name, name_span), value.map(|(v, _s)| v), escape_quotes)
+    };
 
     let invocation_help = if is_from_cargo {
         let help = if name == sym::feature {
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 5c67e21687f..d1da2809cc7 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -81,6 +81,7 @@ mod ptr_nulls;
 mod redundant_semicolon;
 mod reference_casting;
 mod shadowed_into_iter;
+mod static_mut_refs;
 mod tail_expr_drop_order;
 mod traits;
 mod types;
@@ -120,6 +121,7 @@ use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use shadowed_into_iter::ShadowedIntoIter;
 pub use shadowed_into_iter::{ARRAY_INTO_ITER, BOXED_SLICE_INTO_ITER};
+use static_mut_refs::*;
 use tail_expr_drop_order::TailExprDropOrder;
 use traits::*;
 use types::*;
@@ -246,6 +248,7 @@ late_lint_methods!(
             ImplTraitOvercaptures: ImplTraitOvercaptures,
             TailExprDropOrder: TailExprDropOrder,
             IfLetRescope: IfLetRescope::default(),
+            StaticMutRefs: StaticMutRefs,
         ]
     ]
 );
@@ -583,6 +586,11 @@ fn register_builtins(store: &mut LintStore) {
         "const_eval_mutable_ptr_in_final_value",
         "partially allowed now, otherwise turned into a hard error",
     );
+    store.register_removed(
+        "where_clauses_object_safety",
+        "converted into hard error, see PR #125380 \
+         <https://github.com/rust-lang/rust/pull/125380> for more information",
+    );
 }
 
 fn register_internals(store: &mut LintStore) {
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index a2ccb93347a..11006862d05 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -2180,6 +2180,7 @@ pub(crate) struct UnexpectedCfgName {
 pub(crate) mod unexpected_cfg_name {
     use rustc_errors::DiagSymbolList;
     use rustc_macros::Subdiagnostic;
+    use rustc_span::symbol::Ident;
     use rustc_span::{Span, Symbol};
 
     #[derive(Subdiagnostic)]
@@ -2260,7 +2261,7 @@ pub(crate) mod unexpected_cfg_name {
     #[derive(Subdiagnostic)]
     #[help_once(lint_unexpected_cfg_name_expected_names)]
     pub(crate) struct ExpectedNames {
-        pub possibilities: DiagSymbolList,
+        pub possibilities: DiagSymbolList<Ident>,
         pub and_more: usize,
     }
 
@@ -3060,3 +3061,35 @@ pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion {
 pub(crate) struct OutOfScopeMacroCalls {
     pub path: String,
 }
+
+#[derive(LintDiagnostic)]
+#[diag(lint_static_mut_refs_lint)]
+pub(crate) struct RefOfMutStatic<'a> {
+    #[label]
+    pub span: Span,
+    #[subdiagnostic]
+    pub sugg: Option<MutRefSugg>,
+    pub shared_label: &'a str,
+    #[note(lint_shared_note)]
+    pub shared_note: bool,
+    #[note(lint_mut_note)]
+    pub mut_note: bool,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum MutRefSugg {
+    #[multipart_suggestion(lint_suggestion, style = "verbose", applicability = "maybe-incorrect")]
+    Shared {
+        #[suggestion_part(code = "&raw const ")]
+        span: Span,
+    },
+    #[multipart_suggestion(
+        lint_suggestion_mut,
+        style = "verbose",
+        applicability = "maybe-incorrect"
+    )]
+    Mut {
+        #[suggestion_part(code = "&raw mut ")]
+        span: Span,
+    },
+}
diff --git a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
index e0ba6a912f1..c9ca1ea5e7a 100644
--- a/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
+++ b/compiler/rustc_lint/src/opaque_hidden_inferred_bound.rs
@@ -72,6 +72,18 @@ impl<'tcx> LateLintPass<'tcx> for OpaqueHiddenInferredBound {
         let hir::ItemKind::OpaqueTy(opaque) = &item.kind else {
             return;
         };
+
+        // If this is an RPITIT from a trait method with no body, then skip.
+        // That's because although we may have an opaque type on the function,
+        // it won't have a hidden type, so proving predicates about it is
+        // not really meaningful.
+        if let hir::OpaqueTyOrigin::FnReturn(method_def_id) = opaque.origin
+            && let hir::Node::TraitItem(trait_item) = cx.tcx.hir_node_by_def_id(method_def_id)
+            && !trait_item.defaultness.has_value()
+        {
+            return;
+        }
+
         let def_id = item.owner_id.def_id.to_def_id();
         let infcx = &cx.tcx.infer_ctxt().build();
         // For every projection predicate in the opaque type's explicit bounds,
diff --git a/compiler/rustc_lint/src/static_mut_refs.rs b/compiler/rustc_lint/src/static_mut_refs.rs
new file mode 100644
index 00000000000..3dd26fb9c53
--- /dev/null
+++ b/compiler/rustc_lint/src/static_mut_refs.rs
@@ -0,0 +1,154 @@
+use rustc_hir as hir;
+use rustc_hir::{Expr, Stmt};
+use rustc_middle::ty::{Mutability, TyKind};
+use rustc_session::lint::FutureIncompatibilityReason;
+use rustc_session::{declare_lint, declare_lint_pass};
+use rustc_span::edition::Edition;
+use rustc_span::Span;
+
+use crate::lints::{MutRefSugg, RefOfMutStatic};
+use crate::{LateContext, LateLintPass, LintContext};
+
+declare_lint! {
+    /// The `static_mut_refs` lint checks for shared or mutable references
+    /// of mutable static inside `unsafe` blocks and `unsafe` functions.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,edition2021
+    /// fn main() {
+    ///     static mut X: i32 = 23;
+    ///     static mut Y: i32 = 24;
+    ///
+    ///     unsafe {
+    ///         let y = &X;
+    ///         let ref x = X;
+    ///         let (x, y) = (&X, &Y);
+    ///         foo(&X);
+    ///     }
+    /// }
+    ///
+    /// unsafe fn _foo() {
+    ///     static mut X: i32 = 23;
+    ///     static mut Y: i32 = 24;
+    ///
+    ///     let y = &X;
+    ///     let ref x = X;
+    ///     let (x, y) = (&X, &Y);
+    ///     foo(&X);
+    /// }
+    ///
+    /// fn foo<'a>(_x: &'a i32) {}
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Shared or mutable references of mutable static are almost always a mistake and
+    /// can lead to undefined behavior and various other problems in your code.
+    ///
+    /// This lint is "warn" by default on editions up to 2021, in 2024 is "deny".
+    pub STATIC_MUT_REFS,
+    Warn,
+    "shared references or mutable references of mutable static is discouraged",
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
+        reference: "<https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>",
+        explain_reason: false,
+    };
+    @edition Edition2024 => Deny;
+}
+
+declare_lint_pass!(StaticMutRefs => [STATIC_MUT_REFS]);
+
+impl<'tcx> LateLintPass<'tcx> for StaticMutRefs {
+    #[allow(rustc::usage_of_ty_tykind)]
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &Expr<'_>) {
+        let err_span = expr.span;
+        match expr.kind {
+            hir::ExprKind::AddrOf(borrow_kind, m, ex)
+                if matches!(borrow_kind, hir::BorrowKind::Ref)
+                    && let Some(err_span) = path_is_static_mut(ex, err_span) =>
+            {
+                emit_static_mut_refs(
+                    cx,
+                    err_span,
+                    err_span.with_hi(ex.span.lo()),
+                    m,
+                    !expr.span.from_expansion(),
+                );
+            }
+            hir::ExprKind::MethodCall(_, e, _, _)
+                if let Some(err_span) = path_is_static_mut(e, expr.span)
+                    && let typeck = cx.typeck_results()
+                    && let Some(method_def_id) = typeck.type_dependent_def_id(expr.hir_id)
+                    && let inputs =
+                        cx.tcx.fn_sig(method_def_id).skip_binder().inputs().skip_binder()
+                    && let Some(receiver) = inputs.get(0)
+                    && let TyKind::Ref(_, _, m) = receiver.kind() =>
+            {
+                emit_static_mut_refs(cx, err_span, err_span.shrink_to_lo(), *m, false);
+            }
+            _ => {}
+        }
+    }
+
+    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &Stmt<'_>) {
+        if let hir::StmtKind::Let(loc) = stmt.kind
+            && let hir::PatKind::Binding(ba, _, _, _) = loc.pat.kind
+            && let hir::ByRef::Yes(m) = ba.0
+            && let Some(init) = loc.init
+            && let Some(err_span) = path_is_static_mut(init, init.span)
+        {
+            emit_static_mut_refs(cx, err_span, err_span.shrink_to_lo(), m, false);
+        }
+    }
+}
+
+fn path_is_static_mut(mut expr: &hir::Expr<'_>, mut err_span: Span) -> Option<Span> {
+    if err_span.from_expansion() {
+        err_span = expr.span;
+    }
+
+    while let hir::ExprKind::Field(e, _) = expr.kind {
+        expr = e;
+    }
+
+    if let hir::ExprKind::Path(qpath) = expr.kind
+        && let hir::QPath::Resolved(_, path) = qpath
+        && let hir::def::Res::Def(def_kind, _) = path.res
+        && let hir::def::DefKind::Static { safety: _, mutability: Mutability::Mut, nested: false } =
+            def_kind
+    {
+        return Some(err_span);
+    }
+    None
+}
+
+fn emit_static_mut_refs(
+    cx: &LateContext<'_>,
+    span: Span,
+    sugg_span: Span,
+    mutable: Mutability,
+    suggest_addr_of: bool,
+) {
+    let (shared_label, shared_note, mut_note, sugg) = match mutable {
+        Mutability::Mut => {
+            let sugg =
+                if suggest_addr_of { Some(MutRefSugg::Mut { span: sugg_span }) } else { None };
+            ("mutable ", false, true, sugg)
+        }
+        Mutability::Not => {
+            let sugg =
+                if suggest_addr_of { Some(MutRefSugg::Shared { span: sugg_span }) } else { None };
+            ("shared ", true, false, sugg)
+        }
+    };
+
+    cx.emit_span_lint(
+        STATIC_MUT_REFS,
+        span,
+        RefOfMutStatic { span, sugg, shared_label, shared_note, mut_note },
+    );
+}
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 900c496e033..f9d0cd49708 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -3,9 +3,9 @@ use std::ops::ControlFlow;
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::DiagMessage;
-use rustc_hir::{is_range_literal, Expr, ExprKind, Node};
+use rustc_hir::{Expr, ExprKind};
 use rustc_middle::bug;
-use rustc_middle::ty::layout::{IntegerExt, LayoutOf, SizeSkeleton};
+use rustc_middle::ty::layout::{LayoutOf, SizeSkeleton};
 use rustc_middle::ty::{
     self, AdtKind, GenericArgsRef, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
 };
@@ -13,22 +13,23 @@ use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::sym;
 use rustc_span::{source_map, Span, Symbol};
-use rustc_target::abi::{Abi, Integer, Size, TagEncoding, Variants, WrappingRange};
+use rustc_target::abi::{Abi, TagEncoding, Variants, WrappingRange};
 use rustc_target::spec::abi::Abi as SpecAbi;
 use tracing::debug;
-use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
+use {rustc_ast as ast, rustc_hir as hir};
 
 use crate::lints::{
     AmbiguousWidePointerComparisons, AmbiguousWidePointerComparisonsAddrMetadataSuggestion,
     AmbiguousWidePointerComparisonsAddrSuggestion, AtomicOrderingFence, AtomicOrderingLoad,
     AtomicOrderingStore, ImproperCTypes, InvalidAtomicOrderingDiag, InvalidNanComparisons,
-    InvalidNanComparisonsSuggestion, OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign,
-    OverflowingBinHexSignBitSub, OverflowingBinHexSub, OverflowingInt, OverflowingIntHelp,
-    OverflowingLiteral, OverflowingUInt, RangeEndpointOutOfRange, UnusedComparisons,
-    UseInclusiveRange, VariantSizeDifferencesDiag,
+    InvalidNanComparisonsSuggestion, UnusedComparisons, VariantSizeDifferencesDiag,
 };
 use crate::{fluent_generated as fluent, LateContext, LateLintPass, LintContext};
 
+mod literal;
+
+use literal::{int_ty_range, lint_literal, uint_ty_range};
+
 declare_lint! {
     /// The `unused_comparisons` lint detects comparisons made useless by
     /// limits of the types involved.
@@ -185,403 +186,6 @@ impl TypeLimits {
     }
 }
 
-/// Attempts to special-case the overflowing literal lint when it occurs as a range endpoint (`expr..MAX+1`).
-/// Returns `true` iff the lint was emitted.
-fn lint_overflowing_range_endpoint<'tcx>(
-    cx: &LateContext<'tcx>,
-    lit: &hir::Lit,
-    lit_val: u128,
-    max: u128,
-    expr: &'tcx hir::Expr<'tcx>,
-    ty: &str,
-) -> bool {
-    // Look past casts to support cases like `0..256 as u8`
-    let (expr, lit_span) = if let Node::Expr(par_expr) = cx.tcx.parent_hir_node(expr.hir_id)
-        && let ExprKind::Cast(_, _) = par_expr.kind
-    {
-        (par_expr, expr.span)
-    } else {
-        (expr, expr.span)
-    };
-
-    // We only want to handle exclusive (`..`) ranges,
-    // which are represented as `ExprKind::Struct`.
-    let Node::ExprField(field) = cx.tcx.parent_hir_node(expr.hir_id) else { return false };
-    let Node::Expr(struct_expr) = cx.tcx.parent_hir_node(field.hir_id) else { return false };
-    if !is_range_literal(struct_expr) {
-        return false;
-    };
-    let ExprKind::Struct(_, [start, end], _) = &struct_expr.kind else { return false };
-
-    // We can suggest using an inclusive range
-    // (`..=`) instead only if it is the `end` that is
-    // overflowing and only by 1.
-    if !(end.expr.hir_id == expr.hir_id && lit_val - 1 == max) {
-        return false;
-    };
-
-    use rustc_ast::{LitIntType, LitKind};
-    let suffix = match lit.node {
-        LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(),
-        LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(),
-        LitKind::Int(_, LitIntType::Unsuffixed) => "",
-        _ => bug!(),
-    };
-
-    let sub_sugg = if expr.span.lo() == lit_span.lo() {
-        let Ok(start) = cx.sess().source_map().span_to_snippet(start.span) else { return false };
-        UseInclusiveRange::WithoutParen {
-            sugg: struct_expr.span.shrink_to_lo().to(lit_span.shrink_to_hi()),
-            start,
-            literal: lit_val - 1,
-            suffix,
-        }
-    } else {
-        UseInclusiveRange::WithParen {
-            eq_sugg: expr.span.shrink_to_lo(),
-            lit_sugg: lit_span,
-            literal: lit_val - 1,
-            suffix,
-        }
-    };
-
-    cx.emit_span_lint(
-        OVERFLOWING_LITERALS,
-        struct_expr.span,
-        RangeEndpointOutOfRange { ty, sub: sub_sugg },
-    );
-
-    // We've just emitted a lint, special cased for `(...)..MAX+1` ranges,
-    // return `true` so the callers don't also emit a lint
-    true
-}
-
-// For `isize` & `usize`, be conservative with the warnings, so that the
-// warnings are consistent between 32- and 64-bit platforms.
-fn int_ty_range(int_ty: ty::IntTy) -> (i128, i128) {
-    match int_ty {
-        ty::IntTy::Isize => (i64::MIN.into(), i64::MAX.into()),
-        ty::IntTy::I8 => (i8::MIN.into(), i8::MAX.into()),
-        ty::IntTy::I16 => (i16::MIN.into(), i16::MAX.into()),
-        ty::IntTy::I32 => (i32::MIN.into(), i32::MAX.into()),
-        ty::IntTy::I64 => (i64::MIN.into(), i64::MAX.into()),
-        ty::IntTy::I128 => (i128::MIN, i128::MAX),
-    }
-}
-
-fn uint_ty_range(uint_ty: ty::UintTy) -> (u128, u128) {
-    let max = match uint_ty {
-        ty::UintTy::Usize => u64::MAX.into(),
-        ty::UintTy::U8 => u8::MAX.into(),
-        ty::UintTy::U16 => u16::MAX.into(),
-        ty::UintTy::U32 => u32::MAX.into(),
-        ty::UintTy::U64 => u64::MAX.into(),
-        ty::UintTy::U128 => u128::MAX,
-    };
-    (0, max)
-}
-
-fn get_bin_hex_repr(cx: &LateContext<'_>, lit: &hir::Lit) -> Option<String> {
-    let src = cx.sess().source_map().span_to_snippet(lit.span).ok()?;
-    let firstch = src.chars().next()?;
-
-    if firstch == '0' {
-        match src.chars().nth(1) {
-            Some('x' | 'b') => return Some(src),
-            _ => return None,
-        }
-    }
-
-    None
-}
-
-fn report_bin_hex_error(
-    cx: &LateContext<'_>,
-    expr: &hir::Expr<'_>,
-    ty: attr::IntType,
-    size: Size,
-    repr_str: String,
-    val: u128,
-    negative: bool,
-) {
-    let (t, actually) = match ty {
-        attr::IntType::SignedInt(t) => {
-            let actually = if negative { -(size.sign_extend(val)) } else { size.sign_extend(val) };
-            (t.name_str(), actually.to_string())
-        }
-        attr::IntType::UnsignedInt(t) => {
-            let actually = size.truncate(val);
-            (t.name_str(), actually.to_string())
-        }
-    };
-    let sign =
-        if negative { OverflowingBinHexSign::Negative } else { OverflowingBinHexSign::Positive };
-    let sub = get_type_suggestion(cx.typeck_results().node_type(expr.hir_id), val, negative).map(
-        |suggestion_ty| {
-            if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
-                let (sans_suffix, _) = repr_str.split_at(pos);
-                OverflowingBinHexSub::Suggestion { span: expr.span, suggestion_ty, sans_suffix }
-            } else {
-                OverflowingBinHexSub::Help { suggestion_ty }
-            }
-        },
-    );
-    let sign_bit_sub = (!negative)
-        .then(|| {
-            let ty::Int(int_ty) = cx.typeck_results().node_type(expr.hir_id).kind() else {
-                return None;
-            };
-
-            let Some(bit_width) = int_ty.bit_width() else {
-                return None; // isize case
-            };
-
-            // Skip if sign bit is not set
-            if (val & (1 << (bit_width - 1))) == 0 {
-                return None;
-            }
-
-            let lit_no_suffix =
-                if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
-                    repr_str.split_at(pos).0
-                } else {
-                    &repr_str
-                };
-
-            Some(OverflowingBinHexSignBitSub {
-                span: expr.span,
-                lit_no_suffix,
-                negative_val: actually.clone(),
-                int_ty: int_ty.name_str(),
-                uint_ty: int_ty.to_unsigned().name_str(),
-            })
-        })
-        .flatten();
-
-    cx.emit_span_lint(
-        OVERFLOWING_LITERALS,
-        expr.span,
-        OverflowingBinHex {
-            ty: t,
-            lit: repr_str.clone(),
-            dec: val,
-            actually,
-            sign,
-            sub,
-            sign_bit_sub,
-        },
-    )
-}
-
-// This function finds the next fitting type and generates a suggestion string.
-// It searches for fitting types in the following way (`X < Y`):
-//  - `iX`: if literal fits in `uX` => `uX`, else => `iY`
-//  - `-iX` => `iY`
-//  - `uX` => `uY`
-//
-// No suggestion for: `isize`, `usize`.
-fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static str> {
-    use ty::IntTy::*;
-    use ty::UintTy::*;
-    macro_rules! find_fit {
-        ($ty:expr, $val:expr, $negative:expr,
-         $($type:ident => [$($utypes:expr),*] => [$($itypes:expr),*]),+) => {
-            {
-                let _neg = if negative { 1 } else { 0 };
-                match $ty {
-                    $($type => {
-                        $(if !negative && val <= uint_ty_range($utypes).1 {
-                            return Some($utypes.name_str())
-                        })*
-                        $(if val <= int_ty_range($itypes).1 as u128 + _neg {
-                            return Some($itypes.name_str())
-                        })*
-                        None
-                    },)+
-                    _ => None
-                }
-            }
-        }
-    }
-    match t.kind() {
-        ty::Int(i) => find_fit!(i, val, negative,
-                      I8 => [U8] => [I16, I32, I64, I128],
-                      I16 => [U16] => [I32, I64, I128],
-                      I32 => [U32] => [I64, I128],
-                      I64 => [U64] => [I128],
-                      I128 => [U128] => []),
-        ty::Uint(u) => find_fit!(u, val, negative,
-                      U8 => [U8, U16, U32, U64, U128] => [],
-                      U16 => [U16, U32, U64, U128] => [],
-                      U32 => [U32, U64, U128] => [],
-                      U64 => [U64, U128] => [],
-                      U128 => [U128] => []),
-        _ => None,
-    }
-}
-
-fn lint_int_literal<'tcx>(
-    cx: &LateContext<'tcx>,
-    type_limits: &TypeLimits,
-    e: &'tcx hir::Expr<'tcx>,
-    lit: &hir::Lit,
-    t: ty::IntTy,
-    v: u128,
-) {
-    let int_type = t.normalize(cx.sess().target.pointer_width);
-    let (min, max) = int_ty_range(int_type);
-    let max = max as u128;
-    let negative = type_limits.negated_expr_id == Some(e.hir_id);
-
-    // Detect literal value out of range [min, max] inclusive
-    // avoiding use of -min to prevent overflow/panic
-    if (negative && v > max + 1) || (!negative && v > max) {
-        if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
-            report_bin_hex_error(
-                cx,
-                e,
-                attr::IntType::SignedInt(ty::ast_int_ty(t)),
-                Integer::from_int_ty(cx, t).size(),
-                repr_str,
-                v,
-                negative,
-            );
-            return;
-        }
-
-        if lint_overflowing_range_endpoint(cx, lit, v, max, e, t.name_str()) {
-            // The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
-            return;
-        }
-
-        let span = if negative { type_limits.negated_expr_span.unwrap() } else { e.span };
-        let lit = cx
-            .sess()
-            .source_map()
-            .span_to_snippet(span)
-            .unwrap_or_else(|_| if negative { format!("-{v}") } else { v.to_string() });
-        let help = get_type_suggestion(cx.typeck_results().node_type(e.hir_id), v, negative)
-            .map(|suggestion_ty| OverflowingIntHelp { suggestion_ty });
-
-        cx.emit_span_lint(
-            OVERFLOWING_LITERALS,
-            span,
-            OverflowingInt { ty: t.name_str(), lit, min, max, help },
-        );
-    }
-}
-
-fn lint_uint_literal<'tcx>(
-    cx: &LateContext<'tcx>,
-    e: &'tcx hir::Expr<'tcx>,
-    lit: &hir::Lit,
-    t: ty::UintTy,
-) {
-    let uint_type = t.normalize(cx.sess().target.pointer_width);
-    let (min, max) = uint_ty_range(uint_type);
-    let lit_val: u128 = match lit.node {
-        // _v is u8, within range by definition
-        ast::LitKind::Byte(_v) => return,
-        ast::LitKind::Int(v, _) => v.get(),
-        _ => bug!(),
-    };
-
-    if lit_val < min || lit_val > max {
-        if let Node::Expr(par_e) = cx.tcx.parent_hir_node(e.hir_id) {
-            match par_e.kind {
-                hir::ExprKind::Cast(..) => {
-                    if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() {
-                        cx.emit_span_lint(
-                            OVERFLOWING_LITERALS,
-                            par_e.span,
-                            OnlyCastu8ToChar { span: par_e.span, literal: lit_val },
-                        );
-                        return;
-                    }
-                }
-                _ => {}
-            }
-        }
-        if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, t.name_str()) {
-            // The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
-            return;
-        }
-        if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
-            report_bin_hex_error(
-                cx,
-                e,
-                attr::IntType::UnsignedInt(ty::ast_uint_ty(t)),
-                Integer::from_uint_ty(cx, t).size(),
-                repr_str,
-                lit_val,
-                false,
-            );
-            return;
-        }
-        cx.emit_span_lint(
-            OVERFLOWING_LITERALS,
-            e.span,
-            OverflowingUInt {
-                ty: t.name_str(),
-                lit: cx
-                    .sess()
-                    .source_map()
-                    .span_to_snippet(lit.span)
-                    .unwrap_or_else(|_| lit_val.to_string()),
-                min,
-                max,
-            },
-        );
-    }
-}
-
-fn lint_literal<'tcx>(
-    cx: &LateContext<'tcx>,
-    type_limits: &TypeLimits,
-    e: &'tcx hir::Expr<'tcx>,
-    lit: &hir::Lit,
-) {
-    match *cx.typeck_results().node_type(e.hir_id).kind() {
-        ty::Int(t) => {
-            match lit.node {
-                ast::LitKind::Int(v, ast::LitIntType::Signed(_) | ast::LitIntType::Unsuffixed) => {
-                    lint_int_literal(cx, type_limits, e, lit, t, v.get())
-                }
-                _ => bug!(),
-            };
-        }
-        ty::Uint(t) => lint_uint_literal(cx, e, lit, t),
-        ty::Float(t) => {
-            let (is_infinite, sym) = match lit.node {
-                ast::LitKind::Float(v, _) => match t {
-                    // FIXME(f16_f128): add this check once `is_infinite` is reliable (ABI
-                    // issues resolved).
-                    ty::FloatTy::F16 => (Ok(false), v),
-                    ty::FloatTy::F32 => (v.as_str().parse().map(f32::is_infinite), v),
-                    ty::FloatTy::F64 => (v.as_str().parse().map(f64::is_infinite), v),
-                    ty::FloatTy::F128 => (Ok(false), v),
-                },
-                _ => bug!(),
-            };
-            if is_infinite == Ok(true) {
-                cx.emit_span_lint(
-                    OVERFLOWING_LITERALS,
-                    e.span,
-                    OverflowingLiteral {
-                        ty: t.name_str(),
-                        lit: cx
-                            .sess()
-                            .source_map()
-                            .span_to_snippet(lit.span)
-                            .unwrap_or_else(|_| sym.to_string()),
-                    },
-                );
-            }
-        }
-        _ => {}
-    }
-}
-
 fn lint_nan<'tcx>(
     cx: &LateContext<'tcx>,
     e: &'tcx hir::Expr<'tcx>,
@@ -991,6 +595,8 @@ struct CTypesVisitorState<'tcx> {
     /// The original type being checked, before we recursed
     /// to any other types it contains.
     base_ty: Ty<'tcx>,
+    /// Number of times we recursed while checking the type
+    recursion_depth: usize,
 }
 
 enum FfiResult<'tcx> {
@@ -1296,12 +902,23 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
 
         // Protect against infinite recursion, for example
         // `struct S(*mut S);`.
-        // FIXME: A recursion limit is necessary as well, for irregular
-        // recursive types.
         if !acc.cache.insert(ty) {
             return FfiSafe;
         }
 
+        // Additional recursion check for more complex types like
+        // `struct A<T> { v: *const A<A<T>>, ... }` for which the
+        // cache check above won't be enough (fixes #130310)
+        if !tcx.recursion_limit().value_within_limit(acc.recursion_depth) {
+            return FfiUnsafe {
+                ty: acc.base_ty,
+                reason: fluent::lint_improper_ctypes_recursion_limit_reached,
+                help: None,
+            };
+        }
+
+        acc.recursion_depth += 1;
+
         match *ty.kind() {
             ty::Adt(def, args) => {
                 if let Some(boxed) = ty.boxed_ty()
@@ -1644,7 +1261,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             return;
         }
 
-        let mut acc = CTypesVisitorState { cache: FxHashSet::default(), base_ty: ty };
+        let mut acc =
+            CTypesVisitorState { cache: FxHashSet::default(), base_ty: ty, recursion_depth: 0 };
         match self.check_type_for_ffi(&mut acc, ty) {
             FfiResult::FfiSafe => {}
             FfiResult::FfiPhantom(ty) => {
diff --git a/compiler/rustc_lint/src/types/literal.rs b/compiler/rustc_lint/src/types/literal.rs
new file mode 100644
index 00000000000..67404be24b5
--- /dev/null
+++ b/compiler/rustc_lint/src/types/literal.rs
@@ -0,0 +1,386 @@
+use hir::{is_range_literal, ExprKind, Node};
+use rustc_middle::ty::layout::IntegerExt;
+use rustc_middle::ty::Ty;
+use rustc_middle::{bug, ty};
+use rustc_target::abi::{Integer, Size};
+use {rustc_ast as ast, rustc_attr as attr, rustc_hir as hir};
+
+use crate::context::LintContext;
+use crate::lints::{
+    OnlyCastu8ToChar, OverflowingBinHex, OverflowingBinHexSign, OverflowingBinHexSignBitSub,
+    OverflowingBinHexSub, OverflowingInt, OverflowingIntHelp, OverflowingLiteral, OverflowingUInt,
+    RangeEndpointOutOfRange, UseInclusiveRange,
+};
+use crate::types::{TypeLimits, OVERFLOWING_LITERALS};
+use crate::LateContext;
+
+/// Attempts to special-case the overflowing literal lint when it occurs as a range endpoint (`expr..MAX+1`).
+/// Returns `true` iff the lint was emitted.
+fn lint_overflowing_range_endpoint<'tcx>(
+    cx: &LateContext<'tcx>,
+    lit: &hir::Lit,
+    lit_val: u128,
+    max: u128,
+    expr: &'tcx hir::Expr<'tcx>,
+    ty: &str,
+) -> bool {
+    // Look past casts to support cases like `0..256 as u8`
+    let (expr, lit_span) = if let Node::Expr(par_expr) = cx.tcx.parent_hir_node(expr.hir_id)
+        && let ExprKind::Cast(_, _) = par_expr.kind
+    {
+        (par_expr, expr.span)
+    } else {
+        (expr, expr.span)
+    };
+
+    // We only want to handle exclusive (`..`) ranges,
+    // which are represented as `ExprKind::Struct`.
+    let Node::ExprField(field) = cx.tcx.parent_hir_node(expr.hir_id) else { return false };
+    let Node::Expr(struct_expr) = cx.tcx.parent_hir_node(field.hir_id) else { return false };
+    if !is_range_literal(struct_expr) {
+        return false;
+    };
+    let ExprKind::Struct(_, [start, end], _) = &struct_expr.kind else { return false };
+
+    // We can suggest using an inclusive range
+    // (`..=`) instead only if it is the `end` that is
+    // overflowing and only by 1.
+    if !(end.expr.hir_id == expr.hir_id && lit_val - 1 == max) {
+        return false;
+    };
+
+    use rustc_ast::{LitIntType, LitKind};
+    let suffix = match lit.node {
+        LitKind::Int(_, LitIntType::Signed(s)) => s.name_str(),
+        LitKind::Int(_, LitIntType::Unsigned(s)) => s.name_str(),
+        LitKind::Int(_, LitIntType::Unsuffixed) => "",
+        _ => bug!(),
+    };
+
+    let sub_sugg = if expr.span.lo() == lit_span.lo() {
+        let Ok(start) = cx.sess().source_map().span_to_snippet(start.span) else { return false };
+        UseInclusiveRange::WithoutParen {
+            sugg: struct_expr.span.shrink_to_lo().to(lit_span.shrink_to_hi()),
+            start,
+            literal: lit_val - 1,
+            suffix,
+        }
+    } else {
+        UseInclusiveRange::WithParen {
+            eq_sugg: expr.span.shrink_to_lo(),
+            lit_sugg: lit_span,
+            literal: lit_val - 1,
+            suffix,
+        }
+    };
+
+    cx.emit_span_lint(
+        OVERFLOWING_LITERALS,
+        struct_expr.span,
+        RangeEndpointOutOfRange { ty, sub: sub_sugg },
+    );
+
+    // We've just emitted a lint, special cased for `(...)..MAX+1` ranges,
+    // return `true` so the callers don't also emit a lint
+    true
+}
+
+// For `isize` & `usize`, be conservative with the warnings, so that the
+// warnings are consistent between 32- and 64-bit platforms.
+pub(crate) fn int_ty_range(int_ty: ty::IntTy) -> (i128, i128) {
+    match int_ty {
+        ty::IntTy::Isize => (i64::MIN.into(), i64::MAX.into()),
+        ty::IntTy::I8 => (i8::MIN.into(), i8::MAX.into()),
+        ty::IntTy::I16 => (i16::MIN.into(), i16::MAX.into()),
+        ty::IntTy::I32 => (i32::MIN.into(), i32::MAX.into()),
+        ty::IntTy::I64 => (i64::MIN.into(), i64::MAX.into()),
+        ty::IntTy::I128 => (i128::MIN, i128::MAX),
+    }
+}
+
+pub(crate) fn uint_ty_range(uint_ty: ty::UintTy) -> (u128, u128) {
+    let max = match uint_ty {
+        ty::UintTy::Usize => u64::MAX.into(),
+        ty::UintTy::U8 => u8::MAX.into(),
+        ty::UintTy::U16 => u16::MAX.into(),
+        ty::UintTy::U32 => u32::MAX.into(),
+        ty::UintTy::U64 => u64::MAX.into(),
+        ty::UintTy::U128 => u128::MAX,
+    };
+    (0, max)
+}
+
+fn get_bin_hex_repr(cx: &LateContext<'_>, lit: &hir::Lit) -> Option<String> {
+    let src = cx.sess().source_map().span_to_snippet(lit.span).ok()?;
+    let firstch = src.chars().next()?;
+
+    if firstch == '0' {
+        match src.chars().nth(1) {
+            Some('x' | 'b') => return Some(src),
+            _ => return None,
+        }
+    }
+
+    None
+}
+
+fn report_bin_hex_error(
+    cx: &LateContext<'_>,
+    expr: &hir::Expr<'_>,
+    ty: attr::IntType,
+    size: Size,
+    repr_str: String,
+    val: u128,
+    negative: bool,
+) {
+    let (t, actually) = match ty {
+        attr::IntType::SignedInt(t) => {
+            let actually = if negative { -(size.sign_extend(val)) } else { size.sign_extend(val) };
+            (t.name_str(), actually.to_string())
+        }
+        attr::IntType::UnsignedInt(t) => {
+            let actually = size.truncate(val);
+            (t.name_str(), actually.to_string())
+        }
+    };
+    let sign =
+        if negative { OverflowingBinHexSign::Negative } else { OverflowingBinHexSign::Positive };
+    let sub = get_type_suggestion(cx.typeck_results().node_type(expr.hir_id), val, negative).map(
+        |suggestion_ty| {
+            if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
+                let (sans_suffix, _) = repr_str.split_at(pos);
+                OverflowingBinHexSub::Suggestion { span: expr.span, suggestion_ty, sans_suffix }
+            } else {
+                OverflowingBinHexSub::Help { suggestion_ty }
+            }
+        },
+    );
+    let sign_bit_sub = (!negative)
+        .then(|| {
+            let ty::Int(int_ty) = cx.typeck_results().node_type(expr.hir_id).kind() else {
+                return None;
+            };
+
+            let Some(bit_width) = int_ty.bit_width() else {
+                return None; // isize case
+            };
+
+            // Skip if sign bit is not set
+            if (val & (1 << (bit_width - 1))) == 0 {
+                return None;
+            }
+
+            let lit_no_suffix =
+                if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
+                    repr_str.split_at(pos).0
+                } else {
+                    &repr_str
+                };
+
+            Some(OverflowingBinHexSignBitSub {
+                span: expr.span,
+                lit_no_suffix,
+                negative_val: actually.clone(),
+                int_ty: int_ty.name_str(),
+                uint_ty: int_ty.to_unsigned().name_str(),
+            })
+        })
+        .flatten();
+
+    cx.emit_span_lint(
+        OVERFLOWING_LITERALS,
+        expr.span,
+        OverflowingBinHex {
+            ty: t,
+            lit: repr_str.clone(),
+            dec: val,
+            actually,
+            sign,
+            sub,
+            sign_bit_sub,
+        },
+    )
+}
+
+// Find the "next" fitting integer and return a suggestion string
+//
+// No suggestion is offered for `{i,u}size`. Otherwise, we try to suggest an equal-sized type.
+fn get_type_suggestion(t: Ty<'_>, val: u128, negative: bool) -> Option<&'static str> {
+    match t.kind() {
+        ty::Uint(ty::UintTy::Usize) | ty::Int(ty::IntTy::Isize) => None,
+        ty::Uint(_) => Some(Integer::fit_unsigned(val).uint_ty_str()),
+        ty::Int(_) if negative => Some(Integer::fit_signed(-(val as i128)).int_ty_str()),
+        ty::Int(int) => {
+            let signed = Integer::fit_signed(val as i128);
+            let unsigned = Integer::fit_unsigned(val);
+            Some(if Some(unsigned.size().bits()) == int.bit_width() {
+                unsigned.uint_ty_str()
+            } else {
+                signed.int_ty_str()
+            })
+        }
+        _ => None,
+    }
+}
+
+fn lint_int_literal<'tcx>(
+    cx: &LateContext<'tcx>,
+    type_limits: &TypeLimits,
+    e: &'tcx hir::Expr<'tcx>,
+    lit: &hir::Lit,
+    t: ty::IntTy,
+    v: u128,
+) {
+    let int_type = t.normalize(cx.sess().target.pointer_width);
+    let (min, max) = int_ty_range(int_type);
+    let max = max as u128;
+    let negative = type_limits.negated_expr_id == Some(e.hir_id);
+
+    // Detect literal value out of range [min, max] inclusive
+    // avoiding use of -min to prevent overflow/panic
+    if (negative && v > max + 1) || (!negative && v > max) {
+        if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
+            report_bin_hex_error(
+                cx,
+                e,
+                attr::IntType::SignedInt(ty::ast_int_ty(t)),
+                Integer::from_int_ty(cx, t).size(),
+                repr_str,
+                v,
+                negative,
+            );
+            return;
+        }
+
+        if lint_overflowing_range_endpoint(cx, lit, v, max, e, t.name_str()) {
+            // The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
+            return;
+        }
+
+        let span = if negative { type_limits.negated_expr_span.unwrap() } else { e.span };
+        let lit = cx
+            .sess()
+            .source_map()
+            .span_to_snippet(span)
+            .unwrap_or_else(|_| if negative { format!("-{v}") } else { v.to_string() });
+        let help = get_type_suggestion(cx.typeck_results().node_type(e.hir_id), v, negative)
+            .map(|suggestion_ty| OverflowingIntHelp { suggestion_ty });
+
+        cx.emit_span_lint(
+            OVERFLOWING_LITERALS,
+            span,
+            OverflowingInt { ty: t.name_str(), lit, min, max, help },
+        );
+    }
+}
+
+fn lint_uint_literal<'tcx>(
+    cx: &LateContext<'tcx>,
+    e: &'tcx hir::Expr<'tcx>,
+    lit: &hir::Lit,
+    t: ty::UintTy,
+) {
+    let uint_type = t.normalize(cx.sess().target.pointer_width);
+    let (min, max) = uint_ty_range(uint_type);
+    let lit_val: u128 = match lit.node {
+        // _v is u8, within range by definition
+        ast::LitKind::Byte(_v) => return,
+        ast::LitKind::Int(v, _) => v.get(),
+        _ => bug!(),
+    };
+
+    if lit_val < min || lit_val > max {
+        if let Node::Expr(par_e) = cx.tcx.parent_hir_node(e.hir_id) {
+            match par_e.kind {
+                hir::ExprKind::Cast(..) => {
+                    if let ty::Char = cx.typeck_results().expr_ty(par_e).kind() {
+                        cx.emit_span_lint(
+                            OVERFLOWING_LITERALS,
+                            par_e.span,
+                            OnlyCastu8ToChar { span: par_e.span, literal: lit_val },
+                        );
+                        return;
+                    }
+                }
+                _ => {}
+            }
+        }
+        if lint_overflowing_range_endpoint(cx, lit, lit_val, max, e, t.name_str()) {
+            // The overflowing literal lint was emitted by `lint_overflowing_range_endpoint`.
+            return;
+        }
+        if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
+            report_bin_hex_error(
+                cx,
+                e,
+                attr::IntType::UnsignedInt(ty::ast_uint_ty(t)),
+                Integer::from_uint_ty(cx, t).size(),
+                repr_str,
+                lit_val,
+                false,
+            );
+            return;
+        }
+        cx.emit_span_lint(
+            OVERFLOWING_LITERALS,
+            e.span,
+            OverflowingUInt {
+                ty: t.name_str(),
+                lit: cx
+                    .sess()
+                    .source_map()
+                    .span_to_snippet(lit.span)
+                    .unwrap_or_else(|_| lit_val.to_string()),
+                min,
+                max,
+            },
+        );
+    }
+}
+
+pub(crate) fn lint_literal<'tcx>(
+    cx: &LateContext<'tcx>,
+    type_limits: &TypeLimits,
+    e: &'tcx hir::Expr<'tcx>,
+    lit: &hir::Lit,
+) {
+    match *cx.typeck_results().node_type(e.hir_id).kind() {
+        ty::Int(t) => {
+            match lit.node {
+                ast::LitKind::Int(v, ast::LitIntType::Signed(_) | ast::LitIntType::Unsuffixed) => {
+                    lint_int_literal(cx, type_limits, e, lit, t, v.get())
+                }
+                _ => bug!(),
+            };
+        }
+        ty::Uint(t) => lint_uint_literal(cx, e, lit, t),
+        ty::Float(t) => {
+            let (is_infinite, sym) = match lit.node {
+                ast::LitKind::Float(v, _) => match t {
+                    // FIXME(f16_f128): add this check once `is_infinite` is reliable (ABI
+                    // issues resolved).
+                    ty::FloatTy::F16 => (Ok(false), v),
+                    ty::FloatTy::F32 => (v.as_str().parse().map(f32::is_infinite), v),
+                    ty::FloatTy::F64 => (v.as_str().parse().map(f64::is_infinite), v),
+                    ty::FloatTy::F128 => (Ok(false), v),
+                },
+                _ => bug!(),
+            };
+            if is_infinite == Ok(true) {
+                cx.emit_span_lint(
+                    OVERFLOWING_LITERALS,
+                    e.span,
+                    OverflowingLiteral {
+                        ty: t.name_str(),
+                        lit: cx
+                            .sess()
+                            .source_map()
+                            .span_to_snippet(lit.span)
+                            .unwrap_or_else(|_| sym.to_string()),
+                    },
+                );
+            }
+        }
+        _ => {}
+    }
+}
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 9b6d63c2ef4..acdedb06141 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -99,7 +99,6 @@ declare_lint_pass! {
         SINGLE_USE_LIFETIMES,
         SOFT_UNSTABLE,
         STABLE_FEATURES,
-        STATIC_MUT_REFS,
         TEST_UNSTABLE_LINT,
         TEXT_DIRECTION_CODEPOINT_IN_COMMENT,
         TRIVIAL_CASTS,
@@ -1928,57 +1927,6 @@ declare_lint! {
 }
 
 declare_lint! {
-    /// The `static_mut_refs` lint checks for shared or mutable references
-    /// of mutable static inside `unsafe` blocks and `unsafe` functions.
-    ///
-    /// ### Example
-    ///
-    /// ```rust,edition2021
-    /// fn main() {
-    ///     static mut X: i32 = 23;
-    ///     static mut Y: i32 = 24;
-    ///
-    ///     unsafe {
-    ///         let y = &X;
-    ///         let ref x = X;
-    ///         let (x, y) = (&X, &Y);
-    ///         foo(&X);
-    ///     }
-    /// }
-    ///
-    /// unsafe fn _foo() {
-    ///     static mut X: i32 = 23;
-    ///     static mut Y: i32 = 24;
-    ///
-    ///     let y = &X;
-    ///     let ref x = X;
-    ///     let (x, y) = (&X, &Y);
-    ///     foo(&X);
-    /// }
-    ///
-    /// fn foo<'a>(_x: &'a i32) {}
-    /// ```
-    ///
-    /// {{produces}}
-    ///
-    /// ### Explanation
-    ///
-    /// Shared or mutable references of mutable static are almost always a mistake and
-    /// can lead to undefined behavior and various other problems in your code.
-    ///
-    /// This lint is "warn" by default on editions up to 2021, in 2024 there is
-    /// a hard error instead.
-    pub STATIC_MUT_REFS,
-    Warn,
-    "shared references or mutable references of mutable static is discouraged",
-    @future_incompatible = FutureIncompatibleInfo {
-        reason: FutureIncompatibilityReason::EditionError(Edition::Edition2024),
-        reference: "issue #114447 <https://github.com/rust-lang/rust/issues/114447>",
-        explain_reason: false,
-    };
-}
-
-declare_lint! {
     /// The `absolute_paths_not_starting_with_crate` lint detects fully
     /// qualified paths that start with a module name instead of `crate`,
     /// `self`, or an extern crate name
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 5c4b7e5664d..f5ed69658ce 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -12,7 +12,7 @@ use rustc_error_messages::{DiagMessage, MultiSpan};
 use rustc_hir::def::Namespace;
 use rustc_hir::{HashStableContext, HirId, MissingLifetimeKind};
 use rustc_macros::{Decodable, Encodable, HashStable_Generic};
-use rustc_span::edition::Edition;
+pub use rustc_span::edition::Edition;
 use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent};
 use rustc_span::{sym, Span, Symbol};
 use rustc_target::spec::abi::Abi;
diff --git a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
index a8c278741a7..feac6a5649c 100644
--- a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
@@ -196,14 +196,10 @@ extern "C" LLVMRustResult LLVMRustWriteArchive(
     }
   }
 
-#if LLVM_VERSION_LT(18, 0)
-  auto Result = writeArchive(Dst, Members, WriteSymbtab, Kind, true, false);
-#else
   auto SymtabMode = WriteSymbtab ? SymtabWritingMode::NormalSymtab
                                  : SymtabWritingMode::NoSymtab;
   auto Result =
       writeArchive(Dst, Members, SymtabMode, Kind, true, false, nullptr, isEC);
-#endif
   if (!Result)
     return LLVMRustResult::Success;
   LLVMRustSetLastError(toString(std::move(Result)).c_str());
diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
index e842f47f48c..4532fd8d48d 100644
--- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
@@ -58,17 +58,10 @@ fromRust(LLVMRustCounterMappingRegionKind Kind) {
     return coverage::CounterMappingRegion::GapRegion;
   case LLVMRustCounterMappingRegionKind::BranchRegion:
     return coverage::CounterMappingRegion::BranchRegion;
-#if LLVM_VERSION_GE(18, 0)
   case LLVMRustCounterMappingRegionKind::MCDCDecisionRegion:
     return coverage::CounterMappingRegion::MCDCDecisionRegion;
   case LLVMRustCounterMappingRegionKind::MCDCBranchRegion:
     return coverage::CounterMappingRegion::MCDCBranchRegion;
-#else
-  case LLVMRustCounterMappingRegionKind::MCDCDecisionRegion:
-    break;
-  case LLVMRustCounterMappingRegionKind::MCDCBranchRegion:
-    break;
-#endif
   }
   report_fatal_error("Bad LLVMRustCounterMappingRegionKind!");
 }
@@ -100,7 +93,7 @@ struct LLVMRustMCDCParameters {
 // https://github.com/rust-lang/llvm-project/blob/66a2881a/llvm/include/llvm/ProfileData/Coverage/CoverageMapping.h#L253-L263
 // and representations in 19
 // https://github.com/llvm/llvm-project/blob/843cc474faefad1d639f4c44c1cf3ad7dbda76c8/llvm/include/llvm/ProfileData/Coverage/MCDCTypes.h
-#if LLVM_VERSION_GE(18, 0) && LLVM_VERSION_LT(19, 0)
+#if LLVM_VERSION_LT(19, 0)
 static coverage::CounterMappingRegion::MCDCParameters
 fromRust(LLVMRustMCDCParameters Params) {
   auto parameter = coverage::CounterMappingRegion::MCDCParameters{};
@@ -126,7 +119,7 @@ fromRust(LLVMRustMCDCParameters Params) {
   }
   report_fatal_error("Bad LLVMRustMCDCParametersTag!");
 }
-#elif LLVM_VERSION_GE(19, 0)
+#else
 static coverage::mcdc::Parameters fromRust(LLVMRustMCDCParameters Params) {
   switch (Params.Tag) {
   case LLVMRustMCDCParametersTag::None:
@@ -221,7 +214,7 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer(
            RustMappingRegions, NumMappingRegions)) {
     MappingRegions.emplace_back(
         fromRust(Region.Count), fromRust(Region.FalseCount),
-#if LLVM_VERSION_GE(18, 0) && LLVM_VERSION_LT(19, 0)
+#if LLVM_VERSION_LT(19, 0)
         // LLVM 19 may move this argument to last.
         fromRust(Region.MCDCParameters),
 #endif
diff --git a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
index a493abbbc7e..73bbc9de855 100644
--- a/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
+++ b/compiler/rustc_llvm/llvm-wrapper/LLVMWrapper.h
@@ -25,7 +25,6 @@
 #include "llvm/Target/TargetMachine.h"
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/Transforms/IPO.h"
-#include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/Scalar.h"
 
 #define LLVM_VERSION_GE(major, minor)                                          \
@@ -34,6 +33,12 @@
 
 #define LLVM_VERSION_LT(major, minor) (!LLVM_VERSION_GE((major), (minor)))
 
+#if LLVM_VERSION_GE(20, 0)
+#include "llvm/Transforms/Utils/Instrumentation.h"
+#else
+#include "llvm/Transforms/Instrumentation.h"
+#endif
+
 #include "llvm/IR/LegacyPassManager.h"
 
 #include "llvm/Bitcode/BitcodeReader.h"
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index da27db29c87..9f3e0080110 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -26,22 +26,19 @@
 #include "llvm/Passes/StandardInstrumentations.h"
 #include "llvm/Support/CBindingWrapping.h"
 #include "llvm/Support/FileSystem.h"
+#include "llvm/Support/TimeProfiler.h"
 #include "llvm/Support/VirtualFileSystem.h"
 #include "llvm/Target/TargetMachine.h"
+#include "llvm/TargetParser/Host.h"
 #include "llvm/Transforms/IPO/AlwaysInliner.h"
 #include "llvm/Transforms/IPO/FunctionImport.h"
 #include "llvm/Transforms/IPO/Internalize.h"
 #include "llvm/Transforms/IPO/LowerTypeTests.h"
 #include "llvm/Transforms/IPO/ThinLTOBitcodeWriter.h"
-#include "llvm/Transforms/Utils/AddDiscriminators.h"
-#include "llvm/Transforms/Utils/FunctionImportUtils.h"
-#if LLVM_VERSION_GE(18, 0)
-#include "llvm/TargetParser/Host.h"
-#endif
-#include "llvm/Support/TimeProfiler.h"
-#include "llvm/Transforms/Instrumentation.h"
 #include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
 #include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
+#include "llvm/Transforms/Utils/AddDiscriminators.h"
+#include "llvm/Transforms/Utils/FunctionImportUtils.h"
 #if LLVM_VERSION_GE(19, 0)
 #include "llvm/Support/PGOOptions.h"
 #endif
@@ -241,11 +238,7 @@ enum class LLVMRustCodeGenOptLevel {
   Aggressive,
 };
 
-#if LLVM_VERSION_GE(18, 0)
 using CodeGenOptLevelEnum = llvm::CodeGenOptLevel;
-#else
-using CodeGenOptLevelEnum = llvm::CodeGenOpt::Level;
-#endif
 
 static CodeGenOptLevelEnum fromRust(LLVMRustCodeGenOptLevel Level) {
   switch (Level) {
@@ -371,21 +364,16 @@ extern "C" void LLVMRustPrintTargetCPUs(LLVMTargetMachineRef TM,
 }
 
 extern "C" size_t LLVMRustGetTargetFeaturesCount(LLVMTargetMachineRef TM) {
-#if LLVM_VERSION_GE(18, 0)
   const TargetMachine *Target = unwrap(TM);
   const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
   const ArrayRef<SubtargetFeatureKV> FeatTable =
       MCInfo->getAllProcessorFeatures();
   return FeatTable.size();
-#else
-  return 0;
-#endif
 }
 
 extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef TM, size_t Index,
                                          const char **Feature,
                                          const char **Desc) {
-#if LLVM_VERSION_GE(18, 0)
   const TargetMachine *Target = unwrap(TM);
   const MCSubtargetInfo *MCInfo = Target->getMCSubtargetInfo();
   const ArrayRef<SubtargetFeatureKV> FeatTable =
@@ -393,7 +381,6 @@ extern "C" void LLVMRustGetTargetFeature(LLVMTargetMachineRef TM, size_t Index,
   const SubtargetFeatureKV Feat = FeatTable[Index];
   *Feature = Feat.Key;
   *Desc = Feat.Desc;
-#endif
 }
 
 extern "C" const char *LLVMRustGetHostCPUName(size_t *len) {
@@ -570,17 +557,9 @@ enum class LLVMRustFileType {
 static CodeGenFileType fromRust(LLVMRustFileType Type) {
   switch (Type) {
   case LLVMRustFileType::AssemblyFile:
-#if LLVM_VERSION_GE(18, 0)
     return CodeGenFileType::AssemblyFile;
-#else
-    return CGFT_AssemblyFile;
-#endif
   case LLVMRustFileType::ObjectFile:
-#if LLVM_VERSION_GE(18, 0)
     return CodeGenFileType::ObjectFile;
-#else
-    return CGFT_ObjectFile;
-#endif
   default:
     report_fatal_error("Bad FileType.");
   }
@@ -866,11 +845,7 @@ extern "C" LLVMRustResult LLVMRustOptimize(
           // cargo run tests in multhreading mode by default
           // so use atomics for coverage counters
           Options.Atomic = true;
-#if LLVM_VERSION_GE(18, 0)
           MPM.addPass(InstrProfilingLoweringPass(Options, false));
-#else
-          MPM.addPass(InstrProfiling(Options, false));
-#endif
         });
   }
 
@@ -1211,7 +1186,6 @@ struct LLVMRustThinLTOData {
 
   // Not 100% sure what these are, but they impact what's internalized and
   // what's inlined across modules, I believe.
-#if LLVM_VERSION_GE(18, 0)
 #if LLVM_VERSION_GE(20, 0)
   FunctionImporter::ImportListsTy ImportLists;
 #else
@@ -1219,11 +1193,6 @@ struct LLVMRustThinLTOData {
 #endif
   DenseMap<StringRef, FunctionImporter::ExportSetTy> ExportLists;
   DenseMap<StringRef, GVSummaryMapTy> ModuleToDefinedGVSummaries;
-#else
-  StringMap<FunctionImporter::ImportMapTy> ImportLists;
-  StringMap<FunctionImporter::ExportSetTy> ExportLists;
-  StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
-#endif
   StringMap<std::map<GlobalValue::GUID, GlobalValue::LinkageTypes>> ResolvedODR;
 
   LLVMRustThinLTOData() : Index(/* HaveGVs = */ false) {}
@@ -1275,11 +1244,7 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules, int num_modules,
 
     Ret->ModuleMap[module->identifier] = mem_buffer;
 
-#if LLVM_VERSION_GE(18, 0)
     if (Error Err = readModuleSummaryIndex(mem_buffer, Ret->Index)) {
-#else
-    if (Error Err = readModuleSummaryIndex(mem_buffer, Ret->Index, i)) {
-#endif
       LLVMRustSetLastError(toString(std::move(Err)).c_str());
       return nullptr;
     }
@@ -1425,13 +1390,13 @@ LLVMRustPrepareThinLTOInternalize(const LLVMRustThinLTOData *Data,
   return true;
 }
 
-extern "C" bool LLVMRustPrepareThinLTOImport(LLVMRustThinLTOData *Data,
+extern "C" bool LLVMRustPrepareThinLTOImport(const LLVMRustThinLTOData *Data,
                                              LLVMModuleRef M,
                                              LLVMTargetMachineRef TM) {
   Module &Mod = *unwrap(M);
   TargetMachine &Target = *unwrap(TM);
 
-  const auto &ImportList = Data->ImportLists[Mod.getModuleIdentifier()];
+  const auto &ImportList = Data->ImportLists.lookup(Mod.getModuleIdentifier());
   auto Loader = [&](StringRef Identifier) {
     const auto &Memory = Data->ModuleMap.lookup(Identifier);
     auto &Context = Mod.getContext();
@@ -1614,7 +1579,7 @@ extern "C" void LLVMRustComputeLTOCacheKey(RustStringRef KeyOut,
                                            LLVMRustThinLTOData *Data) {
   SmallString<40> Key;
   llvm::lto::Config conf;
-  const auto &ImportList = Data->ImportLists[ModId];
+  const auto &ImportList = Data->ImportLists.lookup(ModId);
   const auto &ExportList = Data->ExportLists.lookup(ModId);
   const auto &ResolvedODR = Data->ResolvedODR.lookup(ModId);
   const auto &DefinedGlobals = Data->ModuleToDefinedGVSummaries.lookup(ModId);
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index ed12318c88d..f9fc2bd6da3 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -310,16 +310,10 @@ static Attribute::AttrKind fromRust(LLVMRustAttribute Kind) {
     return Attribute::SafeStack;
   case FnRetThunkExtern:
     return Attribute::FnRetThunkExtern;
-#if LLVM_VERSION_GE(18, 0)
   case Writable:
     return Attribute::Writable;
   case DeadOnUnwind:
     return Attribute::DeadOnUnwind;
-#else
-  case Writable:
-  case DeadOnUnwind:
-    report_fatal_error("Not supported on this LLVM version");
-#endif
   }
   report_fatal_error("bad AttributeKind");
 }
@@ -1061,11 +1055,7 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateStaticMemberType(
   return wrap(Builder->createStaticMemberType(
       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
       unwrapDI<DIFile>(File), LineNo, unwrapDI<DIType>(Ty), fromRust(Flags),
-      unwrap<llvm::ConstantInt>(val),
-#if LLVM_VERSION_GE(18, 0)
-      llvm::dwarf::DW_TAG_member,
-#endif
-      AlignInBits));
+      unwrap<llvm::ConstantInt>(val), llvm::dwarf::DW_TAG_member, AlignInBits));
 }
 
 extern "C" LLVMMetadataRef
@@ -1182,10 +1172,7 @@ extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateEnumerationType(
       unwrapDI<DIDescriptor>(Scope), StringRef(Name, NameLen),
       unwrapDI<DIFile>(File), LineNumber, SizeInBits, AlignInBits,
       DINodeArray(unwrapDI<MDTuple>(Elements)), unwrapDI<DIType>(ClassTy),
-#if LLVM_VERSION_GE(18, 0)
-      /* RunTimeLang */ 0,
-#endif
-      "", IsScoped));
+      /* RunTimeLang */ 0, "", IsScoped));
 }
 
 extern "C" LLVMMetadataRef LLVMRustDIBuilderCreateUnionType(
@@ -1552,27 +1539,19 @@ LLVMRustGetInstrProfIncrementIntrinsic(LLVMModuleRef M) {
 
 extern "C" LLVMValueRef
 LLVMRustGetInstrProfMCDCParametersIntrinsic(LLVMModuleRef M) {
-#if LLVM_VERSION_GE(18, 0)
   return wrap(llvm::Intrinsic::getDeclaration(
       unwrap(M), llvm::Intrinsic::instrprof_mcdc_parameters));
-#else
-  report_fatal_error("LLVM 18.0 is required for mcdc intrinsic functions");
-#endif
 }
 
 extern "C" LLVMValueRef
 LLVMRustGetInstrProfMCDCTVBitmapUpdateIntrinsic(LLVMModuleRef M) {
-#if LLVM_VERSION_GE(18, 0)
   return wrap(llvm::Intrinsic::getDeclaration(
       unwrap(M), llvm::Intrinsic::instrprof_mcdc_tvbitmap_update));
-#else
-  report_fatal_error("LLVM 18.0 is required for mcdc intrinsic functions");
-#endif
 }
 
 extern "C" LLVMValueRef
 LLVMRustGetInstrProfMCDCCondBitmapIntrinsic(LLVMModuleRef M) {
-#if LLVM_VERSION_GE(18, 0) && LLVM_VERSION_LT(19, 0)
+#if LLVM_VERSION_LT(19, 0)
   return wrap(llvm::Intrinsic::getDeclaration(
       unwrap(M), llvm::Intrinsic::instrprof_mcdc_condbitmap_update));
 #else
diff --git a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
index d625935d925..54ee79dc290 100644
--- a/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/SymbolWrapper.cpp
@@ -150,11 +150,9 @@ extern "C" bool LLVMRustIsECObject(char *BufPtr, size_t BufLen) {
     return cast<llvm::object::COFFObjectFile>(&*Obj)->getMachine() !=
            COFF::IMAGE_FILE_MACHINE_ARM64;
 
-#if LLVM_VERSION_GE(18, 0)
   if (Obj->isCOFFImportFile())
     return cast<llvm::object::COFFImportFile>(&*Obj)->getMachine() !=
            COFF::IMAGE_FILE_MACHINE_ARM64;
-#endif
 
   if (Obj->isIR()) {
     Expected<std::string> TripleStr =
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index 53da07aeaa6..b9d287730fa 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -290,6 +290,7 @@ provide! { tcx, def_id, other, cdata,
     fn_arg_names => { table }
     coroutine_kind => { table_direct }
     coroutine_for_closure => { table }
+    coroutine_by_move_body_def_id => { table }
     eval_static_initializer => {
         Ok(cdata
             .root
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index b617d5236b9..46dc0696638 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1488,9 +1488,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             if def_kind == DefKind::Closure
                 && tcx.type_of(def_id).skip_binder().is_coroutine_closure()
             {
+                let coroutine_for_closure = self.tcx.coroutine_for_closure(def_id);
                 self.tables
                     .coroutine_for_closure
-                    .set_some(def_id.index, self.tcx.coroutine_for_closure(def_id).into());
+                    .set_some(def_id.index, coroutine_for_closure.into());
+
+                // If this async closure has a by-move body, record it too.
+                if tcx.needs_coroutine_by_move_body_def_id(coroutine_for_closure) {
+                    self.tables.coroutine_by_move_body_def_id.set_some(
+                        coroutine_for_closure.index,
+                        self.tcx.coroutine_by_move_body_def_id(coroutine_for_closure).into(),
+                    );
+                }
             }
             if let DefKind::Static { .. } = def_kind {
                 if !self.tcx.is_foreign_item(def_id) {
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 8180a507a51..c791a1f541c 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -446,6 +446,7 @@ define_tables! {
     fn_arg_names: Table<DefIndex, LazyArray<Ident>>,
     coroutine_kind: Table<DefIndex, hir::CoroutineKind>,
     coroutine_for_closure: Table<DefIndex, RawDefId>,
+    coroutine_by_move_body_def_id: Table<DefIndex, RawDefId>,
     eval_static_initializer: Table<DefIndex, LazyValue<mir::interpret::ConstAllocation<'static>>>,
     trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
     trait_item_def_id: Table<DefIndex, RawDefId>,
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index fd6e2ad79b1..23cd247e884 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -33,6 +33,7 @@
 #![feature(allocator_api)]
 #![feature(array_windows)]
 #![feature(assert_matches)]
+#![feature(associated_type_defaults)]
 #![feature(box_as_ptr)]
 #![feature(box_patterns)]
 #![feature(closure_track_caller)]
diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs
index 1236c9efb41..5a32078760e 100644
--- a/compiler/rustc_middle/src/ty/adjustment.rs
+++ b/compiler/rustc_middle/src/ty/adjustment.rs
@@ -104,6 +104,9 @@ pub enum Adjust<'tcx> {
 
     /// Cast into a dyn* object.
     DynStar,
+
+    /// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`.
+    ReborrowPin(ty::Region<'tcx>, hir::Mutability),
 }
 
 /// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 6708ae60562..1a584cf2890 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -521,6 +521,10 @@ impl<'tcx> Const<'tcx> {
         self.try_to_valtree()?.try_to_scalar()
     }
 
+    pub fn try_to_bool(self) -> Option<bool> {
+        self.try_to_scalar()?.to_bool().ok()
+    }
+
     #[inline]
     pub fn try_to_target_usize(self, tcx: TyCtxt<'tcx>) -> Option<u64> {
         self.try_to_valtree()?.try_to_target_usize(tcx)
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 6d878ab7654..877c54c5649 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -627,7 +627,7 @@ pub type TyAndLayout<'tcx> = rustc_target::abi::TyAndLayout<'tcx, Ty<'tcx>>;
 pub trait LayoutOfHelpers<'tcx>: HasDataLayout + HasTyCtxt<'tcx> + HasParamEnv<'tcx> {
     /// The `TyAndLayout`-wrapping type (or `TyAndLayout` itself), which will be
     /// returned from `layout_of` (see also `handle_layout_err`).
-    type LayoutOfResult: MaybeResult<TyAndLayout<'tcx>>;
+    type LayoutOfResult: MaybeResult<TyAndLayout<'tcx>> = TyAndLayout<'tcx>;
 
     /// `Span` to use for `tcx.at(span)`, from `layout_of`.
     // FIXME(eddyb) perhaps make this mandatory to get contexts to track it better?
@@ -1233,7 +1233,7 @@ pub enum FnAbiRequest<'tcx> {
 pub trait FnAbiOfHelpers<'tcx>: LayoutOfHelpers<'tcx> {
     /// The `&FnAbi`-wrapping type (or `&FnAbi` itself), which will be
     /// returned from `fn_abi_of_*` (see also `handle_fn_abi_err`).
-    type FnAbiOfResult: MaybeResult<&'tcx FnAbi<'tcx, Ty<'tcx>>>;
+    type FnAbiOfResult: MaybeResult<&'tcx FnAbi<'tcx, Ty<'tcx>>> = &'tcx FnAbi<'tcx, Ty<'tcx>>;
 
     /// Helper used for `fn_abi_of_*`, to adapt `tcx.fn_abi_of_*(...)` into a
     /// `Self::FnAbiOfResult` (which does not need to be a `Result<...>`).
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index 9e429f5a4c7..6163fa2932d 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -56,7 +56,7 @@ impl<'tcx> Value<TyCtxt<'tcx>> for ty::Binder<'_, ty::FnSig<'_>> {
             && let Some(node) = tcx.hir().get_if_local(def_id)
             && let Some(sig) = node.fn_sig()
         {
-            sig.decl.inputs.len() + sig.decl.implicit_self.has_implicit_self() as usize
+            sig.decl.inputs.len()
         } else {
             tcx.dcx().abort_if_errors();
             unreachable!()
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index c7fcfe3ce2a..4fe984b961e 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -218,6 +218,13 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
                 warnings: self.warnings,
                 suggest_unsafe_block: self.suggest_unsafe_block,
             };
+            // params in THIR may be unsafe, e.g. a union pattern.
+            for param in &inner_thir.params {
+                if let Some(param_pat) = param.pat.as_deref() {
+                    inner_visitor.visit_pat(param_pat);
+                }
+            }
+            // Visit the body.
             inner_visitor.visit_expr(&inner_thir[expr]);
             // Unsafe blocks can be used in the inner body, make sure to take it into account
             self.safety_context = inner_visitor.safety_context;
@@ -315,14 +322,15 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 | PatKind::DerefPattern { .. }
                 | PatKind::Range { .. }
                 | PatKind::Slice { .. }
-                | PatKind::Array { .. } => {
+                | PatKind::Array { .. }
+                // Never constitutes a witness of uninhabitedness.
+                | PatKind::Never => {
                     self.requires_unsafe(pat.span, AccessToUnionField);
                     return; // we can return here since this already requires unsafe
                 }
-                // wildcard/never don't take anything
+                // wildcard doesn't read anything.
                 PatKind::Wild |
-                PatKind::Never |
-                // these just wrap other patterns
+                // these just wrap other patterns, which we recurse on below.
                 PatKind::Or { .. } |
                 PatKind::InlineConstant { .. } |
                 PatKind::AscribeUserType { .. } |
@@ -1032,6 +1040,13 @@ pub(crate) fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
         warnings: &mut warnings,
         suggest_unsafe_block: true,
     };
+    // params in THIR may be unsafe, e.g. a union pattern.
+    for param in &thir.params {
+        if let Some(param_pat) = param.pat.as_deref() {
+            visitor.visit_pat(param_pat);
+        }
+    }
+    // Visit the body.
     visitor.visit_expr(&thir[expr]);
 
     warnings.sort_by_key(|w| w.block_span);
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index aa8ccc8b7dd..3f730b5d183 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -74,6 +74,7 @@ impl<'tcx> Cx<'tcx> {
         self.thir.exprs.push(expr)
     }
 
+    #[instrument(level = "trace", skip(self, expr, span))]
     fn apply_adjustment(
         &mut self,
         hir_expr: &'tcx hir::Expr<'tcx>,
@@ -146,6 +147,67 @@ impl<'tcx> Cx<'tcx> {
                 ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
             }
             Adjust::DynStar => ExprKind::Cast { source: self.thir.exprs.push(expr) },
+            Adjust::ReborrowPin(region, mutbl) => {
+                debug!("apply ReborrowPin adjustment");
+                // Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }`
+
+                // We'll need these types later on
+                let pin_ty_args = match expr.ty.kind() {
+                    ty::Adt(_, args) => args,
+                    _ => bug!("ReborrowPin with non-Pin type"),
+                };
+                let pin_ty = pin_ty_args.iter().next().unwrap().expect_ty();
+                let ptr_target_ty = match pin_ty.kind() {
+                    ty::Ref(_, ty, _) => *ty,
+                    _ => bug!("ReborrowPin with non-Ref type"),
+                };
+
+                // pointer = ($expr).__pointer
+                let pointer_target = ExprKind::Field {
+                    lhs: self.thir.exprs.push(expr),
+                    variant_index: FIRST_VARIANT,
+                    name: FieldIdx::from(0u32),
+                };
+                let arg = Expr { temp_lifetime, ty: pin_ty, span, kind: pointer_target };
+                let arg = self.thir.exprs.push(arg);
+
+                // arg = *pointer
+                let expr = ExprKind::Deref { arg };
+                let arg = self.thir.exprs.push(Expr {
+                    temp_lifetime,
+                    ty: ptr_target_ty,
+                    span,
+                    kind: expr,
+                });
+
+                // expr = &mut target
+                let borrow_kind = match mutbl {
+                    hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
+                    hir::Mutability::Not => BorrowKind::Shared,
+                };
+                let new_pin_target = Ty::new_ref(self.tcx, region, ptr_target_ty, mutbl);
+                let expr = self.thir.exprs.push(Expr {
+                    temp_lifetime,
+                    ty: new_pin_target,
+                    span,
+                    kind: ExprKind::Borrow { borrow_kind, arg },
+                });
+
+                // kind = Pin { __pointer: pointer }
+                let pin_did = self.tcx.require_lang_item(rustc_hir::LangItem::Pin, Some(span));
+                let args = self.tcx.mk_args(&[new_pin_target.into()]);
+                let kind = ExprKind::Adt(Box::new(AdtExpr {
+                    adt_def: self.tcx.adt_def(pin_did),
+                    variant_index: FIRST_VARIANT,
+                    args,
+                    fields: Box::new([FieldExpr { name: FieldIdx::from(0u32), expr }]),
+                    user_ty: None,
+                    base: None,
+                }));
+
+                debug!(?kind);
+                kind
+            }
         };
 
         Expr { temp_lifetime, ty: adjustment.target, span, kind }
@@ -1014,7 +1076,7 @@ impl<'tcx> Cx<'tcx> {
 
         // Reconstruct the output assuming it's a reference with the
         // same region and mutability as the receiver. This holds for
-        // `Deref(Mut)::Deref(_mut)` and `Index(Mut)::index(_mut)`.
+        // `Deref(Mut)::deref(_mut)` and `Index(Mut)::index(_mut)`.
         let ty::Ref(region, _, mutbl) = *self.thir[args[0]].ty.kind() else {
             span_bug!(span, "overloaded_place: receiver is not a reference");
         };
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index 7e3ecad1bce..ef4031c5c03 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -95,11 +95,33 @@ impl CoverageCounters {
         this
     }
 
-    fn make_counter(&mut self, site: CounterIncrementSite) -> BcbCounter {
+    /// Shared helper used by [`Self::make_phys_node_counter`] and
+    /// [`Self::make_phys_edge_counter`]. Don't call this directly.
+    fn make_counter_inner(&mut self, site: CounterIncrementSite) -> BcbCounter {
         let id = self.counter_increment_sites.push(site);
         BcbCounter::Counter { id }
     }
 
+    /// Creates a new physical counter attached a BCB node.
+    /// The node must not already have a counter.
+    fn make_phys_node_counter(&mut self, bcb: BasicCoverageBlock) -> BcbCounter {
+        let counter = self.make_counter_inner(CounterIncrementSite::Node { bcb });
+        debug!(?bcb, ?counter, "node gets a physical counter");
+        self.set_bcb_counter(bcb, counter)
+    }
+
+    /// Creates a new physical counter attached to a BCB edge.
+    /// The edge must not already have a counter.
+    fn make_phys_edge_counter(
+        &mut self,
+        from_bcb: BasicCoverageBlock,
+        to_bcb: BasicCoverageBlock,
+    ) -> BcbCounter {
+        let counter = self.make_counter_inner(CounterIncrementSite::Edge { from_bcb, to_bcb });
+        debug!(?from_bcb, ?to_bcb, ?counter, "edge gets a physical counter");
+        self.set_bcb_edge_counter(from_bcb, to_bcb, counter)
+    }
+
     fn make_expression(&mut self, lhs: BcbCounter, op: Op, rhs: BcbCounter) -> BcbCounter {
         let new_expr = BcbExpression { lhs, op, rhs };
         *self
@@ -294,25 +316,27 @@ impl<'a> MakeBcbCounters<'a> {
 
         let successors = self.basic_coverage_blocks.successors[from_bcb].as_slice();
 
-        // If this node doesn't have multiple out-edges, or all of its out-edges
-        // already have counters, then we don't need to create edge counters.
-        let needs_out_edge_counters = successors.len() > 1
-            && successors.iter().any(|&to_bcb| self.edge_has_no_counter(from_bcb, to_bcb));
-        if !needs_out_edge_counters {
+        // If this node's out-edges won't sum to the node's counter,
+        // then there's no reason to create edge counters here.
+        if !self.basic_coverage_blocks[from_bcb].is_out_summable {
             return;
         }
 
-        if tracing::enabled!(tracing::Level::DEBUG) {
-            let _span =
-                debug_span!("node has some out-edges without counters", ?from_bcb).entered();
-            for &to_bcb in successors {
-                debug!(?to_bcb, counter=?self.edge_counter(from_bcb, to_bcb));
-            }
-        }
+        // Determine the set of out-edges that don't yet have edge counters.
+        let candidate_successors = self.basic_coverage_blocks.successors[from_bcb]
+            .iter()
+            .copied()
+            .filter(|&to_bcb| self.edge_has_no_counter(from_bcb, to_bcb))
+            .collect::<Vec<_>>();
+        debug!(?candidate_successors);
 
-        // Of the out-edges that don't have counters yet, one can be given an expression
-        // (computed from the other out-edges) instead of a dedicated counter.
-        let expression_to_bcb = self.choose_out_edge_for_expression(traversal, from_bcb);
+        // If there are out-edges without counters, choose one to be given an expression
+        // (computed from this node and the other out-edges) instead of a physical counter.
+        let Some(expression_to_bcb) =
+            self.choose_out_edge_for_expression(traversal, &candidate_successors)
+        else {
+            return;
+        };
 
         // For each out-edge other than the one that was chosen to get an expression,
         // ensure that it has a counter (existing counter/expression or a new counter),
@@ -324,10 +348,11 @@ impl<'a> MakeBcbCounters<'a> {
             .filter(|&to_bcb| to_bcb != expression_to_bcb)
             .map(|to_bcb| self.get_or_make_edge_counter(from_bcb, to_bcb))
             .collect::<Vec<_>>();
-        let sum_of_all_other_out_edges: BcbCounter = self
-            .coverage_counters
-            .make_sum(&other_out_edge_counters)
-            .expect("there must be at least one other out-edge");
+        let Some(sum_of_all_other_out_edges) =
+            self.coverage_counters.make_sum(&other_out_edge_counters)
+        else {
+            return;
+        };
 
         // Now create an expression for the chosen edge, by taking the counter
         // for its source node and subtracting the sum of its sibling out-edges.
@@ -338,10 +363,13 @@ impl<'a> MakeBcbCounters<'a> {
         );
 
         debug!("{expression_to_bcb:?} gets an expression: {expression:?}");
-        if self.basic_coverage_blocks.bcb_has_multiple_in_edges(expression_to_bcb) {
-            self.coverage_counters.set_bcb_edge_counter(from_bcb, expression_to_bcb, expression);
-        } else {
+        if let Some(sole_pred) = self.basic_coverage_blocks.sole_predecessor(expression_to_bcb) {
+            // This edge normally wouldn't get its own counter, so attach the expression
+            // to its target node instead, so that `edge_has_no_counter` can see it.
+            assert_eq!(sole_pred, from_bcb);
             self.coverage_counters.set_bcb_counter(expression_to_bcb, expression);
+        } else {
+            self.coverage_counters.set_bcb_edge_counter(from_bcb, expression_to_bcb, expression);
         }
     }
 
@@ -353,28 +381,21 @@ impl<'a> MakeBcbCounters<'a> {
             return counter_kind;
         }
 
-        // A BCB with only one incoming edge gets a simple `Counter` (via `make_counter()`).
-        // Also, a BCB that loops back to itself gets a simple `Counter`. This may indicate the
-        // program results in a tight infinite loop, but it should still compile.
-        let one_path_to_target = !self.basic_coverage_blocks.bcb_has_multiple_in_edges(bcb);
-        if one_path_to_target || self.bcb_predecessors(bcb).contains(&bcb) {
-            let counter_kind =
-                self.coverage_counters.make_counter(CounterIncrementSite::Node { bcb });
-            if one_path_to_target {
-                debug!("{bcb:?} gets a new counter: {counter_kind:?}");
-            } else {
-                debug!(
-                    "{bcb:?} has itself as its own predecessor. It can't be part of its own \
-                    Expression sum, so it will get its own new counter: {counter_kind:?}. \
-                    (Note, the compiled code will generate an infinite loop.)",
-                );
-            }
-            return self.coverage_counters.set_bcb_counter(bcb, counter_kind);
+        let predecessors = self.basic_coverage_blocks.predecessors[bcb].as_slice();
+
+        // Handle cases where we can't compute a node's count from its in-edges:
+        // - START_BCB has no in-edges, so taking the sum would panic (or be wrong).
+        // - For nodes with one in-edge, or that directly loop to themselves,
+        //   trying to get the in-edge counts would require this node's counter,
+        //   leading to infinite recursion.
+        if predecessors.len() <= 1 || predecessors.contains(&bcb) {
+            debug!(?bcb, ?predecessors, "node has <=1 predecessors or is its own predecessor");
+            return self.coverage_counters.make_phys_node_counter(bcb);
         }
 
         // A BCB with multiple incoming edges can compute its count by ensuring that counters
         // exist for each of those edges, and then adding them up to get a total count.
-        let in_edge_counters = self.basic_coverage_blocks.predecessors[bcb]
+        let in_edge_counters = predecessors
             .iter()
             .copied()
             .map(|from_bcb| self.get_or_make_edge_counter(from_bcb, bcb))
@@ -394,16 +415,19 @@ impl<'a> MakeBcbCounters<'a> {
         from_bcb: BasicCoverageBlock,
         to_bcb: BasicCoverageBlock,
     ) -> BcbCounter {
-        // If the target BCB has only one in-edge (i.e. this one), then create
-        // a node counter instead, since it will have the same value.
-        if !self.basic_coverage_blocks.bcb_has_multiple_in_edges(to_bcb) {
-            assert_eq!([from_bcb].as_slice(), self.basic_coverage_blocks.predecessors[to_bcb]);
+        // If the target node has exactly one in-edge (i.e. this one), then just
+        // use the node's counter, since it will have the same value.
+        if let Some(sole_pred) = self.basic_coverage_blocks.sole_predecessor(to_bcb) {
+            assert_eq!(sole_pred, from_bcb);
+            // This call must take care not to invoke `get_or_make_edge` for
+            // this edge, since that would result in infinite recursion!
             return self.get_or_make_node_counter(to_bcb);
         }
 
-        // If the source BCB has only one successor (assumed to be the given target), an edge
-        // counter is unnecessary. Just get or make a counter for the source BCB.
-        if self.bcb_successors(from_bcb).len() == 1 {
+        // If the source node has exactly one out-edge (i.e. this one) and would have
+        // the same execution count as that edge, then just use the node's counter.
+        if let Some(simple_succ) = self.basic_coverage_blocks.simple_successor(from_bcb) {
+            assert_eq!(simple_succ, to_bcb);
             return self.get_or_make_node_counter(from_bcb);
         }
 
@@ -416,118 +440,81 @@ impl<'a> MakeBcbCounters<'a> {
         }
 
         // Make a new counter to count this edge.
-        let counter_kind =
-            self.coverage_counters.make_counter(CounterIncrementSite::Edge { from_bcb, to_bcb });
-        debug!("Edge {from_bcb:?}->{to_bcb:?} gets a new counter: {counter_kind:?}");
-        self.coverage_counters.set_bcb_edge_counter(from_bcb, to_bcb, counter_kind)
+        self.coverage_counters.make_phys_edge_counter(from_bcb, to_bcb)
     }
 
-    /// Choose one of the out-edges of `from_bcb` to receive an expression
-    /// instead of a physical counter, and returns that edge's target node.
-    ///
-    /// - Precondition: The node must have at least one out-edge without a counter.
-    /// - Postcondition: The selected edge does not have an edge counter.
+    /// Given a set of candidate out-edges (represented by their successor node),
+    /// choose one to be given a counter expression instead of a physical counter.
     fn choose_out_edge_for_expression(
         &self,
         traversal: &TraverseCoverageGraphWithLoops<'_>,
-        from_bcb: BasicCoverageBlock,
-    ) -> BasicCoverageBlock {
-        if let Some(reloop_target) = self.find_good_reloop_edge(traversal, from_bcb) {
-            assert!(self.edge_has_no_counter(from_bcb, reloop_target));
+        candidate_successors: &[BasicCoverageBlock],
+    ) -> Option<BasicCoverageBlock> {
+        // Try to find a candidate that leads back to the top of a loop,
+        // because reloop edges tend to be executed more times than loop-exit edges.
+        if let Some(reloop_target) = self.find_good_reloop_edge(traversal, &candidate_successors) {
             debug!("Selecting reloop target {reloop_target:?} to get an expression");
-            return reloop_target;
+            return Some(reloop_target);
         }
 
-        // We couldn't identify a "good" edge, so just choose any edge that
-        // doesn't already have a counter.
-        let arbitrary_target = self
-            .bcb_successors(from_bcb)
-            .iter()
-            .copied()
-            .find(|&to_bcb| self.edge_has_no_counter(from_bcb, to_bcb))
-            .expect("precondition: at least one out-edge without a counter");
+        // We couldn't identify a "good" edge, so just choose an arbitrary one.
+        let arbitrary_target = candidate_successors.first().copied()?;
         debug!(?arbitrary_target, "selecting arbitrary out-edge to get an expression");
-        arbitrary_target
+        Some(arbitrary_target)
     }
 
-    /// Tries to find an edge that leads back to the top of a loop, and that
-    /// doesn't already have a counter. Such edges are good candidates to
-    /// be given an expression (instead of a physical counter), because they
-    /// will tend to be executed more times than a loop-exit edge.
+    /// Given a set of candidate out-edges (represented by their successor node),
+    /// tries to find one that leads back to the top of a loop.
+    ///
+    /// Reloop edges are good candidates for counter expressions, because they
+    /// will tend to be executed more times than a loop-exit edge, so it's nice
+    /// for them to be able to avoid a physical counter increment.
     fn find_good_reloop_edge(
         &self,
         traversal: &TraverseCoverageGraphWithLoops<'_>,
-        from_bcb: BasicCoverageBlock,
+        candidate_successors: &[BasicCoverageBlock],
     ) -> Option<BasicCoverageBlock> {
-        let successors = self.bcb_successors(from_bcb);
+        // If there are no candidates, avoid iterating over the loop stack.
+        if candidate_successors.is_empty() {
+            return None;
+        }
 
         // Consider each loop on the current traversal context stack, top-down.
         for reloop_bcbs in traversal.reloop_bcbs_per_loop() {
-            let mut all_edges_exit_this_loop = true;
-
-            // Try to find an out-edge that doesn't exit this loop and doesn't
-            // already have a counter.
-            for &target_bcb in successors {
+            // Try to find a candidate edge that doesn't exit this loop.
+            for &target_bcb in candidate_successors {
                 // An edge is a reloop edge if its target dominates any BCB that has
                 // an edge back to the loop header. (Otherwise it's an exit edge.)
                 let is_reloop_edge = reloop_bcbs.iter().any(|&reloop_bcb| {
                     self.basic_coverage_blocks.dominates(target_bcb, reloop_bcb)
                 });
-
                 if is_reloop_edge {
-                    all_edges_exit_this_loop = false;
-                    if self.edge_has_no_counter(from_bcb, target_bcb) {
-                        // We found a good out-edge to be given an expression.
-                        return Some(target_bcb);
-                    }
-                    // Keep looking for another reloop edge without a counter.
-                } else {
-                    // This edge exits the loop.
+                    // We found a good out-edge to be given an expression.
+                    return Some(target_bcb);
                 }
             }
 
-            if !all_edges_exit_this_loop {
-                // We found one or more reloop edges, but all of them already
-                // have counters. Let the caller choose one of the other edges.
-                debug!("All reloop edges had counters; skipping the other loops");
-                return None;
-            }
-
-            // All of the out-edges exit this loop, so keep looking for a good
-            // reloop edge for one of the outer loops.
+            // All of the candidate edges exit this loop, so keep looking
+            // for a good reloop edge for one of the outer loops.
         }
 
         None
     }
 
     #[inline]
-    fn bcb_predecessors(&self, bcb: BasicCoverageBlock) -> &[BasicCoverageBlock] {
-        &self.basic_coverage_blocks.predecessors[bcb]
-    }
-
-    #[inline]
-    fn bcb_successors(&self, bcb: BasicCoverageBlock) -> &[BasicCoverageBlock] {
-        &self.basic_coverage_blocks.successors[bcb]
-    }
-
-    #[inline]
     fn edge_has_no_counter(
         &self,
         from_bcb: BasicCoverageBlock,
         to_bcb: BasicCoverageBlock,
     ) -> bool {
-        self.edge_counter(from_bcb, to_bcb).is_none()
-    }
+        let edge_counter =
+            if let Some(sole_pred) = self.basic_coverage_blocks.sole_predecessor(to_bcb) {
+                assert_eq!(sole_pred, from_bcb);
+                self.coverage_counters.bcb_counters[to_bcb]
+            } else {
+                self.coverage_counters.bcb_edge_counters.get(&(from_bcb, to_bcb)).copied()
+            };
 
-    fn edge_counter(
-        &self,
-        from_bcb: BasicCoverageBlock,
-        to_bcb: BasicCoverageBlock,
-    ) -> Option<&BcbCounter> {
-        if self.basic_coverage_blocks.bcb_has_multiple_in_edges(to_bcb) {
-            self.coverage_counters.bcb_edge_counters.get(&(from_bcb, to_bcb))
-        } else {
-            self.coverage_counters.bcb_counters[to_bcb].as_ref()
-        }
+        edge_counter.is_none()
     }
 }
diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs
index 0d874a6c8ba..743aa679058 100644
--- a/compiler/rustc_mir_transform/src/coverage/graph.rs
+++ b/compiler/rustc_mir_transform/src/coverage/graph.rs
@@ -87,7 +87,11 @@ impl CoverageGraph {
             for &bb in basic_blocks.iter() {
                 bb_to_bcb[bb] = Some(bcb);
             }
-            let bcb_data = BasicCoverageBlockData::from(basic_blocks);
+
+            let is_out_summable = basic_blocks.last().map_or(false, |&bb| {
+                bcb_filtered_successors(mir_body[bb].terminator()).is_out_summable()
+            });
+            let bcb_data = BasicCoverageBlockData { basic_blocks, is_out_summable };
             debug!("adding bcb{}: {:?}", bcb.index(), bcb_data);
             bcbs.push(bcb_data);
         };
@@ -161,23 +165,33 @@ impl CoverageGraph {
         self.dominators.as_ref().unwrap().cmp_in_dominator_order(a, b)
     }
 
-    /// Returns true if the given node has 2 or more in-edges, i.e. 2 or more
-    /// predecessors.
-    ///
-    /// This property is interesting to code that assigns counters to nodes and
-    /// edges, because if a node _doesn't_ have multiple in-edges, then there's
-    /// no benefit in having a separate counter for its in-edge, because it
-    /// would have the same value as the node's own counter.
-    ///
-    /// FIXME: That assumption might not be true for [`TerminatorKind::Yield`]?
-    #[inline(always)]
-    pub(crate) fn bcb_has_multiple_in_edges(&self, bcb: BasicCoverageBlock) -> bool {
-        // Even though bcb0 conceptually has an extra virtual in-edge due to
-        // being the entry point, we've already asserted that it has no _other_
-        // in-edges, so there's no possibility of it having _multiple_ in-edges.
-        // (And since its virtual in-edge doesn't exist in the graph, that edge
-        // can't have a separate counter anyway.)
-        self.predecessors[bcb].len() > 1
+    /// Returns the source of this node's sole in-edge, if it has exactly one.
+    /// That edge can be assumed to have the same execution count as the node
+    /// itself (in the absence of panics).
+    pub(crate) fn sole_predecessor(
+        &self,
+        to_bcb: BasicCoverageBlock,
+    ) -> Option<BasicCoverageBlock> {
+        // Unlike `simple_successor`, there is no need for extra checks here.
+        if let &[from_bcb] = self.predecessors[to_bcb].as_slice() { Some(from_bcb) } else { None }
+    }
+
+    /// Returns the target of this node's sole out-edge, if it has exactly
+    /// one, but only if that edge can be assumed to have the same execution
+    /// count as the node itself (in the absence of panics).
+    pub(crate) fn simple_successor(
+        &self,
+        from_bcb: BasicCoverageBlock,
+    ) -> Option<BasicCoverageBlock> {
+        // If a node's count is the sum of its out-edges, and it has exactly
+        // one out-edge, then that edge has the same count as the node.
+        if self.bcbs[from_bcb].is_out_summable
+            && let &[to_bcb] = self.successors[from_bcb].as_slice()
+        {
+            Some(to_bcb)
+        } else {
+            None
+        }
     }
 }
 
@@ -266,14 +280,16 @@ rustc_index::newtype_index! {
 #[derive(Debug, Clone)]
 pub(crate) struct BasicCoverageBlockData {
     pub(crate) basic_blocks: Vec<BasicBlock>,
+
+    /// If true, this node's execution count can be assumed to be the sum of the
+    /// execution counts of all of its **out-edges** (assuming no panics).
+    ///
+    /// Notably, this is false for a node ending with [`TerminatorKind::Yield`],
+    /// because the yielding coroutine might not be resumed.
+    pub(crate) is_out_summable: bool,
 }
 
 impl BasicCoverageBlockData {
-    fn from(basic_blocks: Vec<BasicBlock>) -> Self {
-        assert!(basic_blocks.len() > 0);
-        Self { basic_blocks }
-    }
-
     #[inline(always)]
     pub(crate) fn leader_bb(&self) -> BasicBlock {
         self.basic_blocks[0]
@@ -295,6 +311,9 @@ enum CoverageSuccessors<'a> {
     Chainable(BasicBlock),
     /// The block cannot be combined into the same BCB as its successor(s).
     NotChainable(&'a [BasicBlock]),
+    /// Yield terminators are not chainable, and their execution count can also
+    /// differ from the execution count of their out-edge.
+    Yield(BasicBlock),
 }
 
 impl CoverageSuccessors<'_> {
@@ -302,6 +321,17 @@ impl CoverageSuccessors<'_> {
         match self {
             Self::Chainable(_) => true,
             Self::NotChainable(_) => false,
+            Self::Yield(_) => false,
+        }
+    }
+
+    /// Returns true if the terminator itself is assumed to have the same
+    /// execution count as the sum of its out-edges (assuming no panics).
+    fn is_out_summable(&self) -> bool {
+        match self {
+            Self::Chainable(_) => true,
+            Self::NotChainable(_) => true,
+            Self::Yield(_) => false,
         }
     }
 }
@@ -312,7 +342,9 @@ impl IntoIterator for CoverageSuccessors<'_> {
 
     fn into_iter(self) -> Self::IntoIter {
         match self {
-            Self::Chainable(bb) => Some(bb).into_iter().chain((&[]).iter().copied()),
+            Self::Chainable(bb) | Self::Yield(bb) => {
+                Some(bb).into_iter().chain((&[]).iter().copied())
+            }
             Self::NotChainable(bbs) => None.into_iter().chain(bbs.iter().copied()),
         }
     }
@@ -331,7 +363,7 @@ fn bcb_filtered_successors<'a, 'tcx>(terminator: &'a Terminator<'tcx>) -> Covera
 
         // A yield terminator has exactly 1 successor, but should not be chained,
         // because its resume edge has a different execution count.
-        Yield { ref resume, .. } => CoverageSuccessors::NotChainable(std::slice::from_ref(resume)),
+        Yield { resume, .. } => CoverageSuccessors::Yield(resume),
 
         // These terminators have exactly one coverage-relevant successor,
         // and can be chained into it.
@@ -341,15 +373,15 @@ fn bcb_filtered_successors<'a, 'tcx>(terminator: &'a Terminator<'tcx>) -> Covera
         | FalseUnwind { real_target: target, .. }
         | Goto { target } => CoverageSuccessors::Chainable(target),
 
-        // A call terminator can normally be chained, except when they have no
-        // successor because they are known to diverge.
+        // A call terminator can normally be chained, except when it has no
+        // successor because it is known to diverge.
         Call { target: maybe_target, .. } => match maybe_target {
             Some(target) => CoverageSuccessors::Chainable(target),
             None => CoverageSuccessors::NotChainable(&[]),
         },
 
-        // An inline asm terminator can normally be chained, except when it diverges or uses asm
-        // goto.
+        // An inline asm terminator can normally be chained, except when it
+        // diverges or uses asm goto.
         InlineAsm { ref targets, .. } => {
             if let [target] = targets[..] {
                 CoverageSuccessors::Chainable(target)
diff --git a/compiler/rustc_mir_transform/src/cross_crate_inline.rs b/compiler/rustc_mir_transform/src/cross_crate_inline.rs
index ce109ef7674..42cbece32d8 100644
--- a/compiler/rustc_mir_transform/src/cross_crate_inline.rs
+++ b/compiler/rustc_mir_transform/src/cross_crate_inline.rs
@@ -24,7 +24,7 @@ fn cross_crate_inlinable(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
 
     // This just reproduces the logic from Instance::requires_inline.
     match tcx.def_kind(def_id) {
-        DefKind::Ctor(..) | DefKind::Closure => return true,
+        DefKind::Ctor(..) | DefKind::Closure | DefKind::SyntheticCoroutineBody => return true,
         DefKind::Fn | DefKind::AssocFn => {}
         _ => return false,
     }
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 870cb180ce1..2de75e2ef50 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -357,16 +357,6 @@ impl<'tcx> Inliner<'tcx> {
         }
 
         if callee_def_id.is_local() {
-            // Avoid a cycle here by only using `instance_mir` only if we have
-            // a lower `DefPathHash` than the callee. This ensures that the callee will
-            // not inline us. This trick even works with incremental compilation,
-            // since `DefPathHash` is stable.
-            if self.tcx.def_path_hash(caller_def_id).local_hash()
-                < self.tcx.def_path_hash(callee_def_id).local_hash()
-            {
-                return Ok(());
-            }
-
             // If we know for sure that the function we're calling will itself try to
             // call us, then we avoid inlining that function.
             if self.tcx.mir_callgraph_reachable((callee, caller_def_id.expect_local())) {
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 424e7008326..0868f4b3d88 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -21,9 +21,8 @@ use rustc_const_eval::util;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_data_structures::steal::Steal;
 use rustc_hir as hir;
-use rustc_hir::def::DefKind;
+use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::LocalDefId;
-use rustc_hir::intravisit::{self, Visitor};
 use rustc_index::IndexVec;
 use rustc_middle::mir::{
     AnalysisPhase, Body, CallSource, ClearCrossCrate, ConstOperand, ConstQualifs, LocalDecl,
@@ -224,26 +223,31 @@ fn is_mir_available(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
 /// MIR associated with them.
 fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
     // All body-owners have MIR associated with them.
-    let set: FxIndexSet<_> = tcx.hir().body_owners().collect();
+    let mut set: FxIndexSet<_> = tcx.hir().body_owners().collect();
 
-    // Additionally, tuple struct/variant constructors have MIR, but
-    // they don't have a BodyId, so we need to build them separately.
-    struct GatherCtors {
-        set: FxIndexSet<LocalDefId>,
+    // Coroutine-closures (e.g. async closures) have an additional by-move MIR
+    // body that isn't in the HIR.
+    for body_owner in tcx.hir().body_owners() {
+        if let DefKind::Closure = tcx.def_kind(body_owner)
+            && tcx.needs_coroutine_by_move_body_def_id(body_owner.to_def_id())
+        {
+            set.insert(tcx.coroutine_by_move_body_def_id(body_owner).expect_local());
+        }
     }
-    impl<'tcx> Visitor<'tcx> for GatherCtors {
-        fn visit_variant_data(&mut self, v: &'tcx hir::VariantData<'tcx>) {
-            if let hir::VariantData::Tuple(_, _, def_id) = *v {
-                self.set.insert(def_id);
+
+    // tuple struct/variant constructors have MIR, but they don't have a BodyId,
+    // so we need to build them separately.
+    for item in tcx.hir_crate_items(()).free_items() {
+        if let DefKind::Struct | DefKind::Enum = tcx.def_kind(item.owner_id) {
+            for variant in tcx.adt_def(item.owner_id).variants() {
+                if let Some((CtorKind::Fn, ctor_def_id)) = variant.ctor {
+                    set.insert(ctor_def_id.expect_local());
+                }
             }
-            intravisit::walk_struct_def(self, v)
         }
     }
 
-    let mut gather_ctors = GatherCtors { set };
-    tcx.hir().visit_all_item_likes_in_crate(&mut gather_ctors);
-
-    gather_ctors.set
+    set
 }
 
 fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
diff --git a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
index 5acfec3dee3..4d743c05190 100644
--- a/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/eval_ctxt/canonical.rs
@@ -157,6 +157,17 @@ where
             },
         );
 
+        // HACK: We bail with overflow if the response would have too many non-region
+        // inference variables. This tends to only happen if we encounter a lot of
+        // ambiguous alias types which get replaced with fresh inference variables
+        // during generalization. This prevents a hang in nalgebra.
+        let num_non_region_vars = canonical.variables.iter().filter(|c| !c.is_region()).count();
+        if num_non_region_vars > self.cx().recursion_limit() {
+            return Ok(self.make_ambiguous_response_no_constraints(MaybeCause::Overflow {
+                suggest_increasing_limit: true,
+            }));
+        }
+
         Ok(canonical)
     }
 
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index ec9a676ea31..6cb851eb8df 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -670,7 +670,7 @@ parse_parentheses_with_struct_fields = invalid `struct` delimiters or `fn` call
 parse_parenthesized_lifetime = parenthesized lifetime bounds are not supported
 parse_parenthesized_lifetime_suggestion = remove the parentheses
 
-parse_path_single_colon = path separator must be a double colon
+parse_path_double_colon = path separator must be a double colon
     .suggestion = use a double colon instead
 
 parse_pattern_method_param_without_body = patterns aren't allowed in methods without bodies
@@ -803,15 +803,17 @@ parse_unexpected_expr_in_pat =
     expected {$is_bound ->
         [true] a pattern range bound
        *[false] a pattern
-    }, found {$is_method_call ->
-        [true] a method call
-       *[false] an expression
-    }
+    }, found an expression
+
+    .label = arbitrary expressions are not allowed in patterns
+
+parse_unexpected_expr_in_pat_const_sugg = consider extracting the expression into a `const`
+
+parse_unexpected_expr_in_pat_create_guard_sugg = consider moving the expression to a match arm guard
+
+parse_unexpected_expr_in_pat_inline_const_sugg = consider wrapping the expression in an inline `const` (requires `{"#"}![feature(inline_const_pat)]`)
 
-    .label = {$is_method_call ->
-        [true] method calls
-       *[false] arbitrary expressions
-    } are not allowed in patterns
+parse_unexpected_expr_in_pat_update_guard_sugg = consider moving the expression to the match arm guard
 
 parse_unexpected_if_with_if = unexpected `if` in the condition expression
     .suggestion = remove the `if`
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index da1103a4fe5..e9fe2e6c1dd 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -1,3 +1,5 @@
+// ignore-tidy-filelength
+
 use std::borrow::Cow;
 
 use rustc_ast::token::Token;
@@ -1569,7 +1571,7 @@ pub(crate) struct ExpectedFnPathFoundFnKeyword {
 }
 
 #[derive(Diagnostic)]
-#[diag(parse_path_single_colon)]
+#[diag(parse_path_double_colon)]
 pub(crate) struct PathSingleColon {
     #[primary_span]
     pub span: Span,
@@ -1582,6 +1584,14 @@ pub(crate) struct PathSingleColon {
 }
 
 #[derive(Diagnostic)]
+#[diag(parse_path_double_colon)]
+pub(crate) struct PathTripleColon {
+    #[primary_span]
+    #[suggestion(applicability = "maybe-incorrect", code = "", style = "verbose")]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(parse_colon_as_semi)]
 pub(crate) struct ColonAsSemi {
     #[primary_span]
@@ -2592,13 +2602,86 @@ pub(crate) struct ExpectedCommaAfterPatternField {
 #[derive(Diagnostic)]
 #[diag(parse_unexpected_expr_in_pat)]
 pub(crate) struct UnexpectedExpressionInPattern {
+    /// The unexpected expr's span.
     #[primary_span]
     #[label]
     pub span: Span,
     /// Was a `RangePatternBound` expected?
     pub is_bound: bool,
-    /// Was the unexpected expression a `MethodCallExpression`?
-    pub is_method_call: bool,
+    /// The unexpected expr's precedence (used in match arm guard suggestions).
+    pub expr_precedence: i8,
+}
+
+#[derive(Subdiagnostic)]
+pub(crate) enum UnexpectedExpressionInPatternSugg {
+    #[multipart_suggestion(
+        parse_unexpected_expr_in_pat_create_guard_sugg,
+        applicability = "maybe-incorrect"
+    )]
+    CreateGuard {
+        /// Where to put the suggested identifier.
+        #[suggestion_part(code = "{ident}")]
+        ident_span: Span,
+        /// Where to put the match arm.
+        #[suggestion_part(code = " if {ident} == {expr}")]
+        pat_hi: Span,
+        /// The suggested identifier.
+        ident: String,
+        /// The unexpected expression.
+        expr: String,
+    },
+
+    #[multipart_suggestion(
+        parse_unexpected_expr_in_pat_update_guard_sugg,
+        applicability = "maybe-incorrect"
+    )]
+    UpdateGuard {
+        /// Where to put the suggested identifier.
+        #[suggestion_part(code = "{ident}")]
+        ident_span: Span,
+        /// The beginning of the match arm guard's expression (insert a `(` if `Some`).
+        #[suggestion_part(code = "(")]
+        guard_lo: Option<Span>,
+        /// The end of the match arm guard's expression.
+        #[suggestion_part(code = "{guard_hi_paren} && {ident} == {expr}")]
+        guard_hi: Span,
+        /// Either `")"` or `""`.
+        guard_hi_paren: &'static str,
+        /// The suggested identifier.
+        ident: String,
+        /// The unexpected expression.
+        expr: String,
+    },
+
+    #[multipart_suggestion(
+        parse_unexpected_expr_in_pat_const_sugg,
+        applicability = "has-placeholders"
+    )]
+    Const {
+        /// Where to put the extracted constant declaration.
+        #[suggestion_part(code = "{indentation}const {ident}: /* Type */ = {expr};\n")]
+        stmt_lo: Span,
+        /// Where to put the suggested identifier.
+        #[suggestion_part(code = "{ident}")]
+        ident_span: Span,
+        /// The suggested identifier.
+        ident: String,
+        /// The unexpected expression.
+        expr: String,
+        /// The statement's block's indentation.
+        indentation: String,
+    },
+
+    #[multipart_suggestion(
+        parse_unexpected_expr_in_pat_inline_const_sugg,
+        applicability = "maybe-incorrect"
+    )]
+    InlineConst {
+        #[suggestion_part(code = "const {{ ")]
+        start_span: Span,
+        #[suggestion_part(code = " }}")]
+        end_span: Span,
+    },
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index b7232ff21ca..898c4779b08 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -299,6 +299,9 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
                         lifetime_name += lifetime_name_without_tick;
                         let sym = Symbol::intern(&lifetime_name);
 
+                        // Make sure we mark this as a raw identifier.
+                        self.psess.raw_identifier_spans.push(self.mk_sp(start, self.pos));
+
                         token::Lifetime(sym, IdentIsRaw::Yes)
                     } else {
                         // Otherwise, this should be parsed like `'r`. Warn about it though.
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index bee73c58cb7..fd488cf1d31 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -16,7 +16,7 @@ use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_errors::{
     pluralize, Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, FatalError, PErr, PResult,
-    Subdiagnostic,
+    Subdiagnostic, Suggestions,
 };
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::edit_distance::find_best_match_for_name;
@@ -775,7 +775,7 @@ impl<'a> Parser<'a> {
         }
 
         // Check for misspelled keywords if there are no suggestions added to the diagnostic.
-        if err.suggestions.as_ref().is_ok_and(|code_suggestions| code_suggestions.is_empty()) {
+        if matches!(&err.suggestions, Suggestions::Enabled(list) if list.is_empty()) {
             self.check_for_misspelled_kw(&mut err, &expected);
         }
         Err(err)
@@ -803,6 +803,9 @@ impl<'a> Parser<'a> {
             && let Some(misspelled_kw) = find_similar_kw(curr_ident, &expected_keywords)
         {
             err.subdiagnostic(misspelled_kw);
+            // We don't want other suggestions to be added as they are most likely meaningless
+            // when there is a misspelled keyword.
+            err.seal_suggestions();
         } else if let Some((prev_ident, _)) = self.prev_token.ident()
             && !prev_ident.is_used_keyword()
         {
@@ -818,6 +821,9 @@ impl<'a> Parser<'a> {
             // positives like suggesting keyword `for` for `extern crate foo {}`.
             if let Some(misspelled_kw) = find_similar_kw(prev_ident, &all_keywords) {
                 err.subdiagnostic(misspelled_kw);
+                // We don't want other suggestions to be added as they are most likely meaningless
+                // when there is a misspelled keyword.
+                err.seal_suggestions();
             }
         }
     }
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 2d5a1914fa6..f19cba4c1bf 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -41,7 +41,7 @@ use super::{
 use crate::{errors, maybe_recover_from_interpolated_ty_qpath};
 
 #[derive(Debug)]
-enum DestructuredFloat {
+pub(super) enum DestructuredFloat {
     /// 1e2
     Single(Symbol, Span),
     /// 1.
@@ -1041,7 +1041,7 @@ impl<'a> Parser<'a> {
     //  support pushing "future tokens" (would be also helpful to `break_and_eat`), or
     //  we should break everything including floats into more basic proc-macro style
     //  tokens in the lexer (probably preferable).
-    fn break_up_float(&self, float: Symbol, span: Span) -> DestructuredFloat {
+    pub(super) fn break_up_float(&self, float: Symbol, span: Span) -> DestructuredFloat {
         #[derive(Debug)]
         enum FloatComponent {
             IdentLike(String),
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 104678e081c..afd9871a635 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -707,7 +707,7 @@ impl<'a> Parser<'a> {
             })
         };
 
-        let (ident, item_kind) = if self.eat(&token::PathSep) {
+        let (ident, item_kind) = if self.eat_path_sep() {
             let suffixes = if self.eat(&token::BinOp(token::Star)) {
                 None
             } else {
@@ -1054,7 +1054,7 @@ impl<'a> Parser<'a> {
         {
             // `use *;` or `use ::*;` or `use {...};` or `use ::{...};`
             let mod_sep_ctxt = self.token.span.ctxt();
-            if self.eat(&token::PathSep) {
+            if self.eat_path_sep() {
                 prefix
                     .segments
                     .push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
@@ -1065,7 +1065,7 @@ impl<'a> Parser<'a> {
             // `use path::*;` or `use path::{...};` or `use path;` or `use path as bar;`
             prefix = self.parse_path(PathStyle::Mod)?;
 
-            if self.eat(&token::PathSep) {
+            if self.eat_path_sep() {
                 self.parse_use_tree_glob_or_nested()?
             } else {
                 // Recover from using a colon as path separator.
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 9d9265d5318..3b58b2337f3 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1562,12 +1562,25 @@ impl<'a> Parser<'a> {
         })
     }
 
+    /// Checks for `::` or, potentially, `:::` and then look ahead after it.
+    fn check_path_sep_and_look_ahead(&mut self, looker: impl Fn(&Token) -> bool) -> bool {
+        if self.check(&token::PathSep) {
+            if self.may_recover() && self.look_ahead(1, |t| t.kind == token::Colon) {
+                debug_assert!(!self.look_ahead(1, &looker), "Looker must not match on colon");
+                self.look_ahead(2, looker)
+            } else {
+                self.look_ahead(1, looker)
+            }
+        } else {
+            false
+        }
+    }
+
     /// `::{` or `::*`
     fn is_import_coupler(&mut self) -> bool {
-        self.check(&token::PathSep)
-            && self.look_ahead(1, |t| {
-                *t == token::OpenDelim(Delimiter::Brace) || *t == token::BinOp(token::Star)
-            })
+        self.check_path_sep_and_look_ahead(|t| {
+            matches!(t.kind, token::OpenDelim(Delimiter::Brace) | token::BinOp(token::Star))
+        })
     }
 
     // Debug view of the parser's token stream, up to `{lookahead}` tokens.
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index daced411b8f..647df25c82e 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -1,12 +1,14 @@
-use rustc_ast::mut_visit::{walk_pat, MutVisitor};
+use rustc_ast::mut_visit::{self, MutVisitor};
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token};
+use rustc_ast::visit::{self, Visitor};
 use rustc_ast::{
-    self as ast, AttrVec, BindingMode, ByRef, Expr, ExprKind, MacCall, Mutability, Pat, PatField,
-    PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
+    self as ast, Arm, AttrVec, BinOpKind, BindingMode, ByRef, Expr, ExprKind, ExprPrecedence,
+    LocalKind, MacCall, Mutability, Pat, PatField, PatFieldsRest, PatKind, Path, QSelf, RangeEnd,
+    RangeSyntax, Stmt, StmtKind,
 };
 use rustc_ast_pretty::pprust;
-use rustc_errors::{Applicability, Diag, PResult};
+use rustc_errors::{Applicability, Diag, DiagArgValue, PResult, StashKey};
 use rustc_session::errors::ExprParenthesesNeeded;
 use rustc_span::source_map::{respan, Spanned};
 use rustc_span::symbol::{kw, sym, Ident};
@@ -21,11 +23,11 @@ use crate::errors::{
     InclusiveRangeExtraEquals, InclusiveRangeMatchArrow, InclusiveRangeNoEnd, InvalidMutInPattern,
     ParenRangeSuggestion, PatternOnWrongSideOfAt, RemoveLet, RepeatedMutInPattern,
     SwitchRefBoxOrder, TopLevelOrPatternNotAllowed, TopLevelOrPatternNotAllowedSugg,
-    TrailingVertNotAllowed, UnexpectedExpressionInPattern, UnexpectedLifetimeInPattern,
-    UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg,
+    TrailingVertNotAllowed, UnexpectedExpressionInPattern, UnexpectedExpressionInPatternSugg,
+    UnexpectedLifetimeInPattern, UnexpectedParenInRangePat, UnexpectedParenInRangePatSugg,
     UnexpectedVertVertBeforeFunctionParam, UnexpectedVertVertInPattern, WrapInParens,
 };
-use crate::parser::expr::could_be_unclosed_char_literal;
+use crate::parser::expr::{could_be_unclosed_char_literal, DestructuredFloat};
 use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
 
 #[derive(PartialEq, Copy, Clone)]
@@ -342,7 +344,7 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Ensures that the last parsed pattern (or pattern range bound) is not followed by a method call or an operator.
+    /// Ensures that the last parsed pattern (or pattern range bound) is not followed by an expression.
     ///
     /// `is_end_bound` indicates whether the last parsed thing was the end bound of a range pattern (see [`parse_pat_range_end`](Self::parse_pat_range_end))
     /// in order to say "expected a pattern range bound" instead of "expected a pattern";
@@ -350,38 +352,64 @@ impl<'a> Parser<'a> {
     /// 0..=1 + 2
     ///     ^^^^^
     /// ```
-    /// Only the end bound is spanned, and this function have no idea if there were a `..=` before `pat_span`, hence the parameter.
+    /// Only the end bound is spanned in this case, and this function has no idea if there was a `..=` before `pat_span`, hence the parameter.
+    ///
+    /// This function returns `Some` if a trailing expression was recovered, and said expression's span.
     #[must_use = "the pattern must be discarded as `PatKind::Err` if this function returns Some"]
     fn maybe_recover_trailing_expr(
         &mut self,
         pat_span: Span,
         is_end_bound: bool,
-    ) -> Option<ErrorGuaranteed> {
+    ) -> Option<(ErrorGuaranteed, Span)> {
         if self.prev_token.is_keyword(kw::Underscore) || !self.may_recover() {
             // Don't recover anything after an `_` or if recovery is disabled.
             return None;
         }
 
-        // Check for `.hello()`, but allow `.Hello()` to be recovered as `, Hello()` in `parse_seq_to_before_tokens()`.
-        let has_trailing_method = self.check_noexpect(&token::Dot)
+        // Returns `true` iff `token` is an unsuffixed integer.
+        let is_one_tuple_index = |_: &Self, token: &Token| -> bool {
+            use token::{Lit, LitKind};
+
+            matches!(
+                token.kind,
+                token::Literal(Lit { kind: LitKind::Integer, symbol: _, suffix: None })
+            )
+        };
+
+        // Returns `true` iff `token` is an unsuffixed `x.y` float.
+        let is_two_tuple_indexes = |this: &Self, token: &Token| -> bool {
+            use token::{Lit, LitKind};
+
+            if let token::Literal(Lit { kind: LitKind::Float, symbol, suffix: None }) = token.kind
+                && let DestructuredFloat::MiddleDot(..) = this.break_up_float(symbol, token.span)
+            {
+                true
+            } else {
+                false
+            }
+        };
+
+        // Check for `.hello` or `.0`.
+        let has_dot_expr = self.check_noexpect(&token::Dot) // `.`
             && self.look_ahead(1, |tok| {
-                tok.ident()
-                    .and_then(|(ident, _)| ident.name.as_str().chars().next())
-                    .is_some_and(char::is_lowercase)
-            })
-            && self.look_ahead(2, |t| *t == token::OpenDelim(Delimiter::Parenthesis));
+                tok.is_ident() // `hello`
+                || is_one_tuple_index(&self, &tok) // `0`
+                || is_two_tuple_indexes(&self, &tok) // `0.0`
+            });
 
         // Check for operators.
         // `|` is excluded as it is used in pattern alternatives and lambdas,
         // `?` is included for error propagation,
         // `[` 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`)
+        // `[]` 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)
             || self.token == token::Question
             || (self.token == token::OpenDelim(Delimiter::Bracket)
-                && self.look_ahead(1, |t| *t != token::CloseDelim(Delimiter::Bracket)));
+                && self.look_ahead(1, |t| *t != token::CloseDelim(Delimiter::Bracket))) // excludes `[]`
+            || self.token.is_keyword(kw::As);
 
-        if !has_trailing_method && !has_trailing_operator {
+        if !has_dot_expr && !has_trailing_operator {
             // Nothing to recover here.
             return None;
         }
@@ -391,44 +419,248 @@ impl<'a> Parser<'a> {
         snapshot.restrictions.insert(Restrictions::IS_PAT);
 
         // Parse `?`, `.f`, `(arg0, arg1, ...)` or `[expr]` until they've all been eaten.
-        if let Ok(expr) = snapshot
+        let Ok(expr) = snapshot
             .parse_expr_dot_or_call_with(
                 AttrVec::new(),
                 self.mk_expr(pat_span, ExprKind::Dummy), // equivalent to transforming the parsed pattern into an `Expr`
                 pat_span,
             )
             .map_err(|err| err.cancel())
-        {
-            let non_assoc_span = expr.span;
+        else {
+            // We got a trailing method/operator, but that wasn't an expression.
+            return None;
+        };
 
-            // Parse an associative expression such as `+ expr`, `% expr`, ...
-            // Assignments, ranges and `|` are disabled by [`Restrictions::IS_PAT`].
-            if let Ok((expr, _)) =
-                snapshot.parse_expr_assoc_rest_with(0, false, expr).map_err(|err| err.cancel())
-            {
-                // We got a valid expression.
-                self.restore_snapshot(snapshot);
-                self.restrictions.remove(Restrictions::IS_PAT);
+        // Parse an associative expression such as `+ expr`, `% expr`, ...
+        // Assignments, ranges and `|` are disabled by [`Restrictions::IS_PAT`].
+        let Ok((expr, _)) =
+            snapshot.parse_expr_assoc_rest_with(0, false, expr).map_err(|err| err.cancel())
+        else {
+            // We got a trailing method/operator, but that wasn't an expression.
+            return None;
+        };
 
-                let is_bound = is_end_bound
-                    // is_start_bound: either `..` or `)..`
-                    || self.token.is_range_separator()
-                    || self.token == token::CloseDelim(Delimiter::Parenthesis)
-                        && self.look_ahead(1, Token::is_range_separator);
+        // We got a valid expression.
+        self.restore_snapshot(snapshot);
+        self.restrictions.remove(Restrictions::IS_PAT);
 
-                // Check that `parse_expr_assoc_with` didn't eat a rhs.
-                let is_method_call = has_trailing_method && non_assoc_span == expr.span;
+        let is_bound = is_end_bound
+            // is_start_bound: either `..` or `)..`
+            || self.token.is_range_separator()
+            || self.token == token::CloseDelim(Delimiter::Parenthesis)
+                && self.look_ahead(1, Token::is_range_separator);
 
-                return Some(self.dcx().emit_err(UnexpectedExpressionInPattern {
-                    span: expr.span,
+        let span = expr.span;
+
+        Some((
+            self.dcx()
+                .create_err(UnexpectedExpressionInPattern {
+                    span,
                     is_bound,
-                    is_method_call,
-                }));
+                    expr_precedence: expr.precedence().order(),
+                })
+                .stash(span, StashKey::ExprInPat)
+                .unwrap(),
+            span,
+        ))
+    }
+
+    /// Called by [`Parser::parse_stmt_without_recovery`], used to add statement-aware subdiagnostics to the errors stashed
+    /// by [`Parser::maybe_recover_trailing_expr`].
+    pub(super) fn maybe_augment_stashed_expr_in_pats_with_suggestions(&mut self, stmt: &Stmt) {
+        if self.dcx().has_errors().is_none() {
+            // No need to walk the statement if there's no stashed errors.
+            return;
+        }
+
+        struct PatVisitor<'a> {
+            /// `self`
+            parser: &'a Parser<'a>,
+            /// The freshly-parsed statement.
+            stmt: &'a Stmt,
+            /// The current match arm (for arm guard suggestions).
+            arm: Option<&'a Arm>,
+            /// The current struct field (for variable name suggestions).
+            field: Option<&'a PatField>,
+        }
+
+        impl<'a> PatVisitor<'a> {
+            /// Looks for stashed [`StashKey::ExprInPat`] errors in `stash_span`, and emit them with suggestions.
+            /// `stash_span` is contained in `expr_span`, the latter being larger in borrow patterns;
+            /// ```txt
+            /// &mut x.y
+            /// -----^^^ `stash_span`
+            /// |
+            /// `expr_span`
+            /// ```
+            /// `is_range_bound` is used to exclude arm guard suggestions in range pattern bounds.
+            fn maybe_add_suggestions_then_emit(
+                &self,
+                stash_span: Span,
+                expr_span: Span,
+                is_range_bound: bool,
+            ) {
+                self.parser.dcx().try_steal_modify_and_emit_err(
+                    stash_span,
+                    StashKey::ExprInPat,
+                    |err| {
+                        // Includes pre-pats (e.g. `&mut <err>`) in the diagnostic.
+                        err.span.replace(stash_span, expr_span);
+
+                        let sm = self.parser.psess.source_map();
+                        let stmt = self.stmt;
+                        let line_lo = sm.span_extend_to_line(stmt.span).shrink_to_lo();
+                        let indentation = sm.indentation_before(stmt.span).unwrap_or_default();
+                        let Ok(expr) = self.parser.span_to_snippet(expr_span) else {
+                            // FIXME: some suggestions don't actually need the snippet; see PR #123877's unresolved conversations.
+                            return;
+                        };
+
+                        if let StmtKind::Let(local) = &stmt.kind {
+                            match &local.kind {
+                                LocalKind::Decl | LocalKind::Init(_) => {
+                                    // It's kinda hard to guess what the user intended, so don't make suggestions.
+                                    return;
+                                }
+
+                                LocalKind::InitElse(_, _) => {}
+                            }
+                        }
+
+                        // help: use an arm guard `if val == expr`
+                        // FIXME(guard_patterns): suggest this regardless of a match arm.
+                        if let Some(arm) = &self.arm
+                            && !is_range_bound
+                        {
+                            let (ident, ident_span) = match self.field {
+                                Some(field) => {
+                                    (field.ident.to_string(), field.ident.span.to(expr_span))
+                                }
+                                None => ("val".to_owned(), expr_span),
+                            };
+
+                            // Are parentheses required around `expr`?
+                            // HACK: a neater way would be preferable.
+                            let expr = match &err.args["expr_precedence"] {
+                                DiagArgValue::Number(expr_precedence) => {
+                                    if *expr_precedence
+                                        <= ExprPrecedence::Binary(BinOpKind::Eq).order() as i32
+                                    {
+                                        format!("({expr})")
+                                    } else {
+                                        format!("{expr}")
+                                    }
+                                }
+                                _ => unreachable!(),
+                            };
+
+                            match &arm.guard {
+                                None => {
+                                    err.subdiagnostic(
+                                        UnexpectedExpressionInPatternSugg::CreateGuard {
+                                            ident_span,
+                                            pat_hi: arm.pat.span.shrink_to_hi(),
+                                            ident,
+                                            expr,
+                                        },
+                                    );
+                                }
+                                Some(guard) => {
+                                    // Are parentheses required around the old guard?
+                                    let wrap_guard = guard.precedence().order()
+                                        <= ExprPrecedence::Binary(BinOpKind::And).order();
+
+                                    err.subdiagnostic(
+                                        UnexpectedExpressionInPatternSugg::UpdateGuard {
+                                            ident_span,
+                                            guard_lo: if wrap_guard {
+                                                Some(guard.span.shrink_to_lo())
+                                            } else {
+                                                None
+                                            },
+                                            guard_hi: guard.span.shrink_to_hi(),
+                                            guard_hi_paren: if wrap_guard { ")" } else { "" },
+                                            ident,
+                                            expr,
+                                        },
+                                    );
+                                }
+                            }
+                        }
+
+                        // help: extract the expr into a `const VAL: _ = expr`
+                        let ident = match self.field {
+                            Some(field) => field.ident.as_str().to_uppercase(),
+                            None => "VAL".to_owned(),
+                        };
+                        err.subdiagnostic(UnexpectedExpressionInPatternSugg::Const {
+                            stmt_lo: line_lo,
+                            ident_span: expr_span,
+                            expr,
+                            ident,
+                            indentation,
+                        });
+
+                        // help: wrap the expr in a `const { expr }`
+                        // FIXME(inline_const_pat): once stabilized, remove this check and remove the `(requires #[feature(inline_const_pat)])` note from the message
+                        if self.parser.psess.unstable_features.is_nightly_build() {
+                            err.subdiagnostic(UnexpectedExpressionInPatternSugg::InlineConst {
+                                start_span: expr_span.shrink_to_lo(),
+                                end_span: expr_span.shrink_to_hi(),
+                            });
+                        }
+                    },
+                );
             }
         }
 
-        // We got a trailing method/operator, but we couldn't parse an expression.
-        None
+        impl<'a> Visitor<'a> for PatVisitor<'a> {
+            fn visit_arm(&mut self, a: &'a Arm) -> Self::Result {
+                self.arm = Some(a);
+                visit::walk_arm(self, a);
+                self.arm = None;
+            }
+
+            fn visit_pat_field(&mut self, fp: &'a PatField) -> Self::Result {
+                self.field = Some(fp);
+                visit::walk_pat_field(self, fp);
+                self.field = None;
+            }
+
+            fn visit_pat(&mut self, p: &'a Pat) -> Self::Result {
+                match &p.kind {
+                    // Base expression
+                    PatKind::Err(_) | PatKind::Lit(_) => {
+                        self.maybe_add_suggestions_then_emit(p.span, p.span, false)
+                    }
+
+                    // Sub-patterns
+                    // FIXME: this doesn't work with recursive subpats (`&mut &mut <err>`)
+                    PatKind::Box(subpat) | PatKind::Ref(subpat, _)
+                        if matches!(subpat.kind, PatKind::Err(_) | PatKind::Lit(_)) =>
+                    {
+                        self.maybe_add_suggestions_then_emit(subpat.span, p.span, false)
+                    }
+
+                    // Sub-expressions
+                    PatKind::Range(start, end, _) => {
+                        if let Some(start) = start {
+                            self.maybe_add_suggestions_then_emit(start.span, start.span, true);
+                        }
+
+                        if let Some(end) = end {
+                            self.maybe_add_suggestions_then_emit(end.span, end.span, true);
+                        }
+                    }
+
+                    // Walk continuation
+                    _ => visit::walk_pat(self, p),
+                }
+            }
+        }
+
+        // Starts the visit.
+        PatVisitor { parser: self, stmt, arm: None, field: None }.visit_stmt(stmt);
     }
 
     /// Parses a pattern, with a setting whether modern range patterns (e.g., `a..=b`, `a..b` are
@@ -544,7 +776,7 @@ impl<'a> Parser<'a> {
                 self.parse_pat_tuple_struct(qself, path)?
             } else {
                 match self.maybe_recover_trailing_expr(span, false) {
-                    Some(guar) => PatKind::Err(guar),
+                    Some((guar, _)) => PatKind::Err(guar),
                     None => PatKind::Path(qself, path),
                 }
             }
@@ -577,10 +809,10 @@ impl<'a> Parser<'a> {
             // Try to parse everything else as literal with optional minus
             match self.parse_literal_maybe_minus() {
                 Ok(begin) => {
-                    let begin = match self.maybe_recover_trailing_expr(begin.span, false) {
-                        Some(guar) => self.mk_expr_err(begin.span, guar),
-                        None => begin,
-                    };
+                    let begin = self
+                        .maybe_recover_trailing_expr(begin.span, false)
+                        .map(|(guar, sp)| self.mk_expr_err(sp, guar))
+                        .unwrap_or(begin);
 
                     match self.parse_range_end() {
                         Some(form) => self.parse_pat_range_begin_with(begin, form)?,
@@ -721,7 +953,8 @@ impl<'a> Parser<'a> {
         // For backward compatibility, `(..)` is a tuple pattern as well.
         let paren_pattern =
             fields.len() == 1 && !(matches!(trailing_comma, Trailing::Yes) || fields[0].is_rest());
-        if paren_pattern {
+
+        let pat = if paren_pattern {
             let pat = fields.into_iter().next().unwrap();
             let close_paren = self.prev_token.span;
 
@@ -739,7 +972,7 @@ impl<'a> Parser<'a> {
                         },
                     });
 
-                    self.parse_pat_range_begin_with(begin.clone(), form)
+                    self.parse_pat_range_begin_with(begin.clone(), form)?
                 }
                 // recover ranges with parentheses around the `(start)..`
                 PatKind::Err(guar)
@@ -754,15 +987,20 @@ impl<'a> Parser<'a> {
                         },
                     });
 
-                    self.parse_pat_range_begin_with(self.mk_expr_err(pat.span, *guar), form)
+                    self.parse_pat_range_begin_with(self.mk_expr_err(pat.span, *guar), form)?
                 }
 
                 // (pat) with optional parentheses
-                _ => Ok(PatKind::Paren(pat)),
+                _ => PatKind::Paren(pat),
             }
         } else {
-            Ok(PatKind::Tuple(fields))
-        }
+            PatKind::Tuple(fields)
+        };
+
+        Ok(match self.maybe_recover_trailing_expr(open_paren.to(self.prev_token.span), false) {
+            None => pat,
+            Some((guar, _)) => PatKind::Err(guar),
+        })
     }
 
     /// Parse a mutable binding with the `mut` token already eaten.
@@ -816,7 +1054,7 @@ impl<'a> Parser<'a> {
                     self.0 = true;
                     *m = Mutability::Mut;
                 }
-                walk_pat(self, pat);
+                mut_visit::walk_pat(self, pat);
             }
         }
 
@@ -1015,7 +1253,7 @@ impl<'a> Parser<'a> {
         }
 
         Ok(match recovered {
-            Some(guar) => self.mk_expr_err(bound.span, guar),
+            Some((guar, sp)) => self.mk_expr_err(sp, guar),
             None => bound,
         })
     }
@@ -1084,7 +1322,7 @@ impl<'a> Parser<'a> {
         // but not `ident @ subpat` as `subpat` was already checked and `ident` continues with `@`.
 
         let pat = if sub.is_none()
-            && let Some(guar) = self.maybe_recover_trailing_expr(ident.span, false)
+            && let Some((guar, _)) = self.maybe_recover_trailing_expr(ident.span, false)
         {
             PatKind::Err(guar)
         } else {
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index 42039c621d6..961679b1f56 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -16,7 +16,7 @@ use tracing::debug;
 
 use super::ty::{AllowPlus, RecoverQPath, RecoverReturnSign};
 use super::{Parser, Restrictions, TokenType};
-use crate::errors::PathSingleColon;
+use crate::errors::{PathSingleColon, PathTripleColon};
 use crate::parser::{CommaRecoveryMode, RecoverColon, RecoverComma};
 use crate::{errors, maybe_whole};
 
@@ -210,7 +210,7 @@ impl<'a> Parser<'a> {
         let lo = self.token.span;
         let mut segments = ThinVec::new();
         let mod_sep_ctxt = self.token.span.ctxt();
-        if self.eat(&token::PathSep) {
+        if self.eat_path_sep() {
             segments.push(PathSegment::path_root(lo.shrink_to_lo().with_ctxt(mod_sep_ctxt)));
         }
         self.parse_path_segments(&mut segments, style, ty_generics)?;
@@ -246,7 +246,7 @@ impl<'a> Parser<'a> {
             }
             segments.push(segment);
 
-            if self.is_import_coupler() || !self.eat(&token::PathSep) {
+            if self.is_import_coupler() || !self.eat_path_sep() {
                 if style == PathStyle::Expr
                     && self.may_recover()
                     && self.token == token::Colon
@@ -272,6 +272,18 @@ impl<'a> Parser<'a> {
         }
     }
 
+    /// Eat `::` or, potentially, `:::`.
+    #[must_use]
+    pub(super) fn eat_path_sep(&mut self) -> bool {
+        let result = self.eat(&token::PathSep);
+        if result && self.may_recover() {
+            if self.eat_noexpect(&token::Colon) {
+                self.dcx().emit_err(PathTripleColon { span: self.prev_token.span });
+            }
+        }
+        result
+    }
+
     pub(super) fn parse_path_segment(
         &mut self,
         style: PathStyle,
@@ -297,9 +309,7 @@ impl<'a> Parser<'a> {
 
         Ok(
             if style == PathStyle::Type && check_args_start(self)
-                || style != PathStyle::Mod
-                    && self.check(&token::PathSep)
-                    && self.look_ahead(1, |t| is_args_start(t))
+                || style != PathStyle::Mod && self.check_path_sep_and_look_ahead(is_args_start)
             {
                 // We use `style == PathStyle::Expr` to check if this is in a recursion or not. If
                 // it isn't, then we reset the unmatched angle bracket count as we're about to start
@@ -310,7 +320,8 @@ impl<'a> Parser<'a> {
 
                 // Generic arguments are found - `<`, `(`, `::<` or `::(`.
                 // First, eat `::` if it exists.
-                let _ = self.eat(&token::PathSep);
+                let _ = self.eat_path_sep();
+
                 let lo = self.token.span;
                 let args = if self.eat_lt() {
                     // `<'a, T, A = U>`
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index 26ad39e06cd..92fba89d28a 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -29,6 +29,9 @@ use crate::{errors, maybe_whole};
 impl<'a> Parser<'a> {
     /// Parses a statement. This stops just before trailing semicolons on everything but items.
     /// e.g., a `StmtKind::Semi` parses to a `StmtKind::Expr`, leaving the trailing `;` unconsumed.
+    ///
+    /// If `force_collect` is [`ForceCollect::Yes`], forces collection of tokens regardless of
+    /// whether or not we have attributes.
     // Public for rustfmt usage.
     pub(super) fn parse_stmt(&mut self, force_collect: ForceCollect) -> PResult<'a, Option<Stmt>> {
         Ok(self.parse_stmt_without_recovery(false, force_collect).unwrap_or_else(|e| {
@@ -66,7 +69,7 @@ impl<'a> Parser<'a> {
             });
         }
 
-        Ok(Some(if self.token.is_keyword(kw::Let) {
+        let stmt = if self.token.is_keyword(kw::Let) {
             self.collect_tokens(None, attrs, force_collect, |this, attrs| {
                 this.expect_keyword(kw::Let)?;
                 let local = this.parse_local(attrs)?;
@@ -163,7 +166,10 @@ impl<'a> Parser<'a> {
         } else {
             self.error_outer_attrs(attrs);
             return Ok(None);
-        }))
+        };
+
+        self.maybe_augment_stashed_expr_in_pats_with_suggestions(&stmt);
+        Ok(Some(stmt))
     }
 
     fn parse_stmt_path_start(&mut self, lo: Span, attrs: AttrWrapper) -> PResult<'a, Stmt> {
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index ee892c17376..2f4dc8abfcd 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1779,6 +1779,15 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
             match hint.name_or_empty() {
                 sym::Rust => {
                     is_explicit_rust = true;
+                    match target {
+                        Target::Struct | Target::Union | Target::Enum => continue,
+                        _ => {
+                            self.dcx().emit_err(errors::AttrApplication::StructEnumUnion {
+                                hint_span: hint.span(),
+                                span,
+                            });
+                        }
+                    }
                 }
                 sym::C => {
                     is_c = true;
diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs
index 312cc3a26ef..4fe11589907 100644
--- a/compiler/rustc_passes/src/layout_test.rs
+++ b/compiler/rustc_passes/src/layout_test.rs
@@ -2,7 +2,7 @@ use rustc_ast::Attribute;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::span_bug;
-use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers, TyAndLayout};
+use rustc_middle::ty::layout::{HasParamEnv, HasTyCtxt, LayoutError, LayoutOfHelpers};
 use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
 use rustc_span::source_map::Spanned;
 use rustc_span::symbol::sym;
@@ -139,8 +139,6 @@ struct UnwrapLayoutCx<'tcx> {
 }
 
 impl<'tcx> LayoutOfHelpers<'tcx> for UnwrapLayoutCx<'tcx> {
-    type LayoutOfResult = TyAndLayout<'tcx>;
-
     fn handle_layout_err(&self, err: LayoutError<'tcx>, span: Span, ty: Ty<'tcx>) -> ! {
         span_bug!(span, "`#[rustc_layout(..)]` test resulted in `layout_of({ty}) = Err({err})`",);
     }
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 4bf2cc287da..ac03a3ac42c 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -17,7 +17,7 @@ use rustc_ast::visit::{visit_opt, walk_list, AssocCtxt, BoundKind, FnCtxt, FnKin
 use rustc_ast::*;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
 use rustc_errors::codes::*;
-use rustc_errors::{Applicability, DiagArgValue, IntoDiagArg, StashKey};
+use rustc_errors::{Applicability, DiagArgValue, IntoDiagArg, StashKey, Suggestions};
 use rustc_hir::def::Namespace::{self, *};
 use rustc_hir::def::{self, CtorKind, DefKind, LifetimeRes, NonMacroAttrKind, PartialRes, PerNS};
 use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID, LOCAL_CRATE};
@@ -4085,17 +4085,23 @@ impl<'a, 'ast, 'ra: 'ast, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> {
                 err.sort_span = parent_err.sort_span;
                 err.is_lint = parent_err.is_lint.clone();
 
-                // merge the parent's suggestions with the typo suggestions
-                fn append_result<T, E>(res1: &mut Result<Vec<T>, E>, res2: Result<Vec<T>, E>) {
-                    match res1 {
-                        Ok(vec1) => match res2 {
-                            Ok(mut vec2) => vec1.append(&mut vec2),
-                            Err(e) => *res1 = Err(e),
-                        },
-                        Err(_) => (),
-                    };
+                // merge the parent_err's suggestions with the typo (err's) suggestions
+                match &mut err.suggestions {
+                    Suggestions::Enabled(typo_suggestions) => match &mut parent_err.suggestions {
+                        Suggestions::Enabled(parent_suggestions) => {
+                            // If both suggestions are enabled, append parent_err's suggestions to err's suggestions.
+                            typo_suggestions.append(parent_suggestions)
+                        }
+                        Suggestions::Sealed(_) | Suggestions::Disabled => {
+                            // If the parent's suggestions are either sealed or disabled, it signifies that
+                            // new suggestions cannot be added or removed from the diagnostic. Therefore,
+                            // we assign both types of suggestions to err's suggestions and discard the
+                            // existing suggestions in err.
+                            err.suggestions = std::mem::take(&mut parent_err.suggestions);
+                        }
+                    },
+                    Suggestions::Sealed(_) | Suggestions::Disabled => (),
                 }
-                append_result(&mut err.suggestions, parent_err.suggestions.clone());
 
                 parent_err.cancel();
 
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
index a0a0dd058ff..9c2f869f357 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/encode.rs
@@ -145,7 +145,7 @@ fn encode_const<'tcx>(
                     let _ = write!(s, "{val}");
                 }
                 ty::Bool => {
-                    let val = c.try_eval_bool(tcx, ty::ParamEnv::reveal_all()).unwrap();
+                    let val = c.try_to_bool().expect("expected monomorphic const in cfi");
                     let _ = write!(s, "{val}");
                 }
                 _ => {
@@ -411,7 +411,7 @@ pub fn encode_ty<'tcx>(
 
         ty::Array(ty0, len) => {
             // A<array-length><element-type>
-            let len = len.eval_target_usize(tcx, ty::ParamEnv::reveal_all());
+            let len = len.try_to_target_usize(tcx).expect("expected monomorphic const in cfi");
             let mut s = String::from("A");
             let _ = write!(s, "{len}");
             s.push_str(&encode_ty(tcx, *ty0, dict, options));
diff --git a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
index 34763adde4f..e4231d75506 100644
--- a/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
+++ b/compiler/rustc_sanitizers/src/cfi/typeid/itanium_cxx_abi/transform.rs
@@ -146,7 +146,10 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for TransformTy<'tcx> {
                         !is_zst
                     });
                     if let Some(field) = field {
-                        let ty0 = self.tcx.erase_regions(field.ty(self.tcx, args));
+                        let ty0 = self.tcx.normalize_erasing_regions(
+                            ty::ParamEnv::reveal_all(),
+                            field.ty(self.tcx, args),
+                        );
                         // Generalize any repr(transparent) user-defined type that is either a
                         // pointer or reference, and either references itself or any other type that
                         // contains or references itself, to avoid a reference cycle.
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 908d50a041e..1132d0efebf 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -1376,7 +1376,7 @@ enum OptionStability {
 
 pub struct RustcOptGroup {
     pub apply: Box<dyn Fn(&mut getopts::Options) -> &mut getopts::Options>,
-    name: &'static str,
+    pub name: &'static str,
     stability: OptionStability,
 }
 
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index cbe2bafef21..de4532bcb99 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -309,6 +309,7 @@ symbols! {
         RwLockReadGuard,
         RwLockWriteGuard,
         Saturating,
+        SeekFrom,
         Send,
         SeqCst,
         Sized,
@@ -342,6 +343,7 @@ symbols! {
         Upvars,
         Vec,
         VecDeque,
+        Waker,
         Wrapper,
         Wrapping,
         Yield,
@@ -488,6 +490,7 @@ symbols! {
         begin_panic,
         bench,
         bin,
+        binaryheap_iter,
         bind_by_move_pattern_guards,
         bindings_after_at,
         bitand,
@@ -500,6 +503,7 @@ symbols! {
         black_box,
         block,
         bool,
+        bool_then,
         borrowck_graphviz_format,
         borrowck_graphviz_postflow,
         box_new,
@@ -511,6 +515,9 @@ symbols! {
         breakpoint,
         bridge,
         bswap,
+        btreemap_contains_key,
+        btreemap_insert,
+        btreeset_iter,
         builtin_syntax,
         c,
         c_str,
@@ -678,6 +685,7 @@ symbols! {
         crt_dash_static: "crt-static",
         csky_target_feature,
         cstr_type,
+        cstring_as_c_str,
         cstring_type,
         ctlz,
         ctlz_nonzero,
@@ -833,6 +841,7 @@ symbols! {
         f16_nan,
         f16c_target_feature,
         f32,
+        f32_epsilon,
         f32_legacy_const_digits,
         f32_legacy_const_epsilon,
         f32_legacy_const_infinity,
@@ -849,6 +858,7 @@ symbols! {
         f32_legacy_const_radix,
         f32_nan,
         f64,
+        f64_epsilon,
         f64_legacy_const_digits,
         f64_legacy_const_epsilon,
         f64_legacy_const_infinity,
@@ -886,6 +896,7 @@ symbols! {
         field,
         field_init_shorthand,
         file,
+        file_options,
         float,
         float_to_int_unchecked,
         floorf128,
@@ -971,6 +982,17 @@ symbols! {
         half_open_range_patterns,
         half_open_range_patterns_in_slices,
         hash,
+        hashmap_contains_key,
+        hashmap_drain_ty,
+        hashmap_insert,
+        hashmap_iter_mut_ty,
+        hashmap_iter_ty,
+        hashmap_keys_ty,
+        hashmap_values_mut_ty,
+        hashmap_values_ty,
+        hashset_drain_ty,
+        hashset_iter,
+        hashset_iter_ty,
         hexagon_target_feature,
         hidden,
         homogeneous_aggregate,
@@ -1049,6 +1071,7 @@ symbols! {
         inline_const,
         inline_const_pat,
         inout,
+        instant_now,
         instruction_set,
         integer_: "integer", // underscore to avoid clashing with the function `sym::integer` below
         integral,
@@ -1077,6 +1100,9 @@ symbols! {
         item,
         item_like_imports,
         iter,
+        iter_cloned,
+        iter_copied,
+        iter_filter,
         iter_mut,
         iter_repeat,
         iterator,
@@ -1346,6 +1372,7 @@ symbols! {
         on,
         on_unimplemented,
         opaque,
+        open_options_new,
         ops,
         opt_out_copy,
         optimize,
@@ -1353,10 +1380,14 @@ symbols! {
         optin_builtin_traits,
         option,
         option_env,
+        option_expect,
+        option_unwrap,
         options,
         or,
         or_patterns,
         ord_cmp_method,
+        os_str_to_os_string,
+        os_string_as_os_str,
         other,
         out,
         overflow_checks,
@@ -1410,14 +1441,19 @@ symbols! {
         pat_param,
         patchable_function_entry,
         path,
+        path_main_separator,
+        path_to_pathbuf,
+        pathbuf_as_path,
         pattern_complexity,
         pattern_parentheses,
         pattern_type,
         pattern_types,
+        permissions_from_mode,
         phantom_data,
         pic,
         pie,
         pin,
+        pin_ergonomics,
         platform_intrinsics,
         plugin,
         plugin_registrar,
@@ -1565,6 +1601,7 @@ symbols! {
         residual,
         result,
         result_ffi_guarantees,
+        result_ok_method,
         resume,
         return_position_impl_trait_in_trait,
         return_type_notation,
@@ -1817,6 +1854,8 @@ symbols! {
         slice,
         slice_from_raw_parts,
         slice_from_raw_parts_mut,
+        slice_into_vec,
+        slice_iter,
         slice_len_fn,
         slice_patterns,
         slicing_syntax,
@@ -1849,16 +1888,26 @@ symbols! {
         stop_after_dataflow,
         store,
         str,
+        str_chars,
+        str_ends_with,
         str_from_utf8,
         str_from_utf8_mut,
         str_from_utf8_unchecked,
         str_from_utf8_unchecked_mut,
+        str_len,
         str_split_whitespace,
+        str_starts_with,
         str_trim,
         str_trim_end,
         str_trim_start,
         strict_provenance,
+        string_as_mut_str,
+        string_as_str,
         string_deref_patterns,
+        string_from_utf8,
+        string_insert_str,
+        string_new,
+        string_push_str,
         stringify,
         struct_field_attributes,
         struct_inherit,
@@ -2063,7 +2112,15 @@ symbols! {
         var,
         variant_count,
         vec,
+        vec_as_mut_slice,
+        vec_as_slice,
+        vec_from_elem,
+        vec_is_empty,
         vec_macro,
+        vec_new,
+        vec_pop,
+        vec_with_capacity,
+        vecdeque_iter,
         version,
         vfp2,
         vis,
diff --git a/compiler/rustc_symbol_mangling/src/lib.rs b/compiler/rustc_symbol_mangling/src/lib.rs
index 0c97cda81c8..78e6b9ec6e8 100644
--- a/compiler/rustc_symbol_mangling/src/lib.rs
+++ b/compiler/rustc_symbol_mangling/src/lib.rs
@@ -227,7 +227,11 @@ fn compute_symbol_name<'tcx>(
     // and we want to be sure to avoid any symbol conflicts here.
     let is_globally_shared_function = matches!(
         tcx.def_kind(instance.def_id()),
-        DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Ctor(..)
+        DefKind::Fn
+            | DefKind::AssocFn
+            | DefKind::Closure
+            | DefKind::SyntheticCoroutineBody
+            | DefKind::Ctor(..)
     ) && matches!(
         MonoItem::Fn(instance).instantiation_mode(tcx),
         InstantiationMode::GloballyShared { may_conflict: true }
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index ba35a37c32c..79de9bbb351 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -330,8 +330,12 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             ty::Float(FloatTy::F128) => "C4f128",
             ty::Never => "z",
 
-            // Placeholders (should be demangled as `_`).
-            ty::Param(_) | ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => "p",
+            // Should only be encountered with polymorphization,
+            // or within the identity-substituted impl header of an
+            // item nested within an impl item.
+            ty::Param(_) => "p",
+
+            ty::Bound(..) | ty::Placeholder(_) | ty::Infer(_) | ty::Error(_) => bug!(),
 
             _ => "",
         };
@@ -416,12 +420,18 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
             // Mangle all nominal types as paths.
             ty::Adt(ty::AdtDef(Interned(&ty::AdtDefData { did: def_id, .. }, _)), args)
             | ty::FnDef(def_id, args)
-            | ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. })
             | ty::Closure(def_id, args)
             | ty::CoroutineClosure(def_id, args)
             | ty::Coroutine(def_id, args) => {
                 self.print_def_path(def_id, args)?;
             }
+
+            // We may still encounter projections here due to the printing
+            // logic sometimes passing identity-substituted impl headers.
+            ty::Alias(ty::Projection, ty::AliasTy { def_id, args, .. }) => {
+                self.print_def_path(def_id, args)?;
+            }
+
             ty::Foreign(def_id) => {
                 self.print_def_path(def_id, &[])?;
             }
@@ -467,8 +477,7 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
                 r.print(self)?;
             }
 
-            ty::Alias(ty::Inherent, _) => bug!("symbol_names: unexpected inherent projection"),
-            ty::Alias(ty::Weak, _) => bug!("symbol_names: unexpected weak projection"),
+            ty::Alias(..) => bug!("symbol_names: unexpected alias"),
             ty::CoroutineWitness(..) => bug!("symbol_names: unexpected `CoroutineWitness`"),
         }
 
@@ -550,21 +559,26 @@ impl<'tcx> Printer<'tcx> for SymbolMangler<'tcx> {
         let (ct_ty, valtree) = match ct.kind() {
             ty::ConstKind::Value(ty, val) => (ty, val),
 
-            // Placeholders (should be demangled as `_`).
-            // NOTE(eddyb) despite `Unevaluated` having a `DefId` (and therefore
-            // a path), even for it we still need to encode a placeholder, as
-            // the path could refer back to e.g. an `impl` using the constant.
-            ty::ConstKind::Unevaluated(_)
-            | ty::ConstKind::Expr(_)
-            | ty::ConstKind::Param(_)
-            | ty::ConstKind::Infer(_)
-            | ty::ConstKind::Bound(..)
-            | ty::ConstKind::Placeholder(_)
-            | ty::ConstKind::Error(_) => {
+            // Should only be encountered with polymorphization,
+            // or within the identity-substituted impl header of an
+            // item nested within an impl item.
+            ty::ConstKind::Param(_) => {
                 // Never cached (single-character).
                 self.push("p");
                 return Ok(());
             }
+
+            // We may still encounter unevaluated consts due to the printing
+            // logic sometimes passing identity-substituted impl headers.
+            ty::Unevaluated(ty::UnevaluatedConst { def, args, .. }) => {
+                return self.print_def_path(def, args);
+            }
+
+            ty::ConstKind::Expr(_)
+            | ty::ConstKind::Infer(_)
+            | ty::ConstKind::Bound(..)
+            | ty::ConstKind::Placeholder(_)
+            | ty::ConstKind::Error(_) => bug!(),
         };
 
         if let Some(&i) = self.consts.get(&ct) {
diff --git a/compiler/rustc_target/src/abi/call/m68k.rs b/compiler/rustc_target/src/abi/call/m68k.rs
index b6bd68b66fc..82fe81f8c52 100644
--- a/compiler/rustc_target/src/abi/call/m68k.rs
+++ b/compiler/rustc_target/src/abi/call/m68k.rs
@@ -14,7 +14,7 @@ fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
         return;
     }
     if arg.layout.is_aggregate() {
-        arg.make_indirect_byval(None);
+        arg.pass_by_stack_offset(None);
     } else {
         arg.extend_integer_width_to(32);
     }
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index c2826b55dc5..060ee4a1bc2 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -64,7 +64,7 @@ pub enum PassMode {
     /// (which ensures that padding is preserved and that we do not rely on LLVM's struct layout),
     /// and will use the alignment specified in `attrs.pointee_align` (if `Some`) or the type's
     /// alignment (if `None`). This means that the alignment will not always
-    /// match the Rust type's alignment; see documentation of `make_indirect_byval` for more info.
+    /// match the Rust type's alignment; see documentation of `pass_by_stack_offset` for more info.
     ///
     /// `on_stack` cannot be true for unsized arguments, i.e., when `meta_attrs` is `Some`.
     Indirect { attrs: ArgAttributes, meta_attrs: Option<ArgAttributes>, on_stack: bool },
@@ -681,7 +681,7 @@ impl<'a, Ty> ArgAbi<'a, Ty> {
     /// either in the caller (if the type's alignment is lower than the byval alignment)
     /// or in the callee (if the type's alignment is higher than the byval alignment),
     /// to ensure that Rust code never sees an underaligned pointer.
-    pub fn make_indirect_byval(&mut self, byval_align: Option<Align>) {
+    pub fn pass_by_stack_offset(&mut self, byval_align: Option<Align>) {
         assert!(!self.layout.is_unsized(), "used byval ABI for unsized layout");
         self.make_indirect();
         match self.mode {
@@ -879,8 +879,7 @@ impl<'a, Ty> FnAbi<'a, Ty> {
     {
         if abi == spec::abi::Abi::X86Interrupt {
             if let Some(arg) = self.args.first_mut() {
-                // FIXME(pcwalton): This probably should use the x86 `byval` ABI...
-                arg.make_indirect_byval(None);
+                arg.pass_by_stack_offset(None);
             }
             return Ok(());
         }
diff --git a/compiler/rustc_target/src/abi/call/wasm.rs b/compiler/rustc_target/src/abi/call/wasm.rs
index 4ae8b9490dd..3c4cd76a754 100644
--- a/compiler/rustc_target/src/abi/call/wasm.rs
+++ b/compiler/rustc_target/src/abi/call/wasm.rs
@@ -40,7 +40,7 @@ where
     }
     arg.extend_integer_width_to(32);
     if arg.layout.is_aggregate() && !unwrap_trivial_aggregate(cx, arg) {
-        arg.make_indirect_byval(None);
+        arg.make_indirect();
     }
 }
 
diff --git a/compiler/rustc_target/src/abi/call/x86.rs b/compiler/rustc_target/src/abi/call/x86.rs
index bdb14350ded..d9af83d3205 100644
--- a/compiler/rustc_target/src/abi/call/x86.rs
+++ b/compiler/rustc_target/src/abi/call/x86.rs
@@ -122,7 +122,7 @@ where
                 align_4
             };
 
-            arg.make_indirect_byval(Some(byval_align));
+            arg.pass_by_stack_offset(Some(byval_align));
         } else {
             arg.extend_integer_width_to(32);
         }
diff --git a/compiler/rustc_target/src/abi/call/x86_64.rs b/compiler/rustc_target/src/abi/call/x86_64.rs
index 1209204debf..9910e623ac9 100644
--- a/compiler/rustc_target/src/abi/call/x86_64.rs
+++ b/compiler/rustc_target/src/abi/call/x86_64.rs
@@ -219,7 +219,7 @@ where
                 if is_arg {
                     // The x86_64 ABI doesn't have any special requirements for `byval` alignment,
                     // the type's alignment is always used.
-                    arg.make_indirect_byval(None);
+                    arg.pass_by_stack_offset(None);
                 } else {
                     // `sret` parameter thus one less integer register available
                     arg.make_indirect();
diff --git a/compiler/rustc_target/src/abi/call/xtensa.rs b/compiler/rustc_target/src/abi/call/xtensa.rs
index d7b5fe9d4cc..e1728b08a39 100644
--- a/compiler/rustc_target/src/abi/call/xtensa.rs
+++ b/compiler/rustc_target/src/abi/call/xtensa.rs
@@ -68,7 +68,7 @@ where
     *arg_gprs_left -= needed_arg_gprs;
 
     if must_use_stack {
-        arg.make_indirect_byval(None);
+        arg.pass_by_stack_offset(None);
     } else if is_xtensa_aggregate(arg) {
         // Aggregates which are <= max_size will be passed in
         // registers if possible, so coerce to integers.
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index f12e3e595ad..1d478f84c43 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1714,8 +1714,10 @@ supported_targets! {
     ("x86_64-apple-ios-macabi", x86_64_apple_ios_macabi),
     ("aarch64-apple-ios-macabi", aarch64_apple_ios_macabi),
     ("aarch64-apple-ios-sim", aarch64_apple_ios_sim),
+
     ("aarch64-apple-tvos", aarch64_apple_tvos),
     ("aarch64-apple-tvos-sim", aarch64_apple_tvos_sim),
+    ("arm64e-apple-tvos", arm64e_apple_tvos),
     ("x86_64-apple-tvos", x86_64_apple_tvos),
 
     ("armv7k-apple-watchos", armv7k_apple_watchos),
diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs
new file mode 100644
index 00000000000..d4d66c92857
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_tvos.rs
@@ -0,0 +1,24 @@
+use crate::spec::base::apple::{base, Arch, TargetAbi};
+use crate::spec::{FramePointer, Target, TargetOptions};
+
+pub(crate) fn target() -> Target {
+    let (opts, llvm_target, arch) = base("tvos", Arch::Arm64e, TargetAbi::Normal);
+    Target {
+        llvm_target,
+        metadata: crate::spec::TargetMetadata {
+            description: Some("ARM64e Apple tvOS".into()),
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(true),
+        },
+        pointer_width: 64,
+        data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
+        arch,
+        options: TargetOptions {
+            features: "+neon,+fp-armv8,+apple-a12,+v8.3a,+pauth".into(),
+            max_atomic_width: Some(128),
+            frame_pointer: FramePointer::NonLeaf,
+            ..opts
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
index e0a6c230fd6..71086daaf2c 100644
--- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_gnu.rs
@@ -10,7 +10,7 @@ pub(crate) fn target() -> Target {
     // ABI. Pass the -vector feature string to LLVM to respect this assumption. On LLVM < 16, we
     // also strip v128 from the data_layout below to match the older LLVM's expectation.
     base.features = "-vector".into();
-    base.max_atomic_width = Some(64);
+    base.max_atomic_width = Some(128);
     base.min_global_align = Some(16);
     base.stack_probes = StackProbeType::Inline;
     base.supported_sanitizers =
diff --git a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
index 6aabe9ca519..016ff5abe4c 100644
--- a/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
+++ b/compiler/rustc_target/src/spec/targets/s390x_unknown_linux_musl.rs
@@ -10,7 +10,7 @@ pub(crate) fn target() -> Target {
     // ABI. Pass the -vector feature string to LLVM to respect this assumption. On LLVM < 16, we
     // also strip v128 from the data_layout below to match the older LLVM's expectation.
     base.features = "-vector".into();
-    base.max_atomic_width = Some(64);
+    base.max_atomic_width = Some(128);
     base.min_global_align = Some(16);
     base.static_position_independent_executables = true;
     base.stack_probes = StackProbeType::Inline;
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 5918686213a..2de6ee9cf91 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
@@ -6,7 +6,7 @@ use rustc_data_structures::unord::UnordSet;
 use rustc_errors::codes::*;
 use rustc_errors::{
     pluralize, struct_span_code_err, Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey,
-    StringPart,
+    StringPart, Suggestions,
 };
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::{DefId, LocalDefId, LOCAL_CRATE};
@@ -1669,6 +1669,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             let name = self.tcx.crate_name(trait_def_id.krate);
             let spans: Vec<_> = [trait_def_id, found_type]
                 .into_iter()
+                .filter(|def_id| def_id.krate != LOCAL_CRATE)
                 .filter_map(|def_id| self.tcx.extern_crate(def_id.krate))
                 .map(|data| {
                     let dependency = if data.dependency_of == LOCAL_CRATE {
@@ -2136,8 +2137,8 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
             if let Some(span) = err.span.primary_span()
                 && let Some(mut diag) =
                     self.dcx().steal_non_err(span, StashKey::AssociatedTypeSuggestion)
-                && let Ok(ref mut s1) = err.suggestions
-                && let Ok(ref mut s2) = diag.suggestions
+                && let Suggestions::Enabled(ref mut s1) = err.suggestions
+                && let Suggestions::Enabled(ref mut s2) = diag.suggestions
             {
                 s1.append(s2);
                 diag.cancel()
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index c82eaa5143d..538e23f4449 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -409,6 +409,9 @@ pub fn normalize_param_env_or_error<'tcx>(
     debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
 
     let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal());
+    if !normalize::needs_normalization(&elaborated_env, unnormalized_env.reveal()) {
+        return elaborated_env;
+    }
 
     // HACK: we are trying to normalize the param-env inside *itself*. The problem is that
     // normalization expects its param-env to be already normalized, which means we have
diff --git a/config.example.toml b/config.example.toml
index c66d65e639a..47ebb20d8fa 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -53,7 +53,7 @@
 #
 # Note that many of the LLVM options are not currently supported for
 # downloading. Currently only the "assertions" option can be toggled.
-#download-ci-llvm = if rust.channel == "dev" || rust.download-rustc != false { "if-unchanged" } else { false }
+#download-ci-llvm = true
 
 # Indicates whether the LLVM build is a Release or Debug build
 #optimize = true
diff --git a/library/alloc/src/alloc.rs b/library/alloc/src/alloc.rs
index de58b06545b..a91659b6de5 100644
--- a/library/alloc/src/alloc.rs
+++ b/library/alloc/src/alloc.rs
@@ -171,7 +171,13 @@ pub unsafe fn realloc(ptr: *mut u8, layout: Layout, new_size: usize) -> *mut u8
 #[inline]
 #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
 pub unsafe fn alloc_zeroed(layout: Layout) -> *mut u8 {
-    unsafe { __rust_alloc_zeroed(layout.size(), layout.align()) }
+    unsafe {
+        // Make sure we don't accidentally allow omitting the allocator shim in
+        // stable code until it is actually stabilized.
+        core::ptr::read_volatile(&__rust_no_alloc_shim_is_unstable);
+
+        __rust_alloc_zeroed(layout.size(), layout.align())
+    }
 }
 
 #[cfg(not(test))]
diff --git a/library/alloc/src/collections/binary_heap/mod.rs b/library/alloc/src/collections/binary_heap/mod.rs
index fe9f1010d32..a19a044fc7e 100644
--- a/library/alloc/src/collections/binary_heap/mod.rs
+++ b/library/alloc/src/collections/binary_heap/mod.rs
@@ -959,6 +959,7 @@ impl<T, A: Allocator> BinaryHeap<T, A> {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "binaryheap_iter")]
     pub fn iter(&self) -> Iter<'_, T> {
         Iter { iter: self.data.iter() }
     }
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 60e08b47e3d..0eadc9ecac8 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -916,6 +916,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
     /// assert_eq!(map.contains_key(&2), false);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "btreemap_contains_key")]
     pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool
     where
         K: Borrow<Q> + Ord,
@@ -981,6 +982,7 @@ impl<K, V, A: Allocator + Clone> BTreeMap<K, V, A> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_confusables("push", "put", "set")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "btreemap_insert")]
     pub fn insert(&mut self, key: K, value: V) -> Option<V>
     where
         K: Ord,
diff --git a/library/alloc/src/collections/btree/set.rs b/library/alloc/src/collections/btree/set.rs
index 2b5bebcd8cd..770cd80ea9c 100644
--- a/library/alloc/src/collections/btree/set.rs
+++ b/library/alloc/src/collections/btree/set.rs
@@ -1132,6 +1132,7 @@ impl<T, A: Allocator + Clone> BTreeSet<T, A> {
     /// assert_eq!(set_iter.next(), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "btreeset_iter")]
     pub fn iter(&self) -> Iter<'_, T> {
         Iter { iter: self.map.keys() }
     }
diff --git a/library/alloc/src/collections/linked_list/tests.rs b/library/alloc/src/collections/linked_list/tests.rs
index 9b3c9ac5ce5..c93e5813b11 100644
--- a/library/alloc/src/collections/linked_list/tests.rs
+++ b/library/alloc/src/collections/linked_list/tests.rs
@@ -1,3 +1,6 @@
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use std::panic::{catch_unwind, AssertUnwindSafe};
 use std::thread;
 
diff --git a/library/alloc/src/collections/vec_deque/mod.rs b/library/alloc/src/collections/vec_deque/mod.rs
index 8c9db063105..a438517b75b 100644
--- a/library/alloc/src/collections/vec_deque/mod.rs
+++ b/library/alloc/src/collections/vec_deque/mod.rs
@@ -1201,6 +1201,7 @@ impl<T, A: Allocator> VecDeque<T, A> {
     /// assert_eq!(&c[..], b);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "vecdeque_iter")]
     pub fn iter(&self) -> Iter<'_, T> {
         let (a, b) = self.as_slices();
         Iter::new(a.iter(), b.iter())
diff --git a/library/alloc/src/collections/vec_deque/tests.rs b/library/alloc/src/collections/vec_deque/tests.rs
index f8ce4ca9788..c90679f1797 100644
--- a/library/alloc/src/collections/vec_deque/tests.rs
+++ b/library/alloc/src/collections/vec_deque/tests.rs
@@ -1,3 +1,6 @@
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use core::iter::TrustedLen;
 
 use super::*;
diff --git a/library/alloc/src/ffi/c_str.rs b/library/alloc/src/ffi/c_str.rs
index e32676a6543..45037aa1615 100644
--- a/library/alloc/src/ffi/c_str.rs
+++ b/library/alloc/src/ffi/c_str.rs
@@ -576,6 +576,7 @@ impl CString {
     #[inline]
     #[must_use]
     #[stable(feature = "as_c_str", since = "1.20.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "cstring_as_c_str")]
     pub fn as_c_str(&self) -> &CStr {
         &*self
     }
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index f98c0cca1db..f0597f295b3 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -110,7 +110,6 @@
 #![feature(const_cow_is_borrowed)]
 #![feature(const_eval_select)]
 #![feature(const_heap)]
-#![feature(const_maybe_uninit_as_mut_ptr)]
 #![feature(const_maybe_uninit_write)]
 #![feature(const_option)]
 #![feature(const_pin)]
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 88c7a12db23..b9a92749aae 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -460,42 +460,7 @@ impl<T> Rc<T> {
     where
         F: FnOnce(&Weak<T>) -> T,
     {
-        // Construct the inner in the "uninitialized" state with a single
-        // weak reference.
-        let uninit_ptr: NonNull<_> = Box::leak(Box::new(RcBox {
-            strong: Cell::new(0),
-            weak: Cell::new(1),
-            value: mem::MaybeUninit::<T>::uninit(),
-        }))
-        .into();
-
-        let init_ptr: NonNull<RcBox<T>> = uninit_ptr.cast();
-
-        let weak = Weak { ptr: init_ptr, alloc: Global };
-
-        // It's important we don't give up ownership of the weak pointer, or
-        // else the memory might be freed by the time `data_fn` returns. If
-        // we really wanted to pass ownership, we could create an additional
-        // weak pointer for ourselves, but this would result in additional
-        // updates to the weak reference count which might not be necessary
-        // otherwise.
-        let data = data_fn(&weak);
-
-        let strong = unsafe {
-            let inner = init_ptr.as_ptr();
-            ptr::write(ptr::addr_of_mut!((*inner).value), data);
-
-            let prev_value = (*inner).strong.get();
-            debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
-            (*inner).strong.set(1);
-
-            Rc::from_inner(init_ptr)
-        };
-
-        // Strong references should collectively own a shared weak reference,
-        // so don't run the destructor for our old weak reference.
-        mem::forget(weak);
-        strong
+        Self::new_cyclic_in(data_fn, Global)
     }
 
     /// Constructs a new `Rc` with uninitialized contents.
@@ -762,6 +727,84 @@ impl<T, A: Allocator> Rc<T, A> {
         }
     }
 
+    /// Constructs a new `Rc<T, A>` in the given allocator while giving you a `Weak<T, A>` to the allocation,
+    /// to allow you to construct a `T` which holds a weak pointer to itself.
+    ///
+    /// Generally, a structure circularly referencing itself, either directly or
+    /// indirectly, should not hold a strong reference to itself to prevent a memory leak.
+    /// Using this function, you get access to the weak pointer during the
+    /// initialization of `T`, before the `Rc<T, A>` is created, such that you can
+    /// clone and store it inside the `T`.
+    ///
+    /// `new_cyclic_in` first allocates the managed allocation for the `Rc<T, A>`,
+    /// then calls your closure, giving it a `Weak<T, A>` to this allocation,
+    /// and only afterwards completes the construction of the `Rc<T, A>` by placing
+    /// the `T` returned from your closure into the allocation.
+    ///
+    /// Since the new `Rc<T, A>` is not fully-constructed until `Rc<T, A>::new_cyclic_in`
+    /// returns, calling [`upgrade`] on the weak reference inside your closure will
+    /// fail and result in a `None` value.
+    ///
+    /// # Panics
+    ///
+    /// If `data_fn` panics, the panic is propagated to the caller, and the
+    /// temporary [`Weak<T, A>`] is dropped normally.
+    ///
+    /// # Examples
+    ///
+    /// See [`new_cyclic`].
+    ///
+    /// [`new_cyclic`]: Rc::new_cyclic
+    /// [`upgrade`]: Weak::upgrade
+    #[cfg(not(no_global_oom_handling))]
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    pub fn new_cyclic_in<F>(data_fn: F, alloc: A) -> Rc<T, A>
+    where
+        F: FnOnce(&Weak<T, A>) -> T,
+    {
+        // Construct the inner in the "uninitialized" state with a single
+        // weak reference.
+        let (uninit_raw_ptr, alloc) = Box::into_raw_with_allocator(Box::new_in(
+            RcBox {
+                strong: Cell::new(0),
+                weak: Cell::new(1),
+                value: mem::MaybeUninit::<T>::uninit(),
+            },
+            alloc,
+        ));
+        let uninit_ptr: NonNull<_> = (unsafe { &mut *uninit_raw_ptr }).into();
+        let init_ptr: NonNull<RcBox<T>> = uninit_ptr.cast();
+
+        let weak = Weak { ptr: init_ptr, alloc: alloc };
+
+        // It's important we don't give up ownership of the weak pointer, or
+        // else the memory might be freed by the time `data_fn` returns. If
+        // we really wanted to pass ownership, we could create an additional
+        // weak pointer for ourselves, but this would result in additional
+        // updates to the weak reference count which might not be necessary
+        // otherwise.
+        let data = data_fn(&weak);
+
+        let strong = unsafe {
+            let inner = init_ptr.as_ptr();
+            ptr::write(ptr::addr_of_mut!((*inner).value), data);
+
+            let prev_value = (*inner).strong.get();
+            debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
+            (*inner).strong.set(1);
+
+            // Strong references should collectively own a shared weak reference,
+            // so don't run the destructor for our old weak reference.
+            // Calling into_raw_with_allocator has the double effect of giving us back the allocator,
+            // and forgetting the weak reference.
+            let alloc = weak.into_raw_with_allocator().1;
+
+            Rc::from_inner_in(init_ptr, alloc)
+        };
+
+        strong
+    }
+
     /// Constructs a new `Rc<T>` in the provided allocator, returning an error if the allocation
     /// fails
     ///
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index 8cdba166c9d..45fb88969c6 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -496,6 +496,7 @@ impl<T> [T] {
     #[rustc_allow_incoherent_impl]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "slice_into_vec")]
     pub fn into_vec<A: Allocator>(self: Box<Self, A>) -> Vec<T, A> {
         // N.B., see the `hack` module in this file for more details.
         hack::into_vec(self)
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 6daab5bc73a..d58a016b502 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -440,6 +440,7 @@ impl String {
     /// ```
     #[inline]
     #[rustc_const_stable(feature = "const_string_new", since = "1.39.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "string_new")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[must_use]
     pub const fn new() -> String {
@@ -571,6 +572,7 @@ impl String {
     /// [`into_bytes`]: String::into_bytes
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "string_from_utf8")]
     pub fn from_utf8(vec: Vec<u8>) -> Result<String, FromUtf8Error> {
         match str::from_utf8(&vec) {
             Ok(..) => Ok(String { vec }),
@@ -1073,6 +1075,7 @@ impl String {
     #[inline]
     #[must_use]
     #[stable(feature = "string_as_str", since = "1.7.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "string_as_str")]
     pub fn as_str(&self) -> &str {
         self
     }
@@ -1092,6 +1095,7 @@ impl String {
     #[inline]
     #[must_use]
     #[stable(feature = "string_as_str", since = "1.7.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "string_as_mut_str")]
     pub fn as_mut_str(&mut self) -> &mut str {
         self
     }
@@ -1111,6 +1115,7 @@ impl String {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_confusables("append", "push")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "string_push_str")]
     pub fn push_str(&mut self, string: &str) {
         self.vec.extend_from_slice(string.as_bytes())
     }
@@ -1745,6 +1750,7 @@ impl String {
     #[cfg(not(no_global_oom_handling))]
     #[inline]
     #[stable(feature = "insert_str", since = "1.16.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "string_insert_str")]
     pub fn insert_str(&mut self, idx: usize, string: &str) {
         assert!(self.is_char_boundary(idx));
 
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index 43684f31cb7..4d4e84bfda5 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -450,54 +450,7 @@ impl<T> Arc<T> {
     where
         F: FnOnce(&Weak<T>) -> T,
     {
-        // Construct the inner in the "uninitialized" state with a single
-        // weak reference.
-        let uninit_ptr: NonNull<_> = Box::leak(Box::new(ArcInner {
-            strong: atomic::AtomicUsize::new(0),
-            weak: atomic::AtomicUsize::new(1),
-            data: mem::MaybeUninit::<T>::uninit(),
-        }))
-        .into();
-        let init_ptr: NonNull<ArcInner<T>> = uninit_ptr.cast();
-
-        let weak = Weak { ptr: init_ptr, alloc: Global };
-
-        // It's important we don't give up ownership of the weak pointer, or
-        // else the memory might be freed by the time `data_fn` returns. If
-        // we really wanted to pass ownership, we could create an additional
-        // weak pointer for ourselves, but this would result in additional
-        // updates to the weak reference count which might not be necessary
-        // otherwise.
-        let data = data_fn(&weak);
-
-        // Now we can properly initialize the inner value and turn our weak
-        // reference into a strong reference.
-        let strong = unsafe {
-            let inner = init_ptr.as_ptr();
-            ptr::write(ptr::addr_of_mut!((*inner).data), data);
-
-            // The above write to the data field must be visible to any threads which
-            // observe a non-zero strong count. Therefore we need at least "Release" ordering
-            // in order to synchronize with the `compare_exchange_weak` in `Weak::upgrade`.
-            //
-            // "Acquire" ordering is not required. When considering the possible behaviours
-            // of `data_fn` we only need to look at what it could do with a reference to a
-            // non-upgradeable `Weak`:
-            // - It can *clone* the `Weak`, increasing the weak reference count.
-            // - It can drop those clones, decreasing the weak reference count (but never to zero).
-            //
-            // These side effects do not impact us in any way, and no other side effects are
-            // possible with safe code alone.
-            let prev_value = (*inner).strong.fetch_add(1, Release);
-            debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
-
-            Arc::from_inner(init_ptr)
-        };
-
-        // Strong references should collectively own a shared weak reference,
-        // so don't run the destructor for our old weak reference.
-        mem::forget(weak);
-        strong
+        Self::new_cyclic_in(data_fn, Global)
     }
 
     /// Constructs a new `Arc` with uninitialized contents.
@@ -781,6 +734,98 @@ impl<T, A: Allocator> Arc<T, A> {
         }
     }
 
+    /// Constructs a new `Arc<T, A>` in the given allocator while giving you a `Weak<T, A>` to the allocation,
+    /// to allow you to construct a `T` which holds a weak pointer to itself.
+    ///
+    /// Generally, a structure circularly referencing itself, either directly or
+    /// indirectly, should not hold a strong reference to itself to prevent a memory leak.
+    /// Using this function, you get access to the weak pointer during the
+    /// initialization of `T`, before the `Arc<T, A>` is created, such that you can
+    /// clone and store it inside the `T`.
+    ///
+    /// `new_cyclic_in` first allocates the managed allocation for the `Arc<T, A>`,
+    /// then calls your closure, giving it a `Weak<T, A>` to this allocation,
+    /// and only afterwards completes the construction of the `Arc<T, A>` by placing
+    /// the `T` returned from your closure into the allocation.
+    ///
+    /// Since the new `Arc<T, A>` is not fully-constructed until `Arc<T, A>::new_cyclic_in`
+    /// returns, calling [`upgrade`] on the weak reference inside your closure will
+    /// fail and result in a `None` value.
+    ///
+    /// # Panics
+    ///
+    /// If `data_fn` panics, the panic is propagated to the caller, and the
+    /// temporary [`Weak<T>`] is dropped normally.
+    ///
+    /// # Example
+    ///
+    /// See [`new_cyclic`]
+    ///
+    /// [`new_cyclic`]: Arc::new_cyclic
+    /// [`upgrade`]: Weak::upgrade
+    #[cfg(not(no_global_oom_handling))]
+    #[inline]
+    #[unstable(feature = "allocator_api", issue = "32838")]
+    pub fn new_cyclic_in<F>(data_fn: F, alloc: A) -> Arc<T, A>
+    where
+        F: FnOnce(&Weak<T, A>) -> T,
+    {
+        // Construct the inner in the "uninitialized" state with a single
+        // weak reference.
+        let (uninit_raw_ptr, alloc) = Box::into_raw_with_allocator(Box::new_in(
+            ArcInner {
+                strong: atomic::AtomicUsize::new(0),
+                weak: atomic::AtomicUsize::new(1),
+                data: mem::MaybeUninit::<T>::uninit(),
+            },
+            alloc,
+        ));
+        let uninit_ptr: NonNull<_> = (unsafe { &mut *uninit_raw_ptr }).into();
+        let init_ptr: NonNull<ArcInner<T>> = uninit_ptr.cast();
+
+        let weak = Weak { ptr: init_ptr, alloc: alloc };
+
+        // It's important we don't give up ownership of the weak pointer, or
+        // else the memory might be freed by the time `data_fn` returns. If
+        // we really wanted to pass ownership, we could create an additional
+        // weak pointer for ourselves, but this would result in additional
+        // updates to the weak reference count which might not be necessary
+        // otherwise.
+        let data = data_fn(&weak);
+
+        // Now we can properly initialize the inner value and turn our weak
+        // reference into a strong reference.
+        let strong = unsafe {
+            let inner = init_ptr.as_ptr();
+            ptr::write(ptr::addr_of_mut!((*inner).data), data);
+
+            // The above write to the data field must be visible to any threads which
+            // observe a non-zero strong count. Therefore we need at least "Release" ordering
+            // in order to synchronize with the `compare_exchange_weak` in `Weak::upgrade`.
+            //
+            // "Acquire" ordering is not required. When considering the possible behaviours
+            // of `data_fn` we only need to look at what it could do with a reference to a
+            // non-upgradeable `Weak`:
+            // - It can *clone* the `Weak`, increasing the weak reference count.
+            // - It can drop those clones, decreasing the weak reference count (but never to zero).
+            //
+            // These side effects do not impact us in any way, and no other side effects are
+            // possible with safe code alone.
+            let prev_value = (*inner).strong.fetch_add(1, Release);
+            debug_assert_eq!(prev_value, 0, "No prior strong references should exist");
+
+            // Strong references should collectively own a shared weak reference,
+            // so don't run the destructor for our old weak reference.
+            // Calling into_raw_with_allocator has the double effect of giving us back the allocator,
+            // and forgetting the weak reference.
+            let alloc = weak.into_raw_with_allocator().1;
+
+            Arc::from_inner_in(init_ptr, alloc)
+        };
+
+        strong
+    }
+
     /// Constructs a new `Pin<Arc<T, A>>` in the provided allocator. If `T` does not implement `Unpin`,
     /// then `data` will be pinned in memory and unable to be moved.
     #[cfg(not(no_global_oom_handling))]
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 2afb5dd0d1a..1984cfeefc1 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -416,6 +416,7 @@ impl<T> Vec<T> {
     /// ```
     #[inline]
     #[rustc_const_stable(feature = "const_vec_new", since = "1.39.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "vec_new")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[must_use]
     pub const fn new() -> Self {
@@ -476,6 +477,7 @@ impl<T> Vec<T> {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[must_use]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "vec_with_capacity")]
     pub fn with_capacity(capacity: usize) -> Self {
         Self::with_capacity_in(capacity, Global)
     }
@@ -1545,6 +1547,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// ```
     #[inline]
     #[stable(feature = "vec_as_slice", since = "1.7.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "vec_as_slice")]
     pub fn as_slice(&self) -> &[T] {
         self
     }
@@ -1562,6 +1565,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// ```
     #[inline]
     #[stable(feature = "vec_as_slice", since = "1.7.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "vec_as_mut_slice")]
     pub fn as_mut_slice(&mut self) -> &mut [T] {
         self
     }
@@ -1580,7 +1584,8 @@ impl<T, A: Allocator> Vec<T, A> {
     ///
     /// This method guarantees that for the purpose of the aliasing model, this method
     /// does not materialize a reference to the underlying slice, and thus the returned pointer
-    /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
+    /// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`],
+    /// and [`as_non_null`].
     /// Note that calling other methods that materialize mutable references to the slice,
     /// or mutable references to specific elements you are planning on accessing through this pointer,
     /// as well as writing to those elements, may still invalidate this pointer.
@@ -1617,6 +1622,7 @@ impl<T, A: Allocator> Vec<T, A> {
     ///
     /// [`as_mut_ptr`]: Vec::as_mut_ptr
     /// [`as_ptr`]: Vec::as_ptr
+    /// [`as_non_null`]: Vec::as_non_null
     #[stable(feature = "vec_as_ptr", since = "1.37.0")]
     #[rustc_never_returns_null_ptr]
     #[inline]
@@ -1636,7 +1642,8 @@ impl<T, A: Allocator> Vec<T, A> {
     ///
     /// This method guarantees that for the purpose of the aliasing model, this method
     /// does not materialize a reference to the underlying slice, and thus the returned pointer
-    /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
+    /// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`],
+    /// and [`as_non_null`].
     /// Note that calling other methods that materialize references to the slice,
     /// or references to specific elements you are planning on accessing through this pointer,
     /// may still invalidate this pointer.
@@ -1676,6 +1683,7 @@ impl<T, A: Allocator> Vec<T, A> {
     ///
     /// [`as_mut_ptr`]: Vec::as_mut_ptr
     /// [`as_ptr`]: Vec::as_ptr
+    /// [`as_non_null`]: Vec::as_non_null
     #[stable(feature = "vec_as_ptr", since = "1.37.0")]
     #[rustc_never_returns_null_ptr]
     #[inline]
@@ -1685,6 +1693,69 @@ impl<T, A: Allocator> Vec<T, A> {
         self.buf.ptr()
     }
 
+    /// Returns a `NonNull` pointer to the vector's buffer, or a dangling
+    /// `NonNull` pointer valid for zero sized reads if the vector didn't allocate.
+    ///
+    /// The caller must ensure that the vector outlives the pointer this
+    /// function returns, or else it will end up dangling.
+    /// Modifying the vector may cause its buffer to be reallocated,
+    /// which would also make any pointers to it invalid.
+    ///
+    /// This method guarantees that for the purpose of the aliasing model, this method
+    /// does not materialize a reference to the underlying slice, and thus the returned pointer
+    /// will remain valid when mixed with other calls to [`as_ptr`], [`as_mut_ptr`],
+    /// and [`as_non_null`].
+    /// Note that calling other methods that materialize references to the slice,
+    /// or references to specific elements you are planning on accessing through this pointer,
+    /// may still invalidate this pointer.
+    /// See the second example below for how this guarantee can be used.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(box_vec_non_null)]
+    ///
+    /// // Allocate vector big enough for 4 elements.
+    /// let size = 4;
+    /// let mut x: Vec<i32> = Vec::with_capacity(size);
+    /// let x_ptr = x.as_non_null();
+    ///
+    /// // Initialize elements via raw pointer writes, then set length.
+    /// unsafe {
+    ///     for i in 0..size {
+    ///         x_ptr.add(i).write(i as i32);
+    ///     }
+    ///     x.set_len(size);
+    /// }
+    /// assert_eq!(&*x, &[0, 1, 2, 3]);
+    /// ```
+    ///
+    /// Due to the aliasing guarantee, the following code is legal:
+    ///
+    /// ```rust
+    /// #![feature(box_vec_non_null)]
+    ///
+    /// unsafe {
+    ///     let mut v = vec![0];
+    ///     let ptr1 = v.as_non_null();
+    ///     ptr1.write(1);
+    ///     let ptr2 = v.as_non_null();
+    ///     ptr2.write(2);
+    ///     // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
+    ///     ptr1.write(3);
+    /// }
+    /// ```
+    ///
+    /// [`as_mut_ptr`]: Vec::as_mut_ptr
+    /// [`as_ptr`]: Vec::as_ptr
+    /// [`as_non_null`]: Vec::as_non_null
+    #[unstable(feature = "box_vec_non_null", reason = "new API", issue = "130364")]
+    #[inline]
+    pub fn as_non_null(&mut self) -> NonNull<T> {
+        // SAFETY: A `Vec` always has a non-null pointer.
+        unsafe { NonNull::new_unchecked(self.as_mut_ptr()) }
+    }
+
     /// Returns a reference to the underlying allocator.
     #[unstable(feature = "allocator_api", issue = "32838")]
     #[inline]
@@ -2380,6 +2451,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// Takes *O*(1) time.
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "vec_pop")]
     pub fn pop(&mut self) -> Option<T> {
         if self.len == 0 {
             None
@@ -2573,6 +2645,7 @@ impl<T, A: Allocator> Vec<T, A> {
     /// assert!(!v.is_empty());
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "vec_is_empty")]
     pub fn is_empty(&self) -> bool {
         self.len() == 0
     }
@@ -3044,6 +3117,7 @@ impl<T: PartialEq, A: Allocator> Vec<T, A> {
 #[doc(hidden)]
 #[cfg(not(no_global_oom_handling))]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "vec_from_elem")]
 pub fn from_elem<T: Clone>(elem: T, n: usize) -> Vec<T> {
     <T as SpecFromElem>::from_elem(elem, n, Global)
 }
diff --git a/library/alloc/tests/fmt.rs b/library/alloc/tests/fmt.rs
index ce24a40f4c0..c13074c53b7 100644
--- a/library/alloc/tests/fmt.rs
+++ b/library/alloc/tests/fmt.rs
@@ -1,4 +1,6 @@
 #![deny(warnings)]
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
 
 use std::cell::RefCell;
 use std::fmt::{self, Write};
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index 3722fb06a6a..cf2ca4f0d65 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -1,3 +1,6 @@
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use core::alloc::{Allocator, Layout};
 use core::num::NonZero;
 use core::ptr::NonNull;
@@ -1284,6 +1287,8 @@ fn test_from_iter_specialization_panic_during_iteration_drops() {
 
 #[test]
 #[cfg_attr(not(panic = "unwind"), ignore = "test requires unwinding support")]
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#[cfg_attr(not(bootstrap), allow(static_mut_refs))]
 fn test_from_iter_specialization_panic_during_drop_doesnt_leak() {
     static mut DROP_COUNTER_OLD: [usize; 5] = [0; 5];
     static mut DROP_COUNTER_NEW: [usize; 2] = [0; 2];
diff --git a/library/alloc/tests/vec_deque.rs b/library/alloc/tests/vec_deque.rs
index f32ba8d5aa4..0891d99fe66 100644
--- a/library/alloc/tests/vec_deque.rs
+++ b/library/alloc/tests/vec_deque.rs
@@ -1,3 +1,6 @@
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use core::num::NonZero;
 use std::assert_matches::assert_matches;
 use std::collections::vec_deque::Drain;
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index ad3f9d80878..107d82267e5 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -5,8 +5,10 @@
 // Your performance intuition is useless. Run perf.
 
 use crate::error::Error;
+use crate::intrinsics::{unchecked_add, unchecked_mul, unchecked_sub};
+use crate::mem::SizedTypeProperties;
 use crate::ptr::{Alignment, NonNull};
-use crate::{assert_unsafe_precondition, cmp, fmt, mem};
+use crate::{assert_unsafe_precondition, fmt, mem};
 
 // While this function is used in one place and its implementation
 // could be inlined, the previous attempts to do so made rustc
@@ -98,7 +100,10 @@ impl Layout {
         //
         // Above implies that checking for summation overflow is both
         // necessary and sufficient.
-        isize::MAX as usize - (align.as_usize() - 1)
+
+        // SAFETY: the maximum possible alignment is `isize::MAX + 1`,
+        // so the subtraction cannot overflow.
+        unsafe { unchecked_sub(isize::MAX as usize + 1, align.as_usize()) }
     }
 
     /// Internal helper constructor to skip revalidating alignment validity.
@@ -252,9 +257,14 @@ impl Layout {
     /// Returns an error if the combination of `self.size()` and the given
     /// `align` violates the conditions listed in [`Layout::from_size_align`].
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
+    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
     #[inline]
-    pub fn align_to(&self, align: usize) -> Result<Self, LayoutError> {
-        Layout::from_size_align(self.size(), cmp::max(self.align(), align))
+    pub const fn align_to(&self, align: usize) -> Result<Self, LayoutError> {
+        if let Some(align) = Alignment::new(align) {
+            Layout::from_size_alignment(self.size, Alignment::max(self.align, align))
+        } else {
+            Err(LayoutError)
+        }
     }
 
     /// Returns the amount of padding we must insert after `self`
@@ -279,29 +289,42 @@ impl Layout {
                   without modifying the `Layout`"]
     #[inline]
     pub const fn padding_needed_for(&self, align: usize) -> usize {
-        let len = self.size();
+        // FIXME: Can we just change the type on this to `Alignment`?
+        let Some(align) = Alignment::new(align) else { return usize::MAX };
+        let len_rounded_up = self.size_rounded_up_to_custom_align(align);
+        // SAFETY: Cannot overflow because the rounded-up value is never less
+        unsafe { unchecked_sub(len_rounded_up, self.size) }
+    }
 
+    /// Returns the smallest multiple of `align` greater than or equal to `self.size()`.
+    ///
+    /// This can return at most `Alignment::MAX` (aka `isize::MAX + 1`)
+    /// because the original size is at most `isize::MAX`.
+    #[inline]
+    const fn size_rounded_up_to_custom_align(&self, align: Alignment) -> usize {
+        // SAFETY:
         // Rounded up value is:
-        //   len_rounded_up = (len + align - 1) & !(align - 1);
-        // and then we return the padding difference: `len_rounded_up - len`.
+        //   size_rounded_up = (size + align - 1) & !(align - 1);
         //
-        // We use modular arithmetic throughout:
+        // The arithmetic we do here can never overflow:
         //
         // 1. align is guaranteed to be > 0, so align - 1 is always
         //    valid.
         //
-        // 2. `len + align - 1` can overflow by at most `align - 1`,
-        //    so the &-mask with `!(align - 1)` will ensure that in the
-        //    case of overflow, `len_rounded_up` will itself be 0.
-        //    Thus the returned padding, when added to `len`, yields 0,
-        //    which trivially satisfies the alignment `align`.
+        // 2. size is at most `isize::MAX`, so adding `align - 1` (which is at
+        //    most `isize::MAX`) can never overflow a `usize`.
         //
-        // (Of course, attempts to allocate blocks of memory whose
-        // size and padding overflow in the above manner should cause
-        // the allocator to yield an error anyway.)
-
-        let len_rounded_up = len.wrapping_add(align).wrapping_sub(1) & !align.wrapping_sub(1);
-        len_rounded_up.wrapping_sub(len)
+        // 3. masking by the alignment can remove at most `align - 1`,
+        //    which is what we just added, thus the value we return is never
+        //    less than the original `size`.
+        //
+        // (Size 0 Align MAX is already aligned, so stays the same, but things like
+        // Size 1 Align MAX or Size isize::MAX Align 2 round up to `isize::MAX + 1`.)
+        unsafe {
+            let align_m1 = unchecked_sub(align.as_usize(), 1);
+            let size_rounded_up = unchecked_add(self.size, align_m1) & !align_m1;
+            size_rounded_up
+        }
     }
 
     /// Creates a layout by rounding the size of this layout up to a multiple
@@ -315,12 +338,11 @@ impl Layout {
                   without modifying the original"]
     #[inline]
     pub const fn pad_to_align(&self) -> Layout {
-        let pad = self.padding_needed_for(self.align());
         // This cannot overflow. Quoting from the invariant of Layout:
         // > `size`, when rounded up to the nearest multiple of `align`,
         // > must not overflow isize (i.e., the rounded value must be
         // > less than or equal to `isize::MAX`)
-        let new_size = self.size() + pad;
+        let new_size = self.size_rounded_up_to_custom_align(self.align);
 
         // SAFETY: padded size is guaranteed to not exceed `isize::MAX`.
         unsafe { Layout::from_size_align_unchecked(new_size, self.align()) }
@@ -333,20 +355,36 @@ impl Layout {
     /// layout of the array and `offs` is the distance between the start
     /// of each element in the array.
     ///
+    /// (That distance between elements is sometimes known as "stride".)
+    ///
     /// On arithmetic overflow, returns `LayoutError`.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(alloc_layout_extra)]
+    /// use std::alloc::Layout;
+    ///
+    /// // All rust types have a size that's a multiple of their alignment.
+    /// let normal = Layout::from_size_align(12, 4).unwrap();
+    /// let repeated = normal.repeat(3).unwrap();
+    /// assert_eq!(repeated, (Layout::from_size_align(36, 4).unwrap(), 12));
+    ///
+    /// // But you can manually make layouts which don't meet that rule.
+    /// let padding_needed = Layout::from_size_align(6, 4).unwrap();
+    /// let repeated = padding_needed.repeat(3).unwrap();
+    /// assert_eq!(repeated, (Layout::from_size_align(24, 4).unwrap(), 8));
+    /// ```
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
+    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
     #[inline]
-    pub fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> {
-        // This cannot overflow. Quoting from the invariant of Layout:
-        // > `size`, when rounded up to the nearest multiple of `align`,
-        // > must not overflow isize (i.e., the rounded value must be
-        // > less than or equal to `isize::MAX`)
-        let padded_size = self.size() + self.padding_needed_for(self.align());
-        let alloc_size = padded_size.checked_mul(n).ok_or(LayoutError)?;
-
-        // The safe constructor is called here to enforce the isize size limit.
-        let layout = Layout::from_size_alignment(alloc_size, self.align)?;
-        Ok((layout, padded_size))
+    pub const fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> {
+        let padded = self.pad_to_align();
+        if let Ok(repeated) = padded.repeat_packed(n) {
+            Ok((repeated, padded.size()))
+        } else {
+            Err(LayoutError)
+        }
     }
 
     /// Creates a layout describing the record for `self` followed by
@@ -395,17 +433,23 @@ impl Layout {
     /// # assert_eq!(repr_c(&[u64, u32, u16, u32]), Ok((s, vec![0, 8, 12, 16])));
     /// ```
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
+    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
     #[inline]
-    pub fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> {
-        let new_align = cmp::max(self.align, next.align);
-        let pad = self.padding_needed_for(next.align());
-
-        let offset = self.size().checked_add(pad).ok_or(LayoutError)?;
-        let new_size = offset.checked_add(next.size()).ok_or(LayoutError)?;
-
-        // The safe constructor is called here to enforce the isize size limit.
-        let layout = Layout::from_size_alignment(new_size, new_align)?;
-        Ok((layout, offset))
+    pub const fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> {
+        let new_align = Alignment::max(self.align, next.align);
+        let offset = self.size_rounded_up_to_custom_align(next.align);
+
+        // SAFETY: `offset` is at most `isize::MAX + 1` (such as from aligning
+        // to `Alignment::MAX`) and `next.size` is at most `isize::MAX` (from the
+        // `Layout` type invariant).  Thus the largest possible `new_size` is
+        // `isize::MAX + 1 + isize::MAX`, which is `usize::MAX`, and cannot overflow.
+        let new_size = unsafe { unchecked_add(offset, next.size) };
+
+        if let Ok(layout) = Layout::from_size_alignment(new_size, new_align) {
+            Ok((layout, offset))
+        } else {
+            Err(LayoutError)
+        }
     }
 
     /// Creates a layout describing the record for `n` instances of
@@ -421,11 +465,15 @@ impl Layout {
     ///
     /// On arithmetic overflow, returns `LayoutError`.
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
+    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
     #[inline]
-    pub fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> {
-        let size = self.size().checked_mul(n).ok_or(LayoutError)?;
-        // The safe constructor is called here to enforce the isize size limit.
-        Layout::from_size_alignment(size, self.align)
+    pub const fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> {
+        if let Some(size) = self.size.checked_mul(n) {
+            // The safe constructor is called here to enforce the isize size limit.
+            Layout::from_size_alignment(size, self.align)
+        } else {
+            Err(LayoutError)
+        }
     }
 
     /// Creates a layout describing the record for `self` followed by
@@ -435,10 +483,13 @@ impl Layout {
     ///
     /// On arithmetic overflow, returns `LayoutError`.
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
+    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
     #[inline]
-    pub fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> {
-        let new_size = self.size().checked_add(next.size()).ok_or(LayoutError)?;
-        // The safe constructor is called here to enforce the isize size limit.
+    pub const fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> {
+        // SAFETY: each `size` is at most `isize::MAX == usize::MAX/2`, so the
+        // sum is at most `usize::MAX/2*2 == usize::MAX - 1`, and cannot overflow.
+        let new_size = unsafe { unchecked_add(self.size, next.size) };
+        // The safe constructor enforces that the new size isn't too big for the alignment
         Layout::from_size_alignment(new_size, self.align)
     }
 
@@ -451,14 +502,12 @@ impl Layout {
     #[inline]
     pub const fn array<T>(n: usize) -> Result<Self, LayoutError> {
         // Reduce the amount of code we need to monomorphize per `T`.
-        return inner(mem::size_of::<T>(), Alignment::of::<T>(), n);
+        return inner(T::LAYOUT, n);
 
         #[inline]
-        const fn inner(
-            element_size: usize,
-            align: Alignment,
-            n: usize,
-        ) -> Result<Layout, LayoutError> {
+        const fn inner(element_layout: Layout, n: usize) -> Result<Layout, LayoutError> {
+            let Layout { size: element_size, align } = element_layout;
+
             // We need to check two things about the size:
             //  - That the total size won't overflow a `usize`, and
             //  - That the total size still fits in an `isize`.
@@ -473,7 +522,7 @@ impl Layout {
             // This is a useless hint inside this function, but after inlining this helps
             // deduplicate checks for whether the overall capacity is zero (e.g., in RawVec's
             // allocation path) before/after this multiplication.
-            let array_size = unsafe { element_size.unchecked_mul(n) };
+            let array_size = unsafe { unchecked_mul(element_size, n) };
 
             // SAFETY: We just checked above that the `array_size` will not
             // exceed `isize::MAX` even when rounded up to the alignment.
diff --git a/library/core/src/bool.rs b/library/core/src/bool.rs
index 03cdff9b13b..58a870d2e07 100644
--- a/library/core/src/bool.rs
+++ b/library/core/src/bool.rs
@@ -55,6 +55,7 @@ impl bool {
     /// assert_eq!(a, 1);
     /// ```
     #[stable(feature = "lazy_bool_to_option", since = "1.50.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "bool_then")]
     #[inline]
     pub fn then<T, F: FnOnce() -> T>(self, f: F) -> Option<T> {
         if self { Some(f()) } else { None }
diff --git a/library/core/src/cell/lazy.rs b/library/core/src/cell/lazy.rs
index 6ec1d2a33be..5bc13779af9 100644
--- a/library/core/src/cell/lazy.rs
+++ b/library/core/src/cell/lazy.rs
@@ -1,4 +1,5 @@
 use super::UnsafeCell;
+use crate::hint::unreachable_unchecked;
 use crate::ops::Deref;
 use crate::{fmt, mem};
 
@@ -82,7 +83,7 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
         match this.state.into_inner() {
             State::Init(data) => Ok(data),
             State::Uninit(f) => Err(f),
-            State::Poisoned => panic!("LazyCell instance has previously been poisoned"),
+            State::Poisoned => panic_poisoned(),
         }
     }
 
@@ -114,7 +115,72 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
             State::Init(data) => data,
             // SAFETY: The state is uninitialized.
             State::Uninit(_) => unsafe { LazyCell::really_init(this) },
-            State::Poisoned => panic!("LazyCell has previously been poisoned"),
+            State::Poisoned => panic_poisoned(),
+        }
+    }
+
+    /// Forces the evaluation of this lazy value and returns a mutable reference to
+    /// the result.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(lazy_get)]
+    /// use std::cell::LazyCell;
+    ///
+    /// let mut lazy = LazyCell::new(|| 92);
+    ///
+    /// let p = LazyCell::force_mut(&mut lazy);
+    /// assert_eq!(*p, 92);
+    /// *p = 44;
+    /// assert_eq!(*lazy, 44);
+    /// ```
+    #[inline]
+    #[unstable(feature = "lazy_get", issue = "129333")]
+    pub fn force_mut(this: &mut LazyCell<T, F>) -> &mut T {
+        #[cold]
+        /// # Safety
+        /// May only be called when the state is `Uninit`.
+        unsafe fn really_init_mut<T, F: FnOnce() -> T>(state: &mut State<T, F>) -> &mut T {
+            // INVARIANT: Always valid, but the value may not be dropped.
+            struct PoisonOnPanic<T, F>(*mut State<T, F>);
+            impl<T, F> Drop for PoisonOnPanic<T, F> {
+                #[inline]
+                fn drop(&mut self) {
+                    // SAFETY: Invariant states it is valid, and we don't drop the old value.
+                    unsafe {
+                        self.0.write(State::Poisoned);
+                    }
+                }
+            }
+
+            let State::Uninit(f) = state else {
+                // `unreachable!()` here won't optimize out because the function is cold.
+                // SAFETY: Precondition.
+                unsafe { unreachable_unchecked() };
+            };
+            // SAFETY: We never drop the state after we read `f`, and we write a valid value back
+            // in any case, panic or success. `f` can't access the `LazyCell` because it is mutably
+            // borrowed.
+            let f = unsafe { core::ptr::read(f) };
+            // INVARIANT: Initiated from mutable reference, don't drop because we read it.
+            let guard = PoisonOnPanic(state);
+            let data = f();
+            // SAFETY: `PoisonOnPanic` invariant, and we don't drop the old value.
+            unsafe {
+                core::ptr::write(guard.0, State::Init(data));
+            }
+            core::mem::forget(guard);
+            let State::Init(data) = state else { unreachable!() };
+            data
+        }
+
+        let state = this.state.get_mut();
+        match state {
+            State::Init(data) => data,
+            // SAFETY: `state` is `Uninit`.
+            State::Uninit(_) => unsafe { really_init_mut(state) },
+            State::Poisoned => panic_poisoned(),
         }
     }
 
@@ -152,13 +218,55 @@ impl<T, F: FnOnce() -> T> LazyCell<T, F> {
 }
 
 impl<T, F> LazyCell<T, F> {
+    /// Returns a reference to the value if initialized, or `None` if not.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(lazy_get)]
+    ///
+    /// use std::cell::LazyCell;
+    ///
+    /// let mut lazy = LazyCell::new(|| 92);
+    ///
+    /// assert_eq!(LazyCell::get_mut(&mut lazy), None);
+    /// let _ = LazyCell::force(&lazy);
+    /// *LazyCell::get_mut(&mut lazy).unwrap() = 44;
+    /// assert_eq!(*lazy, 44);
+    /// ```
     #[inline]
-    fn get(&self) -> Option<&T> {
+    #[unstable(feature = "lazy_get", issue = "129333")]
+    pub fn get_mut(this: &mut LazyCell<T, F>) -> Option<&mut T> {
+        let state = this.state.get_mut();
+        match state {
+            State::Init(data) => Some(data),
+            _ => None,
+        }
+    }
+
+    /// Returns a mutable reference to the value if initialized, or `None` if not.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(lazy_get)]
+    ///
+    /// use std::cell::LazyCell;
+    ///
+    /// let lazy = LazyCell::new(|| 92);
+    ///
+    /// assert_eq!(LazyCell::get(&lazy), None);
+    /// let _ = LazyCell::force(&lazy);
+    /// assert_eq!(LazyCell::get(&lazy), Some(&92));
+    /// ```
+    #[inline]
+    #[unstable(feature = "lazy_get", issue = "129333")]
+    pub fn get(this: &LazyCell<T, F>) -> Option<&T> {
         // SAFETY:
         // This is sound for the same reason as in `force`: once the state is
         // initialized, it will not be mutably accessed again, so this reference
         // will stay valid for the duration of the borrow to `self`.
-        let state = unsafe { &*self.state.get() };
+        let state = unsafe { &*this.state.get() };
         match state {
             State::Init(data) => Some(data),
             _ => None,
@@ -188,10 +296,16 @@ impl<T: Default> Default for LazyCell<T> {
 impl<T: fmt::Debug, F> fmt::Debug for LazyCell<T, F> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut d = f.debug_tuple("LazyCell");
-        match self.get() {
+        match LazyCell::get(self) {
             Some(data) => d.field(data),
             None => d.field(&format_args!("<uninit>")),
         };
         d.finish()
     }
 }
+
+#[cold]
+#[inline(never)]
+fn panic_poisoned() -> ! {
+    panic!("LazyCell instance has previously been poisoned")
+}
diff --git a/library/core/src/char/methods.rs b/library/core/src/char/methods.rs
index bc5c7c32490..092d427ecea 100644
--- a/library/core/src/char/methods.rs
+++ b/library/core/src/char/methods.rs
@@ -1,6 +1,7 @@
 //! impl char {}
 
 use super::*;
+use crate::intrinsics::const_eval_select;
 use crate::slice;
 use crate::str::from_utf8_unchecked_mut;
 use crate::unicode::printable::is_printable;
@@ -672,8 +673,9 @@ impl char {
     /// 'ß'.encode_utf8(&mut b);
     /// ```
     #[stable(feature = "unicode_encode_char", since = "1.15.0")]
+    #[rustc_const_unstable(feature = "const_char_encode_utf8", issue = "130512")]
     #[inline]
-    pub fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
+    pub const fn encode_utf8(self, dst: &mut [u8]) -> &mut str {
         // SAFETY: `char` is not a surrogate, so this is valid UTF-8.
         unsafe { from_utf8_unchecked_mut(encode_utf8_raw(self as u32, dst)) }
     }
@@ -1735,14 +1737,11 @@ impl EscapeDebugExtArgs {
 
 #[inline]
 const fn len_utf8(code: u32) -> usize {
-    if code < MAX_ONE_B {
-        1
-    } else if code < MAX_TWO_B {
-        2
-    } else if code < MAX_THREE_B {
-        3
-    } else {
-        4
+    match code {
+        ..MAX_ONE_B => 1,
+        ..MAX_TWO_B => 2,
+        ..MAX_THREE_B => 3,
+        _ => 4,
     }
 }
 
@@ -1760,11 +1759,21 @@ const fn len_utf8(code: u32) -> usize {
 /// Panics if the buffer is not large enough.
 /// A buffer of length four is large enough to encode any `char`.
 #[unstable(feature = "char_internals", reason = "exposed only for libstd", issue = "none")]
+#[rustc_const_unstable(feature = "const_char_encode_utf8", issue = "130512")]
 #[doc(hidden)]
 #[inline]
-pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
+pub const fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
+    const fn panic_at_const(_code: u32, _len: usize, _dst_len: usize) {
+        // Note that we cannot format in constant expressions.
+        panic!("encode_utf8: buffer does not have enough bytes to encode code point");
+    }
+    fn panic_at_rt(code: u32, len: usize, dst_len: usize) {
+        panic!(
+            "encode_utf8: need {len} bytes to encode U+{code:04X} but buffer has just {dst_len}",
+        );
+    }
     let len = len_utf8(code);
-    match (len, &mut dst[..]) {
+    match (len, &mut *dst) {
         (1, [a, ..]) => {
             *a = code as u8;
         }
@@ -1783,14 +1792,11 @@ pub fn encode_utf8_raw(code: u32, dst: &mut [u8]) -> &mut [u8] {
             *c = (code >> 6 & 0x3F) as u8 | TAG_CONT;
             *d = (code & 0x3F) as u8 | TAG_CONT;
         }
-        _ => panic!(
-            "encode_utf8: need {} bytes to encode U+{:X}, but the buffer has {}",
-            len,
-            code,
-            dst.len(),
-        ),
+        // FIXME(const-hack): We would prefer to have streamlined panics when formatters become const-friendly.
+        _ => const_eval_select((code, len, dst.len()), panic_at_const, panic_at_rt),
     };
-    &mut dst[..len]
+    // SAFETY: `<&mut [u8]>::as_mut_ptr` is guaranteed to return a valid pointer and `len` has been tested to be within bounds.
+    unsafe { slice::from_raw_parts_mut(dst.as_mut_ptr(), len) }
 }
 
 /// Encodes a raw u32 value as UTF-16 into the provided `u16` buffer,
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index a1ed993b7d9..818a36002e7 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -901,7 +901,6 @@ pub trait Ord: Eq + PartialOrd<Self> {
     fn clamp(self, min: Self, max: Self) -> Self
     where
         Self: Sized,
-        Self: PartialOrd,
     {
         assert!(min <= max);
         if self < min {
diff --git a/library/core/src/iter/sources/repeat_n.rs b/library/core/src/iter/sources/repeat_n.rs
index 9c062193363..7e162ff387b 100644
--- a/library/core/src/iter/sources/repeat_n.rs
+++ b/library/core/src/iter/sources/repeat_n.rs
@@ -1,5 +1,6 @@
+use crate::fmt;
 use crate::iter::{FusedIterator, TrustedLen, UncheckedIterator};
-use crate::mem::ManuallyDrop;
+use crate::mem::{self, MaybeUninit};
 use crate::num::NonZero;
 
 /// Creates a new iterator that repeats a single element a given number of times.
@@ -58,14 +59,12 @@ use crate::num::NonZero;
 #[inline]
 #[stable(feature = "iter_repeat_n", since = "1.82.0")]
 pub fn repeat_n<T: Clone>(element: T, count: usize) -> RepeatN<T> {
-    let mut element = ManuallyDrop::new(element);
-
-    if count == 0 {
-        // SAFETY: we definitely haven't dropped it yet, since we only just got
-        // passed it in, and because the count is zero the instance we're about
-        // to create won't drop it, so to avoid leaking we need to now.
-        unsafe { ManuallyDrop::drop(&mut element) };
-    }
+    let element = if count == 0 {
+        // `element` gets dropped eagerly.
+        MaybeUninit::uninit()
+    } else {
+        MaybeUninit::new(element)
+    };
 
     RepeatN { element, count }
 }
@@ -74,15 +73,23 @@ pub fn repeat_n<T: Clone>(element: T, count: usize) -> RepeatN<T> {
 ///
 /// This `struct` is created by the [`repeat_n()`] function.
 /// See its documentation for more.
-#[derive(Clone, Debug)]
 #[stable(feature = "iter_repeat_n", since = "1.82.0")]
 pub struct RepeatN<A> {
     count: usize,
-    // Invariant: has been dropped iff count == 0.
-    element: ManuallyDrop<A>,
+    // Invariant: uninit iff count == 0.
+    element: MaybeUninit<A>,
 }
 
 impl<A> RepeatN<A> {
+    /// Returns the element if it hasn't been dropped already.
+    fn element_ref(&self) -> Option<&A> {
+        if self.count > 0 {
+            // SAFETY: The count is non-zero, so it must be initialized.
+            Some(unsafe { self.element.assume_init_ref() })
+        } else {
+            None
+        }
+    }
     /// If we haven't already dropped the element, return it in an option.
     ///
     /// Clears the count so it won't be dropped again later.
@@ -90,9 +97,10 @@ impl<A> RepeatN<A> {
     fn take_element(&mut self) -> Option<A> {
         if self.count > 0 {
             self.count = 0;
+            let element = mem::replace(&mut self.element, MaybeUninit::uninit());
             // SAFETY: We just set count to zero so it won't be dropped again,
             // and it used to be non-zero so it hasn't already been dropped.
-            unsafe { Some(ManuallyDrop::take(&mut self.element)) }
+            unsafe { Some(element.assume_init()) }
         } else {
             None
         }
@@ -100,6 +108,26 @@ impl<A> RepeatN<A> {
 }
 
 #[stable(feature = "iter_repeat_n", since = "1.82.0")]
+impl<A: Clone> Clone for RepeatN<A> {
+    fn clone(&self) -> RepeatN<A> {
+        RepeatN {
+            count: self.count,
+            element: self.element_ref().cloned().map_or_else(MaybeUninit::uninit, MaybeUninit::new),
+        }
+    }
+}
+
+#[stable(feature = "iter_repeat_n", since = "1.82.0")]
+impl<A: fmt::Debug> fmt::Debug for RepeatN<A> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        f.debug_struct("RepeatN")
+            .field("count", &self.count)
+            .field("element", &self.element_ref())
+            .finish()
+    }
+}
+
+#[stable(feature = "iter_repeat_n", since = "1.82.0")]
 impl<A> Drop for RepeatN<A> {
     fn drop(&mut self) {
         self.take_element();
@@ -194,9 +222,11 @@ impl<A: Clone> UncheckedIterator for RepeatN<A> {
             // SAFETY: the check above ensured that the count used to be non-zero,
             // so element hasn't been dropped yet, and we just lowered the count to
             // zero so it won't be dropped later, and thus it's okay to take it here.
-            unsafe { ManuallyDrop::take(&mut self.element) }
+            unsafe { mem::replace(&mut self.element, MaybeUninit::uninit()).assume_init() }
         } else {
-            A::clone(&self.element)
+            // SAFETY: the count is non-zero, so it must have not been dropped yet.
+            let element = unsafe { self.element.assume_init_ref() };
+            A::clone(element)
         }
     }
 }
diff --git a/library/core/src/iter/traits/iterator.rs b/library/core/src/iter/traits/iterator.rs
index 8352486ad41..f53beeb007d 100644
--- a/library/core/src/iter/traits/iterator.rs
+++ b/library/core/src/iter/traits/iterator.rs
@@ -876,6 +876,7 @@ pub trait Iterator {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_do_not_const_check]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "iter_filter")]
     fn filter<P>(self, predicate: P) -> Filter<Self, P>
     where
         Self: Sized,
@@ -3412,6 +3413,7 @@ pub trait Iterator {
     /// ```
     #[stable(feature = "iter_copied", since = "1.36.0")]
     #[rustc_do_not_const_check]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "iter_copied")]
     fn copied<'a, T: 'a>(self) -> Copied<Self>
     where
         Self: Sized + Iterator<Item = &'a T>,
@@ -3460,6 +3462,7 @@ pub trait Iterator {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_do_not_const_check]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "iter_cloned")]
     fn cloned<'a, T: 'a>(self) -> Cloned<Self>
     where
         Self: Sized + Iterator<Item = &'a T>,
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 058dcf34532..8826bf52b41 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -119,6 +119,7 @@
 #![feature(const_bigint_helper_methods)]
 #![feature(const_black_box)]
 #![feature(const_cell_into_inner)]
+#![feature(const_char_encode_utf8)]
 #![feature(const_eval_select)]
 #![feature(const_exact_div)]
 #![feature(const_float_classify)]
@@ -131,7 +132,6 @@
 #![feature(const_ipv4)]
 #![feature(const_ipv6)]
 #![feature(const_likely)]
-#![feature(const_maybe_uninit_as_mut_ptr)]
 #![feature(const_maybe_uninit_assume_init)]
 #![feature(const_nonnull_new)]
 #![feature(const_num_midpoint)]
@@ -170,6 +170,7 @@
 #![feature(is_ascii_octdigit)]
 #![feature(is_val_statically_known)]
 #![feature(isqrt)]
+#![feature(lazy_get)]
 #![feature(link_cfg)]
 #![feature(offset_of_enum)]
 #![feature(panic_internals)]
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 0154caa7c24..c67796ad3db 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -393,7 +393,6 @@ impl<T> MaybeUninit<T> {
     // These are OK to allow since we do not leak &mut to user-visible API
     #[rustc_allow_const_fn_unstable(const_mut_refs)]
     #[rustc_allow_const_fn_unstable(const_ptr_write)]
-    #[rustc_allow_const_fn_unstable(const_maybe_uninit_as_mut_ptr)]
     #[rustc_const_stable(feature = "const_maybe_uninit_zeroed", since = "1.75.0")]
     pub const fn zeroed() -> MaybeUninit<T> {
         let mut u = MaybeUninit::<T>::uninit();
@@ -570,7 +569,11 @@ impl<T> MaybeUninit<T> {
     /// (Notice that the rules around references to uninitialized data are not finalized yet, but
     /// until they are, it is advisable to avoid them.)
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
-    #[rustc_const_unstable(feature = "const_maybe_uninit_as_mut_ptr", issue = "75251")]
+    #[rustc_const_stable(
+        feature = "const_maybe_uninit_as_mut_ptr",
+        since = "CURRENT_RUSTC_VERSION"
+    )]
+    #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
     #[inline(always)]
     pub const fn as_mut_ptr(&mut self) -> *mut T {
         // `MaybeUninit` and `ManuallyDrop` are both `repr(transparent)` so we can cast the pointer.
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index 4c2a4ee3b32..d0eb6bb3f28 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -415,6 +415,7 @@ impl f32 {
     /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
     /// [`MANTISSA_DIGITS`]: f32::MANTISSA_DIGITS
     #[stable(feature = "assoc_int_consts", since = "1.43.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "f32_epsilon")]
     pub const EPSILON: f32 = 1.19209290e-07_f32;
 
     /// Smallest finite `f32` value.
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index 87fb5fe7ebe..4bc275ad147 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -414,6 +414,7 @@ impl f64 {
     /// [Machine epsilon]: https://en.wikipedia.org/wiki/Machine_epsilon
     /// [`MANTISSA_DIGITS`]: f64::MANTISSA_DIGITS
     #[stable(feature = "assoc_int_consts", since = "1.43.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "f64_epsilon")]
     pub const EPSILON: f64 = 2.2204460492503131e-16_f64;
 
     /// Smallest finite `f64` value.
diff --git a/library/core/src/num/mod.rs b/library/core/src/num/mod.rs
index dca644ebef4..15de4fa15c4 100644
--- a/library/core/src/num/mod.rs
+++ b/library/core/src/num/mod.rs
@@ -23,6 +23,16 @@ macro_rules! unlikely {
     };
 }
 
+// Use this when the generated code should differ between signed and unsigned types.
+macro_rules! sign_dependent_expr {
+    (signed ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => {
+        $signed_case
+    };
+    (unsigned ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => {
+        $unsigned_case
+    };
+}
+
 // All these modules are technically private and only exposed for coretests:
 #[cfg(not(no_fp_fmt_parse))]
 pub mod bignum;
@@ -1410,15 +1420,25 @@ const fn from_str_radix_panic(radix: u32) {
 }
 
 macro_rules! from_str_radix {
-    ($($int_ty:ty)+) => {$(
+    ($signedness:ident $($int_ty:ty)+) => {$(
         impl $int_ty {
             /// Converts a string slice in a given base to an integer.
             ///
-            /// The string is expected to be an optional `+` sign
-            /// followed by digits.
-            /// Leading and trailing whitespace represent an error.
-            /// Digits are a subset of these characters, depending on `radix`:
+            /// The string is expected to be an optional
+            #[doc = sign_dependent_expr!{
+                $signedness ?
+                if signed {
+                    " `+` or `-` "
+                }
+                if unsigned {
+                    " `+` "
+                }
+            }]
+            /// sign followed by only digits. Leading and trailing non-digit characters (including
+            /// whitespace) represent an error. Underscores (which are accepted in rust literals)
+            /// also represent an error.
             ///
+            /// Digits are a subset of these characters, depending on `radix`:
             /// * `0-9`
             /// * `a-z`
             /// * `A-Z`
@@ -1430,10 +1450,13 @@ macro_rules! from_str_radix {
             /// # Examples
             ///
             /// Basic usage:
-            ///
             /// ```
             #[doc = concat!("assert_eq!(", stringify!($int_ty), "::from_str_radix(\"A\", 16), Ok(10));")]
             /// ```
+            /// Trailing space returns error:
+            /// ```
+            #[doc = concat!("assert!(", stringify!($int_ty), "::from_str_radix(\"1 \", 10).is_err());")]
+            /// ```
             #[stable(feature = "rust1", since = "1.0.0")]
             #[rustc_const_stable(feature = "const_int_from_str", since = "1.82.0")]
             pub const fn from_str_radix(src: &str, radix: u32) -> Result<$int_ty, ParseIntError> {
@@ -1535,20 +1558,31 @@ macro_rules! from_str_radix {
     )+}
 }
 
-from_str_radix! { i8 u8 i16 u16 i32 u32 i64 u64 i128 u128 }
+from_str_radix! { unsigned u8 u16 u32 u64 u128 }
+from_str_radix! { signed i8 i16 i32 i64 i128 }
 
 // Re-use the relevant implementation of from_str_radix for isize and usize to avoid outputting two
 // identical functions.
 macro_rules! from_str_radix_size_impl {
-    ($($t:ident $size:ty),*) => {$(
+    ($($signedness:ident $t:ident $size:ty),*) => {$(
     impl $size {
         /// Converts a string slice in a given base to an integer.
         ///
-        /// The string is expected to be an optional `+` sign
-        /// followed by digits.
-        /// Leading and trailing whitespace represent an error.
-        /// Digits are a subset of these characters, depending on `radix`:
+        /// The string is expected to be an optional
+        #[doc = sign_dependent_expr!{
+            $signedness ?
+            if signed {
+                " `+` or `-` "
+            }
+            if unsigned {
+                " `+` "
+            }
+        }]
+        /// sign followed by only digits. Leading and trailing non-digit characters (including
+        /// whitespace) represent an error. Underscores (which are accepted in rust literals)
+        /// also represent an error.
         ///
+        /// Digits are a subset of these characters, depending on `radix`:
         /// * `0-9`
         /// * `a-z`
         /// * `A-Z`
@@ -1560,10 +1594,13 @@ macro_rules! from_str_radix_size_impl {
         /// # Examples
         ///
         /// Basic usage:
-        ///
         /// ```
         #[doc = concat!("assert_eq!(", stringify!($size), "::from_str_radix(\"A\", 16), Ok(10));")]
         /// ```
+        /// Trailing space returns error:
+        /// ```
+        #[doc = concat!("assert!(", stringify!($size), "::from_str_radix(\"1 \", 10).is_err());")]
+        /// ```
         #[stable(feature = "rust1", since = "1.0.0")]
         #[rustc_const_stable(feature = "const_int_from_str", since = "1.82.0")]
         pub const fn from_str_radix(src: &str, radix: u32) -> Result<$size, ParseIntError> {
@@ -1576,8 +1613,8 @@ macro_rules! from_str_radix_size_impl {
 }
 
 #[cfg(target_pointer_width = "16")]
-from_str_radix_size_impl! { i16 isize, u16 usize }
+from_str_radix_size_impl! { signed i16 isize, unsigned u16 usize }
 #[cfg(target_pointer_width = "32")]
-from_str_radix_size_impl! { i32 isize, u32 usize }
+from_str_radix_size_impl! { signed i32 isize, unsigned u32 usize }
 #[cfg(target_pointer_width = "64")]
-from_str_radix_size_impl! { i64 isize, u64 usize }
+from_str_radix_size_impl! { signed i64 isize, unsigned u64 usize }
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index 8b888f12da0..e5c9a7e086a 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -1972,16 +1972,6 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
     };
 }
 
-// Use this when the generated code should differ between signed and unsigned types.
-macro_rules! sign_dependent_expr {
-    (signed ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => {
-        $signed_case
-    };
-    (unsigned ? if signed { $signed_case:expr } if unsigned { $unsigned_case:expr } ) => {
-        $unsigned_case
-    };
-}
-
 nonzero_integer! {
     Self = NonZeroU8,
     Primitive = unsigned u8,
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 265f056dc87..5ba13969605 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -923,6 +923,7 @@ impl<T> Option<T> {
     #[inline]
     #[track_caller]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "option_expect")]
     #[rustc_const_unstable(feature = "const_option", issue = "67441")]
     pub const fn expect(self, msg: &str) -> T {
         match self {
@@ -960,6 +961,7 @@ impl<T> Option<T> {
     #[inline(always)]
     #[track_caller]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "option_unwrap")]
     #[rustc_const_unstable(feature = "const_option", issue = "67441")]
     pub const fn unwrap(self) -> T {
         match self {
diff --git a/library/core/src/panic/panic_info.rs b/library/core/src/panic/panic_info.rs
index e4d0c897b65..af2c83b5460 100644
--- a/library/core/src/panic/panic_info.rs
+++ b/library/core/src/panic/panic_info.rs
@@ -12,7 +12,7 @@ use crate::panic::Location;
 #[stable(feature = "panic_hooks", since = "1.10.0")]
 #[derive(Debug)]
 pub struct PanicInfo<'a> {
-    message: fmt::Arguments<'a>,
+    message: &'a fmt::Arguments<'a>,
     location: &'a Location<'a>,
     can_unwind: bool,
     force_no_backtrace: bool,
@@ -26,13 +26,13 @@ pub struct PanicInfo<'a> {
 /// See [`PanicInfo::message`].
 #[stable(feature = "panic_info_message", since = "1.81.0")]
 pub struct PanicMessage<'a> {
-    message: fmt::Arguments<'a>,
+    message: &'a fmt::Arguments<'a>,
 }
 
 impl<'a> PanicInfo<'a> {
     #[inline]
     pub(crate) fn new(
-        message: fmt::Arguments<'a>,
+        message: &'a fmt::Arguments<'a>,
         location: &'a Location<'a>,
         can_unwind: bool,
         force_no_backtrace: bool,
@@ -146,7 +146,7 @@ impl Display for PanicInfo<'_> {
         formatter.write_str("panicked at ")?;
         self.location.fmt(formatter)?;
         formatter.write_str(":\n")?;
-        formatter.write_fmt(self.message)?;
+        formatter.write_fmt(*self.message)?;
         Ok(())
     }
 }
@@ -177,7 +177,7 @@ impl<'a> PanicMessage<'a> {
 impl Display for PanicMessage<'_> {
     #[inline]
     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        formatter.write_fmt(self.message)
+        formatter.write_fmt(*self.message)
     }
 }
 
@@ -185,6 +185,6 @@ impl Display for PanicMessage<'_> {
 impl fmt::Debug for PanicMessage<'_> {
     #[inline]
     fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
-        formatter.write_fmt(self.message)
+        formatter.write_fmt(*self.message)
     }
 }
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index e4a62304087..7420579e3ce 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -64,7 +64,7 @@ pub const fn panic_fmt(fmt: fmt::Arguments<'_>) -> ! {
     }
 
     let pi = PanicInfo::new(
-        fmt,
+        &fmt,
         Location::caller(),
         /* can_unwind */ true,
         /* force_no_backtrace */ false,
@@ -102,7 +102,7 @@ pub const fn panic_nounwind_fmt(fmt: fmt::Arguments<'_>, force_no_backtrace: boo
 
         // PanicInfo with the `can_unwind` flag set to false forces an abort.
         let pi = PanicInfo::new(
-            fmt,
+            &fmt,
             Location::caller(),
             /* can_unwind */ false,
             force_no_backtrace,
diff --git a/library/core/src/ptr/alignment.rs b/library/core/src/ptr/alignment.rs
index 834cec9dcfc..ceb5906d226 100644
--- a/library/core/src/ptr/alignment.rs
+++ b/library/core/src/ptr/alignment.rs
@@ -154,6 +154,11 @@ impl Alignment {
         // SAFETY: The alignment is always nonzero, and therefore decrementing won't overflow.
         !(unsafe { self.as_usize().unchecked_sub(1) })
     }
+
+    // Remove me once `Ord::max` is usable in const
+    pub(crate) const fn max(a: Self, b: Self) -> Self {
+        if a.as_usize() > b.as_usize() { a } else { b }
+    }
 }
 
 #[unstable(feature = "ptr_alignment_type", issue = "102070")]
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 02f6f783b51..9edd58259ba 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -653,6 +653,7 @@ impl<T, E> Result<T, E> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "result_ok_method")]
     pub fn ok(self) -> Option<T> {
         match self {
             Ok(x) => Some(x),
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index b1948ce69c7..cdcca0eee88 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -1010,6 +1010,7 @@ impl<T> [T] {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "slice_iter")]
     pub fn iter(&self) -> Iter<'_, T> {
         Iter::new(self)
     }
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index e947686487e..712bf011c27 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -134,6 +134,7 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_str_len", since = "1.39.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "str_len")]
     #[must_use]
     #[inline]
     pub const fn len(&self) -> usize {
@@ -832,6 +833,7 @@ impl str {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "str_chars")]
     pub fn chars(&self) -> Chars<'_> {
         Chars { iter: self.as_bytes().iter() }
     }
@@ -1156,6 +1158,7 @@ impl str {
     /// assert!(bananas.starts_with(&['a', 'b', 'c', 'd']));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "str_starts_with")]
     pub fn starts_with<P: Pattern>(&self, pat: P) -> bool {
         pat.is_prefix_of(self)
     }
@@ -1180,6 +1183,7 @@ impl str {
     /// assert!(!bananas.ends_with("nana"));
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "str_ends_with")]
     pub fn ends_with<P: Pattern>(&self, pat: P) -> bool
     where
         for<'a> P::Searcher<'a>: ReverseSearcher<'a>,
diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs
index 5e559ad8d2c..a5103499c8a 100644
--- a/library/core/src/task/wake.rs
+++ b/library/core/src/task/wake.rs
@@ -414,6 +414,7 @@ impl<'a> ContextBuilder<'a> {
 /// [`Wake`]: ../../alloc/task/trait.Wake.html
 #[repr(transparent)]
 #[stable(feature = "futures_api", since = "1.36.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "Waker")]
 pub struct Waker {
     waker: RawWaker,
 }
diff --git a/library/core/tests/atomic.rs b/library/core/tests/atomic.rs
index 0d1c72a6892..2bdaeb3845a 100644
--- a/library/core/tests/atomic.rs
+++ b/library/core/tests/atomic.rs
@@ -228,6 +228,8 @@ fn static_init() {
 }
 
 #[test]
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#[cfg_attr(not(bootstrap), allow(static_mut_refs))]
 fn atomic_access_bool() {
     static mut ATOMIC: AtomicBool = AtomicBool::new(false);
 
diff --git a/library/core/tests/iter/sources.rs b/library/core/tests/iter/sources.rs
index eb8c80dd087..506febaa056 100644
--- a/library/core/tests/iter/sources.rs
+++ b/library/core/tests/iter/sources.rs
@@ -156,3 +156,27 @@ fn test_repeat_n_drop() {
     drop((x0, x1, x2));
     assert_eq!(count.get(), 3);
 }
+
+#[test]
+fn test_repeat_n_soundness() {
+    let x = std::iter::repeat_n(String::from("use after free"), 0);
+    println!("{x:?}");
+
+    pub struct PanicOnClone;
+
+    impl Clone for PanicOnClone {
+        fn clone(&self) -> Self {
+            unreachable!()
+        }
+    }
+
+    // `repeat_n` should drop the element immediately if `count` is zero.
+    // `Clone` should then not try to clone the element.
+    let x = std::iter::repeat_n(PanicOnClone, 0);
+    let _ = x.clone();
+
+    let mut y = std::iter::repeat_n(Box::new(0), 1);
+    let x = y.next().unwrap();
+    let _z = y;
+    assert_eq!(0, *x);
+}
diff --git a/library/core/tests/lazy.rs b/library/core/tests/lazy.rs
index a3b89f15b3f..711511eaf4a 100644
--- a/library/core/tests/lazy.rs
+++ b/library/core/tests/lazy.rs
@@ -114,6 +114,27 @@ fn lazy_type_inference() {
 }
 
 #[test]
+#[should_panic = "LazyCell instance has previously been poisoned"]
+fn lazy_force_mut_panic() {
+    let mut lazy = LazyCell::<String>::new(|| panic!());
+    std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
+        let _ = LazyCell::force_mut(&mut lazy);
+    }))
+    .unwrap_err();
+    let _ = &*lazy;
+}
+
+#[test]
+fn lazy_force_mut() {
+    let s = "abc".to_owned();
+    let mut lazy = LazyCell::new(move || s);
+    LazyCell::force_mut(&mut lazy);
+    let p = LazyCell::force_mut(&mut lazy);
+    p.clear();
+    LazyCell::force_mut(&mut lazy);
+}
+
+#[test]
 fn aliasing_in_get() {
     let x = OnceCell::new();
     x.set(42).unwrap();
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 948ea9bc098..5315ac856f6 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -26,7 +26,6 @@
 #![feature(const_ipv4)]
 #![feature(const_ipv6)]
 #![feature(const_likely)]
-#![feature(const_maybe_uninit_as_mut_ptr)]
 #![feature(const_nonnull_new)]
 #![feature(const_option)]
 #![feature(const_option_ext)]
@@ -76,6 +75,7 @@
 #![feature(iterator_try_collect)]
 #![feature(iterator_try_reduce)]
 #![feature(layout_for_ptr)]
+#![feature(lazy_get)]
 #![feature(maybe_uninit_fill)]
 #![feature(maybe_uninit_uninit_array_transpose)]
 #![feature(maybe_uninit_write_slice)]
diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs
index 830a96204ca..6a26bd15a66 100644
--- a/library/core/tests/num/int_macros.rs
+++ b/library/core/tests/num/int_macros.rs
@@ -244,6 +244,8 @@ macro_rules! int_module {
 
             assert_eq!($T::from_str_radix("Z", 35).ok(), None::<$T>);
             assert_eq!($T::from_str_radix("-9", 2).ok(), None::<$T>);
+            assert_eq!($T::from_str_radix("10_0", 10).ok(), None::<$T>);
+            assert_eq!(u32::from_str_radix("-9", 10).ok(), None::<u32>);
         }
 
         #[test]
diff --git a/library/panic_unwind/src/seh.rs b/library/panic_unwind/src/seh.rs
index 070c11926f6..9e74a45a0e2 100644
--- a/library/panic_unwind/src/seh.rs
+++ b/library/panic_unwind/src/seh.rs
@@ -291,6 +291,8 @@ cfg_if::cfg_if! {
    }
 }
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#[allow(static_mut_refs)]
 pub unsafe fn panic(data: Box<dyn Any + Send>) -> u32 {
     use core::intrinsics::atomic_store_seqcst;
 
diff --git a/library/proc_macro/src/bridge/buffer.rs b/library/proc_macro/src/bridge/buffer.rs
index 78fcd1999b2..3760749d83a 100644
--- a/library/proc_macro/src/bridge/buffer.rs
+++ b/library/proc_macro/src/bridge/buffer.rs
@@ -119,9 +119,7 @@ impl Write for Buffer {
 }
 
 impl Drop for Buffer {
-    // HACK(nbdd0121): Hack to prevent LLVM < 17.0.4 from misoptimising,
-    // change to `#[inline]` if fixed.
-    #[inline(never)]
+    #[inline]
     fn drop(&mut self) {
         let b = self.take();
         (b.drop)(b);
diff --git a/library/std/src/collections/hash/map.rs b/library/std/src/collections/hash/map.rs
index 7d21d37f40d..1a18721b15e 100644
--- a/library/std/src/collections/hash/map.rs
+++ b/library/std/src/collections/hash/map.rs
@@ -1037,6 +1037,7 @@ where
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_contains_key")]
     pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
     where
         K: Borrow<Q>,
@@ -1100,6 +1101,7 @@ where
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_confusables("push", "append", "put")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_insert")]
     pub fn insert(&mut self, k: K, v: V) -> Option<V> {
         self.base.insert(k, v)
     }
@@ -1391,6 +1393,7 @@ where
 /// let iter = map.iter();
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_iter_ty")]
 pub struct Iter<'a, K: 'a, V: 'a> {
     base: base::Iter<'a, K, V>,
 }
@@ -1429,6 +1432,7 @@ impl<K: Debug, V: Debug> fmt::Debug for Iter<'_, K, V> {
 /// let iter = map.iter_mut();
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_iter_mut_ty")]
 pub struct IterMut<'a, K: 'a, V: 'a> {
     base: base::IterMut<'a, K, V>,
 }
@@ -1489,6 +1493,7 @@ impl<K, V> IntoIter<K, V> {
 /// let iter_keys = map.keys();
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_keys_ty")]
 pub struct Keys<'a, K: 'a, V: 'a> {
     inner: Iter<'a, K, V>,
 }
@@ -1527,6 +1532,7 @@ impl<K: Debug, V> fmt::Debug for Keys<'_, K, V> {
 /// let iter_values = map.values();
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_values_ty")]
 pub struct Values<'a, K: 'a, V: 'a> {
     inner: Iter<'a, K, V>,
 }
@@ -1565,6 +1571,7 @@ impl<K, V: Debug> fmt::Debug for Values<'_, K, V> {
 /// let iter = map.drain();
 /// ```
 #[stable(feature = "drain", since = "1.6.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_drain_ty")]
 pub struct Drain<'a, K: 'a, V: 'a> {
     base: base::Drain<'a, K, V>,
 }
@@ -1622,6 +1629,7 @@ where
 /// let iter_values = map.values_mut();
 /// ```
 #[stable(feature = "map_values_mut", since = "1.10.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "hashmap_values_mut_ty")]
 pub struct ValuesMut<'a, K: 'a, V: 'a> {
     inner: IterMut<'a, K, V>,
 }
diff --git a/library/std/src/collections/hash/set.rs b/library/std/src/collections/hash/set.rs
index d611353b0d3..4a113ddea3a 100644
--- a/library/std/src/collections/hash/set.rs
+++ b/library/std/src/collections/hash/set.rs
@@ -187,6 +187,7 @@ impl<T, S> HashSet<T, S> {
     #[inline]
     #[rustc_lint_query_instability]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "hashset_iter")]
     pub fn iter(&self) -> Iter<'_, T> {
         Iter { base: self.base.iter() }
     }
@@ -1270,6 +1271,7 @@ where
 /// let mut iter = a.iter();
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "hashset_iter_ty")]
 pub struct Iter<'a, K: 'a> {
     base: base::Iter<'a, K>,
 }
@@ -1312,6 +1314,7 @@ pub struct IntoIter<K> {
 /// let mut drain = a.drain();
 /// ```
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "hashset_drain_ty")]
 pub struct Drain<'a, K: 'a> {
     base: base::Drain<'a, K>,
 }
diff --git a/library/std/src/env.rs b/library/std/src/env.rs
index 28916130b19..97a1b846a91 100644
--- a/library/std/src/env.rs
+++ b/library/std/src/env.rs
@@ -935,106 +935,147 @@ impl fmt::Debug for ArgsOs {
 pub mod consts {
     use crate::sys::env::os;
 
-    /// A string describing the architecture of the CPU that is currently
-    /// in use.
+    /// A string describing the architecture of the CPU that is currently in use.
+    /// An example value may be: `"x86"`, `"arm"` or `"riscv64"`.
     ///
-    /// Some possible values:
+    /// <details><summary>Full list of possible values</summary>
     ///
-    /// - x86
-    /// - x86_64
-    /// - arm
-    /// - aarch64
-    /// - loongarch64
-    /// - m68k
-    /// - csky
-    /// - mips
-    /// - mips64
-    /// - powerpc
-    /// - powerpc64
-    /// - riscv64
-    /// - s390x
-    /// - sparc64
+    /// * `"x86"`
+    /// * `"x86_64"`
+    /// * `"arm"`
+    /// * `"aarch64"`
+    /// * `"m68k"`
+    /// * `"mips"`
+    /// * `"mips32r6"`
+    /// * `"mips64"`
+    /// * `"mips64r6"`
+    /// * `"csky"`
+    /// * `"powerpc"`
+    /// * `"powerpc64"`
+    /// * `"riscv32"`
+    /// * `"riscv64"`
+    /// * `"s390x"`
+    /// * `"sparc"`
+    /// * `"sparc64"`
+    /// * `"hexagon"`
+    /// * `"loongarch64"`
+    ///
+    /// </details>
     #[stable(feature = "env", since = "1.0.0")]
     pub const ARCH: &str = env!("STD_ENV_ARCH");
 
-    /// The family of the operating system. Example value is `unix`.
+    /// A string describing the family of the operating system.
+    /// An example value may be: `"unix"`, or `"windows"`.
+    ///
+    /// This value may be an empty string if the family is unknown.
+    ///
+    /// <details><summary>Full list of possible values</summary>
     ///
-    /// Some possible values:
+    /// * `"unix"`
+    /// * `"windows"`
+    /// * `"itron"`
+    /// * `"wasm"`
+    /// * `""`
     ///
-    /// - unix
-    /// - windows
+    /// </details>
     #[stable(feature = "env", since = "1.0.0")]
     pub const FAMILY: &str = os::FAMILY;
 
     /// A string describing the specific operating system in use.
-    /// Example value is `linux`.
+    /// An example value may be: `"linux"`, or `"freebsd"`.
     ///
-    /// Some possible values:
+    /// <details><summary>Full list of possible values</summary>
     ///
-    /// - linux
-    /// - macos
-    /// - ios
-    /// - freebsd
-    /// - dragonfly
-    /// - netbsd
-    /// - openbsd
-    /// - solaris
-    /// - android
-    /// - windows
+    /// * `"linux"`
+    /// * `"windows"`
+    /// * `"macos"`
+    /// * `"android"`
+    /// * `"ios"`
+    /// * `"openbsd"`
+    /// * `"freebsd"`
+    /// * `"netbsd"`
+    /// * `"wasi"`
+    /// * `"hermit"`
+    /// * `"aix"`
+    /// * `"apple"`
+    /// * `"dragonfly"`
+    /// * `"emscripten"`
+    /// * `"espidf"`
+    /// * `"fortanix"`
+    /// * `"uefi"`
+    /// * `"fuchsia"`
+    /// * `"haiku"`
+    /// * `"hermit"`
+    /// * `"watchos"`
+    /// * `"visionos"`
+    /// * `"tvos"`
+    /// * `"horizon"`
+    /// * `"hurd"`
+    /// * `"illumos"`
+    /// * `"l4re"`
+    /// * `"nto"`
+    /// * `"redox"`
+    /// * `"solaris"`
+    /// * `"solid_asp3`
+    /// * `"vita"`
+    /// * `"vxworks"`
+    /// * `"xous"`
+    ///
+    /// </details>
     #[stable(feature = "env", since = "1.0.0")]
     pub const OS: &str = os::OS;
 
-    /// Specifies the filename prefix used for shared libraries on this
-    /// platform. Example value is `lib`.
-    ///
-    /// Some possible values:
-    ///
-    /// - lib
-    /// - `""` (an empty string)
+    /// Specifies the filename prefix, if any, used for shared libraries on this platform.
+    /// This is either `"lib"` or an empty string. (`""`).
     #[stable(feature = "env", since = "1.0.0")]
     pub const DLL_PREFIX: &str = os::DLL_PREFIX;
 
-    /// Specifies the filename suffix used for shared libraries on this
-    /// platform. Example value is `.so`.
-    ///
-    /// Some possible values:
+    /// Specifies the filename suffix, if any, used for shared libraries on this platform.
+    /// An example value may be: `".so"`, `".elf"`, or `".dll"`.
     ///
-    /// - .so
-    /// - .dylib
-    /// - .dll
+    /// The possible values are identical to those of [`DLL_EXTENSION`], but with the leading period included.
     #[stable(feature = "env", since = "1.0.0")]
     pub const DLL_SUFFIX: &str = os::DLL_SUFFIX;
 
-    /// Specifies the file extension used for shared libraries on this
-    /// platform that goes after the dot. Example value is `so`.
+    /// Specifies the file extension, if any, used for shared libraries on this platform that goes after the dot.
+    /// An example value may be: `"so"`, `"elf"`, or `"dll"`.
+    ///
+    /// <details><summary>Full list of possible values</summary>
     ///
-    /// Some possible values:
+    /// * `"so"`
+    /// * `"dylib"`
+    /// * `"dll"`
+    /// * `"sgxs"`
+    /// * `"a"`
+    /// * `"elf"`
+    /// * `"wasm"`
+    /// * `""` (an empty string)
     ///
-    /// - so
-    /// - dylib
-    /// - dll
+    /// </details>
     #[stable(feature = "env", since = "1.0.0")]
     pub const DLL_EXTENSION: &str = os::DLL_EXTENSION;
 
-    /// Specifies the filename suffix used for executable binaries on this
-    /// platform. Example value is `.exe`.
+    /// Specifies the filename suffix, if any, used for executable binaries on this platform.
+    /// An example value may be: `".exe"`, or `".efi"`.
     ///
-    /// Some possible values:
-    ///
-    /// - .exe
-    /// - .nexe
-    /// - .pexe
-    /// - `""` (an empty string)
+    /// The possible values are identical to those of [`EXE_EXTENSION`], but with the leading period included.
     #[stable(feature = "env", since = "1.0.0")]
     pub const EXE_SUFFIX: &str = os::EXE_SUFFIX;
 
-    /// Specifies the file extension, if any, used for executable binaries
-    /// on this platform. Example value is `exe`.
+    /// Specifies the file extension, if any, used for executable binaries on this platform.
+    /// An example value may be: `"exe"`, or an empty string (`""`).
+    ///
+    /// <details><summary>Full list of possible values</summary>
     ///
-    /// Some possible values:
+    /// * `"exe"`
+    /// * `"efi"`
+    /// * `"js"`
+    /// * `"sgxs"`
+    /// * `"elf"`
+    /// * `"wasm"`
+    /// * `""` (an empty string)
     ///
-    /// - exe
-    /// - `""` (an empty string)
+    /// </details>
     #[stable(feature = "env", since = "1.0.0")]
     pub const EXE_EXTENSION: &str = os::EXE_EXTENSION;
 }
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 99bea676e12..0f905803bb8 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -196,6 +196,7 @@ impl OsString {
     /// let os_str = OsStr::new("foo");
     /// assert_eq!(os_string.as_os_str(), os_str);
     /// ```
+    #[cfg_attr(not(test), rustc_diagnostic_item = "os_string_as_os_str")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[must_use]
     #[inline]
@@ -918,6 +919,7 @@ impl OsStr {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[inline]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "os_str_to_os_string")]
     pub fn to_os_string(&self) -> OsString {
         OsString { inner: self.inner.to_owned() }
     }
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 6a0d9f47960..55f3b628ce8 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -466,6 +466,7 @@ impl File {
     /// ```
     #[must_use]
     #[stable(feature = "with_options", since = "1.58.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "file_options")]
     pub fn options() -> OpenOptions {
         OpenOptions::new()
     }
@@ -835,7 +836,7 @@ impl Read for &File {
 }
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Write for &File {
-    /// Writes some bytes from the file.
+    /// Writes some bytes to the file.
     ///
     /// See [`Write::write`] docs for more info.
     ///
@@ -1009,6 +1010,7 @@ impl OpenOptions {
     /// let mut options = OpenOptions::new();
     /// let file = options.read(true).open("foo.txt");
     /// ```
+    #[cfg_attr(not(test), rustc_diagnostic_item = "open_options_new")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[must_use]
     pub fn new() -> Self {
@@ -1989,6 +1991,11 @@ impl AsInner<fs_imp::DirEntry> for DirEntry {
 /// * The file doesn't exist.
 /// * The user lacks permissions to remove the file.
 ///
+/// This function will only ever return an error of kind `NotFound` if the given
+/// path does not exist. Note that the inverse is not true,
+/// ie. if a path does not exist, its removal may fail for a number of reasons,
+/// such as insufficient permissions.
+///
 /// # Examples
 ///
 /// ```no_run
@@ -2446,6 +2453,11 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// * The user lacks permissions to remove the directory at the provided `path`.
 /// * The directory isn't empty.
 ///
+/// This function will only ever return an error of kind `NotFound` if the given
+/// path does not exist. Note that the inverse is not true,
+/// ie. if a path does not exist, its removal may fail for a number of reasons,
+/// such as insufficient permissions.
+///
 /// # Examples
 ///
 /// ```no_run
@@ -2471,16 +2483,15 @@ pub fn remove_dir<P: AsRef<Path>>(path: P) -> io::Result<()> {
 /// # Platform-specific behavior
 ///
 /// This function currently corresponds to `openat`, `fdopendir`, `unlinkat` and `lstat` functions
-/// on Unix (except for macOS before version 10.10 and REDOX) and the `CreateFileW`,
-/// `GetFileInformationByHandleEx`, `SetFileInformationByHandle`, and `NtCreateFile` functions on
-/// Windows. Note that, this [may change in the future][changes].
+/// on Unix (except for REDOX) and the `CreateFileW`, `GetFileInformationByHandleEx`,
+/// `SetFileInformationByHandle`, and `NtCreateFile` functions on Windows. Note that, this
+/// [may change in the future][changes].
 ///
 /// [changes]: io#platform-specific-behavior
 ///
-/// On macOS before version 10.10 and REDOX, as well as when running in Miri for any target, this
-/// function is not protected against time-of-check to time-of-use (TOCTOU) race conditions, and
-/// should not be used in security-sensitive code on those platforms. All other platforms are
-/// protected.
+/// On REDOX, as well as when running in Miri for any target, this function is not protected against
+/// time-of-check to time-of-use (TOCTOU) race conditions, and should not be used in
+/// security-sensitive code on those platforms. All other platforms are protected.
 ///
 /// # Errors
 ///
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 644b294db8d..2a4262b2367 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -2058,6 +2058,7 @@ pub trait Seek {
 /// It is used by the [`Seek`] trait.
 #[derive(Copy, PartialEq, Eq, Clone, Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "SeekFrom")]
 pub enum SeekFrom {
     /// Sets the offset to the provided number of bytes.
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index bc5369ddc3d..e4ba5e47613 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -337,6 +337,7 @@
 #![feature(hasher_prefixfree_extras)]
 #![feature(hashmap_internals)]
 #![feature(ip)]
+#![feature(lazy_get)]
 #![feature(maybe_uninit_slice)]
 #![feature(maybe_uninit_write_slice)]
 #![feature(panic_can_unwind)]
diff --git a/library/std/src/os/unix/fs.rs b/library/std/src/os/unix/fs.rs
index caf6980afd9..a964db2e0ac 100644
--- a/library/std/src/os/unix/fs.rs
+++ b/library/std/src/os/unix/fs.rs
@@ -334,6 +334,7 @@ pub trait PermissionsExt {
     /// assert_eq!(permissions.mode(), 0o644);
     /// ```
     #[stable(feature = "fs_ext", since = "1.1.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "permissions_from_mode")]
     fn from_mode(mode: u32) -> Self;
 }
 
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index c94df9b5366..aa9f63d915a 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -263,6 +263,7 @@ pub fn is_separator(c: char) -> bool {
 ///
 /// For example, `/` on Unix and `\` on Windows.
 #[stable(feature = "rust1", since = "1.0.0")]
+#[cfg_attr(not(test), rustc_diagnostic_item = "path_main_separator")]
 pub const MAIN_SEPARATOR: char = crate::sys::path::MAIN_SEP;
 
 /// The primary separator of path components for the current platform.
@@ -1226,6 +1227,7 @@ impl PathBuf {
     /// let p = PathBuf::from("/test");
     /// assert_eq!(Path::new("/test"), p.as_path());
     /// ```
+    #[cfg_attr(not(test), rustc_diagnostic_item = "pathbuf_as_path")]
     #[stable(feature = "rust1", since = "1.0.0")]
     #[must_use]
     #[inline]
@@ -2264,6 +2266,7 @@ impl Path {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "path_to_pathbuf")]
     pub fn to_path_buf(&self) -> PathBuf {
         PathBuf::from(self.inner.to_os_string())
     }
diff --git a/library/std/src/sync/lazy_lock.rs b/library/std/src/sync/lazy_lock.rs
index 953aef40e7b..b05615035d7 100644
--- a/library/std/src/sync/lazy_lock.rs
+++ b/library/std/src/sync/lazy_lock.rs
@@ -44,8 +44,6 @@ union Data<T, F> {
 ///
 /// // The `String` is built, stored in the `LazyLock`, and returned as `&String`.
 /// let _ = &*DEEP_THOUGHT;
-/// // The `String` is retrieved from the `LazyLock` and returned as `&String`.
-/// let _ = &*DEEP_THOUGHT;
 /// ```
 ///
 /// Initialize fields with `LazyLock`.
@@ -121,7 +119,7 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
     pub fn into_inner(mut this: Self) -> Result<T, F> {
         let state = this.once.state();
         match state {
-            ExclusiveState::Poisoned => panic!("LazyLock instance has previously been poisoned"),
+            ExclusiveState::Poisoned => panic_poisoned(),
             state => {
                 let this = ManuallyDrop::new(this);
                 let data = unsafe { ptr::read(&this.data) }.into_inner();
@@ -134,6 +132,60 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
         }
     }
 
+    /// Forces the evaluation of this lazy value and returns a mutable reference to
+    /// the result.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(lazy_get)]
+    /// use std::sync::LazyLock;
+    ///
+    /// let mut lazy = LazyLock::new(|| 92);
+    ///
+    /// let p = LazyLock::force_mut(&mut lazy);
+    /// assert_eq!(*p, 92);
+    /// *p = 44;
+    /// assert_eq!(*lazy, 44);
+    /// ```
+    #[inline]
+    #[unstable(feature = "lazy_get", issue = "129333")]
+    pub fn force_mut(this: &mut LazyLock<T, F>) -> &mut T {
+        #[cold]
+        /// # Safety
+        /// May only be called when the state is `Incomplete`.
+        unsafe fn really_init_mut<T, F: FnOnce() -> T>(this: &mut LazyLock<T, F>) -> &mut T {
+            struct PoisonOnPanic<'a, T, F>(&'a mut LazyLock<T, F>);
+            impl<T, F> Drop for PoisonOnPanic<'_, T, F> {
+                #[inline]
+                fn drop(&mut self) {
+                    self.0.once.set_state(ExclusiveState::Poisoned);
+                }
+            }
+
+            // SAFETY: We always poison if the initializer panics (then we never check the data),
+            // or set the data on success.
+            let f = unsafe { ManuallyDrop::take(&mut this.data.get_mut().f) };
+            // INVARIANT: Initiated from mutable reference, don't drop because we read it.
+            let guard = PoisonOnPanic(this);
+            let data = f();
+            guard.0.data.get_mut().value = ManuallyDrop::new(data);
+            guard.0.once.set_state(ExclusiveState::Complete);
+            core::mem::forget(guard);
+            // SAFETY: We put the value there above.
+            unsafe { &mut this.data.get_mut().value }
+        }
+
+        let state = this.once.state();
+        match state {
+            ExclusiveState::Poisoned => panic_poisoned(),
+            // SAFETY: The `Once` states we completed the initialization.
+            ExclusiveState::Complete => unsafe { &mut this.data.get_mut().value },
+            // SAFETY: The state is `Incomplete`.
+            ExclusiveState::Incomplete => unsafe { really_init_mut(this) },
+        }
+    }
+
     /// Forces the evaluation of this lazy value and returns a reference to
     /// result. This is equivalent to the `Deref` impl, but is explicit.
     ///
@@ -174,13 +226,58 @@ impl<T, F: FnOnce() -> T> LazyLock<T, F> {
 }
 
 impl<T, F> LazyLock<T, F> {
-    /// Gets the inner value if it has already been initialized.
-    fn get(&self) -> Option<&T> {
-        if self.once.is_completed() {
+    /// Returns a reference to the value if initialized, or `None` if not.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(lazy_get)]
+    ///
+    /// use std::sync::LazyLock;
+    ///
+    /// let mut lazy = LazyLock::new(|| 92);
+    ///
+    /// assert_eq!(LazyLock::get_mut(&mut lazy), None);
+    /// let _ = LazyLock::force(&lazy);
+    /// *LazyLock::get_mut(&mut lazy).unwrap() = 44;
+    /// assert_eq!(*lazy, 44);
+    /// ```
+    #[inline]
+    #[unstable(feature = "lazy_get", issue = "129333")]
+    pub fn get_mut(this: &mut LazyLock<T, F>) -> Option<&mut T> {
+        // `state()` does not perform an atomic load, so prefer it over `is_complete()`.
+        let state = this.once.state();
+        match state {
+            // SAFETY:
+            // The closure has been run successfully, so `value` has been initialized.
+            ExclusiveState::Complete => Some(unsafe { &mut this.data.get_mut().value }),
+            _ => None,
+        }
+    }
+
+    /// Returns a mutable reference to the value if initialized, or `None` if not.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(lazy_get)]
+    ///
+    /// use std::sync::LazyLock;
+    ///
+    /// let lazy = LazyLock::new(|| 92);
+    ///
+    /// assert_eq!(LazyLock::get(&lazy), None);
+    /// let _ = LazyLock::force(&lazy);
+    /// assert_eq!(LazyLock::get(&lazy), Some(&92));
+    /// ```
+    #[inline]
+    #[unstable(feature = "lazy_get", issue = "129333")]
+    pub fn get(this: &LazyLock<T, F>) -> Option<&T> {
+        if this.once.is_completed() {
             // SAFETY:
             // The closure has been run successfully, so `value` has been initialized
             // and will not be modified again.
-            Some(unsafe { &*(*self.data.get()).value })
+            Some(unsafe { &(*this.data.get()).value })
         } else {
             None
         }
@@ -228,7 +325,7 @@ impl<T: Default> Default for LazyLock<T> {
 impl<T: fmt::Debug, F> fmt::Debug for LazyLock<T, F> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         let mut d = f.debug_tuple("LazyLock");
-        match self.get() {
+        match LazyLock::get(self) {
             Some(v) => d.field(v),
             None => d.field(&format_args!("<uninit>")),
         };
@@ -236,6 +333,12 @@ impl<T: fmt::Debug, F> fmt::Debug for LazyLock<T, F> {
     }
 }
 
+#[cold]
+#[inline(never)]
+fn panic_poisoned() -> ! {
+    panic!("LazyLock instance has previously been poisoned")
+}
+
 // We never create a `&F` from a `&LazyLock<T, F>` so it is fine
 // to not impl `Sync` for `F`.
 #[stable(feature = "lazy_cell", since = "1.80.0")]
diff --git a/library/std/src/sync/lazy_lock/tests.rs b/library/std/src/sync/lazy_lock/tests.rs
index 8a6ab4ac4fd..94044368305 100644
--- a/library/std/src/sync/lazy_lock/tests.rs
+++ b/library/std/src/sync/lazy_lock/tests.rs
@@ -142,3 +142,24 @@ fn is_sync_send() {
     fn assert_traits<T: Send + Sync>() {}
     assert_traits::<LazyLock<String>>();
 }
+
+#[test]
+#[should_panic = "has previously been poisoned"]
+fn lazy_force_mut_panic() {
+    let mut lazy = LazyLock::<String>::new(|| panic!());
+    crate::panic::catch_unwind(crate::panic::AssertUnwindSafe(|| {
+        let _ = LazyLock::force_mut(&mut lazy);
+    }))
+    .unwrap_err();
+    let _ = &*lazy;
+}
+
+#[test]
+fn lazy_force_mut() {
+    let s = "abc".to_owned();
+    let mut lazy = LazyLock::new(move || s);
+    LazyLock::force_mut(&mut lazy);
+    let p = LazyLock::force_mut(&mut lazy);
+    p.clear();
+    LazyLock::force_mut(&mut lazy);
+}
diff --git a/library/std/src/sync/mod.rs b/library/std/src/sync/mod.rs
index d0ba8cc3b47..70b419a1e33 100644
--- a/library/std/src/sync/mod.rs
+++ b/library/std/src/sync/mod.rs
@@ -9,6 +9,9 @@
 //! Consider the following code, operating on some global static variables:
 //!
 //! ```rust
+//! // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+//! #![allow(static_mut_refs)]
+//!
 //! static mut A: u32 = 0;
 //! static mut B: u32 = 0;
 //! static mut C: u32 = 0;
diff --git a/library/std/src/sync/once.rs b/library/std/src/sync/once.rs
index bf595fdea2d..5a1cd7d0b8b 100644
--- a/library/std/src/sync/once.rs
+++ b/library/std/src/sync/once.rs
@@ -314,6 +314,16 @@ impl Once {
     pub(crate) fn state(&mut self) -> ExclusiveState {
         self.inner.state()
     }
+
+    /// Sets current state of the `Once` instance.
+    ///
+    /// Since this takes a mutable reference, no initialization can currently
+    /// be running, so the state must be either "incomplete", "poisoned" or
+    /// "complete".
+    #[inline]
+    pub(crate) fn set_state(&mut self, new_state: ExclusiveState) {
+        self.inner.set_state(new_state);
+    }
 }
 
 #[stable(feature = "std_debug", since = "1.16.0")]
diff --git a/library/std/src/sys/alloc/wasm.rs b/library/std/src/sys/alloc/wasm.rs
index ef9d753d7f8..a308fafc68b 100644
--- a/library/std/src/sys/alloc/wasm.rs
+++ b/library/std/src/sys/alloc/wasm.rs
@@ -16,6 +16,9 @@
 //! The crate itself provides a global allocator which on wasm has no
 //! synchronization as there are no threads!
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use crate::alloc::{GlobalAlloc, Layout, System};
 
 static mut DLMALLOC: dlmalloc::Dlmalloc = dlmalloc::Dlmalloc::new();
diff --git a/library/std/src/sys/pal/unsupported/process.rs b/library/std/src/sys/pal/unsupported/process.rs
index 40231bfc90b..fee81744f09 100644
--- a/library/std/src/sys/pal/unsupported/process.rs
+++ b/library/std/src/sys/pal/unsupported/process.rs
@@ -255,11 +255,11 @@ impl ExitStatusError {
 }
 
 #[derive(PartialEq, Eq, Clone, Copy, Debug)]
-pub struct ExitCode(bool);
+pub struct ExitCode(u8);
 
 impl ExitCode {
-    pub const SUCCESS: ExitCode = ExitCode(false);
-    pub const FAILURE: ExitCode = ExitCode(true);
+    pub const SUCCESS: ExitCode = ExitCode(0);
+    pub const FAILURE: ExitCode = ExitCode(1);
 
     pub fn as_i32(&self) -> i32 {
         self.0 as i32
@@ -268,10 +268,7 @@ impl ExitCode {
 
 impl From<u8> for ExitCode {
     fn from(code: u8) -> Self {
-        match code {
-            0 => Self::SUCCESS,
-            1..=255 => Self::FAILURE,
-        }
+        Self(code)
     }
 }
 
diff --git a/library/std/src/sys/pal/windows/fs/remove_dir_all.rs b/library/std/src/sys/pal/windows/fs/remove_dir_all.rs
index e7234ed8e5f..9416049da78 100644
--- a/library/std/src/sys/pal/windows/fs/remove_dir_all.rs
+++ b/library/std/src/sys/pal/windows/fs/remove_dir_all.rs
@@ -71,10 +71,12 @@ unsafe fn nt_open_file(
 }
 
 /// Open the file `path` in the directory `parent`, requesting the given `access` rights.
+/// `options` will be OR'd with `FILE_OPEN_REPARSE_POINT`.
 fn open_link_no_reparse(
     parent: &File,
     path: &[u16],
     access: u32,
+    options: u32,
 ) -> Result<Option<File>, WinError> {
     // This is implemented using the lower level `NtOpenFile` function as
     // unfortunately opening a file relative to a parent is not supported by
@@ -96,7 +98,7 @@ fn open_link_no_reparse(
             ..c::OBJECT_ATTRIBUTES::default()
         };
         let share = c::FILE_SHARE_DELETE | c::FILE_SHARE_READ | c::FILE_SHARE_WRITE;
-        let options = c::FILE_OPEN_REPARSE_POINT;
+        let options = c::FILE_OPEN_REPARSE_POINT | options;
         let result = nt_open_file(access, &object, share, options);
 
         // Retry without OBJ_DONT_REPARSE if it's not supported.
@@ -128,13 +130,20 @@ fn open_link_no_reparse(
 }
 
 fn open_dir(parent: &File, name: &[u16]) -> Result<Option<File>, WinError> {
-    open_link_no_reparse(parent, name, c::SYNCHRONIZE | c::FILE_LIST_DIRECTORY)
+    // Open the directory for synchronous directory listing.
+    open_link_no_reparse(
+        parent,
+        name,
+        c::SYNCHRONIZE | c::FILE_LIST_DIRECTORY,
+        // "_IO_NONALERT" means that a synchronous call won't be interrupted.
+        c::FILE_SYNCHRONOUS_IO_NONALERT,
+    )
 }
 
 fn delete(parent: &File, name: &[u16]) -> Result<(), WinError> {
     // Note that the `delete` function consumes the opened file to ensure it's
     // dropped immediately. See module comments for why this is important.
-    match open_link_no_reparse(parent, name, c::SYNCHRONIZE | c::DELETE) {
+    match open_link_no_reparse(parent, name, c::DELETE, 0) {
         Ok(Some(f)) => f.delete(),
         Ok(None) => Ok(()),
         Err(e) => Err(e),
diff --git a/library/std/src/sys/sync/once/futex.rs b/library/std/src/sys/sync/once/futex.rs
index 2c8a054282b..25588a4217b 100644
--- a/library/std/src/sys/sync/once/futex.rs
+++ b/library/std/src/sys/sync/once/futex.rs
@@ -91,6 +91,15 @@ impl Once {
         }
     }
 
+    #[inline]
+    pub(crate) fn set_state(&mut self, new_state: ExclusiveState) {
+        *self.state_and_queued.get_mut() = match new_state {
+            ExclusiveState::Incomplete => INCOMPLETE,
+            ExclusiveState::Poisoned => POISONED,
+            ExclusiveState::Complete => COMPLETE,
+        };
+    }
+
     #[cold]
     #[track_caller]
     pub fn wait(&self, ignore_poisoning: bool) {
diff --git a/library/std/src/sys/sync/once/no_threads.rs b/library/std/src/sys/sync/once/no_threads.rs
index 12c1d9f5a6c..cdcffe790f5 100644
--- a/library/std/src/sys/sync/once/no_threads.rs
+++ b/library/std/src/sys/sync/once/no_threads.rs
@@ -55,6 +55,15 @@ impl Once {
         }
     }
 
+    #[inline]
+    pub(crate) fn set_state(&mut self, new_state: ExclusiveState) {
+        self.state.set(match new_state {
+            ExclusiveState::Incomplete => State::Incomplete,
+            ExclusiveState::Poisoned => State::Poisoned,
+            ExclusiveState::Complete => State::Complete,
+        });
+    }
+
     #[cold]
     #[track_caller]
     pub fn wait(&self, _ignore_poisoning: bool) {
diff --git a/library/std/src/sys/sync/once/queue.rs b/library/std/src/sys/sync/once/queue.rs
index 86f72c82008..17abaf0bf26 100644
--- a/library/std/src/sys/sync/once/queue.rs
+++ b/library/std/src/sys/sync/once/queue.rs
@@ -140,6 +140,15 @@ impl Once {
         }
     }
 
+    #[inline]
+    pub(crate) fn set_state(&mut self, new_state: ExclusiveState) {
+        *self.state_and_queue.get_mut() = match new_state {
+            ExclusiveState::Incomplete => ptr::without_provenance_mut(INCOMPLETE),
+            ExclusiveState::Poisoned => ptr::without_provenance_mut(POISONED),
+            ExclusiveState::Complete => ptr::without_provenance_mut(COMPLETE),
+        };
+    }
+
     #[cold]
     #[track_caller]
     pub fn wait(&self, ignore_poisoning: bool) {
diff --git a/library/std/src/thread/local/tests.rs b/library/std/src/thread/local/tests.rs
index 25019b554bb..6abb9b85a2e 100644
--- a/library/std/src/thread/local/tests.rs
+++ b/library/std/src/thread/local/tests.rs
@@ -103,6 +103,9 @@ fn smoke_dtor() {
 
 #[test]
 fn circular() {
+    // FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+    #![allow(static_mut_refs)]
+
     struct S1(&'static LocalKey<UnsafeCell<Option<S1>>>, &'static LocalKey<UnsafeCell<Option<S2>>>);
     struct S2(&'static LocalKey<UnsafeCell<Option<S1>>>, &'static LocalKey<UnsafeCell<Option<S2>>>);
     thread_local!(static K1: UnsafeCell<Option<S1>> = UnsafeCell::new(None));
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index 0fc63c5081b..33cb7e0bcca 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -1503,6 +1503,54 @@ impl Thread {
         self.inner.name.as_str()
     }
 
+    /// Consumes the `Thread`, returning a raw pointer.
+    ///
+    /// To avoid a memory leak the pointer must be converted
+    /// back into a `Thread` using [`Thread::from_raw`].
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(thread_raw)]
+    ///
+    /// use std::thread::{self, Thread};
+    ///
+    /// let thread = thread::current();
+    /// let id = thread.id();
+    /// let ptr = Thread::into_raw(thread);
+    /// unsafe {
+    ///     assert_eq!(Thread::from_raw(ptr).id(), id);
+    /// }
+    /// ```
+    #[unstable(feature = "thread_raw", issue = "97523")]
+    pub fn into_raw(self) -> *const () {
+        // Safety: We only expose an opaque pointer, which maintains the `Pin` invariant.
+        let inner = unsafe { Pin::into_inner_unchecked(self.inner) };
+        Arc::into_raw(inner) as *const ()
+    }
+
+    /// Constructs a `Thread` from a raw pointer.
+    ///
+    /// The raw pointer must have been previously returned
+    /// by a call to [`Thread::into_raw`].
+    ///
+    /// # Safety
+    ///
+    /// This function is unsafe because improper use may lead
+    /// to memory unsafety, even if the returned `Thread` is never
+    /// accessed.
+    ///
+    /// Creating a `Thread` from a pointer other than one returned
+    /// from [`Thread::into_raw`] is **undefined behavior**.
+    ///
+    /// Calling this function twice on the same raw pointer can lead
+    /// to a double-free if both `Thread` instances are dropped.
+    #[unstable(feature = "thread_raw", issue = "97523")]
+    pub unsafe fn from_raw(ptr: *const ()) -> Thread {
+        // Safety: Upheld by caller.
+        unsafe { Thread { inner: Pin::new_unchecked(Arc::from_raw(ptr as *const Inner)) } }
+    }
+
     fn cname(&self) -> Option<&CStr> {
         self.inner.name.as_cstr()
     }
diff --git a/library/std/src/time.rs b/library/std/src/time.rs
index ae46670c25e..f28a0568a3c 100644
--- a/library/std/src/time.rs
+++ b/library/std/src/time.rs
@@ -280,6 +280,7 @@ impl Instant {
     /// ```
     #[must_use]
     #[stable(feature = "time2", since = "1.8.0")]
+    #[cfg_attr(not(test), rustc_diagnostic_item = "instant_now")]
     pub fn now() -> Instant {
         Instant(time::Instant::now())
     }
diff --git a/src/bootstrap/Cargo.lock b/src/bootstrap/Cargo.lock
index 357c6175152..952db063636 100644
--- a/src/bootstrap/Cargo.lock
+++ b/src/bootstrap/Cargo.lock
@@ -84,9 +84,12 @@ dependencies = [
 
 [[package]]
 name = "cc"
-version = "1.0.97"
+version = "1.1.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "099a5357d84c4c61eb35fc8eafa9a79a902c2f76911e5747ced4e032edd8d9b4"
+checksum = "2d74707dde2ba56f86ae90effb3b43ddd369504387e718014de010cec7959800"
+dependencies = [
+ "shlex",
+]
 
 [[package]]
 name = "cfg-if"
@@ -537,6 +540,12 @@ dependencies = [
 ]
 
 [[package]]
+name = "shlex"
+version = "1.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
+
+[[package]]
 name = "syn"
 version = "2.0.75"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/bootstrap/Cargo.toml b/src/bootstrap/Cargo.toml
index 07f7444aaff..1959d0a9662 100644
--- a/src/bootstrap/Cargo.toml
+++ b/src/bootstrap/Cargo.toml
@@ -37,7 +37,7 @@ test = false
 # Most of the time updating these dependencies requires modifications to the
 # bootstrap codebase(e.g., https://github.com/rust-lang/rust/issues/124565);
 # otherwise, some targets will fail. That's why these dependencies are explicitly pinned.
-cc = "=1.0.97"
+cc = "=1.1.19"
 cmake = "=0.1.48"
 
 build_helper = { path = "../tools/build_helper" }
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index 3755f4a33cb..979671cfa9d 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -1058,6 +1058,13 @@ tool_doc!(
     is_library = true,
     crates = ["run_make_support"]
 );
+tool_doc!(
+    Compiletest,
+    "src/tools/compiletest",
+    rustc_tool = false,
+    is_library = true,
+    crates = ["compiletest"]
+);
 
 #[derive(Ord, PartialOrd, Debug, Clone, Hash, PartialEq, Eq)]
 pub struct ErrorIndex {
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index 08e24ecc340..d8752d03761 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -580,11 +580,11 @@ fn check_llvm_version(builder: &Builder<'_>, llvm_config: &Path) {
     let version = command(llvm_config).arg("--version").run_capture_stdout(builder).stdout();
     let mut parts = version.split('.').take(2).filter_map(|s| s.parse::<u32>().ok());
     if let (Some(major), Some(_minor)) = (parts.next(), parts.next()) {
-        if major >= 17 {
+        if major >= 18 {
             return;
         }
     }
-    panic!("\n\nbad LLVM version: {version}, need >=17.0\n\n")
+    panic!("\n\nbad LLVM version: {version}, need >=18\n\n")
 }
 
 fn configure_cmake(
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index a7e9352bb1c..2047345d78a 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1733,6 +1733,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
 
         let is_rustdoc = suite.ends_with("rustdoc-ui") || suite.ends_with("rustdoc-js");
 
+        if mode == "run-make" {
+            let cargo = builder.ensure(tool::Cargo { compiler, target: compiler.host });
+            cmd.arg("--cargo-path").arg(cargo);
+        }
+
         // Avoid depending on rustdoc when we don't need it.
         if mode == "rustdoc"
             || mode == "run-make"
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index 003b11ec7cf..2124890b94f 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -945,6 +945,7 @@ impl<'a> Builder<'a> {
                 doc::Releases,
                 doc::RunMakeSupport,
                 doc::BuildHelper,
+                doc::Compiletest,
             ),
             Kind::Dist => describe!(
                 dist::Docs,
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 555a6a7f8bd..dcecd7f8084 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -2738,6 +2738,8 @@ impl Config {
         download_ci_llvm: Option<StringOrBool>,
         asserts: bool,
     ) -> bool {
+        let download_ci_llvm = download_ci_llvm.unwrap_or(StringOrBool::Bool(true));
+
         let if_unchanged = || {
             if self.rust_info.is_from_tarball() {
                 // Git is needed for running "if-unchanged" logic.
@@ -2761,10 +2763,7 @@ impl Config {
         };
 
         match download_ci_llvm {
-            None => {
-                (self.channel == "dev" || self.download_rustc_commit.is_some()) && if_unchanged()
-            }
-            Some(StringOrBool::Bool(b)) => {
+            StringOrBool::Bool(b) => {
                 if !b && self.download_rustc_commit.is_some() {
                     panic!(
                         "`llvm.download-ci-llvm` cannot be set to `false` if `rust.download-rustc` is set to `true` or `if-unchanged`."
@@ -2774,8 +2773,8 @@ impl Config {
                 // If download-ci-llvm=true we also want to check that CI llvm is available
                 b && llvm::is_ci_llvm_available(self, asserts)
             }
-            Some(StringOrBool::String(s)) if s == "if-unchanged" => if_unchanged(),
-            Some(StringOrBool::String(other)) => {
+            StringOrBool::String(s) if s == "if-unchanged" => if_unchanged(),
+            StringOrBool::String(other) => {
                 panic!("unrecognized option for download-ci-llvm: {:?}", other)
             }
         }
diff --git a/src/bootstrap/src/core/config/tests.rs b/src/bootstrap/src/core/config/tests.rs
index f54a5d3b512..a45e73b5d95 100644
--- a/src/bootstrap/src/core/config/tests.rs
+++ b/src/bootstrap/src/core/config/tests.rs
@@ -32,7 +32,7 @@ fn download_ci_llvm() {
     assert!(!parse_llvm("llvm.download-ci-llvm = false"));
     assert_eq!(parse_llvm(""), if_unchanged);
     assert_eq!(parse_llvm("rust.channel = \"dev\""), if_unchanged);
-    assert!(!parse_llvm("rust.channel = \"stable\""));
+    assert!(parse_llvm("rust.channel = \"stable\""));
     assert_eq!(parse_llvm("build.build = \"x86_64-unknown-linux-gnu\""), if_unchanged);
     assert_eq!(
         parse_llvm(
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 379cd568647..e6f7f105fa2 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -265,4 +265,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "New option `dist.vendor` added to control whether bootstrap should vendor dependencies for dist tarball.",
     },
+    ChangeInfo {
+        change_id: 130529,
+        severity: ChangeSeverity::Info,
+        summary: "If `llvm.download-ci-llvm` is not defined, it defaults to `true`.",
+    },
 ];
diff --git a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile
index c9a6a2dd069..32b5058bce7 100644
--- a/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-x86_64-musl/Dockerfile
@@ -19,6 +19,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
   patch \
   libssl-dev \
   pkg-config \
+  zlib1g-dev \
   && rm -rf /var/lib/apt/lists/*
 
 WORKDIR /build/
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile
deleted file mode 100644
index 3acc2ceb135..00000000000
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-17/Dockerfile
+++ /dev/null
@@ -1,62 +0,0 @@
-FROM ubuntu:23.10
-
-ARG DEBIAN_FRONTEND=noninteractive
-
-RUN apt-get update && apt-get install -y --no-install-recommends \
-  g++ \
-  gcc-multilib \
-  make \
-  ninja-build \
-  file \
-  curl \
-  ca-certificates \
-  python3 \
-  git \
-  cmake \
-  sudo \
-  gdb \
-  llvm-17-tools \
-  llvm-17-dev \
-  libedit-dev \
-  libssl-dev \
-  pkg-config \
-  zlib1g-dev \
-  xz-utils \
-  nodejs \
-  mingw-w64 \
-  # libgccjit dependencies
-  flex \
-  libmpfr-dev \
-  libgmp-dev \
-  libmpc3 \
-  libmpc-dev \
-  && rm -rf /var/lib/apt/lists/*
-
-# Install powershell (universal package) so we can test x.ps1 on Linux
-RUN curl -sL "https://github.com/PowerShell/PowerShell/releases/download/v7.3.1/powershell_7.3.1-1.deb_amd64.deb" > powershell.deb && \
-    dpkg -i powershell.deb && \
-    rm -f powershell.deb
-
-COPY scripts/sccache.sh /scripts/
-RUN sh /scripts/sccache.sh
-
-# We are disabling CI LLVM since this builder is intentionally using a host
-# LLVM, rather than the typical src/llvm-project LLVM.
-ENV NO_DOWNLOAD_CI_LLVM 1
-ENV EXTERNAL_LLVM 1
-
-# Using llvm-link-shared due to libffi issues -- see #34486
-ENV RUST_CONFIGURE_ARGS \
-      --build=x86_64-unknown-linux-gnu \
-      --llvm-root=/usr/lib/llvm-17 \
-      --enable-llvm-link-shared \
-      --set rust.randomize-layout=true \
-      --set rust.thin-lto-import-instr-limit=10
-
-COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
-COPY host-x86_64/dist-x86_64-linux/build-gccjit.sh /scripts/
-
-RUN /scripts/build-gccjit.sh /scripts
-
-COPY scripts/x86_64-gnu-llvm.sh /tmp/script.sh
-ENV SCRIPT /tmp/script.sh
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile
index 3476b10a3ad..487da580152 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-18/Dockerfile
@@ -51,6 +51,7 @@ ENV RUST_CONFIGURE_ARGS \
       --build=x86_64-unknown-linux-gnu \
       --llvm-root=/usr/lib/llvm-18 \
       --enable-llvm-link-shared \
+      --set rust.randomize-layout=true \
       --set rust.thin-lto-import-instr-limit=10
 
 COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile
index 44328b078ad..4991908fe77 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-llvm-19/Dockerfile
@@ -51,6 +51,7 @@ ENV RUST_CONFIGURE_ARGS \
       --build=x86_64-unknown-linux-gnu \
       --llvm-root=/usr/lib/llvm-19 \
       --enable-llvm-link-shared \
+      --set rust.randomize-layout=true \
       --set rust.thin-lto-import-instr-limit=10
 
 COPY host-x86_64/dist-x86_64-linux/shared.sh /scripts/
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index f65083eec47..6379f1ade1c 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -89,7 +89,7 @@ pr:
   - image: mingw-check-tidy
     continue_on_error: true
     <<: *job-linux-4c
-  - image: x86_64-gnu-llvm-17
+  - image: x86_64-gnu-llvm-18
     env:
       ENABLE_GCC_CODEGEN: "1"
     <<: *job-linux-16c
@@ -261,11 +261,6 @@ auto:
       RUST_BACKTRACE: 1
     <<: *job-linux-8c
 
-  - image: x86_64-gnu-llvm-17
-    env:
-      RUST_BACKTRACE: 1
-    <<: *job-linux-8c
-
   - image: x86_64-gnu-nopt
     <<: *job-linux-4c
 
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 3e199539694..b1a5bd604eb 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -25,6 +25,7 @@
         - [\*-apple-ios-macabi](platform-support/apple-ios-macabi.md)
         - [arm64e-apple-ios](platform-support/arm64e-apple-ios.md)
     - [\*-apple-tvos](platform-support/apple-tvos.md)
+        - [arm64e-apple-tvos](platform-support/arm64e-apple-tvos.md)
     - [\*-apple-watchos](platform-support/apple-watchos.md)
     - [\*-apple-visionos](platform-support/apple-visionos.md)
     - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 9a35b35af71..827a7065f3e 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -245,8 +245,9 @@ host tools.
 
 target | std | host | notes
 -------|:---:|:----:|-------
-[`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS
 [`arm64e-apple-darwin`](platform-support/arm64e-apple-darwin.md)  | ✓ | ✓ | ARM64e Apple Darwin
+[`arm64e-apple-ios`](platform-support/arm64e-apple-ios.md) | ✓ | | ARM64e Apple iOS
+[`arm64e-apple-tvos`](platform-support/arm64e-apple-tvos.md)  | ✓ | | ARM64e Apple tvOS
 [`aarch64-apple-tvos`](platform-support/apple-tvos.md) | ✓ |  | ARM64 tvOS
 [`aarch64-apple-tvos-sim`](platform-support/apple-tvos.md) | ✓ |  | ARM64 tvOS Simulator
 [`aarch64-apple-watchos`](platform-support/apple-watchos.md) | ✓ |  | ARM64 Apple WatchOS
diff --git a/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md b/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md
new file mode 100644
index 00000000000..d49383fb853
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/arm64e-apple-tvos.md
@@ -0,0 +1,37 @@
+# `arm64e-apple-tvos`
+
+**Tier: 3**
+
+ARM64e tvOS (10.0+)
+
+## Target maintainers
+
+- Artyom Tetyukhin ([@arttet](https://github.com/https://github.com/arttet))
+
+## Requirements
+
+This target is cross-compiled and supports `std`.
+To build this target Xcode 12 or higher on macOS is required.
+
+## Building the target
+
+You can build Rust with support for the targets by adding it to the `target` list in `config.toml`:
+
+```toml
+[build]
+target = [ "arm64e-apple-tvos" ]
+```
+
+## Building Rust programs
+
+Rust does not yet ship pre-compiled artifacts for this target.
+To compile for this target, you will need to build Rust with the target enabled (see [Building the target](#building-the-target) above).
+
+## Testing
+
+The target does support running binaries on tvOS platforms with `arm64e` architecture.
+
+## Cross-compilation toolchains and C code
+
+The targets do support `C` code.
+To build compatible `C` code, you have to use XCode with the same compiler and flags.
diff --git a/src/doc/rustc/src/platform-support/trusty.md b/src/doc/rustc/src/platform-support/trusty.md
index dec3b96ff64..6b37543b600 100644
--- a/src/doc/rustc/src/platform-support/trusty.md
+++ b/src/doc/rustc/src/platform-support/trusty.md
@@ -8,7 +8,8 @@ Environment (TEE) for Android.
 ## Target maintainers
 
 - Nicole LeGare (@randomPoison)
-- Stephen Crane (@rinon)
+- Andrei Homescu (@ahomescu)
+- Chris Wailes (chriswailes@google.com)
 - As a fallback trusty-dev-team@google.com can be contacted
 
 ## Requirements
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 4fafef65792..b5648bf2c13 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -262,7 +262,7 @@ pub(crate) fn create_config(
         output_file: None,
         output_dir: None,
         file_loader: None,
-        locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES,
+        locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
         lint_caps,
         psess_created: None,
         hash_untracked_state: None,
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 05ef7289201..73eafaf78ca 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -143,7 +143,7 @@ pub(crate) fn run(
         output_file: None,
         output_dir: None,
         file_loader: None,
-        locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES,
+        locale_resources: rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(),
         lint_caps,
         psess_created: None,
         hash_untracked_state: None,
diff --git a/src/librustdoc/doctest/rust.rs b/src/librustdoc/doctest/rust.rs
index 5c0898f28fc..71a0e3d72de 100644
--- a/src/librustdoc/doctest/rust.rs
+++ b/src/librustdoc/doctest/rust.rs
@@ -122,23 +122,14 @@ impl<'a, 'tcx> HirCollector<'a, 'tcx> {
         // anything else, this will combine them for us.
         let attrs = Attributes::from_ast(ast_attrs);
         if let Some(doc) = attrs.opt_doc_value() {
-            // Use the outermost invocation, so that doctest names come from where the docs were written.
-            let span = ast_attrs
-                .iter()
-                .find(|attr| attr.doc_str().is_some())
-                .map(|attr| attr.span.ctxt().outer_expn().expansion_cause().unwrap_or(attr.span))
-                .unwrap_or(DUMMY_SP);
+            let span = span_of_fragments(&attrs.doc_strings).unwrap_or(sp);
             self.collector.position = span;
             markdown::find_testable_code(
                 &doc,
                 &mut self.collector,
                 self.codes,
                 self.enable_per_target_ignores,
-                Some(&crate::html::markdown::ExtraInfo::new(
-                    self.tcx,
-                    def_id,
-                    span_of_fragments(&attrs.doc_strings).unwrap_or(sp),
-                )),
+                Some(&crate::html::markdown::ExtraInfo::new(self.tcx, def_id, span)),
             );
         }
 
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index a402d799504..668bd391348 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -2538,7 +2538,6 @@ fn render_call_locations<W: fmt::Write>(mut w: W, cx: &mut Context<'_>, item: &c
             &cx.root_path(),
             highlight::DecorationInfo(decoration_info),
             sources::SourceContext::Embedded(sources::ScrapedInfo {
-                needs_prev_next_buttons: line_ranges.len() > 1,
                 needs_expansion,
                 offset: line_min,
                 name: &call_data.display_name,
diff --git a/src/librustdoc/html/sources.rs b/src/librustdoc/html/sources.rs
index 551bb56685c..0d6a4603cd2 100644
--- a/src/librustdoc/html/sources.rs
+++ b/src/librustdoc/html/sources.rs
@@ -292,7 +292,6 @@ where
 
 pub(crate) struct ScrapedInfo<'a> {
     pub(crate) offset: usize,
-    pub(crate) needs_prev_next_buttons: bool,
     pub(crate) name: &'a str,
     pub(crate) url: &'a str,
     pub(crate) title: &'a str,
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 38154dee3e2..04b0eba7450 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -801,6 +801,9 @@ both the code example and the line numbers, so we need to remove the radius in t
 	 * and we include additional 10px for padding. */
 	max-height: calc(1.5em * 5 + 10px);
 }
+.more-scraped-examples .scraped-example:not(.expanded) .example-wrap {
+	max-height: calc(1.5em * 10 + 10px);
+}
 
 .rustdoc:not(.src) .scraped-example:not(.expanded) .src-line-numbers,
 .rustdoc:not(.src) .scraped-example:not(.expanded) .src-line-numbers > pre,
@@ -828,10 +831,14 @@ both the code example and the line numbers, so we need to remove the radius in t
 	-webkit-user-select: none;
 	user-select: none;
 	padding: 14px 8px;
+	padding-right: 2px;
 	color: var(--src-line-numbers-span-color);
 }
 
-.rustdoc .scraped-example .src-line-numbers {
+.rustdoc .scraped-example .example-wrap .src-line-numbers {
+	padding: 0;
+}
+.rustdoc .src-line-numbers pre {
 	padding: 14px 0;
 }
 .src-line-numbers a, .src-line-numbers span {
@@ -890,7 +897,7 @@ both the code example and the line numbers, so we need to remove the radius in t
 }
 
 .docblock code, .docblock-short code,
-pre, .rustdoc.src .example-wrap {
+pre, .rustdoc.src .example-wrap, .example-wrap .src-line-numbers {
 	background-color: var(--code-block-background-color);
 }
 
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index 858753a1917..a0ec45b5ef3 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -1855,12 +1855,8 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
         // Since the button will be added, no need to keep this listener around.
         elem.removeEventListener("mouseover", addCopyButton);
 
-        // If this is a scrapped example, there will already be a "button-holder" element.
-        let parent = elem.querySelector(".button-holder");
-        if (!parent) {
-            parent = document.createElement("div");
-            parent.className = "button-holder";
-        }
+        const parent = document.createElement("div");
+        parent.className = "button-holder";
 
         const runButton = elem.querySelector(".test-arrow");
         if (runButton !== null) {
@@ -1876,6 +1872,12 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm
             copyButtonAnimation(copyButton);
         });
         parent.appendChild(copyButton);
+
+        if (!elem.parentElement.classList.contains("scraped-example")) {
+            return;
+        }
+        const scrapedWrapped = elem.parentElement;
+        window.updateScrapedExample(scrapedWrapped, parent);
     }
 
     function showHideCodeExampleButtons(event) {
diff --git a/src/librustdoc/html/static/js/scrape-examples.js b/src/librustdoc/html/static/js/scrape-examples.js
index 06e42814d33..98c53b8656f 100644
--- a/src/librustdoc/html/static/js/scrape-examples.js
+++ b/src/librustdoc/html/static/js/scrape-examples.js
@@ -36,13 +36,30 @@
         elt.querySelector(".rust").scrollTo(0, scrollOffset);
     }
 
-    function updateScrapedExample(example, isHidden) {
-        const locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent);
+    function createScrapeButton(parent, className, content) {
+        const button = document.createElement("button");
+        button.className = className;
+        button.innerText = content;
+        parent.insertBefore(button, parent.firstChild);
+        return button;
+    }
+
+    window.updateScrapedExample = (example, buttonHolder) => {
         let locIndex = 0;
         const highlights = Array.prototype.slice.call(example.querySelectorAll(".highlight"));
         const link = example.querySelector(".scraped-example-title a");
+        let expandButton = null;
+
+        if (!example.classList.contains("expanded")) {
+            expandButton = createScrapeButton(buttonHolder, "expand", "↕");
+        }
+        const isHidden = example.parentElement.classList.contains("more-scraped-examples");
 
+        const locs = example.locs;
         if (locs.length > 1) {
+            const next = createScrapeButton(buttonHolder, "next", "≻");
+            const prev = createScrapeButton(buttonHolder, "prev", "≺");
+
             // Toggle through list of examples in a given file
             const onChangeLoc = changeIndex => {
                 removeClass(highlights[locIndex], "focus");
@@ -57,22 +74,19 @@
                 link.innerHTML = title;
             };
 
-            example.querySelector(".prev")
-                .addEventListener("click", () => {
-                    onChangeLoc(() => {
-                        locIndex = (locIndex - 1 + locs.length) % locs.length;
-                    });
+            prev.addEventListener("click", () => {
+                onChangeLoc(() => {
+                    locIndex = (locIndex - 1 + locs.length) % locs.length;
                 });
+            });
 
-            example.querySelector(".next")
-                .addEventListener("click", () => {
-                    onChangeLoc(() => {
-                        locIndex = (locIndex + 1) % locs.length;
-                    });
+            next.addEventListener("click", () => {
+                onChangeLoc(() => {
+                    locIndex = (locIndex + 1) % locs.length;
                 });
+            });
         }
 
-        const expandButton = example.querySelector(".expand");
         if (expandButton) {
             expandButton.addEventListener("click", () => {
                 if (hasClass(example, "expanded")) {
@@ -83,13 +97,16 @@
                 }
             });
         }
+    };
 
+    function setupLoc(example, isHidden) {
+        example.locs = JSON.parse(example.attributes.getNamedItem("data-locs").textContent);
         // Start with the first example in view
-        scrollToLoc(example, locs[0][0], isHidden);
+        scrollToLoc(example, example.locs[0][0], isHidden);
     }
 
     const firstExamples = document.querySelectorAll(".scraped-example-list > .scraped-example");
-    onEachLazy(firstExamples, el => updateScrapedExample(el, false));
+    onEachLazy(firstExamples, el => setupLoc(el, false));
     onEachLazy(document.querySelectorAll(".more-examples-toggle"), toggle => {
         // Allow users to click the left border of the <details> section to close it,
         // since the section can be large and finding the [+] button is annoying.
@@ -102,11 +119,11 @@
         const moreExamples = toggle.querySelectorAll(".scraped-example");
         toggle.querySelector("summary").addEventListener("click", () => {
             // Wrapping in setTimeout ensures the update happens after the elements are actually
-            // visible. This is necessary since updateScrapedExample calls scrollToLoc which
+            // visible. This is necessary since setupLoc calls scrollToLoc which
             // depends on offsetHeight, a property that requires an element to be visible to
             // compute correctly.
             setTimeout(() => {
-                onEachLazy(moreExamples, el => updateScrapedExample(el, true));
+                onEachLazy(moreExamples, el => setupLoc(el, true));
             });
         }, {once: true});
     });
diff --git a/src/librustdoc/html/templates/scraped_source.html b/src/librustdoc/html/templates/scraped_source.html
index e1fc2e69378..bd54bbf58d5 100644
--- a/src/librustdoc/html/templates/scraped_source.html
+++ b/src/librustdoc/html/templates/scraped_source.html
@@ -1,8 +1,8 @@
 <div class="scraped-example{% if !info.needs_expansion +%} expanded{% endif %}" data-locs="{{info.locations}}"> {# #}
     <div class="scraped-example-title">
        {{info.name +}} (<a href="{{info.url}}">{{info.title}}</a>) {# #}
-    </div>
-    <div class="example-wrap"> {# #}
+    </div> {# #}
+    <div class="example-wrap">
         {# https://developers.google.com/search/docs/crawling-indexing/robots-meta-tag#data-nosnippet-attr
            Do not show "1 2 3 4 5 ..." in web search results. #}
         <div class="src-line-numbers" data-nosnippet> {# #}
@@ -18,16 +18,5 @@
                 {{code_html|safe}}
             </code> {# #}
         </pre> {# #}
-        {% if info.needs_prev_next_buttons || info.needs_expansion %}
-            <div class="button-holder">
-                {% if info.needs_prev_next_buttons %}
-                    <button class="prev">&pr;</button> {# #}
-                    <button class="next">&sc;</button>
-                {% endif %}
-                {% if info.needs_expansion %}
-                    <button class="expand">&varr;</button>
-                {% endif %}
-            </div>
-        {% endif %}
     </div> {# #}
 </div> {# #}
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 92b21f7dbaa..eb5faeeaf9a 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -51,9 +51,7 @@ static HOSTS: &[&str] = &[
 
 static TARGETS: &[&str] = &[
     "aarch64-apple-darwin",
-    "arm64e-apple-darwin",
     "aarch64-apple-ios",
-    "arm64e-apple-ios",
     "aarch64-apple-ios-macabi",
     "aarch64-apple-ios-sim",
     "aarch64-unknown-fuchsia",
@@ -68,6 +66,9 @@ static TARGETS: &[&str] = &[
     "aarch64-unknown-none-softfloat",
     "aarch64-unknown-redox",
     "aarch64-unknown-uefi",
+    "arm64e-apple-darwin",
+    "arm64e-apple-ios",
+    "arm64e-apple-tvos",
     "arm-linux-androideabi",
     "arm-unknown-linux-gnueabi",
     "arm-unknown-linux-gnueabihf",
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject a9a418d1a22f29e7dfd034e3b93f15657e608a2
+Subproject eaee77dc1584be45949b75e4c4c9a841605e3a4
diff --git a/src/tools/clippy/clippy_lints/src/entry.rs b/src/tools/clippy/clippy_lints/src/entry.rs
index b7c9d3d0385..9c5100a8c1a 100644
--- a/src/tools/clippy/clippy_lints/src/entry.rs
+++ b/src/tools/clippy/clippy_lints/src/entry.rs
@@ -1,8 +1,8 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::{reindent_multiline, snippet_indent, snippet_with_applicability, snippet_with_context};
 use clippy_utils::{
-    can_move_expr_to_closure_no_visit, higher, is_expr_final_block_expr, is_expr_used_or_unified, match_def_path,
-    paths, peel_hir_expr_while, SpanlessEq,
+    can_move_expr_to_closure_no_visit, higher, is_expr_final_block_expr, is_expr_used_or_unified,
+    peel_hir_expr_while, SpanlessEq,
 };
 use core::fmt::{self, Write};
 use rustc_errors::Applicability;
@@ -11,7 +11,7 @@ use rustc_hir::intravisit::{walk_expr, Visitor};
 use rustc_hir::{Block, Expr, ExprKind, HirId, Pat, Stmt, StmtKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
-use rustc_span::{Span, SyntaxContext, DUMMY_SP};
+use rustc_span::{sym, Span, SyntaxContext, DUMMY_SP};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -269,9 +269,9 @@ fn try_parse_contains<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'_>) -> Optio
                 key,
                 call_ctxt: expr.span.ctxt(),
             };
-            if match_def_path(cx, id, &paths::BTREEMAP_CONTAINS_KEY) {
+            if cx.tcx.is_diagnostic_item(sym::btreemap_contains_key, id) {
                 Some((MapType::BTree, expr))
-            } else if match_def_path(cx, id, &paths::HASHMAP_CONTAINS_KEY) {
+            } else if cx.tcx.is_diagnostic_item(sym::hashmap_contains_key, id) {
                 Some((MapType::Hash, expr))
             } else {
                 None
@@ -306,7 +306,7 @@ struct InsertExpr<'tcx> {
 fn try_parse_insert<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<InsertExpr<'tcx>> {
     if let ExprKind::MethodCall(_, map, [key, value], _) = expr.kind {
         let id = cx.typeck_results().type_dependent_def_id(expr.hir_id)?;
-        if match_def_path(cx, id, &paths::BTREEMAP_INSERT) || match_def_path(cx, id, &paths::HASHMAP_INSERT) {
+        if cx.tcx.is_diagnostic_item(sym::btreemap_insert, id) || cx.tcx.is_diagnostic_item(sym::hashmap_insert, id) {
             Some(InsertExpr { map, key, value })
         } else {
             None
diff --git a/src/tools/clippy/clippy_lints/src/format_push_string.rs b/src/tools/clippy/clippy_lints/src/format_push_string.rs
index d05c5a01f41..c6f03c3a7cf 100644
--- a/src/tools/clippy/clippy_lints/src/format_push_string.rs
+++ b/src/tools/clippy/clippy_lints/src/format_push_string.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::ty::is_type_lang_item;
-use clippy_utils::{higher, match_def_path, paths};
+use clippy_utils::higher;
 use rustc_hir::{BinOpKind, Expr, ExprKind, LangItem, MatchSource};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
@@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for FormatPushString {
         let arg = match expr.kind {
             ExprKind::MethodCall(_, _, [arg], _) => {
                 if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
-                    && match_def_path(cx, fn_def_id, &paths::PUSH_STR)
+                    && cx.tcx.is_diagnostic_item(sym::string_push_str, fn_def_id)
                 {
                     arg
                 } else {
diff --git a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
index f41fdf3203c..6d6820311b6 100644
--- a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
+++ b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
@@ -112,7 +112,7 @@ impl LateLintPass<'_> for InstantSubtraction {
 fn is_instant_now_call(cx: &LateContext<'_>, expr_block: &'_ Expr<'_>) -> bool {
     if let ExprKind::Call(fn_expr, []) = expr_block.kind
         && let Some(fn_id) = clippy_utils::path_def_id(cx, fn_expr)
-        && clippy_utils::match_def_path(cx, fn_id, &clippy_utils::paths::INSTANT_NOW)
+        && cx.tcx.is_diagnostic_item(sym::instant_now, fn_id)
     {
         true
     } else {
diff --git a/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs b/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs
index fb29d982417..f162948bb44 100644
--- a/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_over_hash_type.rs
@@ -1,10 +1,5 @@
 use clippy_utils::diagnostics::span_lint;
 use clippy_utils::higher::ForLoop;
-use clippy_utils::match_any_def_paths;
-use clippy_utils::paths::{
-    HASHMAP_DRAIN, HASHMAP_ITER, HASHMAP_ITER_MUT, HASHMAP_KEYS, HASHMAP_VALUES, HASHMAP_VALUES_MUT, HASHSET_DRAIN,
-    HASHSET_ITER_TY,
-};
 use clippy_utils::ty::is_type_diagnostic_item;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
@@ -44,28 +39,23 @@ declare_lint_pass!(IterOverHashType => [ITER_OVER_HASH_TYPE]);
 
 impl LateLintPass<'_> for IterOverHashType {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &'_ rustc_hir::Expr<'_>) {
+        let hash_iter_tys = [
+            sym::HashMap,
+            sym::HashSet,
+            sym::hashmap_keys_ty,
+            sym::hashmap_values_ty,
+            sym::hashmap_values_mut_ty,
+            sym::hashmap_iter_ty,
+            sym::hashmap_iter_mut_ty,
+            sym::hashmap_drain_ty,
+            sym::hashset_iter_ty,
+            sym::hashset_drain_ty,
+        ];
+
         if let Some(for_loop) = ForLoop::hir(expr)
             && !for_loop.body.span.from_expansion()
             && let ty = cx.typeck_results().expr_ty(for_loop.arg).peel_refs()
-            && let Some(adt) = ty.ty_adt_def()
-            && let did = adt.did()
-            && (match_any_def_paths(
-                cx,
-                did,
-                &[
-                    &HASHMAP_KEYS,
-                    &HASHMAP_VALUES,
-                    &HASHMAP_VALUES_MUT,
-                    &HASHMAP_ITER,
-                    &HASHMAP_ITER_MUT,
-                    &HASHMAP_DRAIN,
-                    &HASHSET_ITER_TY,
-                    &HASHSET_DRAIN,
-                ],
-            )
-            .is_some()
-                || is_type_diagnostic_item(cx, ty, sym::HashMap)
-                || is_type_diagnostic_item(cx, ty, sym::HashSet))
+            && hash_iter_tys.into_iter().any(|sym| is_type_diagnostic_item(cx, ty, sym))
         {
             span_lint(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs b/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs
index 3d1c666dfea..8206c75927b 100644
--- a/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs
+++ b/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{is_diag_item_method, is_trait_method, match_def_path, path_to_local_id, paths};
+use clippy_utils::{is_diag_item_method, is_trait_method, path_to_local_id};
 use rustc_errors::Applicability;
 use rustc_hir::{Body, Closure, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -96,7 +96,7 @@ fn should_lint(cx: &LateContext<'_>, args: &[Expr<'_>], method_str: &str) -> boo
                 ExprKind::Path(qpath) => cx
                     .qpath_res(qpath, fm_arg.hir_id)
                     .opt_def_id()
-                    .is_some_and(|did| match_def_path(cx, did, &paths::CORE_RESULT_OK_METHOD)),
+                    .is_some_and(|did| cx.tcx.is_diagnostic_item(sym::result_ok_method, did)),
                 // Detect `|x| x.ok()`
                 ExprKind::Closure(Closure { body, .. }) => {
                     if let Body {
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_while_let_some.rs b/src/tools/clippy/clippy_lints/src/loops/manual_while_let_some.rs
index 57434f35544..55d1b9ee676 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_while_let_some.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_while_let_some.rs
@@ -1,10 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet;
-use clippy_utils::{match_def_path, paths, SpanlessEq};
+use clippy_utils::SpanlessEq;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, Pat, Stmt, StmtKind, UnOp};
 use rustc_lint::LateContext;
-use rustc_span::Span;
+use rustc_span::{sym, Symbol, Span};
 use std::borrow::Cow;
 
 use super::MANUAL_WHILE_LET_SOME;
@@ -47,20 +47,20 @@ fn report_lint(cx: &LateContext<'_>, pop_span: Span, pop_stmt_kind: PopStmt<'_>,
     );
 }
 
-fn match_method_call(cx: &LateContext<'_>, expr: &Expr<'_>, method: &[&str]) -> bool {
+fn match_method_call(cx: &LateContext<'_>, expr: &Expr<'_>, method: Symbol) -> bool {
     if let ExprKind::MethodCall(..) = expr.kind
         && let Some(id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
     {
-        match_def_path(cx, id, method)
+        cx.tcx.is_diagnostic_item(method, id)
     } else {
         false
     }
 }
 
 fn is_vec_pop_unwrap(cx: &LateContext<'_>, expr: &Expr<'_>, is_empty_recv: &Expr<'_>) -> bool {
-    if (match_method_call(cx, expr, &paths::OPTION_UNWRAP) || match_method_call(cx, expr, &paths::OPTION_EXPECT))
+    if (match_method_call(cx, expr, sym::option_unwrap) || match_method_call(cx, expr, sym::option_expect))
         && let ExprKind::MethodCall(_, unwrap_recv, ..) = expr.kind
-        && match_method_call(cx, unwrap_recv, &paths::VEC_POP)
+        && match_method_call(cx, unwrap_recv, sym::vec_pop)
         && let ExprKind::MethodCall(_, pop_recv, ..) = unwrap_recv.kind
     {
         // make sure they're the same `Vec`
@@ -96,7 +96,7 @@ fn check_call_arguments(cx: &LateContext<'_>, stmt: &Stmt<'_>, is_empty_recv: &E
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, full_cond: &'tcx Expr<'_>, body: &'tcx Expr<'_>, loop_span: Span) {
     if let ExprKind::Unary(UnOp::Not, cond) = full_cond.kind
         && let ExprKind::MethodCall(_, is_empty_recv, _, _) = cond.kind
-        && match_method_call(cx, cond, &paths::VEC_IS_EMPTY)
+        && match_method_call(cx, cond, sym::vec_is_empty)
         && let ExprKind::Block(body, _) = body.kind
         && let Some(stmt) = body.stmts.first()
     {
diff --git a/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs b/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs
index db491a8c8f6..5198d7838a2 100644
--- a/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_main_separator_str.rs
@@ -1,7 +1,7 @@
 use clippy_config::msrvs::{self, Msrv};
 use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::{is_trait_method, match_def_path, paths, peel_hir_expr_refs};
+use clippy_utils::{is_trait_method, peel_hir_expr_refs};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Expr, ExprKind, Mutability, QPath};
@@ -56,7 +56,7 @@ impl LateLintPass<'_> for ManualMainSeparatorStr {
             && let Res::Def(DefKind::Const, receiver_def_id) = path.res
             && is_trait_method(cx, target, sym::ToString)
             && self.msrv.meets(msrvs::PATH_MAIN_SEPARATOR_STR)
-            && match_def_path(cx, receiver_def_id, &paths::PATH_MAIN_SEPARATOR)
+            && cx.tcx.is_diagnostic_item(sym::path_main_separator, receiver_def_id)
             && let ty::Ref(_, ty, Mutability::Not) = cx.typeck_results().expr_ty_adjusted(expr).kind()
             && ty.is_str()
         {
diff --git a/src/tools/clippy/clippy_lints/src/manual_retain.rs b/src/tools/clippy/clippy_lints/src/manual_retain.rs
index d4e53f8f74b..a35b0f914e0 100644
--- a/src/tools/clippy/clippy_lints/src/manual_retain.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_retain.rs
@@ -3,22 +3,22 @@ use clippy_config::Conf;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
 use clippy_utils::ty::{get_type_diagnostic_name, is_type_lang_item};
-use clippy_utils::{match_def_path, paths, SpanlessEq};
+use clippy_utils::SpanlessEq;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::ExprKind::Assign;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
-use rustc_span::symbol::sym;
+use rustc_span::symbol::{sym, Symbol};
 use rustc_span::Span;
 
-const ACCEPTABLE_METHODS: [&[&str]; 5] = [
-    &paths::BINARYHEAP_ITER,
-    &paths::HASHSET_ITER,
-    &paths::BTREESET_ITER,
-    &paths::SLICE_INTO,
-    &paths::VEC_DEQUE_ITER,
+const ACCEPTABLE_METHODS: [Symbol; 5] = [
+    sym::binaryheap_iter,
+    sym::hashset_iter,
+    sym::btreeset_iter,
+    sym::slice_iter,
+    sym::vecdeque_iter,
 ];
 
 declare_clippy_lint! {
@@ -84,7 +84,7 @@ fn check_into_iter(
 ) {
     if let hir::ExprKind::MethodCall(_, into_iter_expr, [_], _) = &target_expr.kind
         && let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)
-        && match_def_path(cx, filter_def_id, &paths::CORE_ITER_FILTER)
+        && cx.tcx.is_diagnostic_item(sym::iter_filter, filter_def_id)
         && let hir::ExprKind::MethodCall(_, struct_expr, [], _) = &into_iter_expr.kind
         && let Some(into_iter_def_id) = cx.typeck_results().type_dependent_def_id(into_iter_expr.hir_id)
         && Some(into_iter_def_id) == cx.tcx.lang_items().into_iter_fn()
@@ -127,14 +127,14 @@ fn check_iter(
 ) {
     if let hir::ExprKind::MethodCall(_, filter_expr, [], _) = &target_expr.kind
         && let Some(copied_def_id) = cx.typeck_results().type_dependent_def_id(target_expr.hir_id)
-        && (match_def_path(cx, copied_def_id, &paths::CORE_ITER_COPIED)
-            || match_def_path(cx, copied_def_id, &paths::CORE_ITER_CLONED))
+        && (cx.tcx.is_diagnostic_item(sym::iter_copied, copied_def_id)
+            || cx.tcx.is_diagnostic_item(sym::iter_cloned, copied_def_id))
         && let hir::ExprKind::MethodCall(_, iter_expr, [_], _) = &filter_expr.kind
         && let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(filter_expr.hir_id)
-        && match_def_path(cx, filter_def_id, &paths::CORE_ITER_FILTER)
+        && cx.tcx.is_diagnostic_item(sym::iter_filter, filter_def_id)
         && let hir::ExprKind::MethodCall(_, struct_expr, [], _) = &iter_expr.kind
         && let Some(iter_expr_def_id) = cx.typeck_results().type_dependent_def_id(iter_expr.hir_id)
-        && match_acceptable_def_path(cx, iter_expr_def_id)
+        && match_acceptable_sym(cx, iter_expr_def_id)
         && match_acceptable_type(cx, left_expr, msrv)
         && SpanlessEq::new(cx).eq_expr(left_expr, struct_expr)
         && let hir::ExprKind::MethodCall(_, _, [closure_expr], _) = filter_expr.kind
@@ -189,10 +189,10 @@ fn check_to_owned(
         && cx.tcx.is_diagnostic_item(sym::to_owned_method, to_owned_def_id)
         && let hir::ExprKind::MethodCall(_, chars_expr, [_], _) = &filter_expr.kind
         && let Some(filter_def_id) = cx.typeck_results().type_dependent_def_id(filter_expr.hir_id)
-        && match_def_path(cx, filter_def_id, &paths::CORE_ITER_FILTER)
+        && cx.tcx.is_diagnostic_item(sym::iter_filter, filter_def_id)
         && let hir::ExprKind::MethodCall(_, str_expr, [], _) = &chars_expr.kind
         && let Some(chars_expr_def_id) = cx.typeck_results().type_dependent_def_id(chars_expr.hir_id)
-        && match_def_path(cx, chars_expr_def_id, &paths::STR_CHARS)
+        && cx.tcx.is_diagnostic_item(sym::str_chars, chars_expr_def_id)
         && let ty = cx.typeck_results().expr_ty(str_expr).peel_refs()
         && is_type_lang_item(cx, ty, hir::LangItem::String)
         && SpanlessEq::new(cx).eq_expr(left_expr, str_expr)
@@ -247,10 +247,10 @@ fn make_sugg(
     }
 }
 
-fn match_acceptable_def_path(cx: &LateContext<'_>, collect_def_id: DefId) -> bool {
+fn match_acceptable_sym(cx: &LateContext<'_>, collect_def_id: DefId) -> bool {
     ACCEPTABLE_METHODS
         .iter()
-        .any(|&method| match_def_path(cx, collect_def_id, method))
+        .any(|&method| cx.tcx.is_diagnostic_item(method, collect_def_id))
 }
 
 fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, msrv: &Msrv) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs
index 85cabd2800a..02d433ecc5a 100644
--- a/src/tools/clippy/clippy_lints/src/manual_strip.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs
@@ -4,7 +4,7 @@ use clippy_utils::consts::{ConstEvalCtxt, Constant};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet;
 use clippy_utils::usage::mutated_variables;
-use clippy_utils::{eq_expr_value, higher, match_def_path, paths};
+use clippy_utils::{eq_expr_value, higher};
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
@@ -14,7 +14,7 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty;
 use rustc_session::impl_lint_pass;
 use rustc_span::source_map::Spanned;
-use rustc_span::Span;
+use rustc_span::{sym, Span};
 use std::iter;
 
 declare_clippy_lint! {
@@ -76,9 +76,9 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip {
             && self.msrv.meets(msrvs::STR_STRIP_PREFIX)
             && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(cond.hir_id)
         {
-            let strip_kind = if match_def_path(cx, method_def_id, &paths::STR_STARTS_WITH) {
+            let strip_kind = if cx.tcx.is_diagnostic_item(sym::str_starts_with, method_def_id) {
                 StripKind::Prefix
-            } else if match_def_path(cx, method_def_id, &paths::STR_ENDS_WITH) {
+            } else if cx.tcx.is_diagnostic_item(sym::str_ends_with, method_def_id) {
                 StripKind::Suffix
             } else {
                 return;
@@ -137,7 +137,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip {
 fn len_arg<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> Option<&'tcx Expr<'tcx>> {
     if let ExprKind::MethodCall(_, arg, [], _) = expr.kind
         && let Some(method_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id)
-        && match_def_path(cx, method_def_id, &paths::STR_LEN)
+        && cx.tcx.is_diagnostic_item(sym::str_len, method_def_id)
     {
         Some(arg)
     } else {
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
index 4fbf661727d..77a62fbb4fb 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
@@ -1,9 +1,8 @@
 use super::FILTER_MAP_BOOL_THEN;
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::paths::BOOL_THEN;
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::is_copy;
-use clippy_utils::{is_from_proc_macro, is_trait_method, match_def_path, peel_blocks};
+use clippy_utils::{is_from_proc_macro, is_trait_method, peel_blocks};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LintContext};
@@ -35,7 +34,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &
         && let ExprKind::Closure(then_closure) = then_arg.kind
         && let then_body = peel_blocks(cx.tcx.hir().body(then_closure.body).value)
         && let Some(def_id) = cx.typeck_results().type_dependent_def_id(value.hir_id)
-        && match_def_path(cx, def_id, &BOOL_THEN)
+        && cx.tcx.is_diagnostic_item(sym::bool_then, def_id)
         && !is_from_proc_macro(cx, expr)
         // Count the number of derefs needed to get to the bool because we need those in the suggestion
         && let needed_derefs = cx.typeck_results().expr_adjustments(recv)
diff --git a/src/tools/clippy/clippy_lints/src/methods/open_options.rs b/src/tools/clippy/clippy_lints/src/methods/open_options.rs
index cbeb48b6cc3..f1a3c81cebb 100644
--- a/src/tools/clippy/clippy_lints/src/methods/open_options.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/open_options.rs
@@ -126,17 +126,18 @@ fn get_open_options(
         && let ExprKind::Path(path) = callee.kind
         && let Some(did) = cx.qpath_res(&path, callee.hir_id).opt_def_id()
     {
-        match_any_def_paths(
-            cx,
-            did,
-            &[
-                &paths::TOKIO_IO_OPEN_OPTIONS_NEW,
-                &paths::OPEN_OPTIONS_NEW,
-                &paths::FILE_OPTIONS,
-                &paths::TOKIO_FILE_OPTIONS,
-            ],
-        )
-        .is_some()
+        let std_file_options = [
+            sym::file_options,
+            sym::open_options_new,
+        ];
+
+        let tokio_file_options: &[&[&str]] = &[
+            &paths::TOKIO_IO_OPEN_OPTIONS_NEW,
+            &paths::TOKIO_FILE_OPTIONS,
+        ];
+
+        let is_std_options = std_file_options.into_iter().any(|sym| cx.tcx.is_diagnostic_item(sym, did));
+        is_std_options || match_any_def_paths(cx, did, tokio_file_options).is_some()
     } else {
         false
     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
index cb57689b0c4..9a18d8a1421 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
@@ -2,12 +2,12 @@ use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
 use clippy_utils::ty::is_type_diagnostic_item;
-use clippy_utils::{match_def_path, path_to_local_id, paths, peel_blocks};
+use clippy_utils::{path_to_local_id, peel_blocks};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::sym;
+use rustc_span::{sym, Symbol};
 
 use super::OPTION_AS_REF_DEREF;
 
@@ -31,14 +31,14 @@ pub(super) fn check(
         return;
     }
 
-    let deref_aliases: [&[&str]; 7] = [
-        &paths::CSTRING_AS_C_STR,
-        &paths::OS_STRING_AS_OS_STR,
-        &paths::PATH_BUF_AS_PATH,
-        &paths::STRING_AS_STR,
-        &paths::STRING_AS_MUT_STR,
-        &paths::VEC_AS_SLICE,
-        &paths::VEC_AS_MUT_SLICE,
+    let deref_aliases: [Symbol; 7] = [
+        sym::cstring_as_c_str,
+        sym::os_string_as_os_str,
+        sym::pathbuf_as_path,
+        sym::string_as_str,
+        sym::string_as_mut_str,
+        sym::vec_as_slice,
+        sym::vec_as_mut_slice,
     ];
 
     let is_deref = match map_arg.kind {
@@ -48,7 +48,7 @@ pub(super) fn check(
                 .map_or(false, |fun_def_id| {
                     cx.tcx.is_diagnostic_item(sym::deref_method, fun_def_id)
                         || cx.tcx.is_diagnostic_item(sym::deref_mut_method, fun_def_id)
-                        || deref_aliases.iter().any(|path| match_def_path(cx, fun_def_id, path))
+                        || deref_aliases.iter().any(|&sym| cx.tcx.is_diagnostic_item(sym, fun_def_id))
                 })
         },
         hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
@@ -69,7 +69,7 @@ pub(super) fn check(
                         let method_did = cx.typeck_results().type_dependent_def_id(closure_expr.hir_id).unwrap();
                         cx.tcx.is_diagnostic_item(sym::deref_method, method_did)
                             || cx.tcx.is_diagnostic_item(sym::deref_mut_method, method_did)
-                            || deref_aliases.iter().any(|path| match_def_path(cx, method_did, path))
+                            || deref_aliases.iter().any(|&sym| cx.tcx.is_diagnostic_item(sym, method_did))
                     } else {
                         false
                     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs b/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs
index e45c7962f13..8bc535ac47a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/seek_from_current.rs
@@ -8,7 +8,7 @@ use rustc_span::sym;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::ty::implements_trait;
-use clippy_utils::{match_def_path, paths};
+use clippy_utils::is_enum_variant_ctor;
 
 use super::SEEK_FROM_CURRENT;
 
@@ -36,8 +36,8 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'
 fn arg_is_seek_from_current<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) -> bool {
     if let ExprKind::Call(f, args) = expr.kind
         && let ExprKind::Path(ref path) = f.kind
-        && let Some(def_id) = cx.qpath_res(path, f.hir_id).opt_def_id()
-        && match_def_path(cx, def_id, &paths::STD_IO_SEEK_FROM_CURRENT)
+        && let Some(ctor_call_id) = cx.qpath_res(path, f.hir_id).opt_def_id()
+        && is_enum_variant_ctor(cx, sym::SeekFrom, sym!(Current), ctor_call_id)
     {
         // check if argument of `SeekFrom::Current` is `0`
         if args.len() == 1
diff --git a/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs b/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs
index cc4cb47e35c..7c09cc252e1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/seek_to_start_instead_of_rewind.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::ty::implements_trait;
-use clippy_utils::{is_expr_used_or_unified, match_def_path, paths};
+use clippy_utils::{is_expr_used_or_unified, is_enum_variant_ctor};
 use rustc_ast::ast::{LitIntType, LitKind};
 use rustc_data_structures::packed::Pu128;
 use rustc_errors::Applicability;
@@ -28,8 +28,8 @@ pub(super) fn check<'tcx>(
         && implements_trait(cx, ty, seek_trait_id, &[])
         && let ExprKind::Call(func, args1) = arg.kind
         && let ExprKind::Path(ref path) = func.kind
-        && let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id()
-        && match_def_path(cx, def_id, &paths::STD_IO_SEEKFROM_START)
+        && let Some(ctor_call_id) = cx.qpath_res(path, func.hir_id).opt_def_id()
+        && is_enum_variant_ctor(cx, sym::SeekFrom, sym!(Start), ctor_call_id)
         && args1.len() == 1
         && let ExprKind::Lit(lit) = args1[0].kind
         && let LitKind::Int(Pu128(0), LitIntType::Unsuffixed) = lit.node
diff --git a/src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs b/src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs
index 81450fd8c6c..ccdf5529d53 100644
--- a/src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/single_char_add_str.rs
@@ -1,13 +1,13 @@
 use crate::methods::{single_char_insert_string, single_char_push_string};
-use clippy_utils::{match_def_path, paths};
 use rustc_hir as hir;
 use rustc_lint::LateContext;
+use rustc_span::sym;
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, receiver: &hir::Expr<'_>, args: &[hir::Expr<'_>]) {
     if let Some(fn_def_id) = cx.typeck_results().type_dependent_def_id(expr.hir_id) {
-        if match_def_path(cx, fn_def_id, &paths::PUSH_STR) {
+        if cx.tcx.is_diagnostic_item(sym::string_push_str, fn_def_id) {
             single_char_push_string::check(cx, expr, receiver, args);
-        } else if match_def_path(cx, fn_def_id, &paths::INSERT_STR) {
+        } else if cx.tcx.is_diagnostic_item(sym::string_insert_str, fn_def_id) {
             single_char_insert_string::check(cx, expr, receiver, args);
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index 69c5bc57e29..bf7555a29e2 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -6,7 +6,7 @@ use clippy_utils::source::{snippet, SpanRangeExt};
 use clippy_utils::ty::{get_iterator_item_ty, implements_trait, is_copy, is_type_diagnostic_item, is_type_lang_item};
 use clippy_utils::visitors::find_all_ret_expressions;
 use clippy_utils::{
-    fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, match_def_path, paths, peel_middle_ty_refs,
+    fn_def_id, get_parent_expr, is_diag_item_method, is_diag_trait_item, peel_middle_ty_refs,
     return_ty,
 };
 use rustc_errors::Applicability;
@@ -250,7 +250,7 @@ fn check_string_from_utf8<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>,
     if let Some((call, arg)) = skip_addr_of_ancestors(cx, expr)
         && !arg.span.from_expansion()
         && let ExprKind::Call(callee, _) = call.kind
-        && fn_def_id(cx, call).is_some_and(|did| match_def_path(cx, did, &paths::STRING_FROM_UTF8))
+        && fn_def_id(cx, call).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::string_from_utf8, did))
         && let Some(unwrap_call) = get_parent_expr(cx, call)
         && let ExprKind::MethodCall(unwrap_method_name, ..) = unwrap_call.kind
         && matches!(unwrap_method_name.ident.name, sym::unwrap | sym::expect)
diff --git a/src/tools/clippy/clippy_lints/src/methods/waker_clone_wake.rs b/src/tools/clippy/clippy_lints/src/methods/waker_clone_wake.rs
index da66632d55f..9b64cc7589c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/waker_clone_wake.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/waker_clone_wake.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::{is_trait_method, match_def_path, paths};
+use clippy_utils::is_trait_method;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::LateContext;
@@ -12,7 +12,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'
     let ty = cx.typeck_results().expr_ty(recv);
 
     if let Some(did) = ty.ty_adt_def()
-        && match_def_path(cx, did.did(), &paths::WAKER)
+        && cx.tcx.is_diagnostic_item(sym::Waker, did.did())
         && let ExprKind::MethodCall(_, waker_ref, &[], _) = recv.kind
         && is_trait_method(cx, recv, sym::Clone)
     {
diff --git a/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs b/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs
index b915df52762..cfc15d92715 100644
--- a/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs
+++ b/src/tools/clippy/clippy_lints/src/non_octal_unix_permissions.rs
@@ -1,6 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::{snippet_with_applicability, SpanRangeExt};
-use clippy_utils::{match_def_path, paths};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -63,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for NonOctalUnixPermissions {
             ExprKind::Call(func, [param]) => {
                 if let ExprKind::Path(ref path) = func.kind
                     && let Some(def_id) = cx.qpath_res(path, func.hir_id).opt_def_id()
-                    && match_def_path(cx, def_id, &paths::PERMISSIONS_FROM_MODE)
+                    && cx.tcx.is_diagnostic_item(sym::permissions_from_mode, def_id)
                     && let ExprKind::Lit(_) = param.kind
                     && param.span.eq_ctxt(expr.span)
                     && param
diff --git a/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs b/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs
index cace85a2451..be97ad389bf 100644
--- a/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/float_equality_without_abs.rs
@@ -1,12 +1,12 @@
 use clippy_utils::diagnostics::span_lint_and_then;
-use clippy_utils::{match_def_path, paths, sugg};
+use clippy_utils::sugg;
 use rustc_ast::util::parser::AssocOp;
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{BinOpKind, Expr, ExprKind};
 use rustc_lint::LateContext;
 use rustc_middle::ty;
-use rustc_span::source_map::Spanned;
+use rustc_span::{sym, source_map::Spanned};
 
 use super::FLOAT_EQUALITY_WITHOUT_ABS;
 
@@ -36,7 +36,7 @@ pub(crate) fn check<'tcx>(
         // right hand side matches either f32::EPSILON or f64::EPSILON
         && let ExprKind::Path(ref epsilon_path) = rhs.kind
         && let Res::Def(DefKind::AssocConst, def_id) = cx.qpath_res(epsilon_path, rhs.hir_id)
-        && (match_def_path(cx, def_id, &paths::F32_EPSILON) || match_def_path(cx, def_id, &paths::F64_EPSILON))
+        && ([sym::f32_epsilon, sym::f64_epsilon].into_iter().any(|sym| cx.tcx.is_diagnostic_item(sym, def_id)))
 
         // values of the subtractions on the left hand side are of the type float
         && let t_val_l = cx.typeck_results().expr_ty(val_l)
diff --git a/src/tools/clippy/clippy_lints/src/redundant_clone.rs b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
index bfdc1cbeed7..4e24ddad83a 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_clone.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::{span_lint_hir, span_lint_hir_and_then};
 use clippy_utils::mir::{visit_local_usage, LocalUsage, PossibleBorrowerMap};
 use clippy_utils::source::SpanRangeExt;
 use clippy_utils::ty::{has_drop, is_copy, is_type_diagnostic_item, is_type_lang_item, walk_ptrs_ty_depth};
-use clippy_utils::{fn_has_unsatisfiable_preds, match_def_path, paths};
+use clippy_utils::fn_has_unsatisfiable_preds;
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{def_id, Body, FnDecl, LangItem};
@@ -102,8 +102,8 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClone {
                     && is_type_lang_item(cx, arg_ty, LangItem::String));
 
             let from_deref = !from_borrow
-                && (match_def_path(cx, fn_def_id, &paths::PATH_TO_PATH_BUF)
-                    || match_def_path(cx, fn_def_id, &paths::OS_STR_TO_OS_STRING));
+                && (cx.tcx.is_diagnostic_item(sym::path_to_pathbuf, fn_def_id)
+                    || cx.tcx.is_diagnostic_item(sym::os_str_to_os_string, fn_def_id));
 
             if !from_borrow && !from_deref {
                 continue;
diff --git a/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs b/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
index 678681ea425..08de10f69b0 100644
--- a/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
+++ b/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
@@ -3,7 +3,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::higher::VecArgs;
 use clippy_utils::macros::matching_root_macro_call;
 use clippy_utils::source::snippet;
-use clippy_utils::{expr_or_init, fn_def_id, match_def_path, paths};
+use clippy_utils::{expr_or_init, fn_def_id};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
@@ -67,7 +67,7 @@ fn emit_lint(cx: &LateContext<'_>, span: Span, kind: &str, note: &'static str, s
 fn check_vec_macro(cx: &LateContext<'_>, expr: &Expr<'_>) {
     if matching_root_macro_call(cx, expr.span, sym::vec_macro).is_some()
         && let Some(VecArgs::Repeat(repeat_expr, len_expr)) = VecArgs::hir(cx, expr)
-        && fn_def_id(cx, repeat_expr).is_some_and(|did| match_def_path(cx, did, &paths::VEC_WITH_CAPACITY))
+        && fn_def_id(cx, repeat_expr).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::vec_with_capacity, did))
         && !len_expr.span.from_expansion()
         && let Some(Constant::Int(2..)) = ConstEvalCtxt::new(cx).eval(expr_or_init(cx, len_expr))
     {
@@ -91,7 +91,7 @@ fn check_repeat_fn(cx: &LateContext<'_>, expr: &Expr<'_>) {
     if !expr.span.from_expansion()
         && fn_def_id(cx, expr).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::iter_repeat, did))
         && let ExprKind::Call(_, [repeat_expr]) = expr.kind
-        && fn_def_id(cx, repeat_expr).is_some_and(|did| match_def_path(cx, did, &paths::VEC_WITH_CAPACITY))
+        && fn_def_id(cx, repeat_expr).is_some_and(|did| cx.tcx.is_diagnostic_item(sym::vec_with_capacity, did))
         && !repeat_expr.span.from_expansion()
     {
         emit_lint(
diff --git a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
index b0e25c02265..04c16281ec4 100644
--- a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
+++ b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
@@ -2,8 +2,8 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::matching_root_macro_call;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
-    get_enclosing_block, is_expr_path_def_path, is_integer_literal, is_path_diagnostic_item, path_to_local,
-    path_to_local_id, paths, SpanlessEq,
+    get_enclosing_block, is_integer_literal, is_path_diagnostic_item, path_to_local,
+    path_to_local_id, SpanlessEq,
 };
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_block, walk_expr, walk_stmt, Visitor};
@@ -150,10 +150,10 @@ impl SlowVectorInit {
         }
 
         if let ExprKind::Call(func, [len_expr]) = expr.kind
-            && is_expr_path_def_path(cx, func, &paths::VEC_WITH_CAPACITY)
+            && is_path_diagnostic_item(cx, func, sym::vec_with_capacity)
         {
             Some(InitializedSize::Initialized(len_expr))
-        } else if matches!(expr.kind, ExprKind::Call(func, _) if is_expr_path_def_path(cx, func, &paths::VEC_NEW)) {
+        } else if matches!(expr.kind, ExprKind::Call(func, _) if is_path_diagnostic_item(cx, func, sym::vec_new)) {
             Some(InitializedSize::Uninitialized)
         } else {
             None
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs b/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs
index 6b5e6c6ab20..f01cb457af8 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_owned_empty_strings.rs
@@ -1,6 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::ty::is_type_lang_item;
-use clippy_utils::{match_def_path, paths};
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
 use rustc_hir::{BorrowKind, Expr, ExprKind, LangItem, Mutability};
@@ -42,7 +41,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryOwnedEmptyStrings {
             && let ty::Ref(_, inner_str, _) = cx.typeck_results().expr_ty_adjusted(expr).kind()
             && inner_str.is_str()
         {
-            if match_def_path(cx, fun_def_id, &paths::STRING_NEW) {
+            if cx.tcx.is_diagnostic_item(sym::string_new, fun_def_id) {
                 span_lint_and_sugg(
                     cx,
                     UNNECESSARY_OWNED_EMPTY_STRINGS,
diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs
index 8970b4d1229..e09cc9edf3a 100644
--- a/src/tools/clippy/clippy_utils/src/higher.rs
+++ b/src/tools/clippy/clippy_utils/src/higher.rs
@@ -4,7 +4,7 @@
 
 use crate::consts::{ConstEvalCtxt, Constant};
 use crate::ty::is_type_diagnostic_item;
-use crate::{is_expn_of, match_def_path, paths};
+use crate::is_expn_of;
 
 use rustc_ast::ast;
 use rustc_hir as hir;
@@ -297,10 +297,10 @@ impl<'a> VecArgs<'a> {
             && is_expn_of(fun.span, "vec").is_some()
             && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()
         {
-            return if match_def_path(cx, fun_def_id, &paths::VEC_FROM_ELEM) && args.len() == 2 {
+            return if cx.tcx.is_diagnostic_item(sym::vec_from_elem, fun_def_id) && args.len() == 2 {
                 // `vec![elem; size]` case
                 Some(VecArgs::Repeat(&args[0], &args[1]))
-            } else if match_def_path(cx, fun_def_id, &paths::SLICE_INTO_VEC) && args.len() == 1 {
+            } else if cx.tcx.is_diagnostic_item(sym::slice_into_vec, fun_def_id) && args.len() == 1 {
                 // `vec![a, b, c]` case
                 if let ExprKind::Call(_, [arg]) = &args[0].kind
                     && let ExprKind::Array(args) = arg.kind
@@ -309,7 +309,7 @@ impl<'a> VecArgs<'a> {
                 } else {
                     None
                 }
-            } else if match_def_path(cx, fun_def_id, &paths::VEC_NEW) && args.is_empty() {
+            } else if cx.tcx.is_diagnostic_item(sym::vec_new, fun_def_id) && args.is_empty() {
                 Some(VecArgs::Vec(&[]))
             } else {
                 None
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 5db14872c36..0d0d6219c5e 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -263,24 +263,18 @@ pub fn is_res_lang_ctor(cx: &LateContext<'_>, res: Res, lang_item: LangItem) ->
     }
 }
 
-pub fn is_res_diagnostic_ctor(cx: &LateContext<'_>, res: Res, diag_item: Symbol) -> bool {
-    if let Res::Def(DefKind::Ctor(..), id) = res
-        && let Some(id) = cx.tcx.opt_parent(id)
-    {
-        cx.tcx.is_diagnostic_item(diag_item, id)
-    } else {
-        false
-    }
-}
 
-/// Checks if a `QPath` resolves to a constructor of a diagnostic item.
-pub fn is_diagnostic_ctor(cx: &LateContext<'_>, qpath: &QPath<'_>, diagnostic_item: Symbol) -> bool {
-    if let QPath::Resolved(_, path) = qpath {
-        if let Res::Def(DefKind::Ctor(..), ctor_id) = path.res {
-            return cx.tcx.is_diagnostic_item(diagnostic_item, cx.tcx.parent(ctor_id));
-        }
-    }
-    false
+/// Checks if `{ctor_call_id}(...)` is `{enum_item}::{variant_name}(...)`.
+pub fn is_enum_variant_ctor(cx: &LateContext<'_>, enum_item: Symbol, variant_name: Symbol, ctor_call_id: DefId) -> bool {
+    let Some(enum_def_id) = cx.tcx.get_diagnostic_item(enum_item) else {
+        return false;
+    };
+
+    let variants = cx.tcx.adt_def(enum_def_id).variants().iter();
+    variants
+        .filter(|variant| variant.name == variant_name)
+        .filter_map(|variant| variant.ctor.as_ref())
+        .any(|(_, ctor_def_id)| *ctor_def_id == ctor_call_id)
 }
 
 /// Checks if the `DefId` matches the given diagnostic item or it's constructor.
diff --git a/src/tools/clippy/clippy_utils/src/paths.rs b/src/tools/clippy/clippy_utils/src/paths.rs
index 684c645c199..a30edc48fff 100644
--- a/src/tools/clippy/clippy_utils/src/paths.rs
+++ b/src/tools/clippy/clippy_utils/src/paths.rs
@@ -4,6 +4,7 @@
 //! Whenever possible, please consider diagnostic items over hardcoded paths.
 //! See <https://github.com/rust-lang/rust-clippy/issues/5393> for more information.
 
+// Paths inside rustc
 pub const APPLICABILITY: [&str; 2] = ["rustc_lint_defs", "Applicability"];
 pub const APPLICABILITY_VALUES: [[&str; 3]; 4] = [
     ["rustc_lint_defs", "Applicability", "Unspecified"],
@@ -12,56 +13,36 @@ pub const APPLICABILITY_VALUES: [[&str; 3]; 4] = [
     ["rustc_lint_defs", "Applicability", "MachineApplicable"],
 ];
 pub const DIAG: [&str; 2] = ["rustc_errors", "Diag"];
-pub const BINARYHEAP_ITER: [&str; 5] = ["alloc", "collections", "binary_heap", "BinaryHeap", "iter"];
-pub const BTREEMAP_CONTAINS_KEY: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "contains_key"];
-pub const BTREEMAP_INSERT: [&str; 6] = ["alloc", "collections", "btree", "map", "BTreeMap", "insert"];
-pub const BTREESET_ITER: [&str; 6] = ["alloc", "collections", "btree", "set", "BTreeSet", "iter"];
-pub const CORE_ITER_CLONED: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "cloned"];
-pub const CORE_ITER_COPIED: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "copied"];
-pub const CORE_ITER_FILTER: [&str; 6] = ["core", "iter", "traits", "iterator", "Iterator", "filter"];
-pub const CORE_RESULT_OK_METHOD: [&str; 4] = ["core", "result", "Result", "ok"];
-pub const CSTRING_AS_C_STR: [&str; 5] = ["alloc", "ffi", "c_str", "CString", "as_c_str"];
 pub const EARLY_CONTEXT: [&str; 2] = ["rustc_lint", "EarlyContext"];
 pub const EARLY_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "EarlyLintPass"];
-pub const F32_EPSILON: [&str; 4] = ["core", "f32", "<impl f32>", "EPSILON"];
-pub const F64_EPSILON: [&str; 4] = ["core", "f64", "<impl f64>", "EPSILON"];
-pub const FILE_OPTIONS: [&str; 4] = ["std", "fs", "File", "options"];
-#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
-pub const FUTURES_IO_ASYNCREADEXT: [&str; 3] = ["futures_util", "io", "AsyncReadExt"];
-#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
-pub const FUTURES_IO_ASYNCWRITEEXT: [&str; 3] = ["futures_util", "io", "AsyncWriteExt"];
-pub const HASHMAP_CONTAINS_KEY: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "contains_key"];
-pub const HASHMAP_INSERT: [&str; 6] = ["std", "collections", "hash", "map", "HashMap", "insert"];
-pub const HASHMAP_ITER: [&str; 5] = ["std", "collections", "hash", "map", "Iter"];
-pub const HASHMAP_ITER_MUT: [&str; 5] = ["std", "collections", "hash", "map", "IterMut"];
-pub const HASHMAP_KEYS: [&str; 5] = ["std", "collections", "hash", "map", "Keys"];
-pub const HASHMAP_VALUES: [&str; 5] = ["std", "collections", "hash", "map", "Values"];
-pub const HASHMAP_DRAIN: [&str; 5] = ["std", "collections", "hash", "map", "Drain"];
-pub const HASHMAP_VALUES_MUT: [&str; 5] = ["std", "collections", "hash", "map", "ValuesMut"];
-pub const HASHSET_ITER_TY: [&str; 5] = ["std", "collections", "hash", "set", "Iter"];
-pub const HASHSET_ITER: [&str; 6] = ["std", "collections", "hash", "set", "HashSet", "iter"];
-pub const HASHSET_DRAIN: [&str; 5] = ["std", "collections", "hash", "set", "Drain"];
 pub const IDENT: [&str; 3] = ["rustc_span", "symbol", "Ident"];
 pub const IDENT_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Ident", "as_str"];
-pub const INSERT_STR: [&str; 4] = ["alloc", "string", "String", "insert_str"];
-pub const ITERTOOLS_NEXT_TUPLE: [&str; 3] = ["itertools", "Itertools", "next_tuple"];
 pub const KW_MODULE: [&str; 3] = ["rustc_span", "symbol", "kw"];
 pub const LATE_CONTEXT: [&str; 2] = ["rustc_lint", "LateContext"];
 pub const LATE_LINT_PASS: [&str; 3] = ["rustc_lint", "passes", "LateLintPass"];
 pub const LINT: [&str; 2] = ["rustc_lint_defs", "Lint"];
+pub const SYMBOL: [&str; 3] = ["rustc_span", "symbol", "Symbol"];
+pub const SYMBOL_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Symbol", "as_str"];
+pub const SYMBOL_INTERN: [&str; 4] = ["rustc_span", "symbol", "Symbol", "intern"];
+pub const SYMBOL_TO_IDENT_STRING: [&str; 4] = ["rustc_span", "symbol", "Symbol", "to_ident_string"];
+pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"];
+pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];
+
+// Paths in `core`/`alloc`/`std`. This should be avoided and cleaned up by adding diagnostic items.
+// ... none currently!
+
+// Paths in clippy itself
 pub const MSRV: [&str; 3] = ["clippy_config", "msrvs", "Msrv"];
-pub const OPEN_OPTIONS_NEW: [&str; 4] = ["std", "fs", "OpenOptions", "new"];
-pub const OS_STRING_AS_OS_STR: [&str; 5] = ["std", "ffi", "os_str", "OsString", "as_os_str"];
-pub const OS_STR_TO_OS_STRING: [&str; 5] = ["std", "ffi", "os_str", "OsStr", "to_os_string"];
+
+// Paths in external crates
+#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
+pub const FUTURES_IO_ASYNCREADEXT: [&str; 3] = ["futures_util", "io", "AsyncReadExt"];
+#[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
+pub const FUTURES_IO_ASYNCWRITEEXT: [&str; 3] = ["futures_util", "io", "AsyncWriteExt"];
+pub const ITERTOOLS_NEXT_TUPLE: [&str; 3] = ["itertools", "Itertools", "next_tuple"];
 pub const PARKING_LOT_MUTEX_GUARD: [&str; 3] = ["lock_api", "mutex", "MutexGuard"];
 pub const PARKING_LOT_RWLOCK_READ_GUARD: [&str; 3] = ["lock_api", "rwlock", "RwLockReadGuard"];
 pub const PARKING_LOT_RWLOCK_WRITE_GUARD: [&str; 3] = ["lock_api", "rwlock", "RwLockWriteGuard"];
-pub const PATH_BUF_AS_PATH: [&str; 4] = ["std", "path", "PathBuf", "as_path"];
-pub const PATH_MAIN_SEPARATOR: [&str; 3] = ["std", "path", "MAIN_SEPARATOR"];
-pub const PATH_TO_PATH_BUF: [&str; 4] = ["std", "path", "Path", "to_path_buf"];
-#[cfg_attr(not(unix), allow(clippy::invalid_paths))]
-pub const PERMISSIONS_FROM_MODE: [&str; 6] = ["std", "os", "unix", "fs", "PermissionsExt", "from_mode"];
-pub const PUSH_STR: [&str; 4] = ["alloc", "string", "String", "push_str"];
 pub const REGEX_BUILDER_NEW: [&str; 3] = ["regex", "RegexBuilder", "new"];
 pub const REGEX_BYTES_BUILDER_NEW: [&str; 4] = ["regex", "bytes", "RegexBuilder", "new"];
 pub const REGEX_BYTES_NEW: [&str; 4] = ["regex", "bytes", "Regex", "new"];
@@ -70,24 +51,6 @@ pub const REGEX_NEW: [&str; 3] = ["regex", "Regex", "new"];
 pub const REGEX_SET_NEW: [&str; 3] = ["regex", "RegexSet", "new"];
 pub const SERDE_DESERIALIZE: [&str; 3] = ["serde", "de", "Deserialize"];
 pub const SERDE_DE_VISITOR: [&str; 3] = ["serde", "de", "Visitor"];
-pub const SLICE_INTO_VEC: [&str; 4] = ["alloc", "slice", "<impl [T]>", "into_vec"];
-pub const SLICE_INTO: [&str; 4] = ["core", "slice", "<impl [T]>", "iter"];
-pub const STD_IO_SEEK_FROM_CURRENT: [&str; 4] = ["std", "io", "SeekFrom", "Current"];
-pub const STD_IO_SEEKFROM_START: [&str; 4] = ["std", "io", "SeekFrom", "Start"];
-pub const STRING_AS_MUT_STR: [&str; 4] = ["alloc", "string", "String", "as_mut_str"];
-pub const STRING_AS_STR: [&str; 4] = ["alloc", "string", "String", "as_str"];
-pub const STRING_NEW: [&str; 4] = ["alloc", "string", "String", "new"];
-pub const STR_CHARS: [&str; 4] = ["core", "str", "<impl str>", "chars"];
-pub const STR_ENDS_WITH: [&str; 4] = ["core", "str", "<impl str>", "ends_with"];
-pub const STR_LEN: [&str; 4] = ["core", "str", "<impl str>", "len"];
-pub const STR_STARTS_WITH: [&str; 4] = ["core", "str", "<impl str>", "starts_with"];
-pub const SYMBOL: [&str; 3] = ["rustc_span", "symbol", "Symbol"];
-pub const SYMBOL_AS_STR: [&str; 4] = ["rustc_span", "symbol", "Symbol", "as_str"];
-pub const SYMBOL_INTERN: [&str; 4] = ["rustc_span", "symbol", "Symbol", "intern"];
-pub const SYMBOL_TO_IDENT_STRING: [&str; 4] = ["rustc_span", "symbol", "Symbol", "to_ident_string"];
-pub const SYM_MODULE: [&str; 3] = ["rustc_span", "symbol", "sym"];
-pub const SYNTAX_CONTEXT: [&str; 3] = ["rustc_span", "hygiene", "SyntaxContext"];
-pub const STRING_FROM_UTF8: [&str; 4] = ["alloc", "string", "String", "from_utf8"];
 #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const TOKIO_FILE_OPTIONS: [&str; 5] = ["tokio", "fs", "file", "File", "options"];
 #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
@@ -98,16 +61,3 @@ pub const TOKIO_IO_ASYNCWRITEEXT: [&str; 5] = ["tokio", "io", "util", "async_wri
 pub const TOKIO_IO_OPEN_OPTIONS: [&str; 4] = ["tokio", "fs", "open_options", "OpenOptions"];
 #[expect(clippy::invalid_paths)] // internal lints do not know about all external crates
 pub const TOKIO_IO_OPEN_OPTIONS_NEW: [&str; 5] = ["tokio", "fs", "open_options", "OpenOptions", "new"];
-pub const VEC_AS_MUT_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_mut_slice"];
-pub const VEC_AS_SLICE: [&str; 4] = ["alloc", "vec", "Vec", "as_slice"];
-pub const VEC_DEQUE_ITER: [&str; 5] = ["alloc", "collections", "vec_deque", "VecDeque", "iter"];
-pub const VEC_FROM_ELEM: [&str; 3] = ["alloc", "vec", "from_elem"];
-pub const VEC_NEW: [&str; 4] = ["alloc", "vec", "Vec", "new"];
-pub const VEC_WITH_CAPACITY: [&str; 4] = ["alloc", "vec", "Vec", "with_capacity"];
-pub const INSTANT_NOW: [&str; 4] = ["std", "time", "Instant", "now"];
-pub const VEC_IS_EMPTY: [&str; 4] = ["alloc", "vec", "Vec", "is_empty"];
-pub const VEC_POP: [&str; 4] = ["alloc", "vec", "Vec", "pop"];
-pub const WAKER: [&str; 4] = ["core", "task", "wake", "Waker"];
-pub const OPTION_UNWRAP: [&str; 4] = ["core", "option", "Option", "unwrap"];
-pub const OPTION_EXPECT: [&str; 4] = ["core", "option", "Option", "expect"];
-pub const BOOL_THEN: [&str; 4] = ["core", "bool", "<impl bool>", "then"];
diff --git a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
index f7e338935a7..d92c03f4888 100644
--- a/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
+++ b/src/tools/clippy/tests/ui/checked_unwrap/simple_conditionals.stderr
@@ -236,5 +236,16 @@ LL |     if result.is_ok() {
 LL |         result.as_mut().unwrap();
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 25 previous errors
+error: creating a shared reference to mutable static is discouraged
+  --> tests/ui/checked_unwrap/simple_conditionals.rs:174:12
+   |
+LL |         if X.is_some() {
+   |            ^^^^^^^^^^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+   = note: `-D static-mut-refs` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(static_mut_refs)]`
+
+error: aborting due to 26 previous errors
 
diff --git a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
index 6b8a103d4a9..87d3517cd5f 100644
--- a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
+++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.rs
@@ -4,6 +4,7 @@
 #![allow(deref_nullptr)]
 #![allow(clippy::unnecessary_operation)]
 #![allow(dropping_copy_types)]
+#![allow(clippy::assign_op_pattern)]
 #![warn(clippy::multiple_unsafe_ops_per_block)]
 
 extern crate proc_macros;
diff --git a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr
index e732bde0707..a9417a9ef91 100644
--- a/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr
+++ b/src/tools/clippy/tests/ui/multiple_unsafe_ops_per_block.stderr
@@ -1,5 +1,5 @@
 error: this `unsafe` block contains 2 unsafe operations, expected only one
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:37:5
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:38:5
    |
 LL | /     unsafe {
 LL | |         STATIC += 1;
@@ -8,12 +8,12 @@ LL | |     }
    | |_____^
    |
 note: modification of a mutable static occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:38:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:39:9
    |
 LL |         STATIC += 1;
    |         ^^^^^^^^^^^
 note: unsafe function call occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:39:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:40:9
    |
 LL |         not_very_safe();
    |         ^^^^^^^^^^^^^^^
@@ -21,7 +21,7 @@ LL |         not_very_safe();
    = help: to override `-D warnings` add `#[allow(clippy::multiple_unsafe_ops_per_block)]`
 
 error: this `unsafe` block contains 2 unsafe operations, expected only one
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:46:5
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:47:5
    |
 LL | /     unsafe {
 LL | |         drop(u.u);
@@ -30,18 +30,18 @@ LL | |     }
    | |_____^
    |
 note: union field access occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:47:14
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:48:14
    |
 LL |         drop(u.u);
    |              ^^^
 note: raw pointer dereference occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:48:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:49:9
    |
 LL |         *raw_ptr();
    |         ^^^^^^^^^^
 
 error: this `unsafe` block contains 3 unsafe operations, expected only one
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:53:5
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:54:5
    |
 LL | /     unsafe {
 LL | |         asm!("nop");
@@ -51,23 +51,23 @@ LL | |     }
    | |_____^
    |
 note: inline assembly used here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:54:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:55:9
    |
 LL |         asm!("nop");
    |         ^^^^^^^^^^^
 note: unsafe method call occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:55:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:56:9
    |
 LL |         sample.not_very_safe();
    |         ^^^^^^^^^^^^^^^^^^^^^^
 note: modification of a mutable static occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:56:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:57:9
    |
 LL |         STATIC = 0;
    |         ^^^^^^^^^^
 
 error: this `unsafe` block contains 6 unsafe operations, expected only one
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:62:5
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:63:5
    |
 LL | /     unsafe {
 LL | |         drop(u.u);
@@ -79,55 +79,55 @@ LL | |     }
    | |_____^
    |
 note: union field access occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:63:14
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:64:14
    |
 LL |         drop(u.u);
    |              ^^^
 note: access of a mutable static occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:64:14
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:65:14
    |
 LL |         drop(STATIC);
    |              ^^^^^^
 note: unsafe method call occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:65:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:66:9
    |
 LL |         sample.not_very_safe();
    |         ^^^^^^^^^^^^^^^^^^^^^^
 note: unsafe function call occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:66:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:67:9
    |
 LL |         not_very_safe();
    |         ^^^^^^^^^^^^^^^
 note: raw pointer dereference occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:67:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:68:9
    |
 LL |         *raw_ptr();
    |         ^^^^^^^^^^
 note: inline assembly used here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:68:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:69:9
    |
 LL |         asm!("nop");
    |         ^^^^^^^^^^^
 
 error: this `unsafe` block contains 2 unsafe operations, expected only one
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:106:5
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:107:5
    |
 LL |     unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: unsafe function call occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:106:14
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:107:14
    |
 LL |     unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: raw pointer dereference occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:106:39
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:107:39
    |
 LL |     unsafe { char::from_u32_unchecked(*ptr.cast::<u32>()) }
    |                                       ^^^^^^^^^^^^^^^^^^
 
 error: this `unsafe` block contains 2 unsafe operations, expected only one
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:124:5
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:125:5
    |
 LL | /     unsafe {
 LL | |         x();
@@ -136,18 +136,18 @@ LL | |     }
    | |_____^
    |
 note: unsafe function call occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:125:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:126:9
    |
 LL |         x();
    |         ^^^
 note: unsafe function call occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:126:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:127:9
    |
 LL |         x();
    |         ^^^
 
 error: this `unsafe` block contains 2 unsafe operations, expected only one
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:135:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:136:9
    |
 LL | /         unsafe {
 LL | |             T::X();
@@ -156,18 +156,18 @@ LL | |         }
    | |_________^
    |
 note: unsafe function call occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:136:13
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:137:13
    |
 LL |             T::X();
    |             ^^^^^^
 note: unsafe function call occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:137:13
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:138:13
    |
 LL |             T::X();
    |             ^^^^^^
 
 error: this `unsafe` block contains 2 unsafe operations, expected only one
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:145:5
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:146:5
    |
 LL | /     unsafe {
 LL | |         x.0();
@@ -176,12 +176,12 @@ LL | |     }
    | |_____^
    |
 note: unsafe function call occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:146:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:147:9
    |
 LL |         x.0();
    |         ^^^^^
 note: unsafe function call occurs here
-  --> tests/ui/multiple_unsafe_ops_per_block.rs:147:9
+  --> tests/ui/multiple_unsafe_ops_per_block.rs:148:9
    |
 LL |         x.0();
    |         ^^^^^
diff --git a/src/tools/clippy/tests/ui/must_use_candidates.fixed b/src/tools/clippy/tests/ui/must_use_candidates.fixed
index c057eba4aca..adb266ffbc8 100644
--- a/src/tools/clippy/tests/ui/must_use_candidates.fixed
+++ b/src/tools/clippy/tests/ui/must_use_candidates.fixed
@@ -1,5 +1,10 @@
 #![feature(never_type)]
-#![allow(unused_mut, clippy::redundant_allocation, clippy::needless_pass_by_ref_mut)]
+#![allow(
+    unused_mut,
+    clippy::redundant_allocation,
+    clippy::needless_pass_by_ref_mut,
+    static_mut_refs
+)]
 #![warn(clippy::must_use_candidate)]
 use std::rc::Rc;
 use std::sync::atomic::{AtomicBool, Ordering};
diff --git a/src/tools/clippy/tests/ui/must_use_candidates.rs b/src/tools/clippy/tests/ui/must_use_candidates.rs
index 36019652006..49bb16af788 100644
--- a/src/tools/clippy/tests/ui/must_use_candidates.rs
+++ b/src/tools/clippy/tests/ui/must_use_candidates.rs
@@ -1,5 +1,10 @@
 #![feature(never_type)]
-#![allow(unused_mut, clippy::redundant_allocation, clippy::needless_pass_by_ref_mut)]
+#![allow(
+    unused_mut,
+    clippy::redundant_allocation,
+    clippy::needless_pass_by_ref_mut,
+    static_mut_refs
+)]
 #![warn(clippy::must_use_candidate)]
 use std::rc::Rc;
 use std::sync::atomic::{AtomicBool, Ordering};
diff --git a/src/tools/clippy/tests/ui/must_use_candidates.stderr b/src/tools/clippy/tests/ui/must_use_candidates.stderr
index c64636ba442..2117e37866e 100644
--- a/src/tools/clippy/tests/ui/must_use_candidates.stderr
+++ b/src/tools/clippy/tests/ui/must_use_candidates.stderr
@@ -1,5 +1,5 @@
 error: this function could have a `#[must_use]` attribute
-  --> tests/ui/must_use_candidates.rs:11:1
+  --> tests/ui/must_use_candidates.rs:16:1
    |
 LL | pub fn pure(i: u8) -> u8 {
    | ^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn pure(i: u8) -> u8`
@@ -8,25 +8,25 @@ LL | pub fn pure(i: u8) -> u8 {
    = help: to override `-D warnings` add `#[allow(clippy::must_use_candidate)]`
 
 error: this method could have a `#[must_use]` attribute
-  --> tests/ui/must_use_candidates.rs:16:5
+  --> tests/ui/must_use_candidates.rs:21:5
    |
 LL |     pub fn inherent_pure(&self) -> u8 {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn inherent_pure(&self) -> u8`
 
 error: this function could have a `#[must_use]` attribute
-  --> tests/ui/must_use_candidates.rs:47:1
+  --> tests/ui/must_use_candidates.rs:52:1
    |
 LL | pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn with_marker(_d: std::marker::PhantomData<&mut u32>) -> bool`
 
 error: this function could have a `#[must_use]` attribute
-  --> tests/ui/must_use_candidates.rs:59:1
+  --> tests/ui/must_use_candidates.rs:64:1
    |
 LL | pub fn rcd(_x: Rc<u32>) -> bool {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn rcd(_x: Rc<u32>) -> bool`
 
 error: this function could have a `#[must_use]` attribute
-  --> tests/ui/must_use_candidates.rs:67:1
+  --> tests/ui/must_use_candidates.rs:72:1
    |
 LL | pub fn arcd(_x: Arc<u32>) -> bool {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: add the attribute: `#[must_use] pub fn arcd(_x: Arc<u32>) -> bool`
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed b/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
index 9787bb635e7..3d1c78bd12d 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
@@ -1,4 +1,6 @@
 #![allow(unused)]
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
 
 #[derive(Debug)]
 struct Foo;
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs b/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
index b5a4827fa94..5932f14b8d9 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
@@ -1,4 +1,6 @@
 #![allow(unused)]
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
 
 #[derive(Debug)]
 struct Foo;
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr b/src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr
index 5c5e2f2a573..48871eba2dc 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.stderr
@@ -1,5 +1,5 @@
 error: constants have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:6:17
+  --> tests/ui/redundant_static_lifetimes.rs:8:17
    |
 LL | const VAR_ONE: &'static str = "Test constant #1"; // ERROR: Consider removing 'static.
    |                -^^^^^^^---- help: consider removing `'static`: `&str`
@@ -8,103 +8,103 @@ LL | const VAR_ONE: &'static str = "Test constant #1"; // ERROR: Consider removi
    = help: to override `-D warnings` add `#[allow(clippy::redundant_static_lifetimes)]`
 
 error: constants have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:10:21
+  --> tests/ui/redundant_static_lifetimes.rs:12:21
    |
 LL | const VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static
    |                    -^^^^^^^---- help: consider removing `'static`: `&str`
 
 error: constants have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:12:32
+  --> tests/ui/redundant_static_lifetimes.rs:14:32
    |
 LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static
    |                               -^^^^^^^---- help: consider removing `'static`: `&str`
 
 error: constants have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:12:47
+  --> tests/ui/redundant_static_lifetimes.rs:14:47
    |
 LL | const VAR_FOUR: (&str, (&str, &'static str), &'static str) = ("on", ("th", "th"), "on"); // ERROR: Consider removing 'static
    |                                              -^^^^^^^---- help: consider removing `'static`: `&str`
 
 error: constants have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:14:17
+  --> tests/ui/redundant_static_lifetimes.rs:16:17
    |
 LL | const VAR_SIX: &'static u8 = &5;
    |                -^^^^^^^--- help: consider removing `'static`: `&u8`
 
 error: constants have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:16:20
+  --> tests/ui/redundant_static_lifetimes.rs:18:20
    |
 LL | const VAR_HEIGHT: &'static Foo = &Foo {};
    |                   -^^^^^^^---- help: consider removing `'static`: `&Foo`
 
 error: constants have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:18:19
+  --> tests/ui/redundant_static_lifetimes.rs:20:19
    |
 LL | const VAR_SLICE: &'static [u8] = b"Test constant #1"; // ERROR: Consider removing 'static.
    |                  -^^^^^^^----- help: consider removing `'static`: `&[u8]`
 
 error: constants have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:20:19
+  --> tests/ui/redundant_static_lifetimes.rs:22:19
    |
 LL | const VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static.
    |                  -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)`
 
 error: constants have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:22:19
+  --> tests/ui/redundant_static_lifetimes.rs:24:19
    |
 LL | const VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static.
    |                  -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]`
 
 error: statics have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:24:25
+  --> tests/ui/redundant_static_lifetimes.rs:26:25
    |
 LL | static STATIC_VAR_ONE: &'static str = "Test static #1"; // ERROR: Consider removing 'static.
    |                        -^^^^^^^---- help: consider removing `'static`: `&str`
 
 error: statics have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:28:29
+  --> tests/ui/redundant_static_lifetimes.rs:30:29
    |
 LL | static STATIC_VAR_THREE: &[&'static str] = &["one", "two"]; // ERROR: Consider removing 'static
    |                            -^^^^^^^---- help: consider removing `'static`: `&str`
 
 error: statics have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:30:25
+  --> tests/ui/redundant_static_lifetimes.rs:32:25
    |
 LL | static STATIC_VAR_SIX: &'static u8 = &5;
    |                        -^^^^^^^--- help: consider removing `'static`: `&u8`
 
 error: statics have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:32:28
+  --> tests/ui/redundant_static_lifetimes.rs:34:28
    |
 LL | static STATIC_VAR_HEIGHT: &'static Foo = &Foo {};
    |                           -^^^^^^^---- help: consider removing `'static`: `&Foo`
 
 error: statics have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:34:27
+  --> tests/ui/redundant_static_lifetimes.rs:36:27
    |
 LL | static STATIC_VAR_SLICE: &'static [u8] = b"Test static #3"; // ERROR: Consider removing 'static.
    |                          -^^^^^^^----- help: consider removing `'static`: `&[u8]`
 
 error: statics have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:36:27
+  --> tests/ui/redundant_static_lifetimes.rs:38:27
    |
 LL | static STATIC_VAR_TUPLE: &'static (u8, u8) = &(1, 2); // ERROR: Consider removing 'static.
    |                          -^^^^^^^--------- help: consider removing `'static`: `&(u8, u8)`
 
 error: statics have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:38:27
+  --> tests/ui/redundant_static_lifetimes.rs:40:27
    |
 LL | static STATIC_VAR_ARRAY: &'static [u8; 1] = b"T"; // ERROR: Consider removing 'static.
    |                          -^^^^^^^-------- help: consider removing `'static`: `&[u8; 1]`
 
 error: statics have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:40:31
+  --> tests/ui/redundant_static_lifetimes.rs:42:31
    |
 LL | static mut STATIC_MUT_SLICE: &'static mut [u32] = &mut [0];
    |                              -^^^^^^^---------- help: consider removing `'static`: `&mut [u32]`
 
 error: statics have by default a `'static` lifetime
-  --> tests/ui/redundant_static_lifetimes.rs:69:16
+  --> tests/ui/redundant_static_lifetimes.rs:71:16
    |
 LL |     static V: &'static u8 = &17;
    |               -^^^^^^^--- help: consider removing `'static`: `&u8`
diff --git a/src/tools/clippy/tests/ui/useless_conversion.fixed b/src/tools/clippy/tests/ui/useless_conversion.fixed
index ce00fde2f99..eff617a8016 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.fixed
+++ b/src/tools/clippy/tests/ui/useless_conversion.fixed
@@ -1,5 +1,7 @@
 #![deny(clippy::useless_conversion)]
 #![allow(clippy::needless_if, clippy::unnecessary_wraps)]
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
 
 fn test_generic<T: Copy>(val: T) -> T {
     let _ = val;
diff --git a/src/tools/clippy/tests/ui/useless_conversion.rs b/src/tools/clippy/tests/ui/useless_conversion.rs
index 39979619586..64b06620789 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.rs
+++ b/src/tools/clippy/tests/ui/useless_conversion.rs
@@ -1,5 +1,7 @@
 #![deny(clippy::useless_conversion)]
 #![allow(clippy::needless_if, clippy::unnecessary_wraps)]
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
 
 fn test_generic<T: Copy>(val: T) -> T {
     let _ = T::from(val);
diff --git a/src/tools/clippy/tests/ui/useless_conversion.stderr b/src/tools/clippy/tests/ui/useless_conversion.stderr
index 82f945c5e89..b149357bcf4 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.stderr
+++ b/src/tools/clippy/tests/ui/useless_conversion.stderr
@@ -1,5 +1,5 @@
 error: useless conversion to the same type: `T`
-  --> tests/ui/useless_conversion.rs:5:13
+  --> tests/ui/useless_conversion.rs:7:13
    |
 LL |     let _ = T::from(val);
    |             ^^^^^^^^^^^^ help: consider removing `T::from()`: `val`
@@ -11,217 +11,217 @@ LL | #![deny(clippy::useless_conversion)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: useless conversion to the same type: `T`
-  --> tests/ui/useless_conversion.rs:6:5
+  --> tests/ui/useless_conversion.rs:8:5
    |
 LL |     val.into()
    |     ^^^^^^^^^^ help: consider removing `.into()`: `val`
 
 error: useless conversion to the same type: `i32`
-  --> tests/ui/useless_conversion.rs:18:22
+  --> tests/ui/useless_conversion.rs:20:22
    |
 LL |         let _: i32 = 0i32.into();
    |                      ^^^^^^^^^^^ help: consider removing `.into()`: `0i32`
 
 error: useless conversion to the same type: `std::str::Lines<'_>`
-  --> tests/ui/useless_conversion.rs:48:22
+  --> tests/ui/useless_conversion.rs:50:22
    |
 LL |     if Some("ok") == lines.into_iter().next() {}
    |                      ^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `lines`
 
 error: useless conversion to the same type: `std::str::Lines<'_>`
-  --> tests/ui/useless_conversion.rs:53:21
+  --> tests/ui/useless_conversion.rs:55:21
    |
 LL |     let mut lines = text.lines().into_iter();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()`
 
 error: useless conversion to the same type: `std::str::Lines<'_>`
-  --> tests/ui/useless_conversion.rs:59:22
+  --> tests/ui/useless_conversion.rs:61:22
    |
 LL |     if Some("ok") == text.lines().into_iter().next() {}
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `text.lines()`
 
 error: useless conversion to the same type: `std::ops::Range<i32>`
-  --> tests/ui/useless_conversion.rs:65:13
+  --> tests/ui/useless_conversion.rs:67:13
    |
 LL |     let _ = NUMBERS.into_iter().next();
    |             ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS`
 
 error: useless conversion to the same type: `std::ops::Range<i32>`
-  --> tests/ui/useless_conversion.rs:70:17
+  --> tests/ui/useless_conversion.rs:72:17
    |
 LL |     let mut n = NUMBERS.into_iter();
    |                 ^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `NUMBERS`
 
 error: useless conversion to the same type: `std::string::String`
-  --> tests/ui/useless_conversion.rs:132:21
+  --> tests/ui/useless_conversion.rs:134:21
    |
 LL |     let _: String = "foo".to_string().into();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `"foo".to_string()`
 
 error: useless conversion to the same type: `std::string::String`
-  --> tests/ui/useless_conversion.rs:133:21
+  --> tests/ui/useless_conversion.rs:135:21
    |
 LL |     let _: String = From::from("foo".to_string());
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `From::from()`: `"foo".to_string()`
 
 error: useless conversion to the same type: `std::string::String`
-  --> tests/ui/useless_conversion.rs:134:13
+  --> tests/ui/useless_conversion.rs:136:13
    |
 LL |     let _ = String::from("foo".to_string());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `"foo".to_string()`
 
 error: useless conversion to the same type: `std::string::String`
-  --> tests/ui/useless_conversion.rs:135:13
+  --> tests/ui/useless_conversion.rs:137:13
    |
 LL |     let _ = String::from(format!("A: {:04}", 123));
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `String::from()`: `format!("A: {:04}", 123)`
 
 error: useless conversion to the same type: `std::str::Lines<'_>`
-  --> tests/ui/useless_conversion.rs:136:13
+  --> tests/ui/useless_conversion.rs:138:13
    |
 LL |     let _ = "".lines().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `"".lines()`
 
 error: useless conversion to the same type: `std::vec::IntoIter<i32>`
-  --> tests/ui/useless_conversion.rs:137:13
+  --> tests/ui/useless_conversion.rs:139:13
    |
 LL |     let _ = vec![1, 2, 3].into_iter().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![1, 2, 3].into_iter()`
 
 error: useless conversion to the same type: `std::string::String`
-  --> tests/ui/useless_conversion.rs:138:21
+  --> tests/ui/useless_conversion.rs:140:21
    |
 LL |     let _: String = format!("Hello {}", "world").into();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into()`: `format!("Hello {}", "world")`
 
 error: useless conversion to the same type: `i32`
-  --> tests/ui/useless_conversion.rs:143:13
+  --> tests/ui/useless_conversion.rs:145:13
    |
 LL |     let _ = i32::from(a + b) * 3;
    |             ^^^^^^^^^^^^^^^^ help: consider removing `i32::from()`: `(a + b)`
 
 error: useless conversion to the same type: `Foo<'a'>`
-  --> tests/ui/useless_conversion.rs:149:23
+  --> tests/ui/useless_conversion.rs:151:23
    |
 LL |     let _: Foo<'a'> = s2.into();
    |                       ^^^^^^^^^ help: consider removing `.into()`: `s2`
 
 error: useless conversion to the same type: `Foo<'a'>`
-  --> tests/ui/useless_conversion.rs:151:13
+  --> tests/ui/useless_conversion.rs:153:13
    |
 LL |     let _ = Foo::<'a'>::from(s3);
    |             ^^^^^^^^^^^^^^^^^^^^ help: consider removing `Foo::<'a'>::from()`: `s3`
 
 error: useless conversion to the same type: `std::vec::IntoIter<Foo<'a'>>`
-  --> tests/ui/useless_conversion.rs:153:13
+  --> tests/ui/useless_conversion.rs:155:13
    |
 LL |     let _ = vec![s4, s4, s4].into_iter().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![s4, s4, s4].into_iter()`
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:185:7
+  --> tests/ui/useless_conversion.rs:187:7
    |
 LL |     b(vec![1, 2].into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:175:13
+  --> tests/ui/useless_conversion.rs:177:13
    |
 LL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:186:7
+  --> tests/ui/useless_conversion.rs:188:7
    |
 LL |     c(vec![1, 2].into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:176:18
+  --> tests/ui/useless_conversion.rs:178:18
    |
 LL |     fn c(_: impl IntoIterator<Item = i32>) {}
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:187:7
+  --> tests/ui/useless_conversion.rs:189:7
    |
 LL |     d(vec![1, 2].into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:179:12
+  --> tests/ui/useless_conversion.rs:181:12
    |
 LL |         T: IntoIterator<Item = i32>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:190:7
+  --> tests/ui/useless_conversion.rs:192:7
    |
 LL |     b(vec![1, 2].into_iter().into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:175:13
+  --> tests/ui/useless_conversion.rs:177:13
    |
 LL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:191:7
+  --> tests/ui/useless_conversion.rs:193:7
    |
 LL |     b(vec![1, 2].into_iter().into_iter().into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:175:13
+  --> tests/ui/useless_conversion.rs:177:13
    |
 LL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:237:24
+  --> tests/ui/useless_conversion.rs:239:24
    |
 LL |         foo2::<i32, _>([1, 2, 3].into_iter());
    |                        ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:216:12
+  --> tests/ui/useless_conversion.rs:218:12
    |
 LL |         I: IntoIterator<Item = i32> + Helper<X>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:245:14
+  --> tests/ui/useless_conversion.rs:247:14
    |
 LL |         foo3([1, 2, 3].into_iter());
    |              ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:225:12
+  --> tests/ui/useless_conversion.rs:227:12
    |
 LL |         I: IntoIterator<Item = i32>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:254:16
+  --> tests/ui/useless_conversion.rs:256:16
    |
 LL |         S1.foo([1, 2].into_iter());
    |                ^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:251:27
+  --> tests/ui/useless_conversion.rs:253:27
    |
 LL |             pub fn foo<I: IntoIterator>(&self, _: I) {}
    |                           ^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> tests/ui/useless_conversion.rs:273:44
+  --> tests/ui/useless_conversion.rs:275:44
    |
 LL |         v0.into_iter().interleave_shortest(v1.into_iter());
    |                                            ^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `v1`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> tests/ui/useless_conversion.rs:260:20
+  --> tests/ui/useless_conversion.rs:262:20
    |
 LL |                 J: IntoIterator,
    |                    ^^^^^^^^^^^^
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 5c18179b6fe..414f9f3a7f1 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -183,6 +183,9 @@ pub struct Config {
     /// The rustc executable.
     pub rustc_path: PathBuf,
 
+    /// The cargo executable.
+    pub cargo_path: Option<PathBuf>,
+
     /// The rustdoc executable.
     pub rustdoc_path: Option<PathBuf>,
 
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 933913eb47c..93df6aa7255 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -125,7 +125,7 @@ pub struct TestProps {
     // Build documentation for all specified aux-builds as well
     pub build_aux_docs: bool,
     /// Build the documentation for each crate in a unique output directory.
-    /// Uses <root output directory>/docs/<test name>/doc
+    /// Uses `<root output directory>/docs/<test name>/doc`.
     pub unique_doc_out_dir: bool,
     // Flag to force a crate to be built with the host architecture
     pub force_host: bool,
@@ -1304,12 +1304,12 @@ pub fn llvm_has_libzstd(config: &Config) -> bool {
     false
 }
 
-/// Takes a directive of the form "<version1> [- <version2>]",
-/// returns the numeric representation of <version1> and <version2> as
-/// tuple: (<version1> as u32, <version2> as u32)
+/// Takes a directive of the form `"<version1> [- <version2>]"`,
+/// returns the numeric representation of `<version1>` and `<version2>` as
+/// tuple: `(<version1> as u32, <version2> as u32)`.
 ///
-/// If the <version2> part is omitted, the second component of the tuple
-/// is the same as <version1>.
+/// If the `<version2>` part is omitted, the second component of the tuple
+/// is the same as `<version1>`.
 fn extract_version_range<F>(line: &str, parse: F) -> Option<(u32, u32)>
 where
     F: Fn(&str) -> Option<u32>,
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index 250b5084d13..3339116d542 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -47,6 +47,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
     opts.reqopt("", "compile-lib-path", "path to host shared libraries", "PATH")
         .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("", "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")
@@ -260,6 +261,7 @@ pub fn parse_config(args: Vec<String>) -> Config {
         compile_lib_path: make_absolute(opt_path(matches, "compile-lib-path")),
         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),
         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(),
@@ -364,6 +366,7 @@ pub fn log_config(config: &Config) {
     logv(c, format!("compile_lib_path: {:?}", config.compile_lib_path));
     logv(c, format!("run_lib_path: {:?}", config.run_lib_path));
     logv(c, format!("rustc_path: {:?}", config.rustc_path.display()));
+    logv(c, format!("cargo_path: {:?}", config.cargo_path));
     logv(c, format!("rustdoc_path: {:?}", config.rustdoc_path));
     logv(c, format!("src_base: {:?}", config.src_base.display()));
     logv(c, format!("build_base: {:?}", config.build_base.display()));
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index c18f569e528..7b23aa34639 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2,8 +2,8 @@
 
 use std::borrow::Cow;
 use std::collections::{HashMap, HashSet};
-use std::ffi::{OsStr, OsString};
-use std::fs::{self, create_dir_all, File, OpenOptions};
+use std::ffi::OsString;
+use std::fs::{self, create_dir_all, File};
 use std::hash::{DefaultHasher, Hash, Hasher};
 use std::io::prelude::*;
 use std::io::{self, BufReader};
@@ -14,10 +14,7 @@ use std::{env, iter, str};
 
 use anyhow::Context;
 use colored::Colorize;
-use glob::glob;
-use miropt_test_tools::{files_for_miropt_test, MiroptTest, MiroptTestFile};
 use regex::{Captures, Regex};
-use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
 use tracing::*;
 
 use crate::common::{
@@ -31,12 +28,29 @@ use crate::compute_diff::{write_diff, write_filtered_diff};
 use crate::errors::{self, Error, ErrorKind};
 use crate::header::TestProps;
 use crate::read2::{read2_abbreviated, Truncated};
-use crate::util::{add_dylib_path, copy_dir_all, dylib_env_var, logv, static_regex, PathBufExt};
-use crate::{extract_gdb_version, is_android_gdb_target, json, ColorConfig};
+use crate::util::{add_dylib_path, logv, static_regex, PathBufExt};
+use crate::{json, ColorConfig};
 
-mod coverage;
 mod debugger;
-use debugger::DebuggerCommands;
+
+// Helper modules that implement test running logic for each test suite.
+// tidy-alphabet-start
+mod assembly;
+mod codegen;
+mod codegen_units;
+mod coverage;
+mod crash;
+mod debuginfo;
+mod incremental;
+mod js_doc;
+mod mir_opt;
+mod pretty;
+mod run_make;
+mod rustdoc;
+mod rustdoc_json;
+mod ui;
+mod valgrind;
+// tidy-alphabet-end
 
 #[cfg(test)]
 mod tests;
@@ -325,81 +339,6 @@ impl<'test> TestCx<'test> {
         }
     }
 
-    fn run_cfail_test(&self) {
-        let pm = self.pass_mode();
-        let proc_res = self.compile_test(WillExecute::No, self.should_emit_metadata(pm));
-        self.check_if_test_should_compile(&proc_res, pm);
-        self.check_no_compiler_crash(&proc_res, self.props.should_ice);
-
-        let output_to_check = self.get_output(&proc_res);
-        let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
-        if !expected_errors.is_empty() {
-            if !self.props.error_patterns.is_empty() || !self.props.regex_error_patterns.is_empty()
-            {
-                self.fatal("both error pattern and expected errors specified");
-            }
-            self.check_expected_errors(expected_errors, &proc_res);
-        } else {
-            self.check_all_error_patterns(&output_to_check, &proc_res, pm);
-        }
-        if self.props.should_ice {
-            match proc_res.status.code() {
-                Some(101) => (),
-                _ => self.fatal("expected ICE"),
-            }
-        }
-
-        self.check_forbid_output(&output_to_check, &proc_res);
-    }
-
-    fn run_crash_test(&self) {
-        let pm = self.pass_mode();
-        let proc_res = self.compile_test(WillExecute::No, self.should_emit_metadata(pm));
-
-        if std::env::var("COMPILETEST_VERBOSE_CRASHES").is_ok() {
-            eprintln!("{}", proc_res.status);
-            eprintln!("{}", proc_res.stdout);
-            eprintln!("{}", proc_res.stderr);
-            eprintln!("{}", proc_res.cmdline);
-        }
-
-        // if a test does not crash, consider it an error
-        if proc_res.status.success() || matches!(proc_res.status.code(), Some(1 | 0)) {
-            self.fatal(&format!(
-                "crashtest no longer crashes/triggers ICE, horray! Please give it a meaningful name, \
-            add a doc-comment to the start of the test explaining why it exists and \
-            move it to tests/ui or wherever you see fit. Adding 'Fixes #<issueNr>' to your PR description \
-            ensures that the corresponding ticket is auto-closed upon merge."
-            ));
-        }
-    }
-
-    fn run_rfail_test(&self) {
-        let pm = self.pass_mode();
-        let should_run = self.run_if_enabled();
-        let proc_res = self.compile_test(should_run, self.should_emit_metadata(pm));
-
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("compilation failed!", &proc_res);
-        }
-
-        if let WillExecute::Disabled = should_run {
-            return;
-        }
-
-        let proc_res = self.exec_compiled_test();
-
-        // The value our Makefile configures valgrind to return on failure
-        const VALGRIND_ERR: i32 = 100;
-        if proc_res.status.code() == Some(VALGRIND_ERR) {
-            self.fatal_proc_rec("run-fail test isn't valgrind-clean!", &proc_res);
-        }
-
-        let output_to_check = self.get_output(&proc_res);
-        self.check_correct_failure_status(&proc_res);
-        self.check_all_error_patterns(&output_to_check, &proc_res, pm);
-    }
-
     fn get_output(&self, proc_res: &ProcRes) -> String {
         if self.props.check_stdout {
             format!("{}{}", proc_res.stdout, proc_res.stderr)
@@ -423,73 +362,6 @@ impl<'test> TestCx<'test> {
         }
     }
 
-    fn run_cpass_test(&self) {
-        let emit_metadata = self.should_emit_metadata(self.pass_mode());
-        let proc_res = self.compile_test(WillExecute::No, emit_metadata);
-
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("compilation failed!", &proc_res);
-        }
-
-        // FIXME(#41968): Move this check to tidy?
-        if !errors::load_errors(&self.testpaths.file, self.revision).is_empty() {
-            self.fatal("compile-pass tests with expected warnings should be moved to ui/");
-        }
-    }
-
-    fn run_rpass_test(&self) {
-        let emit_metadata = self.should_emit_metadata(self.pass_mode());
-        let should_run = self.run_if_enabled();
-        let proc_res = self.compile_test(should_run, emit_metadata);
-
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("compilation failed!", &proc_res);
-        }
-
-        // FIXME(#41968): Move this check to tidy?
-        if !errors::load_errors(&self.testpaths.file, self.revision).is_empty() {
-            self.fatal("run-pass tests with expected warnings should be moved to ui/");
-        }
-
-        if let WillExecute::Disabled = should_run {
-            return;
-        }
-
-        let proc_res = self.exec_compiled_test();
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("test run failed!", &proc_res);
-        }
-    }
-
-    fn run_valgrind_test(&self) {
-        assert!(self.revision.is_none(), "revisions not relevant here");
-
-        if self.config.valgrind_path.is_none() {
-            assert!(!self.config.force_valgrind);
-            return self.run_rpass_test();
-        }
-
-        let should_run = self.run_if_enabled();
-        let mut proc_res = self.compile_test(should_run, Emit::None);
-
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("compilation failed!", &proc_res);
-        }
-
-        if let WillExecute::Disabled = should_run {
-            return;
-        }
-
-        let mut new_config = self.config.clone();
-        new_config.runner = new_config.valgrind_path.clone();
-        let new_cx = TestCx { config: &new_config, ..*self };
-        proc_res = new_cx.exec_compiled_test();
-
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("test run failed!", &proc_res);
-        }
-    }
-
     /// Runs a [`Command`] and waits for it to finish, then converts its exit
     /// status and output streams into a [`ProcRes`].
     ///
@@ -517,104 +389,6 @@ impl<'test> TestCx<'test> {
         proc_res
     }
 
-    fn run_pretty_test(&self) {
-        if self.props.pp_exact.is_some() {
-            logv(self.config, "testing for exact pretty-printing".to_owned());
-        } else {
-            logv(self.config, "testing for converging pretty-printing".to_owned());
-        }
-
-        let rounds = match self.props.pp_exact {
-            Some(_) => 1,
-            None => 2,
-        };
-
-        let src = fs::read_to_string(&self.testpaths.file).unwrap();
-        let mut srcs = vec![src];
-
-        let mut round = 0;
-        while round < rounds {
-            logv(
-                self.config,
-                format!("pretty-printing round {} revision {:?}", round, self.revision),
-            );
-            let read_from =
-                if round == 0 { ReadFrom::Path } else { ReadFrom::Stdin(srcs[round].to_owned()) };
-
-            let proc_res = self.print_source(read_from, &self.props.pretty_mode);
-            if !proc_res.status.success() {
-                self.fatal_proc_rec(
-                    &format!(
-                        "pretty-printing failed in round {} revision {:?}",
-                        round, self.revision
-                    ),
-                    &proc_res,
-                );
-            }
-
-            let ProcRes { stdout, .. } = proc_res;
-            srcs.push(stdout);
-            round += 1;
-        }
-
-        let mut expected = match self.props.pp_exact {
-            Some(ref file) => {
-                let filepath = self.testpaths.file.parent().unwrap().join(file);
-                fs::read_to_string(&filepath).unwrap()
-            }
-            None => srcs[srcs.len() - 2].clone(),
-        };
-        let mut actual = srcs[srcs.len() - 1].clone();
-
-        if self.props.pp_exact.is_some() {
-            // Now we have to care about line endings
-            let cr = "\r".to_owned();
-            actual = actual.replace(&cr, "");
-            expected = expected.replace(&cr, "");
-        }
-
-        if !self.config.bless {
-            self.compare_source(&expected, &actual);
-        } else if expected != actual {
-            let filepath_buf;
-            let filepath = match &self.props.pp_exact {
-                Some(file) => {
-                    filepath_buf = self.testpaths.file.parent().unwrap().join(file);
-                    &filepath_buf
-                }
-                None => &self.testpaths.file,
-            };
-            fs::write(filepath, &actual).unwrap();
-        }
-
-        // If we're only making sure that the output matches then just stop here
-        if self.props.pretty_compare_only {
-            return;
-        }
-
-        // Finally, let's make sure it actually appears to remain valid code
-        let proc_res = self.typecheck_source(actual);
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("pretty-printed source does not typecheck", &proc_res);
-        }
-
-        if !self.props.pretty_expanded {
-            return;
-        }
-
-        // additionally, run `-Zunpretty=expanded` and try to build it.
-        let proc_res = self.print_source(ReadFrom::Path, "expanded");
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("pretty-printing (expanded) failed", &proc_res);
-        }
-
-        let ProcRes { stdout: expanded_src, .. } = proc_res;
-        let proc_res = self.typecheck_source(expanded_src);
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("pretty-printed source (expanded) does not typecheck", &proc_res);
-        }
-    }
-
     fn print_source(&self, read_from: ReadFrom, pretty_type: &str) -> ProcRes {
         let aux_dir = self.aux_output_dir_name();
         let input: &str = match read_from {
@@ -727,500 +501,6 @@ impl<'test> TestCx<'test> {
         self.compose_and_run_compiler(rustc, Some(src), self.testpaths)
     }
 
-    fn run_debuginfo_test(&self) {
-        match self.config.debugger.unwrap() {
-            Debugger::Cdb => self.run_debuginfo_cdb_test(),
-            Debugger::Gdb => self.run_debuginfo_gdb_test(),
-            Debugger::Lldb => self.run_debuginfo_lldb_test(),
-        }
-    }
-
-    fn run_debuginfo_cdb_test(&self) {
-        let config = Config {
-            target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
-            host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
-            ..self.config.clone()
-        };
-
-        let test_cx = TestCx { config: &config, ..*self };
-
-        test_cx.run_debuginfo_cdb_test_no_opt();
-    }
-
-    fn run_debuginfo_cdb_test_no_opt(&self) {
-        let exe_file = self.make_exe_name();
-
-        // Existing PDB files are update in-place. When changing the debuginfo
-        // the compiler generates for something, this can lead to the situation
-        // where both the old and the new version of the debuginfo for the same
-        // type is present in the PDB, which is very confusing.
-        // Therefore we delete any existing PDB file before compiling the test
-        // case.
-        // FIXME: If can reliably detect that MSVC's link.exe is used, then
-        //        passing `/INCREMENTAL:NO` might be a cleaner way to do this.
-        let pdb_file = exe_file.with_extension(".pdb");
-        if pdb_file.exists() {
-            std::fs::remove_file(pdb_file).unwrap();
-        }
-
-        // compile test file (it should have 'compile-flags:-g' in the header)
-        let should_run = self.run_if_enabled();
-        let compile_result = self.compile_test(should_run, Emit::None);
-        if !compile_result.status.success() {
-            self.fatal_proc_rec("compilation failed!", &compile_result);
-        }
-        if let WillExecute::Disabled = should_run {
-            return;
-        }
-
-        let prefixes = {
-            static PREFIXES: &[&str] = &["cdb", "cdbg"];
-            // No "native rust support" variation for CDB yet.
-            PREFIXES
-        };
-
-        // Parse debugger commands etc from test files
-        let dbg_cmds = DebuggerCommands::parse_from(
-            &self.testpaths.file,
-            self.config,
-            prefixes,
-            self.revision,
-        )
-        .unwrap_or_else(|e| self.fatal(&e));
-
-        // https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-commands
-        let mut script_str = String::with_capacity(2048);
-        script_str.push_str("version\n"); // List CDB (and more) version info in test output
-        script_str.push_str(".nvlist\n"); // List loaded `*.natvis` files, bulk of custom MSVC debug
-
-        // If a .js file exists next to the source file being tested, then this is a JavaScript
-        // debugging extension that needs to be loaded.
-        let mut js_extension = self.testpaths.file.clone();
-        js_extension.set_extension("cdb.js");
-        if js_extension.exists() {
-            script_str.push_str(&format!(".scriptload \"{}\"\n", js_extension.to_string_lossy()));
-        }
-
-        // Set breakpoints on every line that contains the string "#break"
-        let source_file_name = self.testpaths.file.file_name().unwrap().to_string_lossy();
-        for line in &dbg_cmds.breakpoint_lines {
-            script_str.push_str(&format!("bp `{}:{}`\n", source_file_name, line));
-        }
-
-        // Append the other `cdb-command:`s
-        for line in &dbg_cmds.commands {
-            script_str.push_str(line);
-            script_str.push('\n');
-        }
-
-        script_str.push_str("qq\n"); // Quit the debugger (including remote debugger, if any)
-
-        // Write the script into a file
-        debug!("script_str = {}", script_str);
-        self.dump_output_file(&script_str, "debugger.script");
-        let debugger_script = self.make_out_name("debugger.script");
-
-        let cdb_path = &self.config.cdb.as_ref().unwrap();
-        let mut cdb = Command::new(cdb_path);
-        cdb.arg("-lines") // Enable source line debugging.
-            .arg("-cf")
-            .arg(&debugger_script)
-            .arg(&exe_file);
-
-        let debugger_run_result = self.compose_and_run(
-            cdb,
-            self.config.run_lib_path.to_str().unwrap(),
-            None, // aux_path
-            None, // input
-        );
-
-        if !debugger_run_result.status.success() {
-            self.fatal_proc_rec("Error while running CDB", &debugger_run_result);
-        }
-
-        if let Err(e) = dbg_cmds.check_output(&debugger_run_result) {
-            self.fatal_proc_rec(&e, &debugger_run_result);
-        }
-    }
-
-    fn run_debuginfo_gdb_test(&self) {
-        let config = Config {
-            target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
-            host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
-            ..self.config.clone()
-        };
-
-        let test_cx = TestCx { config: &config, ..*self };
-
-        test_cx.run_debuginfo_gdb_test_no_opt();
-    }
-
-    fn run_debuginfo_gdb_test_no_opt(&self) {
-        let dbg_cmds = DebuggerCommands::parse_from(
-            &self.testpaths.file,
-            self.config,
-            &["gdb"],
-            self.revision,
-        )
-        .unwrap_or_else(|e| self.fatal(&e));
-        let mut cmds = dbg_cmds.commands.join("\n");
-
-        // compile test file (it should have 'compile-flags:-g' in the header)
-        let should_run = self.run_if_enabled();
-        let compiler_run_result = self.compile_test(should_run, Emit::None);
-        if !compiler_run_result.status.success() {
-            self.fatal_proc_rec("compilation failed!", &compiler_run_result);
-        }
-        if let WillExecute::Disabled = should_run {
-            return;
-        }
-
-        let exe_file = self.make_exe_name();
-
-        let debugger_run_result;
-        if is_android_gdb_target(&self.config.target) {
-            cmds = cmds.replace("run", "continue");
-
-            let tool_path = match self.config.android_cross_path.to_str() {
-                Some(x) => x.to_owned(),
-                None => self.fatal("cannot find android cross path"),
-            };
-
-            // write debugger script
-            let mut script_str = String::with_capacity(2048);
-            script_str.push_str(&format!("set charset {}\n", Self::charset()));
-            script_str.push_str(&format!("set sysroot {}\n", tool_path));
-            script_str.push_str(&format!("file {}\n", exe_file.to_str().unwrap()));
-            script_str.push_str("target remote :5039\n");
-            script_str.push_str(&format!(
-                "set solib-search-path \
-                 ./{}/stage2/lib/rustlib/{}/lib/\n",
-                self.config.host, self.config.target
-            ));
-            for line in &dbg_cmds.breakpoint_lines {
-                script_str.push_str(
-                    format!(
-                        "break {:?}:{}\n",
-                        self.testpaths.file.file_name().unwrap().to_string_lossy(),
-                        *line
-                    )
-                    .as_str(),
-                );
-            }
-            script_str.push_str(&cmds);
-            script_str.push_str("\nquit\n");
-
-            debug!("script_str = {}", script_str);
-            self.dump_output_file(&script_str, "debugger.script");
-
-            let adb_path = &self.config.adb_path;
-
-            Command::new(adb_path)
-                .arg("push")
-                .arg(&exe_file)
-                .arg(&self.config.adb_test_dir)
-                .status()
-                .unwrap_or_else(|e| panic!("failed to exec `{adb_path:?}`: {e:?}"));
-
-            Command::new(adb_path)
-                .args(&["forward", "tcp:5039", "tcp:5039"])
-                .status()
-                .unwrap_or_else(|e| panic!("failed to exec `{adb_path:?}`: {e:?}"));
-
-            let adb_arg = format!(
-                "export LD_LIBRARY_PATH={}; \
-                 gdbserver{} :5039 {}/{}",
-                self.config.adb_test_dir.clone(),
-                if self.config.target.contains("aarch64") { "64" } else { "" },
-                self.config.adb_test_dir.clone(),
-                exe_file.file_name().unwrap().to_str().unwrap()
-            );
-
-            debug!("adb arg: {}", adb_arg);
-            let mut adb = Command::new(adb_path)
-                .args(&["shell", &adb_arg])
-                .stdout(Stdio::piped())
-                .stderr(Stdio::inherit())
-                .spawn()
-                .unwrap_or_else(|e| panic!("failed to exec `{adb_path:?}`: {e:?}"));
-
-            // Wait for the gdbserver to print out "Listening on port ..."
-            // at which point we know that it's started and then we can
-            // execute the debugger below.
-            let mut stdout = BufReader::new(adb.stdout.take().unwrap());
-            let mut line = String::new();
-            loop {
-                line.truncate(0);
-                stdout.read_line(&mut line).unwrap();
-                if line.starts_with("Listening on port 5039") {
-                    break;
-                }
-            }
-            drop(stdout);
-
-            let mut debugger_script = OsString::from("-command=");
-            debugger_script.push(self.make_out_name("debugger.script"));
-            let debugger_opts: &[&OsStr] =
-                &["-quiet".as_ref(), "-batch".as_ref(), "-nx".as_ref(), &debugger_script];
-
-            let gdb_path = self.config.gdb.as_ref().unwrap();
-            let Output { status, stdout, stderr } = Command::new(&gdb_path)
-                .args(debugger_opts)
-                .output()
-                .unwrap_or_else(|e| panic!("failed to exec `{gdb_path:?}`: {e:?}"));
-            let cmdline = {
-                let mut gdb = Command::new(&format!("{}-gdb", self.config.target));
-                gdb.args(debugger_opts);
-                let cmdline = self.make_cmdline(&gdb, "");
-                logv(self.config, format!("executing {}", cmdline));
-                cmdline
-            };
-
-            debugger_run_result = ProcRes {
-                status,
-                stdout: String::from_utf8(stdout).unwrap(),
-                stderr: String::from_utf8(stderr).unwrap(),
-                truncated: Truncated::No,
-                cmdline,
-            };
-            if adb.kill().is_err() {
-                println!("Adb process is already finished.");
-            }
-        } else {
-            let rust_src_root =
-                self.config.find_rust_src_root().expect("Could not find Rust source root");
-            let rust_pp_module_rel_path = Path::new("./src/etc");
-            let rust_pp_module_abs_path =
-                rust_src_root.join(rust_pp_module_rel_path).to_str().unwrap().to_owned();
-            // write debugger script
-            let mut script_str = String::with_capacity(2048);
-            script_str.push_str(&format!("set charset {}\n", Self::charset()));
-            script_str.push_str("show version\n");
-
-            match self.config.gdb_version {
-                Some(version) => {
-                    println!("NOTE: compiletest thinks it is using GDB version {}", version);
-
-                    if version > extract_gdb_version("7.4").unwrap() {
-                        // Add the directory containing the pretty printers to
-                        // GDB's script auto loading safe path
-                        script_str.push_str(&format!(
-                            "add-auto-load-safe-path {}\n",
-                            rust_pp_module_abs_path.replace(r"\", r"\\")
-                        ));
-
-                        let output_base_dir = self.output_base_dir().to_str().unwrap().to_owned();
-
-                        // Add the directory containing the output binary to
-                        // include embedded pretty printers to GDB's script
-                        // auto loading safe path
-                        script_str.push_str(&format!(
-                            "add-auto-load-safe-path {}\n",
-                            output_base_dir.replace(r"\", r"\\")
-                        ));
-                    }
-                }
-                _ => {
-                    println!(
-                        "NOTE: compiletest does not know which version of \
-                         GDB it is using"
-                    );
-                }
-            }
-
-            // The following line actually doesn't have to do anything with
-            // pretty printing, it just tells GDB to print values on one line:
-            script_str.push_str("set print pretty off\n");
-
-            // Add the pretty printer directory to GDB's source-file search path
-            script_str
-                .push_str(&format!("directory {}\n", rust_pp_module_abs_path.replace(r"\", r"\\")));
-
-            // Load the target executable
-            script_str
-                .push_str(&format!("file {}\n", exe_file.to_str().unwrap().replace(r"\", r"\\")));
-
-            // Force GDB to print values in the Rust format.
-            script_str.push_str("set language rust\n");
-
-            // Add line breakpoints
-            for line in &dbg_cmds.breakpoint_lines {
-                script_str.push_str(&format!(
-                    "break '{}':{}\n",
-                    self.testpaths.file.file_name().unwrap().to_string_lossy(),
-                    *line
-                ));
-            }
-
-            script_str.push_str(&cmds);
-            script_str.push_str("\nquit\n");
-
-            debug!("script_str = {}", script_str);
-            self.dump_output_file(&script_str, "debugger.script");
-
-            let mut debugger_script = OsString::from("-command=");
-            debugger_script.push(self.make_out_name("debugger.script"));
-
-            let debugger_opts: &[&OsStr] =
-                &["-quiet".as_ref(), "-batch".as_ref(), "-nx".as_ref(), &debugger_script];
-
-            let mut gdb = Command::new(self.config.gdb.as_ref().unwrap());
-            let pythonpath = if let Ok(pp) = std::env::var("PYTHONPATH") {
-                format!("{pp}:{rust_pp_module_abs_path}")
-            } else {
-                rust_pp_module_abs_path
-            };
-            gdb.args(debugger_opts).env("PYTHONPATH", pythonpath);
-
-            debugger_run_result =
-                self.compose_and_run(gdb, self.config.run_lib_path.to_str().unwrap(), None, None);
-        }
-
-        if !debugger_run_result.status.success() {
-            self.fatal_proc_rec("gdb failed to execute", &debugger_run_result);
-        }
-
-        if let Err(e) = dbg_cmds.check_output(&debugger_run_result) {
-            self.fatal_proc_rec(&e, &debugger_run_result);
-        }
-    }
-
-    fn run_debuginfo_lldb_test(&self) {
-        if self.config.lldb_python_dir.is_none() {
-            self.fatal("Can't run LLDB test because LLDB's python path is not set.");
-        }
-
-        let config = Config {
-            target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
-            host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
-            ..self.config.clone()
-        };
-
-        let test_cx = TestCx { config: &config, ..*self };
-
-        test_cx.run_debuginfo_lldb_test_no_opt();
-    }
-
-    fn run_debuginfo_lldb_test_no_opt(&self) {
-        // compile test file (it should have 'compile-flags:-g' in the header)
-        let should_run = self.run_if_enabled();
-        let compile_result = self.compile_test(should_run, Emit::None);
-        if !compile_result.status.success() {
-            self.fatal_proc_rec("compilation failed!", &compile_result);
-        }
-        if let WillExecute::Disabled = should_run {
-            return;
-        }
-
-        let exe_file = self.make_exe_name();
-
-        match self.config.lldb_version {
-            Some(ref version) => {
-                println!("NOTE: compiletest thinks it is using LLDB version {}", version);
-            }
-            _ => {
-                println!(
-                    "NOTE: compiletest does not know which version of \
-                     LLDB it is using"
-                );
-            }
-        }
-
-        // Parse debugger commands etc from test files
-        let dbg_cmds = DebuggerCommands::parse_from(
-            &self.testpaths.file,
-            self.config,
-            &["lldb"],
-            self.revision,
-        )
-        .unwrap_or_else(|e| self.fatal(&e));
-
-        // Write debugger script:
-        // We don't want to hang when calling `quit` while the process is still running
-        let mut script_str = String::from("settings set auto-confirm true\n");
-
-        // Make LLDB emit its version, so we have it documented in the test output
-        script_str.push_str("version\n");
-
-        // Switch LLDB into "Rust mode"
-        let rust_src_root =
-            self.config.find_rust_src_root().expect("Could not find Rust source root");
-        let rust_pp_module_rel_path = Path::new("./src/etc");
-        let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path);
-
-        script_str.push_str(&format!(
-            "command script import {}/lldb_lookup.py\n",
-            rust_pp_module_abs_path.to_str().unwrap()
-        ));
-        File::open(rust_pp_module_abs_path.join("lldb_commands"))
-            .and_then(|mut file| file.read_to_string(&mut script_str))
-            .expect("Failed to read lldb_commands");
-
-        // Set breakpoints on every line that contains the string "#break"
-        let source_file_name = self.testpaths.file.file_name().unwrap().to_string_lossy();
-        for line in &dbg_cmds.breakpoint_lines {
-            script_str.push_str(&format!(
-                "breakpoint set --file '{}' --line {}\n",
-                source_file_name, line
-            ));
-        }
-
-        // Append the other commands
-        for line in &dbg_cmds.commands {
-            script_str.push_str(line);
-            script_str.push('\n');
-        }
-
-        // Finally, quit the debugger
-        script_str.push_str("\nquit\n");
-
-        // Write the script into a file
-        debug!("script_str = {}", script_str);
-        self.dump_output_file(&script_str, "debugger.script");
-        let debugger_script = self.make_out_name("debugger.script");
-
-        // Let LLDB execute the script via lldb_batchmode.py
-        let debugger_run_result = self.run_lldb(&exe_file, &debugger_script, &rust_src_root);
-
-        if !debugger_run_result.status.success() {
-            self.fatal_proc_rec("Error while running LLDB", &debugger_run_result);
-        }
-
-        if let Err(e) = dbg_cmds.check_output(&debugger_run_result) {
-            self.fatal_proc_rec(&e, &debugger_run_result);
-        }
-    }
-
-    fn run_lldb(
-        &self,
-        test_executable: &Path,
-        debugger_script: &Path,
-        rust_src_root: &Path,
-    ) -> ProcRes {
-        // Prepare the lldb_batchmode which executes the debugger script
-        let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py");
-        let pythonpath = if let Ok(pp) = std::env::var("PYTHONPATH") {
-            format!("{pp}:{}", self.config.lldb_python_dir.as_ref().unwrap())
-        } else {
-            self.config.lldb_python_dir.as_ref().unwrap().to_string()
-        };
-        self.run_command_to_procres(
-            Command::new(&self.config.python)
-                .arg(&lldb_script_path)
-                .arg(test_executable)
-                .arg(debugger_script)
-                .env("PYTHONUNBUFFERED", "1") // Help debugging #78665
-                .env("PYTHONPATH", pythonpath),
-        )
-    }
-
-    fn cleanup_debug_info_options(&self, options: &Vec<String>) -> Vec<String> {
-        // Remove options that are either unwanted (-O) or may lead to duplicates due to RUSTFLAGS.
-        let options_to_remove = ["-O".to_owned(), "-g".to_owned(), "--debuginfo".to_owned()];
-
-        options.iter().filter(|x| !options_to_remove.contains(x)).cloned().collect()
-    }
-
     fn maybe_add_external_args(&self, cmd: &mut Command, args: &Vec<String>) {
         // Filter out the arguments that should not be added by runtest here.
         //
@@ -2016,6 +1296,14 @@ impl<'test> TestCx<'test> {
             || self.config.src_base.ends_with("rustdoc-json")
     }
 
+    fn get_mir_dump_dir(&self) -> PathBuf {
+        let mut mir_dump_dir = PathBuf::from(self.config.build_base.as_path());
+        debug!("input_file: {:?}", self.testpaths.file);
+        mir_dump_dir.push(&self.testpaths.relative_dir);
+        mir_dump_dir.push(self.testpaths.file.file_stem().unwrap());
+        mir_dump_dir
+    }
+
     fn make_compile_args(
         &self,
         input_file: &Path,
@@ -2626,75 +1914,11 @@ impl<'test> TestCx<'test> {
         self.compose_and_run(filecheck, "", None, None)
     }
 
-    fn run_codegen_test(&self) {
-        if self.config.llvm_filecheck.is_none() {
-            self.fatal("missing --llvm-filecheck");
-        }
-
-        let (proc_res, output_path) = self.compile_test_and_save_ir();
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("compilation failed!", &proc_res);
-        }
-
-        if let Some(PassMode::Build) = self.pass_mode() {
-            return;
-        }
-        let proc_res = self.verify_with_filecheck(&output_path);
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
-        }
-    }
-
-    fn run_assembly_test(&self) {
-        if self.config.llvm_filecheck.is_none() {
-            self.fatal("missing --llvm-filecheck");
-        }
-
-        let (proc_res, output_path) = self.compile_test_and_save_assembly();
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("compilation failed!", &proc_res);
-        }
-
-        let proc_res = self.verify_with_filecheck(&output_path);
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
-        }
-    }
-
     fn charset() -> &'static str {
         // FreeBSD 10.1 defaults to GDB 6.1.1 which doesn't support "auto" charset
         if cfg!(target_os = "freebsd") { "ISO-8859-1" } else { "UTF-8" }
     }
 
-    fn run_rustdoc_test(&self) {
-        assert!(self.revision.is_none(), "revisions not relevant here");
-
-        let out_dir = self.output_base_dir();
-        remove_and_create_dir_all(&out_dir);
-
-        let proc_res = self.document(&out_dir, &self.testpaths);
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("rustdoc failed!", &proc_res);
-        }
-
-        if self.props.check_test_line_numbers_match {
-            self.check_rustdoc_test_option(proc_res);
-        } else {
-            let root = self.config.find_rust_src_root().unwrap();
-            let mut cmd = Command::new(&self.config.python);
-            cmd.arg(root.join("src/etc/htmldocck.py")).arg(&out_dir).arg(&self.testpaths.file);
-            if self.config.bless {
-                cmd.arg("--bless");
-            }
-            let res = self.run_command_to_procres(&mut cmd);
-            if !res.status.success() {
-                self.fatal_proc_rec_with_ctx("htmldocck failed!", &res, |mut this| {
-                    this.compare_to_default_rustdoc(&out_dir)
-                });
-            }
-        }
-    }
-
     fn compare_to_default_rustdoc(&mut self, out_dir: &Path) {
         if !self.config.has_tidy {
             return;
@@ -2847,49 +2071,6 @@ impl<'test> TestCx<'test> {
         };
     }
 
-    fn run_rustdoc_json_test(&self) {
-        //FIXME: Add bless option.
-
-        assert!(self.revision.is_none(), "revisions not relevant here");
-
-        let out_dir = self.output_base_dir();
-        remove_and_create_dir_all(&out_dir);
-
-        let proc_res = self.document(&out_dir, &self.testpaths);
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("rustdoc failed!", &proc_res);
-        }
-
-        let root = self.config.find_rust_src_root().unwrap();
-        let mut json_out = out_dir.join(self.testpaths.file.file_stem().unwrap());
-        json_out.set_extension("json");
-        let res = self.run_command_to_procres(
-            Command::new(self.config.jsondocck_path.as_ref().unwrap())
-                .arg("--doc-dir")
-                .arg(root.join(&out_dir))
-                .arg("--template")
-                .arg(&self.testpaths.file),
-        );
-
-        if !res.status.success() {
-            self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| {
-                println!("Rustdoc Output:");
-                proc_res.print_info();
-            })
-        }
-
-        let mut json_out = out_dir.join(self.testpaths.file.file_stem().unwrap());
-        json_out.set_extension("json");
-
-        let res = self.run_command_to_procres(
-            Command::new(self.config.jsondoclint_path.as_ref().unwrap()).arg(&json_out),
-        );
-
-        if !res.status.success() {
-            self.fatal_proc_rec("jsondoclint failed!", &res);
-        }
-    }
-
     fn get_lines<P: AsRef<Path>>(
         &self,
         path: &P,
@@ -2990,824 +2171,6 @@ impl<'test> TestCx<'test> {
         }
     }
 
-    fn run_codegen_units_test(&self) {
-        assert!(self.revision.is_none(), "revisions not relevant here");
-
-        let proc_res = self.compile_test(WillExecute::No, Emit::None);
-
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("compilation failed!", &proc_res);
-        }
-
-        self.check_no_compiler_crash(&proc_res, self.props.should_ice);
-
-        const PREFIX: &str = "MONO_ITEM ";
-        const CGU_MARKER: &str = "@@";
-
-        // Some MonoItems can contain {closure@/path/to/checkout/tests/codgen-units/test.rs}
-        // To prevent the current dir from leaking, we just replace the entire path to the test
-        // file with TEST_PATH.
-        let actual: Vec<MonoItem> = proc_res
-            .stdout
-            .lines()
-            .filter(|line| line.starts_with(PREFIX))
-            .map(|line| {
-                line.replace(&self.testpaths.file.display().to_string(), "TEST_PATH").to_string()
-            })
-            .map(|line| str_to_mono_item(&line, true))
-            .collect();
-
-        let expected: Vec<MonoItem> = errors::load_errors(&self.testpaths.file, None)
-            .iter()
-            .map(|e| str_to_mono_item(&e.msg[..], false))
-            .collect();
-
-        let mut missing = Vec::new();
-        let mut wrong_cgus = Vec::new();
-
-        for expected_item in &expected {
-            let actual_item_with_same_name = actual.iter().find(|ti| ti.name == expected_item.name);
-
-            if let Some(actual_item) = actual_item_with_same_name {
-                if !expected_item.codegen_units.is_empty() &&
-                   // Also check for codegen units
-                   expected_item.codegen_units != actual_item.codegen_units
-                {
-                    wrong_cgus.push((expected_item.clone(), actual_item.clone()));
-                }
-            } else {
-                missing.push(expected_item.string.clone());
-            }
-        }
-
-        let unexpected: Vec<_> = actual
-            .iter()
-            .filter(|acgu| !expected.iter().any(|ecgu| acgu.name == ecgu.name))
-            .map(|acgu| acgu.string.clone())
-            .collect();
-
-        if !missing.is_empty() {
-            missing.sort();
-
-            println!("\nThese items should have been contained but were not:\n");
-
-            for item in &missing {
-                println!("{}", item);
-            }
-
-            println!("\n");
-        }
-
-        if !unexpected.is_empty() {
-            let sorted = {
-                let mut sorted = unexpected.clone();
-                sorted.sort();
-                sorted
-            };
-
-            println!("\nThese items were contained but should not have been:\n");
-
-            for item in sorted {
-                println!("{}", item);
-            }
-
-            println!("\n");
-        }
-
-        if !wrong_cgus.is_empty() {
-            wrong_cgus.sort_by_key(|pair| pair.0.name.clone());
-            println!("\nThe following items were assigned to wrong codegen units:\n");
-
-            for &(ref expected_item, ref actual_item) in &wrong_cgus {
-                println!("{}", expected_item.name);
-                println!("  expected: {}", codegen_units_to_str(&expected_item.codegen_units));
-                println!("  actual:   {}", codegen_units_to_str(&actual_item.codegen_units));
-                println!();
-            }
-        }
-
-        if !(missing.is_empty() && unexpected.is_empty() && wrong_cgus.is_empty()) {
-            panic!();
-        }
-
-        #[derive(Clone, Eq, PartialEq)]
-        struct MonoItem {
-            name: String,
-            codegen_units: HashSet<String>,
-            string: String,
-        }
-
-        // [MONO_ITEM] name [@@ (cgu)+]
-        fn str_to_mono_item(s: &str, cgu_has_crate_disambiguator: bool) -> MonoItem {
-            let s = if s.starts_with(PREFIX) { (&s[PREFIX.len()..]).trim() } else { s.trim() };
-
-            let full_string = format!("{}{}", PREFIX, s);
-
-            let parts: Vec<&str> =
-                s.split(CGU_MARKER).map(str::trim).filter(|s| !s.is_empty()).collect();
-
-            let name = parts[0].trim();
-
-            let cgus = if parts.len() > 1 {
-                let cgus_str = parts[1];
-
-                cgus_str
-                    .split(' ')
-                    .map(str::trim)
-                    .filter(|s| !s.is_empty())
-                    .map(|s| {
-                        if cgu_has_crate_disambiguator {
-                            remove_crate_disambiguators_from_set_of_cgu_names(s)
-                        } else {
-                            s.to_string()
-                        }
-                    })
-                    .collect()
-            } else {
-                HashSet::new()
-            };
-
-            MonoItem { name: name.to_owned(), codegen_units: cgus, string: full_string }
-        }
-
-        fn codegen_units_to_str(cgus: &HashSet<String>) -> String {
-            let mut cgus: Vec<_> = cgus.iter().collect();
-            cgus.sort();
-
-            let mut string = String::new();
-            for cgu in cgus {
-                string.push_str(&cgu[..]);
-                string.push(' ');
-            }
-
-            string
-        }
-
-        // Given a cgu-name-prefix of the form <crate-name>.<crate-disambiguator> or
-        // the form <crate-name1>.<crate-disambiguator1>-in-<crate-name2>.<crate-disambiguator2>,
-        // remove all crate-disambiguators.
-        fn remove_crate_disambiguator_from_cgu(cgu: &str) -> String {
-            let Some(captures) =
-                static_regex!(r"^[^\.]+(?P<d1>\.[[:alnum:]]+)(-in-[^\.]+(?P<d2>\.[[:alnum:]]+))?")
-                    .captures(cgu)
-            else {
-                panic!("invalid cgu name encountered: {cgu}");
-            };
-
-            let mut new_name = cgu.to_owned();
-
-            if let Some(d2) = captures.name("d2") {
-                new_name.replace_range(d2.start()..d2.end(), "");
-            }
-
-            let d1 = captures.name("d1").unwrap();
-            new_name.replace_range(d1.start()..d1.end(), "");
-
-            new_name
-        }
-
-        // The name of merged CGUs is constructed as the names of the original
-        // CGUs joined with "--". This function splits such composite CGU names
-        // and handles each component individually.
-        fn remove_crate_disambiguators_from_set_of_cgu_names(cgus: &str) -> String {
-            cgus.split("--").map(remove_crate_disambiguator_from_cgu).collect::<Vec<_>>().join("--")
-        }
-    }
-
-    fn init_incremental_test(&self) {
-        // (See `run_incremental_test` for an overview of how incremental tests work.)
-
-        // Before any of the revisions have executed, create the
-        // incremental workproduct directory.  Delete any old
-        // incremental work products that may be there from prior
-        // runs.
-        let incremental_dir = self.props.incremental_dir.as_ref().unwrap();
-        if incremental_dir.exists() {
-            // Canonicalizing the path will convert it to the //?/ format
-            // on Windows, which enables paths longer than 260 character
-            let canonicalized = incremental_dir.canonicalize().unwrap();
-            fs::remove_dir_all(canonicalized).unwrap();
-        }
-        fs::create_dir_all(&incremental_dir).unwrap();
-
-        if self.config.verbose {
-            println!("init_incremental_test: incremental_dir={}", incremental_dir.display());
-        }
-    }
-
-    fn run_incremental_test(&self) {
-        // Basic plan for a test incremental/foo/bar.rs:
-        // - load list of revisions rpass1, cfail2, rpass3
-        //   - each should begin with `cpass`, `rpass`, `cfail`, or `rfail`
-        //   - if `cpass`, expect compilation to succeed, don't execute
-        //   - if `rpass`, expect compilation and execution to succeed
-        //   - if `cfail`, expect compilation to fail
-        //   - if `rfail`, expect compilation to succeed and execution to fail
-        // - create a directory build/foo/bar.incremental
-        // - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C rpass1
-        //   - because name of revision starts with "rpass", expect success
-        // - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C cfail2
-        //   - because name of revision starts with "cfail", expect an error
-        //   - load expected errors as usual, but filter for those that end in `[rfail2]`
-        // - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C rpass3
-        //   - because name of revision starts with "rpass", expect success
-        // - execute build/foo/bar.exe and save output
-        //
-        // FIXME -- use non-incremental mode as an oracle? That doesn't apply
-        // to #[rustc_dirty] and clean tests I guess
-
-        let revision = self.revision.expect("incremental tests require a list of revisions");
-
-        // Incremental workproduct directory should have already been created.
-        let incremental_dir = self.props.incremental_dir.as_ref().unwrap();
-        assert!(incremental_dir.exists(), "init_incremental_test failed to create incremental dir");
-
-        if self.config.verbose {
-            print!("revision={:?} props={:#?}", revision, self.props);
-        }
-
-        if revision.starts_with("cpass") {
-            if self.props.should_ice {
-                self.fatal("can only use should-ice in cfail tests");
-            }
-            self.run_cpass_test();
-        } else if revision.starts_with("rpass") {
-            if self.props.should_ice {
-                self.fatal("can only use should-ice in cfail tests");
-            }
-            self.run_rpass_test();
-        } else if revision.starts_with("rfail") {
-            if self.props.should_ice {
-                self.fatal("can only use should-ice in cfail tests");
-            }
-            self.run_rfail_test();
-        } else if revision.starts_with("cfail") {
-            self.run_cfail_test();
-        } else {
-            self.fatal("revision name must begin with cpass, rpass, rfail, or cfail");
-        }
-    }
-
-    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();
-        let src_root = self.config.src_base.parent().unwrap().parent().unwrap();
-        let src_root = cwd.join(&src_root);
-
-        let tmpdir = cwd.join(self.output_base_name());
-        if tmpdir.exists() {
-            self.aggressive_rm_rf(&tmpdir).unwrap();
-        }
-        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", 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 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 aggressive_rm_rf(&self, path: &Path) -> io::Result<()> {
-        for e in path.read_dir()? {
-            let entry = e?;
-            let path = entry.path();
-            if entry.file_type()?.is_dir() {
-                self.aggressive_rm_rf(&path)?;
-            } else {
-                // Remove readonly files as well on windows (by default we can't)
-                fs::remove_file(&path).or_else(|e| {
-                    if cfg!(windows) && e.kind() == io::ErrorKind::PermissionDenied {
-                        let mut meta = entry.metadata()?.permissions();
-                        meta.set_readonly(false);
-                        fs::set_permissions(&path, meta)?;
-                        fs::remove_file(&path)
-                    } else {
-                        Err(e)
-                    }
-                })?;
-            }
-        }
-        fs::remove_dir(path)
-    }
-
-    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`.
-        //
-        // 1. We need to build the recipe `rmake.rs` as a binary and link in the `run_make_support`
-        //    library.
-        // 2. We need to run the recipe binary.
-
-        // So we assume the rust-lang/rust project setup looks like the following (our `.` is the
-        // top-level directory, irrelevant entries to our purposes omitted):
-        //
-        // ```
-        // .                               // <- `source_root`
-        // ├── build/                      // <- `build_root`
-        // ├── compiler/
-        // ├── library/
-        // ├── src/
-        // │  └── tools/
-        // │     └── run_make_support/
-        // └── tests
-        //    └── run-make/
-        // ```
-
-        // `source_root` is the top-level directory containing the rust-lang/rust checkout.
-        let source_root =
-            self.config.find_rust_src_root().expect("could not determine rust source root");
-        // `self.config.build_base` is actually the build base folder + "test" + test suite name, it
-        // looks like `build/<host_triple>/test/run-make`. But we want `build/<host_triple>/`. Note
-        // that the `build` directory does not need to be called `build`, nor does it need to be
-        // under `source_root`, so we must compute it based off of `self.config.build_base`.
-        let build_root =
-            self.config.build_base.parent().and_then(Path::parent).unwrap().to_path_buf();
-
-        // We construct the following directory tree for each rmake.rs test:
-        // ```
-        // <base_dir>/
-        //     rmake.exe
-        //     rmake_out/
-        // ```
-        // having the recipe executable separate from the output artifacts directory allows the
-        // 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_name();
-        if base_dir.exists() {
-            self.aggressive_rm_rf(&base_dir).unwrap();
-        }
-        let rmake_out_dir = base_dir.join("rmake_out");
-        create_dir_all(&rmake_out_dir).unwrap();
-
-        // Copy all input files (apart from rmake.rs) to the temporary directory,
-        // so that the input directory structure from `tests/run-make/<test>` is mirrored
-        // to the `rmake_out` directory.
-        for path in walkdir::WalkDir::new(&self.testpaths.file).min_depth(1) {
-            let path = path.unwrap().path().to_path_buf();
-            if path.file_name().is_some_and(|s| s != "rmake.rs") {
-                let target = rmake_out_dir.join(path.strip_prefix(&self.testpaths.file).unwrap());
-                if path.is_dir() {
-                    copy_dir_all(&path, target).unwrap();
-                } else {
-                    fs::copy(&path, target).unwrap();
-                }
-            }
-        }
-
-        // `self.config.stage_id` looks like `stage1-<target_triple>`, but we only want
-        // the `stage1` part as that is what the output directories of bootstrap are prefixed with.
-        // Note that this *assumes* build layout from bootstrap is produced as:
-        //
-        // ```
-        // build/<target_triple>/          // <- this is `build_root`
-        // ├── stage0
-        // ├── stage0-bootstrap-tools
-        // ├── stage0-codegen
-        // ├── stage0-rustc
-        // ├── stage0-std
-        // ├── stage0-sysroot
-        // ├── stage0-tools
-        // ├── stage0-tools-bin
-        // ├── stage1
-        // ├── stage1-std
-        // ├── stage1-tools
-        // ├── stage1-tools-bin
-        // └── test
-        // ```
-        // FIXME(jieyouxu): improve the communication between bootstrap and compiletest here so
-        // we don't have to hack out a `stageN`.
-        let stage = self.config.stage_id.split('-').next().unwrap();
-
-        // In order to link in the support library as a rlib when compiling recipes, we need three
-        // paths:
-        // 1. Path of the built support library rlib itself.
-        // 2. Path of the built support library's dependencies directory.
-        // 3. Path of the built support library's dependencies' dependencies directory.
-        //
-        // The paths look like
-        //
-        // ```
-        // 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
-        // ```
-        //
-        // 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.
-
-        let stage_tools_bin = build_root.join(format!("{stage}-tools-bin"));
-        let support_lib_path = stage_tools_bin.join("librun_make_support.rlib");
-
-        let stage_tools = build_root.join(format!("{stage}-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");
-
-        // To compile the recipe with rustc, we need to provide suitable dynamic library search
-        // paths to rustc. This includes both:
-        // 1. The "base" dylib search paths that was provided to compiletest, e.g. `LD_LIBRARY_PATH`
-        //    on some linux distros.
-        // 2. Specific library paths in `self.config.compile_lib_path` needed for running rustc.
-
-        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.
-        let recipe_bin = {
-            let mut p = base_dir.join("rmake");
-            p.set_extension(env::consts::EXE_EXTENSION);
-            p
-        };
-
-        let mut rustc = Command::new(&self.config.rustc_path);
-        rustc
-            .arg("-o")
-            .arg(&recipe_bin)
-            // Specify library search paths for `run_make_support`.
-            .arg(format!("-Ldependency={}", &support_lib_path.parent().unwrap().to_string_lossy()))
-            .arg(format!("-Ldependency={}", &support_lib_deps.to_string_lossy()))
-            .arg(format!("-Ldependency={}", &support_lib_deps_deps.to_string_lossy()))
-            // Provide `run_make_support` as extern prelude, so test writers don't need to write
-            // `extern run_make_support;`.
-            .arg("--extern")
-            .arg(format!("run_make_support={}", &support_lib_path.to_string_lossy()))
-            .arg("--edition=2021")
-            .arg(&self.testpaths.file.join("rmake.rs"))
-            // Provide necessary library search paths for rustc.
-            .env(dylib_env_var(), &env::join_paths(host_dylib_search_paths).unwrap());
-
-        // 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.
-        if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() {
-            let stage0_sysroot = build_root.join("stage0-sysroot");
-            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() {
-            self.fatal_proc_rec("run-make test failed: could not build `rmake.rs` recipe", &res);
-        }
-
-        // 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 = build_root.join(&stage).join("lib");
-
-        // Compute dynamic library search paths for recipes.
-        let recipe_dylib_search_paths = {
-            let mut paths = base_dylib_search_paths.clone();
-            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
-        };
-
-        // 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())
-            .stderr(Stdio::piped())
-            // Provide the target-specific env var that is used to record dylib search paths. For
-            // 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.
-            .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 target.
-            .env("TARGET", &self.config.target)
-            // Some tests unfortunately still need Python, so provide path to a Python interpreter.
-            .env("PYTHON", &self.config.python)
-            // Provide path to checkout root. This is the top-level directory containing
-            // rust-lang/rust checkout.
-            .env("SOURCE_ROOT", &source_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);
-
-        if let Some(ref rustdoc) = self.config.rustdoc_path {
-            cmd.env("RUSTDOC", source_root.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 {
-            // If we're running in `--bless` mode, set an environment variable to tell
-            // `run_make_support` to bless snapshot files instead of checking them.
-            //
-            // The value is this test's source directory, because the support code
-            // will need that path in order to bless the _original_ snapshot files,
-            // not the copies in `rmake_out`.
-            // (See <https://github.com/rust-lang/rust/issues/129038>.)
-            cmd.env("RUSTC_BLESS_TEST", &self.testpaths.file);
-        }
-
-        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()))
-                // Note: we diverge from legacy run_make and don't lump `CC` the compiler and
-                // default flags together.
-                .env("CC_DEFAULT_FLAGS", &cflags)
-                .env("CC", &self.config.cc)
-                .env("CXX_DEFAULT_FLAGS", &cxxflags)
-                .env("CXX", &self.config.cxx);
-        } else {
-            cmd.env("CC_DEFAULT_FLAGS", &self.config.cflags)
-                .env("CC", &self.config.cc)
-                .env("CXX_DEFAULT_FLAGS", &self.config.cxxflags)
-                .env("CXX", &self.config.cxx)
-                .env("AR", &self.config.ar);
-
-            if self.config.target.contains("windows") {
-                cmd.env("IS_WINDOWS", "1");
-            }
-        }
-
-        let (Output { stdout, stderr, status }, truncated) =
-            self.read2_abbreviated(cmd.spawn().expect("failed to spawn `rmake`"));
-        if !status.success() {
-            let res = ProcRes {
-                status,
-                stdout: String::from_utf8_lossy(&stdout).into_owned(),
-                stderr: String::from_utf8_lossy(&stderr).into_owned(),
-                truncated,
-                cmdline: format!("{:?}", cmd),
-            };
-            self.fatal_proc_rec("rmake recipe failed to complete", &res);
-        }
-    }
-
-    fn run_js_doc_test(&self) {
-        if let Some(nodejs) = &self.config.nodejs {
-            let out_dir = self.output_base_dir();
-
-            self.document(&out_dir, &self.testpaths);
-
-            let root = self.config.find_rust_src_root().unwrap();
-            let file_stem =
-                self.testpaths.file.file_stem().and_then(|f| f.to_str()).expect("no file stem");
-            let res = self.run_command_to_procres(
-                Command::new(&nodejs)
-                    .arg(root.join("src/tools/rustdoc-js/tester.js"))
-                    .arg("--doc-folder")
-                    .arg(out_dir)
-                    .arg("--crate-name")
-                    .arg(file_stem.replace("-", "_"))
-                    .arg("--test-file")
-                    .arg(self.testpaths.file.with_extension("js")),
-            );
-            if !res.status.success() {
-                self.fatal_proc_rec("rustdoc-js test failed!", &res);
-            }
-        } else {
-            self.fatal("no nodeJS");
-        }
-    }
-
     fn force_color_svg(&self) -> bool {
         self.props.compile_flags.iter().any(|s| s.contains("--color=always"))
     }
@@ -3895,377 +2258,6 @@ impl<'test> TestCx<'test> {
         errors
     }
 
-    fn run_ui_test(&self) {
-        if let Some(FailMode::Build) = self.props.fail_mode {
-            // Make sure a build-fail test cannot fail due to failing analysis (e.g. typeck).
-            let pm = Some(PassMode::Check);
-            let proc_res =
-                self.compile_test_general(WillExecute::No, Emit::Metadata, pm, Vec::new());
-            self.check_if_test_should_compile(&proc_res, pm);
-        }
-
-        let pm = self.pass_mode();
-        let should_run = self.should_run(pm);
-        let emit_metadata = self.should_emit_metadata(pm);
-        let proc_res = self.compile_test(should_run, emit_metadata);
-        self.check_if_test_should_compile(&proc_res, pm);
-        if matches!(proc_res.truncated, Truncated::Yes)
-            && !self.props.dont_check_compiler_stdout
-            && !self.props.dont_check_compiler_stderr
-        {
-            self.fatal_proc_rec(
-                "compiler output got truncated, cannot compare with reference file",
-                &proc_res,
-            );
-        }
-
-        // if the user specified a format in the ui test
-        // print the output to the stderr file, otherwise extract
-        // the rendered error messages from json and print them
-        let explicit = self.props.compile_flags.iter().any(|s| s.contains("--error-format"));
-
-        let expected_fixed = self.load_expected_output(UI_FIXED);
-
-        self.check_and_prune_duplicate_outputs(&proc_res, &[], &[]);
-
-        let mut errors = self.load_compare_outputs(&proc_res, TestOutput::Compile, explicit);
-        let rustfix_input = json::rustfix_diagnostics_only(&proc_res.stderr);
-
-        if self.config.compare_mode.is_some() {
-            // don't test rustfix with nll right now
-        } else if self.config.rustfix_coverage {
-            // Find out which tests have `MachineApplicable` suggestions but are missing
-            // `run-rustfix` or `run-rustfix-only-machine-applicable` headers.
-            //
-            // This will return an empty `Vec` in case the executed test file has a
-            // `compile-flags: --error-format=xxxx` header with a value other than `json`.
-            let suggestions = get_suggestions_from_json(
-                &rustfix_input,
-                &HashSet::new(),
-                Filter::MachineApplicableOnly,
-            )
-            .unwrap_or_default();
-            if !suggestions.is_empty()
-                && !self.props.run_rustfix
-                && !self.props.rustfix_only_machine_applicable
-            {
-                let mut coverage_file_path = self.config.build_base.clone();
-                coverage_file_path.push("rustfix_missing_coverage.txt");
-                debug!("coverage_file_path: {}", coverage_file_path.display());
-
-                let mut file = OpenOptions::new()
-                    .create(true)
-                    .append(true)
-                    .open(coverage_file_path.as_path())
-                    .expect("could not create or open file");
-
-                if let Err(e) = writeln!(file, "{}", self.testpaths.file.display()) {
-                    panic!("couldn't write to {}: {e:?}", coverage_file_path.display());
-                }
-            }
-        } else if self.props.run_rustfix {
-            // Apply suggestions from rustc to the code itself
-            let unfixed_code = self.load_expected_output_from_path(&self.testpaths.file).unwrap();
-            let suggestions = get_suggestions_from_json(
-                &rustfix_input,
-                &HashSet::new(),
-                if self.props.rustfix_only_machine_applicable {
-                    Filter::MachineApplicableOnly
-                } else {
-                    Filter::Everything
-                },
-            )
-            .unwrap();
-            let fixed_code = apply_suggestions(&unfixed_code, &suggestions).unwrap_or_else(|e| {
-                panic!(
-                    "failed to apply suggestions for {:?} with rustfix: {}",
-                    self.testpaths.file, e
-                )
-            });
-
-            errors += self.compare_output("fixed", &fixed_code, &expected_fixed);
-        } else if !expected_fixed.is_empty() {
-            panic!(
-                "the `//@ run-rustfix` directive wasn't found but a `*.fixed` \
-                 file was found"
-            );
-        }
-
-        if errors > 0 {
-            println!("To update references, rerun the tests and pass the `--bless` flag");
-            let relative_path_to_file =
-                self.testpaths.relative_dir.join(self.testpaths.file.file_name().unwrap());
-            println!(
-                "To only update this specific test, also pass `--test-args {}`",
-                relative_path_to_file.display(),
-            );
-            self.fatal_proc_rec(
-                &format!("{} errors occurred comparing output.", errors),
-                &proc_res,
-            );
-        }
-
-        let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
-
-        if let WillExecute::Yes = should_run {
-            let proc_res = self.exec_compiled_test();
-            let run_output_errors = if self.props.check_run_results {
-                self.load_compare_outputs(&proc_res, TestOutput::Run, explicit)
-            } else {
-                0
-            };
-            if run_output_errors > 0 {
-                self.fatal_proc_rec(
-                    &format!("{} errors occurred comparing run output.", run_output_errors),
-                    &proc_res,
-                );
-            }
-            if self.should_run_successfully(pm) {
-                if !proc_res.status.success() {
-                    self.fatal_proc_rec("test run failed!", &proc_res);
-                }
-            } else if proc_res.status.success() {
-                self.fatal_proc_rec("test run succeeded!", &proc_res);
-            }
-
-            if !self.props.error_patterns.is_empty() || !self.props.regex_error_patterns.is_empty()
-            {
-                // "// error-pattern" comments
-                let output_to_check = self.get_output(&proc_res);
-                self.check_all_error_patterns(&output_to_check, &proc_res, pm);
-            }
-        }
-
-        debug!(
-            "run_ui_test: explicit={:?} config.compare_mode={:?} expected_errors={:?} \
-               proc_res.status={:?} props.error_patterns={:?}",
-            explicit,
-            self.config.compare_mode,
-            expected_errors,
-            proc_res.status,
-            self.props.error_patterns
-        );
-
-        let check_patterns = should_run == WillExecute::No
-            && (!self.props.error_patterns.is_empty()
-                || !self.props.regex_error_patterns.is_empty());
-        if !explicit && self.config.compare_mode.is_none() {
-            let check_annotations = !check_patterns || !expected_errors.is_empty();
-
-            if check_annotations {
-                // "//~ERROR comments"
-                self.check_expected_errors(expected_errors, &proc_res);
-            }
-        } else if explicit && !expected_errors.is_empty() {
-            let msg = format!(
-                "line {}: cannot combine `--error-format` with {} annotations; use `error-pattern` instead",
-                expected_errors[0].line_num,
-                expected_errors[0].kind.unwrap_or(ErrorKind::Error),
-            );
-            self.fatal(&msg);
-        }
-        if check_patterns {
-            // "// error-pattern" comments
-            let output_to_check = self.get_output(&proc_res);
-            self.check_all_error_patterns(&output_to_check, &proc_res, pm);
-        }
-
-        if self.props.run_rustfix && self.config.compare_mode.is_none() {
-            // And finally, compile the fixed code and make sure it both
-            // succeeds and has no diagnostics.
-            let mut rustc = self.make_compile_args(
-                &self.expected_output_path(UI_FIXED),
-                TargetLocation::ThisFile(self.make_exe_name()),
-                emit_metadata,
-                AllowUnused::No,
-                LinkToAux::Yes,
-                Vec::new(),
-            );
-
-            // If a test is revisioned, it's fixed source file can be named "a.foo.fixed", which,
-            // well, "a.foo" isn't a valid crate name. So we explicitly mangle the test name
-            // (including the revision) here to avoid the test writer having to manually specify a
-            // `#![crate_name = "..."]` as a workaround. This is okay since we're only checking if
-            // the fixed code is compilable.
-            if self.revision.is_some() {
-                let crate_name =
-                    self.testpaths.file.file_stem().expect("test must have a file stem");
-                // crate name must be alphanumeric or `_`.
-                let crate_name =
-                    crate_name.to_str().expect("crate name implies file name must be valid UTF-8");
-                // replace `a.foo` -> `a__foo` for crate name purposes.
-                // replace `revision-name-with-dashes` -> `revision_name_with_underscore`
-                let crate_name = crate_name.replace('.', "__");
-                let crate_name = crate_name.replace('-', "_");
-                rustc.arg("--crate-name");
-                rustc.arg(crate_name);
-            }
-
-            let res = self.compose_and_run_compiler(rustc, None, self.testpaths);
-            if !res.status.success() {
-                self.fatal_proc_rec("failed to compile fixed code", &res);
-            }
-            if !res.stderr.is_empty()
-                && !self.props.rustfix_only_machine_applicable
-                && !json::rustfix_diagnostics_only(&res.stderr).is_empty()
-            {
-                self.fatal_proc_rec("fixed code is still producing diagnostics", &res);
-            }
-        }
-    }
-
-    fn run_mir_opt_test(&self) {
-        let pm = self.pass_mode();
-        let should_run = self.should_run(pm);
-
-        let mut test_info = files_for_miropt_test(
-            &self.testpaths.file,
-            self.config.get_pointer_width(),
-            self.config.target_cfg().panic.for_miropt_test_tools(),
-        );
-
-        let passes = std::mem::take(&mut test_info.passes);
-
-        let proc_res = self.compile_test_with_passes(should_run, Emit::Mir, passes);
-        if !proc_res.status.success() {
-            self.fatal_proc_rec("compilation failed!", &proc_res);
-        }
-        self.check_mir_dump(test_info);
-
-        if let WillExecute::Yes = should_run {
-            let proc_res = self.exec_compiled_test();
-
-            if !proc_res.status.success() {
-                self.fatal_proc_rec("test run failed!", &proc_res);
-            }
-        }
-    }
-
-    fn check_mir_dump(&self, test_info: MiroptTest) {
-        let test_dir = self.testpaths.file.parent().unwrap();
-        let test_crate =
-            self.testpaths.file.file_stem().unwrap().to_str().unwrap().replace('-', "_");
-
-        let MiroptTest { run_filecheck, suffix, files, passes: _ } = test_info;
-
-        if self.config.bless {
-            for e in
-                glob(&format!("{}/{}.*{}.mir", test_dir.display(), test_crate, suffix)).unwrap()
-            {
-                std::fs::remove_file(e.unwrap()).unwrap();
-            }
-            for e in
-                glob(&format!("{}/{}.*{}.diff", test_dir.display(), test_crate, suffix)).unwrap()
-            {
-                std::fs::remove_file(e.unwrap()).unwrap();
-            }
-        }
-
-        for MiroptTestFile { from_file, to_file, expected_file } in files {
-            let dumped_string = if let Some(after) = to_file {
-                self.diff_mir_files(from_file.into(), after.into())
-            } else {
-                let mut output_file = PathBuf::new();
-                output_file.push(self.get_mir_dump_dir());
-                output_file.push(&from_file);
-                debug!(
-                    "comparing the contents of: {} with {}",
-                    output_file.display(),
-                    expected_file.display()
-                );
-                if !output_file.exists() {
-                    panic!(
-                        "Output file `{}` from test does not exist, available files are in `{}`",
-                        output_file.display(),
-                        output_file.parent().unwrap().display()
-                    );
-                }
-                self.check_mir_test_timestamp(&from_file, &output_file);
-                let dumped_string = fs::read_to_string(&output_file).unwrap();
-                self.normalize_output(&dumped_string, &[])
-            };
-
-            if self.config.bless {
-                let _ = std::fs::remove_file(&expected_file);
-                std::fs::write(expected_file, dumped_string.as_bytes()).unwrap();
-            } else {
-                if !expected_file.exists() {
-                    panic!("Output file `{}` from test does not exist", expected_file.display());
-                }
-                let expected_string = fs::read_to_string(&expected_file).unwrap();
-                if dumped_string != expected_string {
-                    print!("{}", write_diff(&expected_string, &dumped_string, 3));
-                    panic!(
-                        "Actual MIR output differs from expected MIR output {}",
-                        expected_file.display()
-                    );
-                }
-            }
-        }
-
-        if run_filecheck {
-            let output_path = self.output_base_name().with_extension("mir");
-            let proc_res = self.verify_with_filecheck(&output_path);
-            if !proc_res.status.success() {
-                self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
-            }
-        }
-    }
-
-    fn diff_mir_files(&self, before: PathBuf, after: PathBuf) -> String {
-        let to_full_path = |path: PathBuf| {
-            let full = self.get_mir_dump_dir().join(&path);
-            if !full.exists() {
-                panic!(
-                    "the mir dump file for {} does not exist (requested in {})",
-                    path.display(),
-                    self.testpaths.file.display(),
-                );
-            }
-            full
-        };
-        let before = to_full_path(before);
-        let after = to_full_path(after);
-        debug!("comparing the contents of: {} with {}", before.display(), after.display());
-        let before = fs::read_to_string(before).unwrap();
-        let after = fs::read_to_string(after).unwrap();
-        let before = self.normalize_output(&before, &[]);
-        let after = self.normalize_output(&after, &[]);
-        let mut dumped_string = String::new();
-        for result in diff::lines(&before, &after) {
-            use std::fmt::Write;
-            match result {
-                diff::Result::Left(s) => writeln!(dumped_string, "- {}", s).unwrap(),
-                diff::Result::Right(s) => writeln!(dumped_string, "+ {}", s).unwrap(),
-                diff::Result::Both(s, _) => writeln!(dumped_string, "  {}", s).unwrap(),
-            }
-        }
-        dumped_string
-    }
-
-    fn check_mir_test_timestamp(&self, test_name: &str, output_file: &Path) {
-        let t = |file| fs::metadata(file).unwrap().modified().unwrap();
-        let source_file = &self.testpaths.file;
-        let output_time = t(output_file);
-        let source_time = t(source_file);
-        if source_time > output_time {
-            debug!("source file time: {:?} output file time: {:?}", source_time, output_time);
-            panic!(
-                "test source file `{}` is newer than potentially stale output file `{}`.",
-                source_file.display(),
-                test_name
-            );
-        }
-    }
-
-    fn get_mir_dump_dir(&self) -> PathBuf {
-        let mut mir_dump_dir = PathBuf::from(self.config.build_base.as_path());
-        debug!("input_file: {:?}", self.testpaths.file);
-        mir_dump_dir.push(&self.testpaths.relative_dir);
-        mir_dump_dir.push(self.testpaths.file.file_stem().unwrap());
-        mir_dump_dir
-    }
-
     fn normalize_output(&self, output: &str, custom_rules: &[(String, String)]) -> String {
         // Crude heuristic to detect when the output should have JSON-specific
         // normalization steps applied.
@@ -4634,6 +2626,77 @@ impl<'test> TestCx<'test> {
         let stamp = crate::stamp(&self.config, self.testpaths, self.revision);
         fs::write(&stamp, compute_stamp_hash(&self.config)).unwrap();
     }
+
+    fn init_incremental_test(&self) {
+        // (See `run_incremental_test` for an overview of how incremental tests work.)
+
+        // Before any of the revisions have executed, create the
+        // incremental workproduct directory.  Delete any old
+        // incremental work products that may be there from prior
+        // runs.
+        let incremental_dir = self.props.incremental_dir.as_ref().unwrap();
+        if incremental_dir.exists() {
+            // Canonicalizing the path will convert it to the //?/ format
+            // on Windows, which enables paths longer than 260 character
+            let canonicalized = incremental_dir.canonicalize().unwrap();
+            fs::remove_dir_all(canonicalized).unwrap();
+        }
+        fs::create_dir_all(&incremental_dir).unwrap();
+
+        if self.config.verbose {
+            println!("init_incremental_test: incremental_dir={}", incremental_dir.display());
+        }
+    }
+
+    // FIXME(jieyouxu): `run_rpass_test` is hoisted out here and not in incremental because
+    // apparently valgrind test falls back to `run_rpass_test` if valgrind isn't available, which
+    // seems highly questionable to me.
+    fn run_rpass_test(&self) {
+        let emit_metadata = self.should_emit_metadata(self.pass_mode());
+        let should_run = self.run_if_enabled();
+        let proc_res = self.compile_test(should_run, emit_metadata);
+
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+
+        // FIXME(#41968): Move this check to tidy?
+        if !errors::load_errors(&self.testpaths.file, self.revision).is_empty() {
+            self.fatal("run-pass tests with expected warnings should be moved to ui/");
+        }
+
+        if let WillExecute::Disabled = should_run {
+            return;
+        }
+
+        let proc_res = self.exec_compiled_test();
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("test run failed!", &proc_res);
+        }
+    }
+
+    fn aggressive_rm_rf(&self, path: &Path) -> io::Result<()> {
+        for e in path.read_dir()? {
+            let entry = e?;
+            let path = entry.path();
+            if entry.file_type()?.is_dir() {
+                self.aggressive_rm_rf(&path)?;
+            } else {
+                // Remove readonly files as well on windows (by default we can't)
+                fs::remove_file(&path).or_else(|e| {
+                    if cfg!(windows) && e.kind() == io::ErrorKind::PermissionDenied {
+                        let mut meta = entry.metadata()?.permissions();
+                        meta.set_readonly(false);
+                        fs::set_permissions(&path, meta)?;
+                        fs::remove_file(&path)
+                    } else {
+                        Err(e)
+                    }
+                })?;
+            }
+        }
+        fs::remove_dir(path)
+    }
 }
 
 struct ProcArgs {
diff --git a/src/tools/compiletest/src/runtest/assembly.rs b/src/tools/compiletest/src/runtest/assembly.rs
new file mode 100644
index 00000000000..430a5534da1
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/assembly.rs
@@ -0,0 +1,19 @@
+use super::TestCx;
+
+impl TestCx<'_> {
+    pub(super) fn run_assembly_test(&self) {
+        if self.config.llvm_filecheck.is_none() {
+            self.fatal("missing --llvm-filecheck");
+        }
+
+        let (proc_res, output_path) = self.compile_test_and_save_assembly();
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+
+        let proc_res = self.verify_with_filecheck(&output_path);
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
+        }
+    }
+}
diff --git a/src/tools/compiletest/src/runtest/codegen.rs b/src/tools/compiletest/src/runtest/codegen.rs
new file mode 100644
index 00000000000..6e61ab5e46d
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/codegen.rs
@@ -0,0 +1,22 @@
+use super::{PassMode, TestCx};
+
+impl TestCx<'_> {
+    pub(super) fn run_codegen_test(&self) {
+        if self.config.llvm_filecheck.is_none() {
+            self.fatal("missing --llvm-filecheck");
+        }
+
+        let (proc_res, output_path) = self.compile_test_and_save_ir();
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+
+        if let Some(PassMode::Build) = self.pass_mode() {
+            return;
+        }
+        let proc_res = self.verify_with_filecheck(&output_path);
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
+        }
+    }
+}
diff --git a/src/tools/compiletest/src/runtest/codegen_units.rs b/src/tools/compiletest/src/runtest/codegen_units.rs
new file mode 100644
index 00000000000..6c866cbef21
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/codegen_units.rs
@@ -0,0 +1,191 @@
+use std::collections::HashSet;
+
+use super::{Emit, TestCx, WillExecute};
+use crate::errors;
+use crate::util::static_regex;
+
+impl TestCx<'_> {
+    pub(super) fn run_codegen_units_test(&self) {
+        assert!(self.revision.is_none(), "revisions not relevant here");
+
+        let proc_res = self.compile_test(WillExecute::No, Emit::None);
+
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+
+        self.check_no_compiler_crash(&proc_res, self.props.should_ice);
+
+        const PREFIX: &str = "MONO_ITEM ";
+        const CGU_MARKER: &str = "@@";
+
+        // Some MonoItems can contain {closure@/path/to/checkout/tests/codgen-units/test.rs}
+        // To prevent the current dir from leaking, we just replace the entire path to the test
+        // file with TEST_PATH.
+        let actual: Vec<MonoItem> = proc_res
+            .stdout
+            .lines()
+            .filter(|line| line.starts_with(PREFIX))
+            .map(|line| {
+                line.replace(&self.testpaths.file.display().to_string(), "TEST_PATH").to_string()
+            })
+            .map(|line| str_to_mono_item(&line, true))
+            .collect();
+
+        let expected: Vec<MonoItem> = errors::load_errors(&self.testpaths.file, None)
+            .iter()
+            .map(|e| str_to_mono_item(&e.msg[..], false))
+            .collect();
+
+        let mut missing = Vec::new();
+        let mut wrong_cgus = Vec::new();
+
+        for expected_item in &expected {
+            let actual_item_with_same_name = actual.iter().find(|ti| ti.name == expected_item.name);
+
+            if let Some(actual_item) = actual_item_with_same_name {
+                if !expected_item.codegen_units.is_empty() &&
+                   // Also check for codegen units
+                   expected_item.codegen_units != actual_item.codegen_units
+                {
+                    wrong_cgus.push((expected_item.clone(), actual_item.clone()));
+                }
+            } else {
+                missing.push(expected_item.string.clone());
+            }
+        }
+
+        let unexpected: Vec<_> = actual
+            .iter()
+            .filter(|acgu| !expected.iter().any(|ecgu| acgu.name == ecgu.name))
+            .map(|acgu| acgu.string.clone())
+            .collect();
+
+        if !missing.is_empty() {
+            missing.sort();
+
+            println!("\nThese items should have been contained but were not:\n");
+
+            for item in &missing {
+                println!("{}", item);
+            }
+
+            println!("\n");
+        }
+
+        if !unexpected.is_empty() {
+            let sorted = {
+                let mut sorted = unexpected.clone();
+                sorted.sort();
+                sorted
+            };
+
+            println!("\nThese items were contained but should not have been:\n");
+
+            for item in sorted {
+                println!("{}", item);
+            }
+
+            println!("\n");
+        }
+
+        if !wrong_cgus.is_empty() {
+            wrong_cgus.sort_by_key(|pair| pair.0.name.clone());
+            println!("\nThe following items were assigned to wrong codegen units:\n");
+
+            for &(ref expected_item, ref actual_item) in &wrong_cgus {
+                println!("{}", expected_item.name);
+                println!("  expected: {}", codegen_units_to_str(&expected_item.codegen_units));
+                println!("  actual:   {}", codegen_units_to_str(&actual_item.codegen_units));
+                println!();
+            }
+        }
+
+        if !(missing.is_empty() && unexpected.is_empty() && wrong_cgus.is_empty()) {
+            panic!();
+        }
+
+        #[derive(Clone, Eq, PartialEq)]
+        struct MonoItem {
+            name: String,
+            codegen_units: HashSet<String>,
+            string: String,
+        }
+
+        // [MONO_ITEM] name [@@ (cgu)+]
+        fn str_to_mono_item(s: &str, cgu_has_crate_disambiguator: bool) -> MonoItem {
+            let s = if s.starts_with(PREFIX) { (&s[PREFIX.len()..]).trim() } else { s.trim() };
+
+            let full_string = format!("{}{}", PREFIX, s);
+
+            let parts: Vec<&str> =
+                s.split(CGU_MARKER).map(str::trim).filter(|s| !s.is_empty()).collect();
+
+            let name = parts[0].trim();
+
+            let cgus = if parts.len() > 1 {
+                let cgus_str = parts[1];
+
+                cgus_str
+                    .split(' ')
+                    .map(str::trim)
+                    .filter(|s| !s.is_empty())
+                    .map(|s| {
+                        if cgu_has_crate_disambiguator {
+                            remove_crate_disambiguators_from_set_of_cgu_names(s)
+                        } else {
+                            s.to_string()
+                        }
+                    })
+                    .collect()
+            } else {
+                HashSet::new()
+            };
+
+            MonoItem { name: name.to_owned(), codegen_units: cgus, string: full_string }
+        }
+
+        fn codegen_units_to_str(cgus: &HashSet<String>) -> String {
+            let mut cgus: Vec<_> = cgus.iter().collect();
+            cgus.sort();
+
+            let mut string = String::new();
+            for cgu in cgus {
+                string.push_str(&cgu[..]);
+                string.push(' ');
+            }
+
+            string
+        }
+
+        // Given a cgu-name-prefix of the form <crate-name>.<crate-disambiguator> or
+        // the form <crate-name1>.<crate-disambiguator1>-in-<crate-name2>.<crate-disambiguator2>,
+        // remove all crate-disambiguators.
+        fn remove_crate_disambiguator_from_cgu(cgu: &str) -> String {
+            let Some(captures) =
+                static_regex!(r"^[^\.]+(?P<d1>\.[[:alnum:]]+)(-in-[^\.]+(?P<d2>\.[[:alnum:]]+))?")
+                    .captures(cgu)
+            else {
+                panic!("invalid cgu name encountered: {cgu}");
+            };
+
+            let mut new_name = cgu.to_owned();
+
+            if let Some(d2) = captures.name("d2") {
+                new_name.replace_range(d2.start()..d2.end(), "");
+            }
+
+            let d1 = captures.name("d1").unwrap();
+            new_name.replace_range(d1.start()..d1.end(), "");
+
+            new_name
+        }
+
+        // The name of merged CGUs is constructed as the names of the original
+        // CGUs joined with "--". This function splits such composite CGU names
+        // and handles each component individually.
+        fn remove_crate_disambiguators_from_set_of_cgu_names(cgus: &str) -> String {
+            cgus.split("--").map(remove_crate_disambiguator_from_cgu).collect::<Vec<_>>().join("--")
+        }
+    }
+}
diff --git a/src/tools/compiletest/src/runtest/coverage.rs b/src/tools/compiletest/src/runtest/coverage.rs
index 05191a15980..961a1602986 100644
--- a/src/tools/compiletest/src/runtest/coverage.rs
+++ b/src/tools/compiletest/src/runtest/coverage.rs
@@ -18,7 +18,7 @@ impl<'test> TestCx<'test> {
             .unwrap_or_else(|| self.fatal("missing --coverage-dump"))
     }
 
-    pub(crate) fn run_coverage_map_test(&self) {
+    pub(super) fn run_coverage_map_test(&self) {
         let coverage_dump_path = self.coverage_dump_path();
 
         let (proc_res, llvm_ir_path) = self.compile_test_and_save_ir();
@@ -50,7 +50,7 @@ impl<'test> TestCx<'test> {
         }
     }
 
-    pub(crate) fn run_coverage_run_test(&self) {
+    pub(super) fn run_coverage_run_test(&self) {
         let should_run = self.run_if_enabled();
         let proc_res = self.compile_test(should_run, Emit::None);
 
diff --git a/src/tools/compiletest/src/runtest/crash.rs b/src/tools/compiletest/src/runtest/crash.rs
new file mode 100644
index 00000000000..7f2bec4949b
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/crash.rs
@@ -0,0 +1,25 @@
+use super::{TestCx, WillExecute};
+
+impl TestCx<'_> {
+    pub(super) fn run_crash_test(&self) {
+        let pm = self.pass_mode();
+        let proc_res = self.compile_test(WillExecute::No, self.should_emit_metadata(pm));
+
+        if std::env::var("COMPILETEST_VERBOSE_CRASHES").is_ok() {
+            eprintln!("{}", proc_res.status);
+            eprintln!("{}", proc_res.stdout);
+            eprintln!("{}", proc_res.stderr);
+            eprintln!("{}", proc_res.cmdline);
+        }
+
+        // if a test does not crash, consider it an error
+        if proc_res.status.success() || matches!(proc_res.status.code(), Some(1 | 0)) {
+            self.fatal(&format!(
+                "crashtest no longer crashes/triggers ICE, horray! Please give it a meaningful name, \
+            add a doc-comment to the start of the test explaining why it exists and \
+            move it to tests/ui or wherever you see fit. Adding 'Fixes #<issueNr>' to your PR description \
+            ensures that the corresponding ticket is auto-closed upon merge."
+            ));
+        }
+    }
+}
diff --git a/src/tools/compiletest/src/runtest/debuginfo.rs b/src/tools/compiletest/src/runtest/debuginfo.rs
new file mode 100644
index 00000000000..36127414ab1
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/debuginfo.rs
@@ -0,0 +1,509 @@
+use std::ffi::{OsStr, OsString};
+use std::fs::File;
+use std::io::{BufRead, BufReader, Read};
+use std::path::Path;
+use std::process::{Command, Output, Stdio};
+
+use tracing::debug;
+
+use super::debugger::DebuggerCommands;
+use super::{Debugger, Emit, ProcRes, TestCx, Truncated, WillExecute};
+use crate::common::Config;
+use crate::util::logv;
+use crate::{extract_gdb_version, is_android_gdb_target};
+
+impl TestCx<'_> {
+    pub(super) fn run_debuginfo_test(&self) {
+        match self.config.debugger.unwrap() {
+            Debugger::Cdb => self.run_debuginfo_cdb_test(),
+            Debugger::Gdb => self.run_debuginfo_gdb_test(),
+            Debugger::Lldb => self.run_debuginfo_lldb_test(),
+        }
+    }
+
+    fn run_debuginfo_cdb_test(&self) {
+        let config = Config {
+            target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
+            host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
+            ..self.config.clone()
+        };
+
+        let test_cx = TestCx { config: &config, ..*self };
+
+        test_cx.run_debuginfo_cdb_test_no_opt();
+    }
+
+    fn run_debuginfo_cdb_test_no_opt(&self) {
+        let exe_file = self.make_exe_name();
+
+        // Existing PDB files are update in-place. When changing the debuginfo
+        // the compiler generates for something, this can lead to the situation
+        // where both the old and the new version of the debuginfo for the same
+        // type is present in the PDB, which is very confusing.
+        // Therefore we delete any existing PDB file before compiling the test
+        // case.
+        // FIXME: If can reliably detect that MSVC's link.exe is used, then
+        //        passing `/INCREMENTAL:NO` might be a cleaner way to do this.
+        let pdb_file = exe_file.with_extension(".pdb");
+        if pdb_file.exists() {
+            std::fs::remove_file(pdb_file).unwrap();
+        }
+
+        // compile test file (it should have 'compile-flags:-g' in the header)
+        let should_run = self.run_if_enabled();
+        let compile_result = self.compile_test(should_run, Emit::None);
+        if !compile_result.status.success() {
+            self.fatal_proc_rec("compilation failed!", &compile_result);
+        }
+        if let WillExecute::Disabled = should_run {
+            return;
+        }
+
+        let prefixes = {
+            static PREFIXES: &[&str] = &["cdb", "cdbg"];
+            // No "native rust support" variation for CDB yet.
+            PREFIXES
+        };
+
+        // Parse debugger commands etc from test files
+        let dbg_cmds = DebuggerCommands::parse_from(
+            &self.testpaths.file,
+            self.config,
+            prefixes,
+            self.revision,
+        )
+        .unwrap_or_else(|e| self.fatal(&e));
+
+        // https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/debugger-commands
+        let mut script_str = String::with_capacity(2048);
+        script_str.push_str("version\n"); // List CDB (and more) version info in test output
+        script_str.push_str(".nvlist\n"); // List loaded `*.natvis` files, bulk of custom MSVC debug
+
+        // If a .js file exists next to the source file being tested, then this is a JavaScript
+        // debugging extension that needs to be loaded.
+        let mut js_extension = self.testpaths.file.clone();
+        js_extension.set_extension("cdb.js");
+        if js_extension.exists() {
+            script_str.push_str(&format!(".scriptload \"{}\"\n", js_extension.to_string_lossy()));
+        }
+
+        // Set breakpoints on every line that contains the string "#break"
+        let source_file_name = self.testpaths.file.file_name().unwrap().to_string_lossy();
+        for line in &dbg_cmds.breakpoint_lines {
+            script_str.push_str(&format!("bp `{}:{}`\n", source_file_name, line));
+        }
+
+        // Append the other `cdb-command:`s
+        for line in &dbg_cmds.commands {
+            script_str.push_str(line);
+            script_str.push('\n');
+        }
+
+        script_str.push_str("qq\n"); // Quit the debugger (including remote debugger, if any)
+
+        // Write the script into a file
+        debug!("script_str = {}", script_str);
+        self.dump_output_file(&script_str, "debugger.script");
+        let debugger_script = self.make_out_name("debugger.script");
+
+        let cdb_path = &self.config.cdb.as_ref().unwrap();
+        let mut cdb = Command::new(cdb_path);
+        cdb.arg("-lines") // Enable source line debugging.
+            .arg("-cf")
+            .arg(&debugger_script)
+            .arg(&exe_file);
+
+        let debugger_run_result = self.compose_and_run(
+            cdb,
+            self.config.run_lib_path.to_str().unwrap(),
+            None, // aux_path
+            None, // input
+        );
+
+        if !debugger_run_result.status.success() {
+            self.fatal_proc_rec("Error while running CDB", &debugger_run_result);
+        }
+
+        if let Err(e) = dbg_cmds.check_output(&debugger_run_result) {
+            self.fatal_proc_rec(&e, &debugger_run_result);
+        }
+    }
+
+    fn run_debuginfo_gdb_test(&self) {
+        let config = Config {
+            target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
+            host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
+            ..self.config.clone()
+        };
+
+        let test_cx = TestCx { config: &config, ..*self };
+
+        test_cx.run_debuginfo_gdb_test_no_opt();
+    }
+
+    fn run_debuginfo_gdb_test_no_opt(&self) {
+        let dbg_cmds = DebuggerCommands::parse_from(
+            &self.testpaths.file,
+            self.config,
+            &["gdb"],
+            self.revision,
+        )
+        .unwrap_or_else(|e| self.fatal(&e));
+        let mut cmds = dbg_cmds.commands.join("\n");
+
+        // compile test file (it should have 'compile-flags:-g' in the header)
+        let should_run = self.run_if_enabled();
+        let compiler_run_result = self.compile_test(should_run, Emit::None);
+        if !compiler_run_result.status.success() {
+            self.fatal_proc_rec("compilation failed!", &compiler_run_result);
+        }
+        if let WillExecute::Disabled = should_run {
+            return;
+        }
+
+        let exe_file = self.make_exe_name();
+
+        let debugger_run_result;
+        if is_android_gdb_target(&self.config.target) {
+            cmds = cmds.replace("run", "continue");
+
+            let tool_path = match self.config.android_cross_path.to_str() {
+                Some(x) => x.to_owned(),
+                None => self.fatal("cannot find android cross path"),
+            };
+
+            // write debugger script
+            let mut script_str = String::with_capacity(2048);
+            script_str.push_str(&format!("set charset {}\n", Self::charset()));
+            script_str.push_str(&format!("set sysroot {}\n", tool_path));
+            script_str.push_str(&format!("file {}\n", exe_file.to_str().unwrap()));
+            script_str.push_str("target remote :5039\n");
+            script_str.push_str(&format!(
+                "set solib-search-path \
+                 ./{}/stage2/lib/rustlib/{}/lib/\n",
+                self.config.host, self.config.target
+            ));
+            for line in &dbg_cmds.breakpoint_lines {
+                script_str.push_str(
+                    format!(
+                        "break {:?}:{}\n",
+                        self.testpaths.file.file_name().unwrap().to_string_lossy(),
+                        *line
+                    )
+                    .as_str(),
+                );
+            }
+            script_str.push_str(&cmds);
+            script_str.push_str("\nquit\n");
+
+            debug!("script_str = {}", script_str);
+            self.dump_output_file(&script_str, "debugger.script");
+
+            let adb_path = &self.config.adb_path;
+
+            Command::new(adb_path)
+                .arg("push")
+                .arg(&exe_file)
+                .arg(&self.config.adb_test_dir)
+                .status()
+                .unwrap_or_else(|e| panic!("failed to exec `{adb_path:?}`: {e:?}"));
+
+            Command::new(adb_path)
+                .args(&["forward", "tcp:5039", "tcp:5039"])
+                .status()
+                .unwrap_or_else(|e| panic!("failed to exec `{adb_path:?}`: {e:?}"));
+
+            let adb_arg = format!(
+                "export LD_LIBRARY_PATH={}; \
+                 gdbserver{} :5039 {}/{}",
+                self.config.adb_test_dir.clone(),
+                if self.config.target.contains("aarch64") { "64" } else { "" },
+                self.config.adb_test_dir.clone(),
+                exe_file.file_name().unwrap().to_str().unwrap()
+            );
+
+            debug!("adb arg: {}", adb_arg);
+            let mut adb = Command::new(adb_path)
+                .args(&["shell", &adb_arg])
+                .stdout(Stdio::piped())
+                .stderr(Stdio::inherit())
+                .spawn()
+                .unwrap_or_else(|e| panic!("failed to exec `{adb_path:?}`: {e:?}"));
+
+            // Wait for the gdbserver to print out "Listening on port ..."
+            // at which point we know that it's started and then we can
+            // execute the debugger below.
+            let mut stdout = BufReader::new(adb.stdout.take().unwrap());
+            let mut line = String::new();
+            loop {
+                line.truncate(0);
+                stdout.read_line(&mut line).unwrap();
+                if line.starts_with("Listening on port 5039") {
+                    break;
+                }
+            }
+            drop(stdout);
+
+            let mut debugger_script = OsString::from("-command=");
+            debugger_script.push(self.make_out_name("debugger.script"));
+            let debugger_opts: &[&OsStr] =
+                &["-quiet".as_ref(), "-batch".as_ref(), "-nx".as_ref(), &debugger_script];
+
+            let gdb_path = self.config.gdb.as_ref().unwrap();
+            let Output { status, stdout, stderr } = Command::new(&gdb_path)
+                .args(debugger_opts)
+                .output()
+                .unwrap_or_else(|e| panic!("failed to exec `{gdb_path:?}`: {e:?}"));
+            let cmdline = {
+                let mut gdb = Command::new(&format!("{}-gdb", self.config.target));
+                gdb.args(debugger_opts);
+                let cmdline = self.make_cmdline(&gdb, "");
+                logv(self.config, format!("executing {}", cmdline));
+                cmdline
+            };
+
+            debugger_run_result = ProcRes {
+                status,
+                stdout: String::from_utf8(stdout).unwrap(),
+                stderr: String::from_utf8(stderr).unwrap(),
+                truncated: Truncated::No,
+                cmdline,
+            };
+            if adb.kill().is_err() {
+                println!("Adb process is already finished.");
+            }
+        } else {
+            let rust_src_root =
+                self.config.find_rust_src_root().expect("Could not find Rust source root");
+            let rust_pp_module_rel_path = Path::new("./src/etc");
+            let rust_pp_module_abs_path =
+                rust_src_root.join(rust_pp_module_rel_path).to_str().unwrap().to_owned();
+            // write debugger script
+            let mut script_str = String::with_capacity(2048);
+            script_str.push_str(&format!("set charset {}\n", Self::charset()));
+            script_str.push_str("show version\n");
+
+            match self.config.gdb_version {
+                Some(version) => {
+                    println!("NOTE: compiletest thinks it is using GDB version {}", version);
+
+                    if version > extract_gdb_version("7.4").unwrap() {
+                        // Add the directory containing the pretty printers to
+                        // GDB's script auto loading safe path
+                        script_str.push_str(&format!(
+                            "add-auto-load-safe-path {}\n",
+                            rust_pp_module_abs_path.replace(r"\", r"\\")
+                        ));
+
+                        let output_base_dir = self.output_base_dir().to_str().unwrap().to_owned();
+
+                        // Add the directory containing the output binary to
+                        // include embedded pretty printers to GDB's script
+                        // auto loading safe path
+                        script_str.push_str(&format!(
+                            "add-auto-load-safe-path {}\n",
+                            output_base_dir.replace(r"\", r"\\")
+                        ));
+                    }
+                }
+                _ => {
+                    println!(
+                        "NOTE: compiletest does not know which version of \
+                         GDB it is using"
+                    );
+                }
+            }
+
+            // The following line actually doesn't have to do anything with
+            // pretty printing, it just tells GDB to print values on one line:
+            script_str.push_str("set print pretty off\n");
+
+            // Add the pretty printer directory to GDB's source-file search path
+            script_str
+                .push_str(&format!("directory {}\n", rust_pp_module_abs_path.replace(r"\", r"\\")));
+
+            // Load the target executable
+            script_str
+                .push_str(&format!("file {}\n", exe_file.to_str().unwrap().replace(r"\", r"\\")));
+
+            // Force GDB to print values in the Rust format.
+            script_str.push_str("set language rust\n");
+
+            // Add line breakpoints
+            for line in &dbg_cmds.breakpoint_lines {
+                script_str.push_str(&format!(
+                    "break '{}':{}\n",
+                    self.testpaths.file.file_name().unwrap().to_string_lossy(),
+                    *line
+                ));
+            }
+
+            script_str.push_str(&cmds);
+            script_str.push_str("\nquit\n");
+
+            debug!("script_str = {}", script_str);
+            self.dump_output_file(&script_str, "debugger.script");
+
+            let mut debugger_script = OsString::from("-command=");
+            debugger_script.push(self.make_out_name("debugger.script"));
+
+            let debugger_opts: &[&OsStr] =
+                &["-quiet".as_ref(), "-batch".as_ref(), "-nx".as_ref(), &debugger_script];
+
+            let mut gdb = Command::new(self.config.gdb.as_ref().unwrap());
+            let pythonpath = if let Ok(pp) = std::env::var("PYTHONPATH") {
+                format!("{pp}:{rust_pp_module_abs_path}")
+            } else {
+                rust_pp_module_abs_path
+            };
+            gdb.args(debugger_opts).env("PYTHONPATH", pythonpath);
+
+            debugger_run_result =
+                self.compose_and_run(gdb, self.config.run_lib_path.to_str().unwrap(), None, None);
+        }
+
+        if !debugger_run_result.status.success() {
+            self.fatal_proc_rec("gdb failed to execute", &debugger_run_result);
+        }
+
+        if let Err(e) = dbg_cmds.check_output(&debugger_run_result) {
+            self.fatal_proc_rec(&e, &debugger_run_result);
+        }
+    }
+
+    fn run_debuginfo_lldb_test(&self) {
+        if self.config.lldb_python_dir.is_none() {
+            self.fatal("Can't run LLDB test because LLDB's python path is not set.");
+        }
+
+        let config = Config {
+            target_rustcflags: self.cleanup_debug_info_options(&self.config.target_rustcflags),
+            host_rustcflags: self.cleanup_debug_info_options(&self.config.host_rustcflags),
+            ..self.config.clone()
+        };
+
+        let test_cx = TestCx { config: &config, ..*self };
+
+        test_cx.run_debuginfo_lldb_test_no_opt();
+    }
+
+    fn run_debuginfo_lldb_test_no_opt(&self) {
+        // compile test file (it should have 'compile-flags:-g' in the header)
+        let should_run = self.run_if_enabled();
+        let compile_result = self.compile_test(should_run, Emit::None);
+        if !compile_result.status.success() {
+            self.fatal_proc_rec("compilation failed!", &compile_result);
+        }
+        if let WillExecute::Disabled = should_run {
+            return;
+        }
+
+        let exe_file = self.make_exe_name();
+
+        match self.config.lldb_version {
+            Some(ref version) => {
+                println!("NOTE: compiletest thinks it is using LLDB version {}", version);
+            }
+            _ => {
+                println!(
+                    "NOTE: compiletest does not know which version of \
+                     LLDB it is using"
+                );
+            }
+        }
+
+        // Parse debugger commands etc from test files
+        let dbg_cmds = DebuggerCommands::parse_from(
+            &self.testpaths.file,
+            self.config,
+            &["lldb"],
+            self.revision,
+        )
+        .unwrap_or_else(|e| self.fatal(&e));
+
+        // Write debugger script:
+        // We don't want to hang when calling `quit` while the process is still running
+        let mut script_str = String::from("settings set auto-confirm true\n");
+
+        // Make LLDB emit its version, so we have it documented in the test output
+        script_str.push_str("version\n");
+
+        // Switch LLDB into "Rust mode"
+        let rust_src_root =
+            self.config.find_rust_src_root().expect("Could not find Rust source root");
+        let rust_pp_module_rel_path = Path::new("./src/etc");
+        let rust_pp_module_abs_path = rust_src_root.join(rust_pp_module_rel_path);
+
+        script_str.push_str(&format!(
+            "command script import {}/lldb_lookup.py\n",
+            rust_pp_module_abs_path.to_str().unwrap()
+        ));
+        File::open(rust_pp_module_abs_path.join("lldb_commands"))
+            .and_then(|mut file| file.read_to_string(&mut script_str))
+            .expect("Failed to read lldb_commands");
+
+        // Set breakpoints on every line that contains the string "#break"
+        let source_file_name = self.testpaths.file.file_name().unwrap().to_string_lossy();
+        for line in &dbg_cmds.breakpoint_lines {
+            script_str.push_str(&format!(
+                "breakpoint set --file '{}' --line {}\n",
+                source_file_name, line
+            ));
+        }
+
+        // Append the other commands
+        for line in &dbg_cmds.commands {
+            script_str.push_str(line);
+            script_str.push('\n');
+        }
+
+        // Finally, quit the debugger
+        script_str.push_str("\nquit\n");
+
+        // Write the script into a file
+        debug!("script_str = {}", script_str);
+        self.dump_output_file(&script_str, "debugger.script");
+        let debugger_script = self.make_out_name("debugger.script");
+
+        // Let LLDB execute the script via lldb_batchmode.py
+        let debugger_run_result = self.run_lldb(&exe_file, &debugger_script, &rust_src_root);
+
+        if !debugger_run_result.status.success() {
+            self.fatal_proc_rec("Error while running LLDB", &debugger_run_result);
+        }
+
+        if let Err(e) = dbg_cmds.check_output(&debugger_run_result) {
+            self.fatal_proc_rec(&e, &debugger_run_result);
+        }
+    }
+
+    fn run_lldb(
+        &self,
+        test_executable: &Path,
+        debugger_script: &Path,
+        rust_src_root: &Path,
+    ) -> ProcRes {
+        // Prepare the lldb_batchmode which executes the debugger script
+        let lldb_script_path = rust_src_root.join("src/etc/lldb_batchmode.py");
+        let pythonpath = if let Ok(pp) = std::env::var("PYTHONPATH") {
+            format!("{pp}:{}", self.config.lldb_python_dir.as_ref().unwrap())
+        } else {
+            self.config.lldb_python_dir.as_ref().unwrap().to_string()
+        };
+        self.run_command_to_procres(
+            Command::new(&self.config.python)
+                .arg(&lldb_script_path)
+                .arg(test_executable)
+                .arg(debugger_script)
+                .env("PYTHONUNBUFFERED", "1") // Help debugging #78665
+                .env("PYTHONPATH", pythonpath),
+        )
+    }
+
+    fn cleanup_debug_info_options(&self, options: &Vec<String>) -> Vec<String> {
+        // Remove options that are either unwanted (-O) or may lead to duplicates due to RUSTFLAGS.
+        let options_to_remove = ["-O".to_owned(), "-g".to_owned(), "--debuginfo".to_owned()];
+
+        options.iter().filter(|x| !options_to_remove.contains(x)).cloned().collect()
+    }
+}
diff --git a/src/tools/compiletest/src/runtest/incremental.rs b/src/tools/compiletest/src/runtest/incremental.rs
new file mode 100644
index 00000000000..81b006292e4
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/incremental.rs
@@ -0,0 +1,128 @@
+use super::{TestCx, WillExecute};
+use crate::errors;
+
+// FIXME(jieyouxu): `run_rpass_test` got hoisted out of this because apparently valgrind falls back
+// to `run_rpass_test` if valgrind isn't available, which is questionable, but keeping it for
+// refactoring changes to preserve current behavior.
+
+impl TestCx<'_> {
+    pub(super) fn run_incremental_test(&self) {
+        // Basic plan for a test incremental/foo/bar.rs:
+        // - load list of revisions rpass1, cfail2, rpass3
+        //   - each should begin with `cpass`, `rpass`, `cfail`, or `rfail`
+        //   - if `cpass`, expect compilation to succeed, don't execute
+        //   - if `rpass`, expect compilation and execution to succeed
+        //   - if `cfail`, expect compilation to fail
+        //   - if `rfail`, expect compilation to succeed and execution to fail
+        // - create a directory build/foo/bar.incremental
+        // - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C rpass1
+        //   - because name of revision starts with "rpass", expect success
+        // - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C cfail2
+        //   - because name of revision starts with "cfail", expect an error
+        //   - load expected errors as usual, but filter for those that end in `[rfail2]`
+        // - compile foo/bar.rs with -C incremental=.../foo/bar.incremental and -C rpass3
+        //   - because name of revision starts with "rpass", expect success
+        // - execute build/foo/bar.exe and save output
+        //
+        // FIXME -- use non-incremental mode as an oracle? That doesn't apply
+        // to #[rustc_dirty] and clean tests I guess
+
+        let revision = self.revision.expect("incremental tests require a list of revisions");
+
+        // Incremental workproduct directory should have already been created.
+        let incremental_dir = self.props.incremental_dir.as_ref().unwrap();
+        assert!(incremental_dir.exists(), "init_incremental_test failed to create incremental dir");
+
+        if self.config.verbose {
+            print!("revision={:?} props={:#?}", revision, self.props);
+        }
+
+        if revision.starts_with("cpass") {
+            if self.props.should_ice {
+                self.fatal("can only use should-ice in cfail tests");
+            }
+            self.run_cpass_test();
+        } else if revision.starts_with("rpass") {
+            if self.props.should_ice {
+                self.fatal("can only use should-ice in cfail tests");
+            }
+            self.run_rpass_test();
+        } else if revision.starts_with("rfail") {
+            if self.props.should_ice {
+                self.fatal("can only use should-ice in cfail tests");
+            }
+            self.run_rfail_test();
+        } else if revision.starts_with("cfail") {
+            self.run_cfail_test();
+        } else {
+            self.fatal("revision name must begin with cpass, rpass, rfail, or cfail");
+        }
+    }
+
+    fn run_cpass_test(&self) {
+        let emit_metadata = self.should_emit_metadata(self.pass_mode());
+        let proc_res = self.compile_test(WillExecute::No, emit_metadata);
+
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+
+        // FIXME(#41968): Move this check to tidy?
+        if !errors::load_errors(&self.testpaths.file, self.revision).is_empty() {
+            self.fatal("compile-pass tests with expected warnings should be moved to ui/");
+        }
+    }
+
+    fn run_cfail_test(&self) {
+        let pm = self.pass_mode();
+        let proc_res = self.compile_test(WillExecute::No, self.should_emit_metadata(pm));
+        self.check_if_test_should_compile(&proc_res, pm);
+        self.check_no_compiler_crash(&proc_res, self.props.should_ice);
+
+        let output_to_check = self.get_output(&proc_res);
+        let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
+        if !expected_errors.is_empty() {
+            if !self.props.error_patterns.is_empty() || !self.props.regex_error_patterns.is_empty()
+            {
+                self.fatal("both error pattern and expected errors specified");
+            }
+            self.check_expected_errors(expected_errors, &proc_res);
+        } else {
+            self.check_all_error_patterns(&output_to_check, &proc_res, pm);
+        }
+        if self.props.should_ice {
+            match proc_res.status.code() {
+                Some(101) => (),
+                _ => self.fatal("expected ICE"),
+            }
+        }
+
+        self.check_forbid_output(&output_to_check, &proc_res);
+    }
+
+    fn run_rfail_test(&self) {
+        let pm = self.pass_mode();
+        let should_run = self.run_if_enabled();
+        let proc_res = self.compile_test(should_run, self.should_emit_metadata(pm));
+
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+
+        if let WillExecute::Disabled = should_run {
+            return;
+        }
+
+        let proc_res = self.exec_compiled_test();
+
+        // The value our Makefile configures valgrind to return on failure
+        const VALGRIND_ERR: i32 = 100;
+        if proc_res.status.code() == Some(VALGRIND_ERR) {
+            self.fatal_proc_rec("run-fail test isn't valgrind-clean!", &proc_res);
+        }
+
+        let output_to_check = self.get_output(&proc_res);
+        self.check_correct_failure_status(&proc_res);
+        self.check_all_error_patterns(&output_to_check, &proc_res, pm);
+    }
+}
diff --git a/src/tools/compiletest/src/runtest/js_doc.rs b/src/tools/compiletest/src/runtest/js_doc.rs
new file mode 100644
index 00000000000..68c74cd155c
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/js_doc.rs
@@ -0,0 +1,32 @@
+use std::process::Command;
+
+use super::TestCx;
+
+impl TestCx<'_> {
+    pub(super) fn run_js_doc_test(&self) {
+        if let Some(nodejs) = &self.config.nodejs {
+            let out_dir = self.output_base_dir();
+
+            self.document(&out_dir, &self.testpaths);
+
+            let root = self.config.find_rust_src_root().unwrap();
+            let file_stem =
+                self.testpaths.file.file_stem().and_then(|f| f.to_str()).expect("no file stem");
+            let res = self.run_command_to_procres(
+                Command::new(&nodejs)
+                    .arg(root.join("src/tools/rustdoc-js/tester.js"))
+                    .arg("--doc-folder")
+                    .arg(out_dir)
+                    .arg("--crate-name")
+                    .arg(file_stem.replace("-", "_"))
+                    .arg("--test-file")
+                    .arg(self.testpaths.file.with_extension("js")),
+            );
+            if !res.status.success() {
+                self.fatal_proc_rec("rustdoc-js test failed!", &res);
+            }
+        } else {
+            self.fatal("no nodeJS");
+        }
+    }
+}
diff --git a/src/tools/compiletest/src/runtest/mir_opt.rs b/src/tools/compiletest/src/runtest/mir_opt.rs
new file mode 100644
index 00000000000..02289a8df1e
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/mir_opt.rs
@@ -0,0 +1,155 @@
+use std::fs;
+use std::path::{Path, PathBuf};
+
+use glob::glob;
+use miropt_test_tools::{files_for_miropt_test, MiroptTest, MiroptTestFile};
+use tracing::debug;
+
+use super::{Emit, TestCx, WillExecute};
+use crate::compute_diff::write_diff;
+
+impl TestCx<'_> {
+    pub(super) fn run_mir_opt_test(&self) {
+        let pm = self.pass_mode();
+        let should_run = self.should_run(pm);
+
+        let mut test_info = files_for_miropt_test(
+            &self.testpaths.file,
+            self.config.get_pointer_width(),
+            self.config.target_cfg().panic.for_miropt_test_tools(),
+        );
+
+        let passes = std::mem::take(&mut test_info.passes);
+
+        let proc_res = self.compile_test_with_passes(should_run, Emit::Mir, passes);
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+        self.check_mir_dump(test_info);
+
+        if let WillExecute::Yes = should_run {
+            let proc_res = self.exec_compiled_test();
+
+            if !proc_res.status.success() {
+                self.fatal_proc_rec("test run failed!", &proc_res);
+            }
+        }
+    }
+
+    fn check_mir_dump(&self, test_info: MiroptTest) {
+        let test_dir = self.testpaths.file.parent().unwrap();
+        let test_crate =
+            self.testpaths.file.file_stem().unwrap().to_str().unwrap().replace('-', "_");
+
+        let MiroptTest { run_filecheck, suffix, files, passes: _ } = test_info;
+
+        if self.config.bless {
+            for e in
+                glob(&format!("{}/{}.*{}.mir", test_dir.display(), test_crate, suffix)).unwrap()
+            {
+                fs::remove_file(e.unwrap()).unwrap();
+            }
+            for e in
+                glob(&format!("{}/{}.*{}.diff", test_dir.display(), test_crate, suffix)).unwrap()
+            {
+                fs::remove_file(e.unwrap()).unwrap();
+            }
+        }
+
+        for MiroptTestFile { from_file, to_file, expected_file } in files {
+            let dumped_string = if let Some(after) = to_file {
+                self.diff_mir_files(from_file.into(), after.into())
+            } else {
+                let mut output_file = PathBuf::new();
+                output_file.push(self.get_mir_dump_dir());
+                output_file.push(&from_file);
+                debug!(
+                    "comparing the contents of: {} with {}",
+                    output_file.display(),
+                    expected_file.display()
+                );
+                if !output_file.exists() {
+                    panic!(
+                        "Output file `{}` from test does not exist, available files are in `{}`",
+                        output_file.display(),
+                        output_file.parent().unwrap().display()
+                    );
+                }
+                self.check_mir_test_timestamp(&from_file, &output_file);
+                let dumped_string = fs::read_to_string(&output_file).unwrap();
+                self.normalize_output(&dumped_string, &[])
+            };
+
+            if self.config.bless {
+                let _ = fs::remove_file(&expected_file);
+                fs::write(expected_file, dumped_string.as_bytes()).unwrap();
+            } else {
+                if !expected_file.exists() {
+                    panic!("Output file `{}` from test does not exist", expected_file.display());
+                }
+                let expected_string = fs::read_to_string(&expected_file).unwrap();
+                if dumped_string != expected_string {
+                    print!("{}", write_diff(&expected_string, &dumped_string, 3));
+                    panic!(
+                        "Actual MIR output differs from expected MIR output {}",
+                        expected_file.display()
+                    );
+                }
+            }
+        }
+
+        if run_filecheck {
+            let output_path = self.output_base_name().with_extension("mir");
+            let proc_res = self.verify_with_filecheck(&output_path);
+            if !proc_res.status.success() {
+                self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
+            }
+        }
+    }
+
+    fn diff_mir_files(&self, before: PathBuf, after: PathBuf) -> String {
+        let to_full_path = |path: PathBuf| {
+            let full = self.get_mir_dump_dir().join(&path);
+            if !full.exists() {
+                panic!(
+                    "the mir dump file for {} does not exist (requested in {})",
+                    path.display(),
+                    self.testpaths.file.display(),
+                );
+            }
+            full
+        };
+        let before = to_full_path(before);
+        let after = to_full_path(after);
+        debug!("comparing the contents of: {} with {}", before.display(), after.display());
+        let before = fs::read_to_string(before).unwrap();
+        let after = fs::read_to_string(after).unwrap();
+        let before = self.normalize_output(&before, &[]);
+        let after = self.normalize_output(&after, &[]);
+        let mut dumped_string = String::new();
+        for result in diff::lines(&before, &after) {
+            use std::fmt::Write;
+            match result {
+                diff::Result::Left(s) => writeln!(dumped_string, "- {}", s).unwrap(),
+                diff::Result::Right(s) => writeln!(dumped_string, "+ {}", s).unwrap(),
+                diff::Result::Both(s, _) => writeln!(dumped_string, "  {}", s).unwrap(),
+            }
+        }
+        dumped_string
+    }
+
+    fn check_mir_test_timestamp(&self, test_name: &str, output_file: &Path) {
+        let t = |file| fs::metadata(file).unwrap().modified().unwrap();
+        let source_file = &self.testpaths.file;
+        let output_time = t(output_file);
+        let source_time = t(source_file);
+        if source_time > output_time {
+            debug!("source file time: {:?} output file time: {:?}", source_time, output_time);
+            panic!(
+                "test source file `{}` is newer than potentially stale output file `{}`.",
+                source_file.display(),
+                test_name
+            );
+        }
+    }
+}
diff --git a/src/tools/compiletest/src/runtest/pretty.rs b/src/tools/compiletest/src/runtest/pretty.rs
new file mode 100644
index 00000000000..40e767e84ef
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/pretty.rs
@@ -0,0 +1,104 @@
+use std::fs;
+
+use super::{ProcRes, ReadFrom, TestCx};
+use crate::util::logv;
+
+impl TestCx<'_> {
+    pub(super) fn run_pretty_test(&self) {
+        if self.props.pp_exact.is_some() {
+            logv(self.config, "testing for exact pretty-printing".to_owned());
+        } else {
+            logv(self.config, "testing for converging pretty-printing".to_owned());
+        }
+
+        let rounds = match self.props.pp_exact {
+            Some(_) => 1,
+            None => 2,
+        };
+
+        let src = fs::read_to_string(&self.testpaths.file).unwrap();
+        let mut srcs = vec![src];
+
+        let mut round = 0;
+        while round < rounds {
+            logv(
+                self.config,
+                format!("pretty-printing round {} revision {:?}", round, self.revision),
+            );
+            let read_from =
+                if round == 0 { ReadFrom::Path } else { ReadFrom::Stdin(srcs[round].to_owned()) };
+
+            let proc_res = self.print_source(read_from, &self.props.pretty_mode);
+            if !proc_res.status.success() {
+                self.fatal_proc_rec(
+                    &format!(
+                        "pretty-printing failed in round {} revision {:?}",
+                        round, self.revision
+                    ),
+                    &proc_res,
+                );
+            }
+
+            let ProcRes { stdout, .. } = proc_res;
+            srcs.push(stdout);
+            round += 1;
+        }
+
+        let mut expected = match self.props.pp_exact {
+            Some(ref file) => {
+                let filepath = self.testpaths.file.parent().unwrap().join(file);
+                fs::read_to_string(&filepath).unwrap()
+            }
+            None => srcs[srcs.len() - 2].clone(),
+        };
+        let mut actual = srcs[srcs.len() - 1].clone();
+
+        if self.props.pp_exact.is_some() {
+            // Now we have to care about line endings
+            let cr = "\r".to_owned();
+            actual = actual.replace(&cr, "");
+            expected = expected.replace(&cr, "");
+        }
+
+        if !self.config.bless {
+            self.compare_source(&expected, &actual);
+        } else if expected != actual {
+            let filepath_buf;
+            let filepath = match &self.props.pp_exact {
+                Some(file) => {
+                    filepath_buf = self.testpaths.file.parent().unwrap().join(file);
+                    &filepath_buf
+                }
+                None => &self.testpaths.file,
+            };
+            fs::write(filepath, &actual).unwrap();
+        }
+
+        // If we're only making sure that the output matches then just stop here
+        if self.props.pretty_compare_only {
+            return;
+        }
+
+        // Finally, let's make sure it actually appears to remain valid code
+        let proc_res = self.typecheck_source(actual);
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("pretty-printed source does not typecheck", &proc_res);
+        }
+
+        if !self.props.pretty_expanded {
+            return;
+        }
+
+        // additionally, run `-Zunpretty=expanded` and try to build it.
+        let proc_res = self.print_source(ReadFrom::Path, "expanded");
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("pretty-printing (expanded) failed", &proc_res);
+        }
+
+        let ProcRes { stdout: expanded_src, .. } = proc_res;
+        let proc_res = self.typecheck_source(expanded_src);
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("pretty-printed source (expanded) does not typecheck", &proc_res);
+        }
+    }
+}
diff --git a/src/tools/compiletest/src/runtest/run_make.rs b/src/tools/compiletest/src/runtest/run_make.rs
new file mode 100644
index 00000000000..75fe6a6baaf
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/run_make.rs
@@ -0,0 +1,526 @@
+use std::path::Path;
+use std::process::{Command, Output, Stdio};
+use std::{env, fs};
+
+use super::{ProcRes, TestCx};
+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();
+        let src_root = self.config.src_base.parent().unwrap().parent().unwrap();
+        let src_root = cwd.join(&src_root);
+
+        let tmpdir = cwd.join(self.output_base_name());
+        if tmpdir.exists() {
+            self.aggressive_rm_rf(&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", 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`.
+        //
+        // 1. We need to build the recipe `rmake.rs` as a binary and link in the `run_make_support`
+        //    library.
+        // 2. We need to run the recipe binary.
+
+        // So we assume the rust-lang/rust project setup looks like the following (our `.` is the
+        // top-level directory, irrelevant entries to our purposes omitted):
+        //
+        // ```
+        // .                               // <- `source_root`
+        // ├── build/                      // <- `build_root`
+        // ├── compiler/
+        // ├── library/
+        // ├── src/
+        // │  └── tools/
+        // │     └── run_make_support/
+        // └── tests
+        //    └── run-make/
+        // ```
+
+        // `source_root` is the top-level directory containing the rust-lang/rust checkout.
+        let source_root =
+            self.config.find_rust_src_root().expect("could not determine rust source root");
+        // `self.config.build_base` is actually the build base folder + "test" + test suite name, it
+        // looks like `build/<host_triple>/test/run-make`. But we want `build/<host_triple>/`. Note
+        // that the `build` directory does not need to be called `build`, nor does it need to be
+        // under `source_root`, so we must compute it based off of `self.config.build_base`.
+        let build_root =
+            self.config.build_base.parent().and_then(Path::parent).unwrap().to_path_buf();
+
+        // We construct the following directory tree for each rmake.rs test:
+        // ```
+        // <base_dir>/
+        //     rmake.exe
+        //     rmake_out/
+        // ```
+        // having the recipe executable separate from the output artifacts directory allows the
+        // 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_name();
+        if base_dir.exists() {
+            self.aggressive_rm_rf(&base_dir).unwrap();
+        }
+        let rmake_out_dir = base_dir.join("rmake_out");
+        fs::create_dir_all(&rmake_out_dir).unwrap();
+
+        // Copy all input files (apart from rmake.rs) to the temporary directory,
+        // so that the input directory structure from `tests/run-make/<test>` is mirrored
+        // to the `rmake_out` directory.
+        for path in walkdir::WalkDir::new(&self.testpaths.file).min_depth(1) {
+            let path = path.unwrap().path().to_path_buf();
+            if path.file_name().is_some_and(|s| s != "rmake.rs") {
+                let target = rmake_out_dir.join(path.strip_prefix(&self.testpaths.file).unwrap());
+                if path.is_dir() {
+                    copy_dir_all(&path, target).unwrap();
+                } else {
+                    fs::copy(&path, target).unwrap();
+                }
+            }
+        }
+
+        // `self.config.stage_id` looks like `stage1-<target_triple>`, but we only want
+        // the `stage1` part as that is what the output directories of bootstrap are prefixed with.
+        // Note that this *assumes* build layout from bootstrap is produced as:
+        //
+        // ```
+        // build/<target_triple>/          // <- this is `build_root`
+        // ├── stage0
+        // ├── stage0-bootstrap-tools
+        // ├── stage0-codegen
+        // ├── stage0-rustc
+        // ├── stage0-std
+        // ├── stage0-sysroot
+        // ├── stage0-tools
+        // ├── stage0-tools-bin
+        // ├── stage1
+        // ├── stage1-std
+        // ├── stage1-tools
+        // ├── stage1-tools-bin
+        // └── test
+        // ```
+        // FIXME(jieyouxu): improve the communication between bootstrap and compiletest here so
+        // we don't have to hack out a `stageN`.
+        let stage = self.config.stage_id.split('-').next().unwrap();
+
+        // In order to link in the support library as a rlib when compiling recipes, we need three
+        // paths:
+        // 1. Path of the built support library rlib itself.
+        // 2. Path of the built support library's dependencies directory.
+        // 3. Path of the built support library's dependencies' dependencies directory.
+        //
+        // The paths look like
+        //
+        // ```
+        // 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
+        // ```
+        //
+        // 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.
+
+        let stage_tools_bin = build_root.join(format!("{stage}-tools-bin"));
+        let support_lib_path = stage_tools_bin.join("librun_make_support.rlib");
+
+        let stage_tools = build_root.join(format!("{stage}-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");
+
+        // To compile the recipe with rustc, we need to provide suitable dynamic library search
+        // paths to rustc. This includes both:
+        // 1. The "base" dylib search paths that was provided to compiletest, e.g. `LD_LIBRARY_PATH`
+        //    on some linux distros.
+        // 2. Specific library paths in `self.config.compile_lib_path` needed for running rustc.
+
+        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.
+        let recipe_bin = {
+            let mut p = base_dir.join("rmake");
+            p.set_extension(env::consts::EXE_EXTENSION);
+            p
+        };
+
+        let mut rustc = Command::new(&self.config.rustc_path);
+        rustc
+            .arg("-o")
+            .arg(&recipe_bin)
+            // Specify library search paths for `run_make_support`.
+            .arg(format!("-Ldependency={}", &support_lib_path.parent().unwrap().to_string_lossy()))
+            .arg(format!("-Ldependency={}", &support_lib_deps.to_string_lossy()))
+            .arg(format!("-Ldependency={}", &support_lib_deps_deps.to_string_lossy()))
+            // Provide `run_make_support` as extern prelude, so test writers don't need to write
+            // `extern run_make_support;`.
+            .arg("--extern")
+            .arg(format!("run_make_support={}", &support_lib_path.to_string_lossy()))
+            .arg("--edition=2021")
+            .arg(&self.testpaths.file.join("rmake.rs"))
+            // Provide necessary library search paths for rustc.
+            .env(dylib_env_var(), &env::join_paths(host_dylib_search_paths).unwrap());
+
+        // 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.
+        if std::env::var_os("COMPILETEST_FORCE_STAGE0").is_some() {
+            let stage0_sysroot = build_root.join("stage0-sysroot");
+            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() {
+            self.fatal_proc_rec("run-make test failed: could not build `rmake.rs` recipe", &res);
+        }
+
+        // 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 = build_root.join(&stage).join("lib");
+
+        // Compute dynamic library search paths for recipes.
+        let recipe_dylib_search_paths = {
+            let mut paths = base_dylib_search_paths.clone();
+            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
+        };
+
+        // 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())
+            .stderr(Stdio::piped())
+            // Provide the target-specific env var that is used to record dylib search paths. For
+            // 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.
+            .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 target.
+            .env("TARGET", &self.config.target)
+            // Some tests unfortunately still need Python, so provide path to a Python interpreter.
+            .env("PYTHON", &self.config.python)
+            // Provide path to checkout root. This is the top-level directory containing
+            // rust-lang/rust checkout.
+            .env("SOURCE_ROOT", &source_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);
+
+        if let Some(ref cargo) = self.config.cargo_path {
+            cmd.env("CARGO", source_root.join(cargo));
+        }
+
+        if let Some(ref rustdoc) = self.config.rustdoc_path {
+            cmd.env("RUSTDOC", source_root.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 {
+            // If we're running in `--bless` mode, set an environment variable to tell
+            // `run_make_support` to bless snapshot files instead of checking them.
+            //
+            // The value is this test's source directory, because the support code
+            // will need that path in order to bless the _original_ snapshot files,
+            // not the copies in `rmake_out`.
+            // (See <https://github.com/rust-lang/rust/issues/129038>.)
+            cmd.env("RUSTC_BLESS_TEST", &self.testpaths.file);
+        }
+
+        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()))
+                // Note: we diverge from legacy run_make and don't lump `CC` the compiler and
+                // default flags together.
+                .env("CC_DEFAULT_FLAGS", &cflags)
+                .env("CC", &self.config.cc)
+                .env("CXX_DEFAULT_FLAGS", &cxxflags)
+                .env("CXX", &self.config.cxx);
+        } else {
+            cmd.env("CC_DEFAULT_FLAGS", &self.config.cflags)
+                .env("CC", &self.config.cc)
+                .env("CXX_DEFAULT_FLAGS", &self.config.cxxflags)
+                .env("CXX", &self.config.cxx)
+                .env("AR", &self.config.ar);
+
+            if self.config.target.contains("windows") {
+                cmd.env("IS_WINDOWS", "1");
+            }
+        }
+
+        let (Output { stdout, stderr, status }, truncated) =
+            self.read2_abbreviated(cmd.spawn().expect("failed to spawn `rmake`"));
+        if !status.success() {
+            let res = ProcRes {
+                status,
+                stdout: String::from_utf8_lossy(&stdout).into_owned(),
+                stderr: String::from_utf8_lossy(&stderr).into_owned(),
+                truncated,
+                cmdline: format!("{:?}", cmd),
+            };
+            self.fatal_proc_rec("rmake recipe failed to complete", &res);
+        }
+    }
+}
diff --git a/src/tools/compiletest/src/runtest/rustdoc.rs b/src/tools/compiletest/src/runtest/rustdoc.rs
new file mode 100644
index 00000000000..6a31888527e
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/rustdoc.rs
@@ -0,0 +1,34 @@
+use std::process::Command;
+
+use super::{remove_and_create_dir_all, TestCx};
+
+impl TestCx<'_> {
+    pub(super) fn run_rustdoc_test(&self) {
+        assert!(self.revision.is_none(), "revisions not relevant here");
+
+        let out_dir = self.output_base_dir();
+        remove_and_create_dir_all(&out_dir);
+
+        let proc_res = self.document(&out_dir, &self.testpaths);
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("rustdoc failed!", &proc_res);
+        }
+
+        if self.props.check_test_line_numbers_match {
+            self.check_rustdoc_test_option(proc_res);
+        } else {
+            let root = self.config.find_rust_src_root().unwrap();
+            let mut cmd = Command::new(&self.config.python);
+            cmd.arg(root.join("src/etc/htmldocck.py")).arg(&out_dir).arg(&self.testpaths.file);
+            if self.config.bless {
+                cmd.arg("--bless");
+            }
+            let res = self.run_command_to_procres(&mut cmd);
+            if !res.status.success() {
+                self.fatal_proc_rec_with_ctx("htmldocck failed!", &res, |mut this| {
+                    this.compare_to_default_rustdoc(&out_dir)
+                });
+            }
+        }
+    }
+}
diff --git a/src/tools/compiletest/src/runtest/rustdoc_json.rs b/src/tools/compiletest/src/runtest/rustdoc_json.rs
new file mode 100644
index 00000000000..a39887ccd02
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/rustdoc_json.rs
@@ -0,0 +1,48 @@
+use std::process::Command;
+
+use super::{remove_and_create_dir_all, TestCx};
+
+impl TestCx<'_> {
+    pub(super) fn run_rustdoc_json_test(&self) {
+        //FIXME: Add bless option.
+
+        assert!(self.revision.is_none(), "revisions not relevant here");
+
+        let out_dir = self.output_base_dir();
+        remove_and_create_dir_all(&out_dir);
+
+        let proc_res = self.document(&out_dir, &self.testpaths);
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("rustdoc failed!", &proc_res);
+        }
+
+        let root = self.config.find_rust_src_root().unwrap();
+        let mut json_out = out_dir.join(self.testpaths.file.file_stem().unwrap());
+        json_out.set_extension("json");
+        let res = self.run_command_to_procres(
+            Command::new(self.config.jsondocck_path.as_ref().unwrap())
+                .arg("--doc-dir")
+                .arg(root.join(&out_dir))
+                .arg("--template")
+                .arg(&self.testpaths.file),
+        );
+
+        if !res.status.success() {
+            self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| {
+                println!("Rustdoc Output:");
+                proc_res.print_info();
+            })
+        }
+
+        let mut json_out = out_dir.join(self.testpaths.file.file_stem().unwrap());
+        json_out.set_extension("json");
+
+        let res = self.run_command_to_procres(
+            Command::new(self.config.jsondoclint_path.as_ref().unwrap()).arg(&json_out),
+        );
+
+        if !res.status.success() {
+            self.fatal_proc_rec("jsondoclint failed!", &res);
+        }
+    }
+}
diff --git a/src/tools/compiletest/src/runtest/ui.rs b/src/tools/compiletest/src/runtest/ui.rs
new file mode 100644
index 00000000000..88a0ec3aa3b
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/ui.rs
@@ -0,0 +1,233 @@
+use std::collections::HashSet;
+use std::fs::OpenOptions;
+use std::io::Write;
+
+use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
+use tracing::debug;
+
+use super::{
+    AllowUnused, Emit, ErrorKind, FailMode, LinkToAux, PassMode, TargetLocation, TestCx,
+    TestOutput, Truncated, WillExecute, UI_FIXED,
+};
+use crate::{errors, json};
+
+impl TestCx<'_> {
+    pub(super) fn run_ui_test(&self) {
+        if let Some(FailMode::Build) = self.props.fail_mode {
+            // Make sure a build-fail test cannot fail due to failing analysis (e.g. typeck).
+            let pm = Some(PassMode::Check);
+            let proc_res =
+                self.compile_test_general(WillExecute::No, Emit::Metadata, pm, Vec::new());
+            self.check_if_test_should_compile(&proc_res, pm);
+        }
+
+        let pm = self.pass_mode();
+        let should_run = self.should_run(pm);
+        let emit_metadata = self.should_emit_metadata(pm);
+        let proc_res = self.compile_test(should_run, emit_metadata);
+        self.check_if_test_should_compile(&proc_res, pm);
+        if matches!(proc_res.truncated, Truncated::Yes)
+            && !self.props.dont_check_compiler_stdout
+            && !self.props.dont_check_compiler_stderr
+        {
+            self.fatal_proc_rec(
+                "compiler output got truncated, cannot compare with reference file",
+                &proc_res,
+            );
+        }
+
+        // if the user specified a format in the ui test
+        // print the output to the stderr file, otherwise extract
+        // the rendered error messages from json and print them
+        let explicit = self.props.compile_flags.iter().any(|s| s.contains("--error-format"));
+
+        let expected_fixed = self.load_expected_output(UI_FIXED);
+
+        self.check_and_prune_duplicate_outputs(&proc_res, &[], &[]);
+
+        let mut errors = self.load_compare_outputs(&proc_res, TestOutput::Compile, explicit);
+        let rustfix_input = json::rustfix_diagnostics_only(&proc_res.stderr);
+
+        if self.config.compare_mode.is_some() {
+            // don't test rustfix with nll right now
+        } else if self.config.rustfix_coverage {
+            // Find out which tests have `MachineApplicable` suggestions but are missing
+            // `run-rustfix` or `run-rustfix-only-machine-applicable` headers.
+            //
+            // This will return an empty `Vec` in case the executed test file has a
+            // `compile-flags: --error-format=xxxx` header with a value other than `json`.
+            let suggestions = get_suggestions_from_json(
+                &rustfix_input,
+                &HashSet::new(),
+                Filter::MachineApplicableOnly,
+            )
+            .unwrap_or_default();
+            if !suggestions.is_empty()
+                && !self.props.run_rustfix
+                && !self.props.rustfix_only_machine_applicable
+            {
+                let mut coverage_file_path = self.config.build_base.clone();
+                coverage_file_path.push("rustfix_missing_coverage.txt");
+                debug!("coverage_file_path: {}", coverage_file_path.display());
+
+                let mut file = OpenOptions::new()
+                    .create(true)
+                    .append(true)
+                    .open(coverage_file_path.as_path())
+                    .expect("could not create or open file");
+
+                if let Err(e) = writeln!(file, "{}", self.testpaths.file.display()) {
+                    panic!("couldn't write to {}: {e:?}", coverage_file_path.display());
+                }
+            }
+        } else if self.props.run_rustfix {
+            // Apply suggestions from rustc to the code itself
+            let unfixed_code = self.load_expected_output_from_path(&self.testpaths.file).unwrap();
+            let suggestions = get_suggestions_from_json(
+                &rustfix_input,
+                &HashSet::new(),
+                if self.props.rustfix_only_machine_applicable {
+                    Filter::MachineApplicableOnly
+                } else {
+                    Filter::Everything
+                },
+            )
+            .unwrap();
+            let fixed_code = apply_suggestions(&unfixed_code, &suggestions).unwrap_or_else(|e| {
+                panic!(
+                    "failed to apply suggestions for {:?} with rustfix: {}",
+                    self.testpaths.file, e
+                )
+            });
+
+            errors += self.compare_output("fixed", &fixed_code, &expected_fixed);
+        } else if !expected_fixed.is_empty() {
+            panic!(
+                "the `//@ run-rustfix` directive wasn't found but a `*.fixed` \
+                 file was found"
+            );
+        }
+
+        if errors > 0 {
+            println!("To update references, rerun the tests and pass the `--bless` flag");
+            let relative_path_to_file =
+                self.testpaths.relative_dir.join(self.testpaths.file.file_name().unwrap());
+            println!(
+                "To only update this specific test, also pass `--test-args {}`",
+                relative_path_to_file.display(),
+            );
+            self.fatal_proc_rec(
+                &format!("{} errors occurred comparing output.", errors),
+                &proc_res,
+            );
+        }
+
+        let expected_errors = errors::load_errors(&self.testpaths.file, self.revision);
+
+        if let WillExecute::Yes = should_run {
+            let proc_res = self.exec_compiled_test();
+            let run_output_errors = if self.props.check_run_results {
+                self.load_compare_outputs(&proc_res, TestOutput::Run, explicit)
+            } else {
+                0
+            };
+            if run_output_errors > 0 {
+                self.fatal_proc_rec(
+                    &format!("{} errors occurred comparing run output.", run_output_errors),
+                    &proc_res,
+                );
+            }
+            if self.should_run_successfully(pm) {
+                if !proc_res.status.success() {
+                    self.fatal_proc_rec("test run failed!", &proc_res);
+                }
+            } else if proc_res.status.success() {
+                self.fatal_proc_rec("test run succeeded!", &proc_res);
+            }
+
+            if !self.props.error_patterns.is_empty() || !self.props.regex_error_patterns.is_empty()
+            {
+                // "// error-pattern" comments
+                let output_to_check = self.get_output(&proc_res);
+                self.check_all_error_patterns(&output_to_check, &proc_res, pm);
+            }
+        }
+
+        debug!(
+            "run_ui_test: explicit={:?} config.compare_mode={:?} expected_errors={:?} \
+               proc_res.status={:?} props.error_patterns={:?}",
+            explicit,
+            self.config.compare_mode,
+            expected_errors,
+            proc_res.status,
+            self.props.error_patterns
+        );
+
+        let check_patterns = should_run == WillExecute::No
+            && (!self.props.error_patterns.is_empty()
+                || !self.props.regex_error_patterns.is_empty());
+        if !explicit && self.config.compare_mode.is_none() {
+            let check_annotations = !check_patterns || !expected_errors.is_empty();
+
+            if check_annotations {
+                // "//~ERROR comments"
+                self.check_expected_errors(expected_errors, &proc_res);
+            }
+        } else if explicit && !expected_errors.is_empty() {
+            let msg = format!(
+                "line {}: cannot combine `--error-format` with {} annotations; use `error-pattern` instead",
+                expected_errors[0].line_num,
+                expected_errors[0].kind.unwrap_or(ErrorKind::Error),
+            );
+            self.fatal(&msg);
+        }
+        if check_patterns {
+            // "// error-pattern" comments
+            let output_to_check = self.get_output(&proc_res);
+            self.check_all_error_patterns(&output_to_check, &proc_res, pm);
+        }
+
+        if self.props.run_rustfix && self.config.compare_mode.is_none() {
+            // And finally, compile the fixed code and make sure it both
+            // succeeds and has no diagnostics.
+            let mut rustc = self.make_compile_args(
+                &self.expected_output_path(UI_FIXED),
+                TargetLocation::ThisFile(self.make_exe_name()),
+                emit_metadata,
+                AllowUnused::No,
+                LinkToAux::Yes,
+                Vec::new(),
+            );
+
+            // If a test is revisioned, it's fixed source file can be named "a.foo.fixed", which,
+            // well, "a.foo" isn't a valid crate name. So we explicitly mangle the test name
+            // (including the revision) here to avoid the test writer having to manually specify a
+            // `#![crate_name = "..."]` as a workaround. This is okay since we're only checking if
+            // the fixed code is compilable.
+            if self.revision.is_some() {
+                let crate_name =
+                    self.testpaths.file.file_stem().expect("test must have a file stem");
+                // crate name must be alphanumeric or `_`.
+                let crate_name =
+                    crate_name.to_str().expect("crate name implies file name must be valid UTF-8");
+                // replace `a.foo` -> `a__foo` for crate name purposes.
+                // replace `revision-name-with-dashes` -> `revision_name_with_underscore`
+                let crate_name = crate_name.replace('.', "__");
+                let crate_name = crate_name.replace('-', "_");
+                rustc.arg("--crate-name");
+                rustc.arg(crate_name);
+            }
+
+            let res = self.compose_and_run_compiler(rustc, None, self.testpaths);
+            if !res.status.success() {
+                self.fatal_proc_rec("failed to compile fixed code", &res);
+            }
+            if !res.stderr.is_empty()
+                && !self.props.rustfix_only_machine_applicable
+                && !json::rustfix_diagnostics_only(&res.stderr).is_empty()
+            {
+                self.fatal_proc_rec("fixed code is still producing diagnostics", &res);
+            }
+        }
+    }
+}
diff --git a/src/tools/compiletest/src/runtest/valgrind.rs b/src/tools/compiletest/src/runtest/valgrind.rs
new file mode 100644
index 00000000000..8d72c4be9ff
--- /dev/null
+++ b/src/tools/compiletest/src/runtest/valgrind.rs
@@ -0,0 +1,34 @@
+use super::{Emit, TestCx, WillExecute};
+
+impl TestCx<'_> {
+    pub(super) fn run_valgrind_test(&self) {
+        assert!(self.revision.is_none(), "revisions not relevant here");
+
+        // FIXME(jieyouxu): does this really make any sense? If a valgrind test isn't testing
+        // valgrind, what is it even testing?
+        if self.config.valgrind_path.is_none() {
+            assert!(!self.config.force_valgrind);
+            return self.run_rpass_test();
+        }
+
+        let should_run = self.run_if_enabled();
+        let mut proc_res = self.compile_test(should_run, Emit::None);
+
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("compilation failed!", &proc_res);
+        }
+
+        if let WillExecute::Disabled = should_run {
+            return;
+        }
+
+        let mut new_config = self.config.clone();
+        new_config.runner = new_config.valgrind_path.clone();
+        let new_cx = TestCx { config: &new_config, ..*self };
+        proc_res = new_cx.exec_compiled_test();
+
+        if !proc_res.status.success() {
+            self.fatal_proc_rec("test run failed!", &proc_res);
+        }
+    }
+}
diff --git a/src/tools/miri/miri-script/src/args.rs b/src/tools/miri/miri-script/src/args.rs
index 16a21757b35..c1688ca0fb6 100644
--- a/src/tools/miri/miri-script/src/args.rs
+++ b/src/tools/miri/miri-script/src/args.rs
@@ -1,7 +1,7 @@
 use std::env;
 use std::iter;
 
-use anyhow::{bail, Result};
+use anyhow::{Result, bail};
 
 pub struct Args {
     args: iter::Peekable<env::Args>,
diff --git a/src/tools/miri/miri-script/src/commands.rs b/src/tools/miri/miri-script/src/commands.rs
index b18c8453d66..b0e62d5cda6 100644
--- a/src/tools/miri/miri-script/src/commands.rs
+++ b/src/tools/miri/miri-script/src/commands.rs
@@ -8,13 +8,13 @@ use std::path::PathBuf;
 use std::process;
 use std::time::Duration;
 
-use anyhow::{anyhow, bail, Context, Result};
+use anyhow::{Context, Result, anyhow, bail};
 use path_macro::path;
 use walkdir::WalkDir;
-use xshell::{cmd, Shell};
+use xshell::{Shell, cmd};
 
-use crate::util::*;
 use crate::Command;
+use crate::util::*;
 
 /// Used for rustc syncs.
 const JOSH_FILTER: &str =
diff --git a/src/tools/miri/miri-script/src/main.rs b/src/tools/miri/miri-script/src/main.rs
index 92148237107..0620f3aaf09 100644
--- a/src/tools/miri/miri-script/src/main.rs
+++ b/src/tools/miri/miri-script/src/main.rs
@@ -6,7 +6,7 @@ mod util;
 
 use std::ops::Range;
 
-use anyhow::{anyhow, bail, Context, Result};
+use anyhow::{Context, Result, anyhow, bail};
 
 #[derive(Clone, Debug)]
 pub enum Command {
diff --git a/src/tools/miri/miri-script/src/util.rs b/src/tools/miri/miri-script/src/util.rs
index 9d1a8e4fb1d..f5a6a8188a0 100644
--- a/src/tools/miri/miri-script/src/util.rs
+++ b/src/tools/miri/miri-script/src/util.rs
@@ -5,10 +5,10 @@ use std::path::{Path, PathBuf};
 use std::sync::atomic::{AtomicBool, AtomicU32, Ordering};
 use std::{env, iter, thread};
 
-use anyhow::{anyhow, bail, Context, Result};
+use anyhow::{Context, Result, anyhow, bail};
 use dunce::canonicalize;
 use path_macro::path;
-use xshell::{cmd, Cmd, Shell};
+use xshell::{Cmd, Shell, cmd};
 
 pub fn miri_dir() -> std::io::Result<PathBuf> {
     const MIRI_SCRIPT_ROOT_DIR: &str = env!("CARGO_MANIFEST_DIR");
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 3f4d095fc19..c3276d82d4f 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-e2dc1a1c0f97a90319181a721ab317210307617a
+c0838c8ebec23fb87855bb6de3a287981cb1df98
diff --git a/src/tools/miri/src/alloc_addresses/reuse_pool.rs b/src/tools/miri/src/alloc_addresses/reuse_pool.rs
index 77fc9f53f9e..f6c16756344 100644
--- a/src/tools/miri/src/alloc_addresses/reuse_pool.rs
+++ b/src/tools/miri/src/alloc_addresses/reuse_pool.rs
@@ -4,7 +4,7 @@ use rand::Rng;
 
 use rustc_target::abi::{Align, Size};
 
-use crate::{concurrency::VClock, MemoryKind, MiriConfig, ThreadId};
+use crate::{MemoryKind, MiriConfig, ThreadId, concurrency::VClock};
 
 const MAX_POOL_SIZE: usize = 64;
 
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
index fc2b3f9c6ea..e7d7cc28eee 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -12,12 +12,12 @@ use std::mem;
 
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::mir::{Mutability, RetagKind};
-use rustc_middle::ty::{self, layout::HasParamEnv, Ty};
+use rustc_middle::ty::{self, Ty, layout::HasParamEnv};
 use rustc_target::abi::{Abi, Size};
 
 use crate::borrow_tracker::{
-    stacked_borrows::diagnostics::{AllocHistory, DiagnosticCx, DiagnosticCxBuilder},
     GlobalStateInner, ProtectorKind,
+    stacked_borrows::diagnostics::{AllocHistory, DiagnosticCx, DiagnosticCxBuilder},
 };
 use crate::concurrency::data_race::{NaReadType, NaWriteType};
 use crate::*;
@@ -913,11 +913,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 new_perm: NewPermission,
             ) -> InterpResult<'tcx> {
                 let val = self.ecx.read_immediate(&self.ecx.place_to_op(place)?)?;
-                let val = self.ecx.sb_retag_reference(
-                    &val,
-                    new_perm,
-                    RetagInfo { cause: self.retag_cause, in_field: self.in_field },
-                )?;
+                let val = self.ecx.sb_retag_reference(&val, new_perm, RetagInfo {
+                    cause: self.retag_cause,
+                    in_field: self.in_field,
+                })?;
                 self.ecx.write_immediate(*val, place)?;
                 Ok(())
             }
@@ -1003,11 +1002,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             access: Some(AccessKind::Write),
             protector: Some(ProtectorKind::StrongProtector),
         };
-        this.sb_retag_place(
-            place,
-            new_perm,
-            RetagInfo { cause: RetagCause::InPlaceFnPassing, in_field: false },
-        )
+        this.sb_retag_place(place, new_perm, RetagInfo {
+            cause: RetagCause::InPlaceFnPassing,
+            in_field: false,
+        })
     }
 
     /// Mark the given tag as exposed. It was found on a pointer with the given AllocId.
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
index 774b36919fe..5c040983142 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
@@ -4,11 +4,11 @@ use std::ops::Range;
 use rustc_data_structures::fx::FxHashSet;
 use tracing::trace;
 
+use crate::ProvenanceExtra;
 use crate::borrow_tracker::{
-    stacked_borrows::{Item, Permission},
     AccessKind, BorTag,
+    stacked_borrows::{Item, Permission},
 };
-use crate::ProvenanceExtra;
 
 /// Exactly what cache size we should use is a difficult trade-off. There will always be some
 /// workload which has a `BorTag` working set which exceeds the size of the cache, and ends up
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs
index a753de28a04..44ea7533b00 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/diagnostics.rs
@@ -4,12 +4,12 @@ use std::ops::Range;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_span::{Span, SpanData};
 
+use crate::borrow_tracker::ProtectorKind;
 use crate::borrow_tracker::tree_borrows::{
     perms::{PermTransition, Permission},
     tree::LocationState,
     unimap::UniIndex,
 };
-use crate::borrow_tracker::ProtectorKind;
 use crate::*;
 
 /// Cause of an access: either a real access or one
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
index 722cb79c66b..89b8ff1af8b 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
@@ -1,6 +1,6 @@
 use rustc_middle::{
     mir::{Mutability, RetagKind},
-    ty::{self, layout::HasParamEnv, Ty},
+    ty::{self, Ty, layout::HasParamEnv},
 };
 use rustc_span::def_id::DefId;
 use rustc_target::abi::{Abi, Size};
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
index c29bd719b15..dfb9b8637fd 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
@@ -1,9 +1,9 @@
 use std::cmp::{Ordering, PartialOrd};
 use std::fmt;
 
+use crate::AccessKind;
 use crate::borrow_tracker::tree_borrows::diagnostics::TransitionError;
 use crate::borrow_tracker::tree_borrows::tree::AccessRelatedness;
-use crate::AccessKind;
 
 /// The activation states of a pointer.
 #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
@@ -345,18 +345,14 @@ pub mod diagnostics {
     use super::*;
     impl fmt::Display for PermissionPriv {
         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-            write!(
-                f,
-                "{}",
-                match self {
-                    ReservedFrz { conflicted: false } => "Reserved",
-                    ReservedFrz { conflicted: true } => "Reserved (conflicted)",
-                    ReservedIM => "Reserved (interior mutable)",
-                    Active => "Active",
-                    Frozen => "Frozen",
-                    Disabled => "Disabled",
-                }
-            )
+            write!(f, "{}", match self {
+                ReservedFrz { conflicted: false } => "Reserved",
+                ReservedFrz { conflicted: true } => "Reserved (conflicted)",
+                ReservedIM => "Reserved (interior mutable)",
+                Active => "Active",
+                Frozen => "Frozen",
+                Disabled => "Disabled",
+            })
         }
     }
 
@@ -551,7 +547,7 @@ impl Permission {
 #[cfg(test)]
 mod propagation_optimization_checks {
     pub use super::*;
-    use crate::borrow_tracker::tree_borrows::exhaustive::{precondition, Exhaustive};
+    use crate::borrow_tracker::tree_borrows::exhaustive::{Exhaustive, precondition};
 
     impl Exhaustive for PermissionPriv {
         fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
index 53e722259fd..a99c71d96b4 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
@@ -19,10 +19,10 @@ use rustc_span::Span;
 use rustc_target::abi::Size;
 
 use crate::borrow_tracker::tree_borrows::{
+    Permission,
     diagnostics::{self, NodeDebugInfo, TbError, TransitionError},
     perms::PermTransition,
     unimap::{UniEntry, UniIndex, UniKeyMap, UniValMap},
-    Permission,
 };
 use crate::borrow_tracker::{GlobalState, ProtectorKind};
 use crate::*;
@@ -587,16 +587,13 @@ impl Tree {
             let mut debug_info = NodeDebugInfo::new(root_tag, root_default_perm, span);
             // name the root so that all allocations contain one named pointer
             debug_info.add_name("root of the allocation");
-            nodes.insert(
-                root_idx,
-                Node {
-                    tag: root_tag,
-                    parent: None,
-                    children: SmallVec::default(),
-                    default_initial_perm: root_default_perm,
-                    debug_info,
-                },
-            );
+            nodes.insert(root_idx, Node {
+                tag: root_tag,
+                parent: None,
+                children: SmallVec::default(),
+                default_initial_perm: root_default_perm,
+                debug_info,
+            });
             nodes
         };
         let rperms = {
@@ -626,16 +623,13 @@ impl<'tcx> Tree {
         let idx = self.tag_mapping.insert(new_tag);
         let parent_idx = self.tag_mapping.get(&parent_tag).unwrap();
         // Create the node
-        self.nodes.insert(
-            idx,
-            Node {
-                tag: new_tag,
-                parent: Some(parent_idx),
-                children: SmallVec::default(),
-                default_initial_perm,
-                debug_info: NodeDebugInfo::new(new_tag, default_initial_perm, span),
-            },
-        );
+        self.nodes.insert(idx, Node {
+            tag: new_tag,
+            parent: Some(parent_idx),
+            children: SmallVec::default(),
+            default_initial_perm,
+            debug_info: NodeDebugInfo::new(new_tag, default_initial_perm, span),
+        });
         // Register new_tag as a child of parent_tag
         self.nodes.get_mut(parent_idx).unwrap().children.push(idx);
         // Initialize perms
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs
index f64f7bf8e8c..5cd5040f807 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs
@@ -2,7 +2,7 @@
 #![cfg(test)]
 
 use super::*;
-use crate::borrow_tracker::tree_borrows::exhaustive::{precondition, Exhaustive};
+use crate::borrow_tracker::tree_borrows::exhaustive::{Exhaustive, precondition};
 use std::fmt;
 
 impl Exhaustive for LocationState {
diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs
index 1f910d885ca..bc4d8056872 100644
--- a/src/tools/miri/src/concurrency/sync.rs
+++ b/src/tools/miri/src/concurrency/sync.rs
@@ -1,5 +1,5 @@
 use std::any::Any;
-use std::collections::{hash_map::Entry, VecDeque};
+use std::collections::{VecDeque, hash_map::Entry};
 use std::ops::Not;
 use std::time::Duration;
 
@@ -283,12 +283,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         data: Option<Box<dyn Any>>,
     ) -> InterpResult<'tcx, MutexId> {
         let this = self.eval_context_mut();
-        this.create_id(
-            lock,
-            offset,
-            |ecx| &mut ecx.machine.sync.mutexes,
-            Mutex { data, ..Default::default() },
-        )
+        this.create_id(lock, offset, |ecx| &mut ecx.machine.sync.mutexes, Mutex {
+            data,
+            ..Default::default()
+        })
     }
 
     /// Lazily create a new mutex.
@@ -355,12 +353,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         data: Option<Box<dyn Any>>,
     ) -> InterpResult<'tcx, CondvarId> {
         let this = self.eval_context_mut();
-        this.create_id(
-            condvar,
-            offset,
-            |ecx| &mut ecx.machine.sync.condvars,
-            Condvar { data, ..Default::default() },
-        )
+        this.create_id(condvar, offset, |ecx| &mut ecx.machine.sync.condvars, Condvar {
+            data,
+            ..Default::default()
+        })
     }
 
     fn condvar_get_or_create_id(
diff --git a/src/tools/miri/src/concurrency/vector_clock.rs b/src/tools/miri/src/concurrency/vector_clock.rs
index 0968e10bbee..901b097c1bd 100644
--- a/src/tools/miri/src/concurrency/vector_clock.rs
+++ b/src/tools/miri/src/concurrency/vector_clock.rs
@@ -1,5 +1,5 @@
 use rustc_index::Idx;
-use rustc_span::{Span, SpanData, DUMMY_SP};
+use rustc_span::{DUMMY_SP, Span, SpanData};
 use smallvec::SmallVec;
 use std::{
     cmp::Ordering,
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index 92f344d13b7..4445550512b 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -2,7 +2,7 @@ use std::fmt::{self, Write};
 use std::num::NonZero;
 
 use rustc_errors::{Diag, DiagMessage, Level};
-use rustc_span::{SpanData, Symbol, DUMMY_SP};
+use rustc_span::{DUMMY_SP, SpanData, Symbol};
 use rustc_target::abi::{Align, Size};
 
 use crate::borrow_tracker::stacked_borrows::diagnostics::TagHistory;
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index f95177684ae..8c8ed9c4ddc 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -13,9 +13,8 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::{
-    self,
+    self, Ty, TyCtxt,
     layout::{LayoutCx, LayoutOf},
-    Ty, TyCtxt,
 };
 use rustc_target::spec::abi::Abi;
 
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index cba99c0bd7a..10e5882b5ba 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -7,12 +7,12 @@ use std::time::Duration;
 
 use rand::RngCore;
 
-use rustc_apfloat::ieee::{Double, Half, Quad, Single};
 use rustc_apfloat::Float;
+use rustc_apfloat::ieee::{Double, Half, Quad, Single};
 use rustc_hir::{
-    def::{DefKind, Namespace},
-    def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE},
     Safety,
+    def::{DefKind, Namespace},
+    def_id::{CRATE_DEF_INDEX, CrateNum, DefId, LOCAL_CRATE},
 };
 use rustc_index::IndexVec;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
@@ -21,9 +21,8 @@ use rustc_middle::middle::exported_symbols::ExportedSymbol;
 use rustc_middle::mir;
 use rustc_middle::ty::layout::{FnAbiOf, MaybeResult};
 use rustc_middle::ty::{
-    self,
+    self, FloatTy, IntTy, Ty, TyCtxt, UintTy,
     layout::{LayoutOf, TyAndLayout},
-    FloatTy, IntTy, Ty, TyCtxt, UintTy,
 };
 use rustc_session::config::CrateType;
 use rustc_span::{Span, Symbol};
diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs
index 7acc99a8af0..3eeb11dbbb4 100644
--- a/src/tools/miri/src/intrinsics/mod.rs
+++ b/src/tools/miri/src/intrinsics/mod.rs
@@ -9,12 +9,12 @@ use rustc_middle::{
     mir,
     ty::{self, FloatTy},
 };
-use rustc_span::{sym, Symbol};
+use rustc_span::{Symbol, sym};
 use rustc_target::abi::Size;
 
 use crate::*;
 use atomic::EvalContextExt as _;
-use helpers::{check_arg_count, ToHost, ToSoft};
+use helpers::{ToHost, ToSoft, check_arg_count};
 use simd::EvalContextExt as _;
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs
index e22306ca82f..2bc11d63a39 100644
--- a/src/tools/miri/src/intrinsics/simd.rs
+++ b/src/tools/miri/src/intrinsics/simd.rs
@@ -3,10 +3,10 @@ use either::Either;
 use rustc_apfloat::{Float, Round};
 use rustc_middle::ty::layout::{HasParamEnv, LayoutOf};
 use rustc_middle::{mir, ty, ty::FloatTy};
-use rustc_span::{sym, Symbol};
+use rustc_span::{Symbol, sym};
 use rustc_target::abi::{Endian, HasDataLayout};
 
-use crate::helpers::{bool_to_simd_element, check_arg_count, simd_element_to_bool, ToHost, ToSoft};
+use crate::helpers::{ToHost, ToSoft, bool_to_simd_element, check_arg_count, simd_element_to_bool};
 use crate::*;
 
 #[derive(Copy, Clone)]
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 8a59206943d..b39f88dd1c9 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -113,13 +113,13 @@ pub type PlaceTy<'tcx> = interpret::PlaceTy<'tcx, machine::Provenance>;
 pub type MPlaceTy<'tcx> = interpret::MPlaceTy<'tcx, machine::Provenance>;
 
 pub use crate::intrinsics::EvalContextExt as _;
+pub use crate::shims::EmulateItemResult;
 pub use crate::shims::env::{EnvVars, EvalContextExt as _};
 pub use crate::shims::foreign_items::{DynSym, EvalContextExt as _};
 pub use crate::shims::os_str::EvalContextExt as _;
 pub use crate::shims::panic::{CatchUnwindData, EvalContextExt as _};
 pub use crate::shims::time::EvalContextExt as _;
 pub use crate::shims::tls::TlsData;
-pub use crate::shims::EmulateItemResult;
 
 pub use crate::alloc_addresses::{EvalContextExt as _, ProvenanceMode};
 pub use crate::alloc_bytes::MiriAllocBytes;
@@ -140,11 +140,11 @@ pub use crate::concurrency::{
     },
 };
 pub use crate::diagnostics::{
-    report_error, EvalContextExt as _, NonHaltingDiagnostic, TerminationInfo,
+    EvalContextExt as _, NonHaltingDiagnostic, TerminationInfo, report_error,
 };
 pub use crate::eval::{
-    create_ecx, eval_entry, AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, RejectOpWith,
-    ValidationMode,
+    AlignmentCheck, BacktraceStyle, IsolatedOp, MiriConfig, RejectOpWith, ValidationMode,
+    create_ecx, eval_entry,
 };
 pub use crate::helpers::{AccessKind, EvalContextExt as _};
 pub use crate::machine::{
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index bde94cec87f..b93feeeee33 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -8,9 +8,9 @@ use std::fmt;
 use std::path::Path;
 use std::process;
 
-use rand::rngs::StdRng;
 use rand::Rng;
 use rand::SeedableRng;
+use rand::rngs::StdRng;
 
 use rustc_attr::InlineAttr;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -20,9 +20,8 @@ use rustc_middle::{
     mir,
     query::TyCtxtAt,
     ty::{
-        self,
+        self, Instance, Ty, TyCtxt,
         layout::{HasTyCtxt, LayoutCx, LayoutError, LayoutOf, TyAndLayout},
-        Instance, Ty, TyCtxt,
     },
 };
 use rustc_session::config::InliningThreshold;
@@ -1080,13 +1079,10 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         // Call the lang item.
         let panic = ecx.tcx.lang_items().get(reason.lang_item()).unwrap();
         let panic = ty::Instance::mono(ecx.tcx.tcx, panic);
-        ecx.call_function(
-            panic,
-            Abi::Rust,
-            &[],
-            None,
-            StackPopCleanup::Goto { ret: None, unwind: mir::UnwindAction::Unreachable },
-        )?;
+        ecx.call_function(panic, Abi::Rust, &[], None, StackPopCleanup::Goto {
+            ret: None,
+            unwind: mir::UnwindAction::Unreachable,
+        })?;
         Ok(())
     }
 
diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs
index bc44e672bd8..1b6a7255eef 100644
--- a/src/tools/miri/src/operator.rs
+++ b/src/tools/miri/src/operator.rs
@@ -1,6 +1,6 @@
 use std::iter;
 
-use rand::{seq::IteratorRandom, Rng};
+use rand::{Rng, seq::IteratorRandom};
 use rustc_apfloat::{Float, FloatConvert};
 use rustc_middle::mir;
 use rustc_target::abi::Size;
diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs
index 9bb6777a9b0..edff17c0514 100644
--- a/src/tools/miri/src/shims/backtrace.rs
+++ b/src/tools/miri/src/shims/backtrace.rs
@@ -2,7 +2,7 @@ use crate::*;
 use rustc_ast::ast::Mutability;
 use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_middle::ty::{self, Instance, Ty};
-use rustc_span::{hygiene, BytePos, Loc, Symbol};
+use rustc_span::{BytePos, Loc, Symbol, hygiene};
 use rustc_target::{abi::Size, spec::abi::Abi};
 
 impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
diff --git a/src/tools/miri/src/shims/extern_static.rs b/src/tools/miri/src/shims/extern_static.rs
index 17ac2638a69..788de8162cb 100644
--- a/src/tools/miri/src/shims/extern_static.rs
+++ b/src/tools/miri/src/shims/extern_static.rs
@@ -63,10 +63,10 @@ impl<'tcx> MiriMachine<'tcx> {
 
         match this.tcx.sess.target.os.as_ref() {
             "linux" => {
-                Self::null_ptr_extern_statics(
-                    this,
-                    &["__cxa_thread_atexit_impl", "__clock_gettime64"],
-                )?;
+                Self::null_ptr_extern_statics(this, &[
+                    "__cxa_thread_atexit_impl",
+                    "__clock_gettime64",
+                ])?;
                 Self::weak_symbol_extern_statics(this, &["getrandom", "statx"])?;
             }
             "freebsd" => {
diff --git a/src/tools/miri/src/shims/os_str.rs b/src/tools/miri/src/shims/os_str.rs
index 533992e35ab..a1be2ae8b58 100644
--- a/src/tools/miri/src/shims/os_str.rs
+++ b/src/tools/miri/src/shims/os_str.rs
@@ -7,8 +7,8 @@ use std::os::unix::ffi::{OsStrExt, OsStringExt};
 #[cfg(windows)]
 use std::os::windows::ffi::{OsStrExt, OsStringExt};
 
-use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::Ty;
+use rustc_middle::ty::layout::LayoutOf;
 
 use crate::*;
 
diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs
index ab705ddccab..44f942cb4c5 100644
--- a/src/tools/miri/src/shims/panic.rs
+++ b/src/tools/miri/src/shims/panic.rs
@@ -13,8 +13,8 @@
 
 use rustc_ast::Mutability;
 use rustc_middle::{mir, ty};
-use rustc_target::spec::abi::Abi;
 use rustc_target::spec::PanicStrategy;
+use rustc_target::spec::abi::Abi;
 
 use crate::*;
 use helpers::check_arg_count;
@@ -248,13 +248,10 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // Call the lang item associated with this message.
                 let fn_item = this.tcx.require_lang_item(msg.panic_function(), None);
                 let instance = ty::Instance::mono(this.tcx.tcx, fn_item);
-                this.call_function(
-                    instance,
-                    Abi::Rust,
-                    &[],
-                    None,
-                    StackPopCleanup::Goto { ret: None, unwind },
-                )?;
+                this.call_function(instance, Abi::Rust, &[], None, StackPopCleanup::Goto {
+                    ret: None,
+                    unwind,
+                })?;
             }
         }
         Ok(())
diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs
index 52d83cd7299..b3ea7098dfe 100644
--- a/src/tools/miri/src/shims/tls.rs
+++ b/src/tools/miri/src/shims/tls.rs
@@ -1,7 +1,7 @@
 //! Implement thread-local storage.
 
-use std::collections::btree_map::Entry as BTreeEntry;
 use std::collections::BTreeMap;
+use std::collections::btree_map::Entry as BTreeEntry;
 use std::task::Poll;
 
 use rustc_middle::ty;
diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs
index 54bf3a3ae82..324607cc1ed 100644
--- a/src/tools/miri/src/shims/unix/env.rs
+++ b/src/tools/miri/src/shims/unix/env.rs
@@ -4,8 +4,8 @@ use std::io::ErrorKind;
 use std::mem;
 
 use rustc_data_structures::fx::FxHashMap;
-use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::Ty;
+use rustc_middle::ty::layout::LayoutOf;
 use rustc_target::abi::Size;
 
 use crate::*;
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index e1697a47415..f5fe2b4b30b 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -2,7 +2,7 @@
 
 use std::borrow::Cow;
 use std::fs::{
-    read_dir, remove_dir, remove_file, rename, DirBuilder, File, FileType, OpenOptions, ReadDir,
+    DirBuilder, File, FileType, OpenOptions, ReadDir, read_dir, remove_dir, remove_file, rename,
 };
 use std::io::{self, ErrorKind, IsTerminal, Read, Seek, SeekFrom, Write};
 use std::path::{Path, PathBuf};
@@ -173,7 +173,7 @@ impl FileDescription for FileHandle {
             use windows_sys::Win32::{
                 Foundation::{ERROR_IO_PENDING, ERROR_LOCK_VIOLATION, FALSE, HANDLE, TRUE},
                 Storage::FileSystem::{
-                    LockFileEx, UnlockFile, LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY,
+                    LOCKFILE_EXCLUSIVE_LOCK, LOCKFILE_FAIL_IMMEDIATELY, LockFileEx, UnlockFile,
                 },
             };
             let fh = self.file.as_raw_handle() as HANDLE;
diff --git a/src/tools/miri/src/shims/x86/aesni.rs b/src/tools/miri/src/shims/x86/aesni.rs
index e4e1531157a..dbbae0731e0 100644
--- a/src/tools/miri/src/shims/x86/aesni.rs
+++ b/src/tools/miri/src/shims/x86/aesni.rs
@@ -1,5 +1,5 @@
-use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_middle::ty::Ty;
+use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_span::Symbol;
 use rustc_target::spec::abi::Abi;
 
diff --git a/src/tools/miri/src/shims/x86/avx.rs b/src/tools/miri/src/shims/x86/avx.rs
index 1ddc9efcf6b..bdc4fc94469 100644
--- a/src/tools/miri/src/shims/x86/avx.rs
+++ b/src/tools/miri/src/shims/x86/avx.rs
@@ -1,14 +1,14 @@
 use rustc_apfloat::{ieee::Double, ieee::Single};
 use rustc_middle::mir;
-use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_middle::ty::Ty;
+use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_span::Symbol;
 use rustc_target::spec::abi::Abi;
 
 use super::{
-    bin_op_simd_float_all, conditional_dot_product, convert_float_to_int, horizontal_bin_op,
-    mask_load, mask_store, round_all, test_bits_masked, test_high_bits_masked, unary_op_ps,
-    FloatBinOp, FloatUnaryOp,
+    FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, conditional_dot_product, convert_float_to_int,
+    horizontal_bin_op, mask_load, mask_store, round_all, test_bits_masked, test_high_bits_masked,
+    unary_op_ps,
 };
 use crate::*;
 
diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs
index 74d4673bd82..1dda1a10a05 100644
--- a/src/tools/miri/src/shims/x86/avx2.rs
+++ b/src/tools/miri/src/shims/x86/avx2.rs
@@ -1,12 +1,12 @@
 use rustc_middle::mir;
-use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_middle::ty::Ty;
+use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_span::Symbol;
 use rustc_target::spec::abi::Abi;
 
 use super::{
-    horizontal_bin_op, int_abs, mask_load, mask_store, mpsadbw, packssdw, packsswb, packusdw,
-    packuswb, pmulhrsw, psign, shift_simd_by_scalar, shift_simd_by_simd, ShiftOp,
+    ShiftOp, horizontal_bin_op, int_abs, mask_load, mask_store, mpsadbw, packssdw, packsswb,
+    packusdw, packuswb, pmulhrsw, psign, shift_simd_by_scalar, shift_simd_by_simd,
 };
 use crate::*;
 
diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs
index d7241f87d0e..7c7a0935c47 100644
--- a/src/tools/miri/src/shims/x86/mod.rs
+++ b/src/tools/miri/src/shims/x86/mod.rs
@@ -1,8 +1,8 @@
 use rand::Rng as _;
 
-use rustc_apfloat::{ieee::Single, Float};
-use rustc_middle::ty::layout::LayoutOf as _;
+use rustc_apfloat::{Float, ieee::Single};
 use rustc_middle::ty::Ty;
+use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_middle::{mir, ty};
 use rustc_span::Symbol;
 use rustc_target::abi::Size;
diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs
index 8de7ddc7931..254d25bb529 100644
--- a/src/tools/miri/src/shims/x86/sse.rs
+++ b/src/tools/miri/src/shims/x86/sse.rs
@@ -3,8 +3,8 @@ use rustc_span::Symbol;
 use rustc_target::spec::abi::Abi;
 
 use super::{
-    bin_op_simd_float_all, bin_op_simd_float_first, unary_op_ps, unary_op_ss, FloatBinOp,
-    FloatUnaryOp,
+    FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, bin_op_simd_float_first, unary_op_ps,
+    unary_op_ss,
 };
 use crate::*;
 
diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs
index bdb52a04a91..7c23e372664 100644
--- a/src/tools/miri/src/shims/x86/sse2.rs
+++ b/src/tools/miri/src/shims/x86/sse2.rs
@@ -3,8 +3,8 @@ use rustc_span::Symbol;
 use rustc_target::spec::abi::Abi;
 
 use super::{
-    bin_op_simd_float_all, bin_op_simd_float_first, convert_float_to_int, packssdw, packsswb,
-    packuswb, shift_simd_by_scalar, FloatBinOp, ShiftOp,
+    FloatBinOp, ShiftOp, bin_op_simd_float_all, bin_op_simd_float_first, convert_float_to_int,
+    packssdw, packsswb, packuswb, shift_simd_by_scalar,
 };
 use crate::*;
 
diff --git a/src/tools/miri/src/shims/x86/sse42.rs b/src/tools/miri/src/shims/x86/sse42.rs
index 4e50d5e5dcf..0b6e0d9e0d7 100644
--- a/src/tools/miri/src/shims/x86/sse42.rs
+++ b/src/tools/miri/src/shims/x86/sse42.rs
@@ -1,6 +1,6 @@
 use rustc_middle::mir;
-use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_middle::ty::Ty;
+use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_span::Symbol;
 use rustc_target::abi::Size;
 use rustc_target::spec::abi::Abi;
diff --git a/src/tools/miri/test-cargo-miri/src/main.rs b/src/tools/miri/test-cargo-miri/src/main.rs
index 048577ef15a..d171ec1c0d1 100644
--- a/src/tools/miri/test-cargo-miri/src/main.rs
+++ b/src/tools/miri/test-cargo-miri/src/main.rs
@@ -23,7 +23,7 @@ fn main() {
     // (We rely on the test runner to always disable isolation when passing no arguments.)
     if std::env::args().len() <= 1 {
         fn host_to_target_path(path: String) -> PathBuf {
-            use std::ffi::{c_char, CStr, CString};
+            use std::ffi::{CStr, CString, c_char};
 
             let path = CString::new(path).unwrap();
             let mut out = Vec::with_capacity(1024);
diff --git a/src/tools/miri/test-cargo-miri/subcrate/main.rs b/src/tools/miri/test-cargo-miri/subcrate/main.rs
index 52161098788..96f849e7633 100644
--- a/src/tools/miri/test-cargo-miri/subcrate/main.rs
+++ b/src/tools/miri/test-cargo-miri/subcrate/main.rs
@@ -5,7 +5,7 @@ fn main() {
     println!("subcrate running");
 
     fn host_to_target_path(path: String) -> PathBuf {
-        use std::ffi::{c_char, CStr, CString};
+        use std::ffi::{CStr, CString, c_char};
 
         let path = CString::new(path).unwrap();
         let mut out = Vec::with_capacity(1024);
diff --git a/src/tools/miri/test-cargo-miri/subcrate/test.rs b/src/tools/miri/test-cargo-miri/subcrate/test.rs
index 1681c721dc2..b60cf20339b 100644
--- a/src/tools/miri/test-cargo-miri/subcrate/test.rs
+++ b/src/tools/miri/test-cargo-miri/subcrate/test.rs
@@ -8,7 +8,7 @@ fn main() {
     println!("subcrate testing");
 
     fn host_to_target_path(path: String) -> PathBuf {
-        use std::ffi::{c_char, CStr, CString};
+        use std::ffi::{CStr, CString, c_char};
 
         let path = CString::new(path).unwrap();
         let mut out = Vec::with_capacity(1024);
diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs
index e28b0343135..279201df867 100644
--- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_main.rs
@@ -8,7 +8,7 @@
 use std::thread;
 
 use windows_sys::Win32::Foundation::{HANDLE, WAIT_OBJECT_0};
-use windows_sys::Win32::System::Threading::{WaitForSingleObject, INFINITE};
+use windows_sys::Win32::System::Threading::{INFINITE, WaitForSingleObject};
 
 // XXX HACK: This is how miri represents the handle for thread 0.
 // This value can be "legitimately" obtained by using `GetCurrentThread` with `DuplicateHandle`
diff --git a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.rs b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.rs
index 4d48e839bb4..eee2979f3cf 100644
--- a/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/windows_join_self.rs
@@ -8,7 +8,7 @@
 use std::thread;
 
 use windows_sys::Win32::Foundation::WAIT_OBJECT_0;
-use windows_sys::Win32::System::Threading::{GetCurrentThread, WaitForSingleObject, INFINITE};
+use windows_sys::Win32::System::Threading::{GetCurrentThread, INFINITE, WaitForSingleObject};
 
 fn main() {
     thread::spawn(|| {
diff --git a/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.rs b/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.rs
index 552a67419b2..f04927beb16 100644
--- a/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.rs
+++ b/src/tools/miri/tests/fail/alloc/deallocate-bad-alignment.rs
@@ -1,4 +1,4 @@
-use std::alloc::{alloc, dealloc, Layout};
+use std::alloc::{Layout, alloc, dealloc};
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/alloc/deallocate-bad-size.rs b/src/tools/miri/tests/fail/alloc/deallocate-bad-size.rs
index 906a3b52a22..d818f3a9304 100644
--- a/src/tools/miri/tests/fail/alloc/deallocate-bad-size.rs
+++ b/src/tools/miri/tests/fail/alloc/deallocate-bad-size.rs
@@ -1,4 +1,4 @@
-use std::alloc::{alloc, dealloc, Layout};
+use std::alloc::{Layout, alloc, dealloc};
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/alloc/deallocate-twice.rs b/src/tools/miri/tests/fail/alloc/deallocate-twice.rs
index ee514f4c55e..340ca1f75ef 100644
--- a/src/tools/miri/tests/fail/alloc/deallocate-twice.rs
+++ b/src/tools/miri/tests/fail/alloc/deallocate-twice.rs
@@ -1,4 +1,4 @@
-use std::alloc::{alloc, dealloc, Layout};
+use std::alloc::{Layout, alloc, dealloc};
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/alloc/reallocate-bad-size.rs b/src/tools/miri/tests/fail/alloc/reallocate-bad-size.rs
index 174e4f22761..7b9ef1d9121 100644
--- a/src/tools/miri/tests/fail/alloc/reallocate-bad-size.rs
+++ b/src/tools/miri/tests/fail/alloc/reallocate-bad-size.rs
@@ -1,4 +1,4 @@
-use std::alloc::{alloc, realloc, Layout};
+use std::alloc::{Layout, alloc, realloc};
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.rs b/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.rs
index ecdd3ae5fee..9f9921b1817 100644
--- a/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.rs
+++ b/src/tools/miri/tests/fail/alloc/reallocate-change-alloc.rs
@@ -1,4 +1,4 @@
-use std::alloc::{alloc, realloc, Layout};
+use std::alloc::{Layout, alloc, realloc};
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs b/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs
index c605f68a7f6..97357c629af 100644
--- a/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs
+++ b/src/tools/miri/tests/fail/alloc/reallocate-dangling.rs
@@ -1,4 +1,4 @@
-use std::alloc::{alloc, dealloc, realloc, Layout};
+use std::alloc::{Layout, alloc, dealloc, realloc};
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.rs b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.rs
index 170bcf9590a..44ec4129d60 100644
--- a/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.rs
+++ b/src/tools/miri/tests/fail/both_borrows/invalidate_against_protector3.rs
@@ -1,7 +1,7 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
 
-use std::alloc::{alloc, Layout};
+use std::alloc::{Layout, alloc};
 
 fn inner(x: *mut i32, _y: &i32) {
     // If `x` and `y` alias, retagging is fine with this... but we really
diff --git a/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.rs b/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.rs
index c8060d4c9cb..df9a73a444e 100644
--- a/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.rs
+++ b/src/tools/miri/tests/fail/both_borrows/zero-sized-protected.rs
@@ -1,6 +1,6 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
-use std::alloc::{alloc, dealloc, Layout};
+use std::alloc::{Layout, alloc, dealloc};
 
 // `x` is strongly protected but covers zero bytes.
 // Let's see if deallocating the allocation x points to is UB:
diff --git a/src/tools/miri/tests/fail/data_race/fence_after_load.rs b/src/tools/miri/tests/fail/data_race/fence_after_load.rs
index 92cb4ccccf5..5dfb260c20b 100644
--- a/src/tools/miri/tests/fail/data_race/fence_after_load.rs
+++ b/src/tools/miri/tests/fail/data_race/fence_after_load.rs
@@ -3,8 +3,8 @@
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
-use std::sync::atomic::{fence, AtomicUsize, Ordering};
 use std::sync::Arc;
+use std::sync::atomic::{AtomicUsize, Ordering, fence};
 use std::thread;
 use std::time::Duration;
 
diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_read.rs b/src/tools/miri/tests/fail/data_race/mixed_size_read.rs
index 61af972b3dc..828b47f0a65 100644
--- a/src/tools/miri/tests/fail/data_race/mixed_size_read.rs
+++ b/src/tools/miri/tests/fail/data_race/mixed_size_read.rs
@@ -2,7 +2,7 @@
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
-use std::sync::atomic::{AtomicU16, AtomicU8, Ordering};
+use std::sync::atomic::{AtomicU8, AtomicU16, Ordering};
 use std::thread;
 
 fn convert(a: &AtomicU16) -> &[AtomicU8; 2] {
diff --git a/src/tools/miri/tests/fail/data_race/mixed_size_write.rs b/src/tools/miri/tests/fail/data_race/mixed_size_write.rs
index 12e51bb9429..89afda2fff5 100644
--- a/src/tools/miri/tests/fail/data_race/mixed_size_write.rs
+++ b/src/tools/miri/tests/fail/data_race/mixed_size_write.rs
@@ -2,7 +2,7 @@
 // Avoid accidental synchronization via address reuse inside `thread::spawn`.
 //@compile-flags: -Zmiri-address-reuse-cross-thread-rate=0
 
-use std::sync::atomic::{AtomicU16, AtomicU8, Ordering};
+use std::sync::atomic::{AtomicU8, AtomicU16, Ordering};
 use std::thread;
 
 fn convert(a: &AtomicU16) -> &[AtomicU8; 2] {
diff --git a/src/tools/miri/tests/fail/should-pass/cpp20_rwc_syncs.rs b/src/tools/miri/tests/fail/should-pass/cpp20_rwc_syncs.rs
index 545875a582a..cebad507ea9 100644
--- a/src/tools/miri/tests/fail/should-pass/cpp20_rwc_syncs.rs
+++ b/src/tools/miri/tests/fail/should-pass/cpp20_rwc_syncs.rs
@@ -8,7 +8,7 @@
 // so we have to stick to C++11 emulation from existing research.
 
 use std::sync::atomic::Ordering::*;
-use std::sync::atomic::{fence, AtomicUsize};
+use std::sync::atomic::{AtomicUsize, fence};
 use std::thread::spawn;
 
 // Spins until it reads the given value
diff --git a/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs b/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs
index 76a5e6a0b62..49df267c4c3 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/illegal_dealloc1.rs
@@ -1,4 +1,4 @@
-use std::alloc::{alloc, dealloc, Layout};
+use std::alloc::{Layout, alloc, dealloc};
 
 fn main() {
     unsafe {
diff --git a/src/tools/miri/tests/fail/tree_borrows/children-can-alias.rs b/src/tools/miri/tests/fail/tree_borrows/children-can-alias.rs
index b5a01cd4324..036267dc11e 100644
--- a/src/tools/miri/tests/fail/tree_borrows/children-can-alias.rs
+++ b/src/tools/miri/tests/fail/tree_borrows/children-can-alias.rs
@@ -8,8 +8,8 @@
 
 #![feature(ptr_internals)]
 
-use core::ptr::addr_of_mut;
 use core::ptr::Unique;
+use core::ptr::addr_of_mut;
 
 fn main() {
     let mut data = 0u8;
diff --git a/src/tools/miri/tests/fail/uninit/padding-enum.rs b/src/tools/miri/tests/fail/uninit/padding-enum.rs
index a9628799b7d..e1a16bea23c 100644
--- a/src/tools/miri/tests/fail/uninit/padding-enum.rs
+++ b/src/tools/miri/tests/fail/uninit/padding-enum.rs
@@ -17,10 +17,11 @@ fn main() {
         assert!(matches!(*p.as_ptr(), E::None));
 
         // Turns out the discriminant is (currently) stored
-        // in the 2nd pointer, so the first half is padding.
+        // in the 1st pointer, so the second half is padding.
         let c = &p as *const _ as *const u8;
+        let padding_offset = mem::size_of::<&'static ()>();
         // Read a padding byte.
-        let _val = *c.add(0);
+        let _val = *c.add(padding_offset);
         //~^ERROR: uninitialized
     }
 }
diff --git a/src/tools/miri/tests/fail/uninit/padding-enum.stderr b/src/tools/miri/tests/fail/uninit/padding-enum.stderr
index 66d3092c9ba..765e7cc4e63 100644
--- a/src/tools/miri/tests/fail/uninit/padding-enum.stderr
+++ b/src/tools/miri/tests/fail/uninit/padding-enum.stderr
@@ -1,8 +1,8 @@
 error: Undefined Behavior: using uninitialized data, but this operation requires initialized memory
   --> tests/fail/uninit/padding-enum.rs:LL:CC
    |
-LL |         let _val = *c.add(0);
-   |                    ^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
+LL |         let _val = *c.add(padding_offset);
+   |                    ^^^^^^^^^^^^^^^^^^^^^^ using uninitialized data, but this operation requires initialized memory
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.rs b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.rs
index 8deaa30d50f..5edf4bbb1cc 100644
--- a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.rs
+++ b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic.rs
@@ -3,7 +3,7 @@
 
 #![allow(dropping_copy_types)]
 
-use std::alloc::{alloc, dealloc, Layout};
+use std::alloc::{Layout, alloc, dealloc};
 use std::slice::from_raw_parts;
 
 fn main() {
diff --git a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.rs b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.rs
index adabff4a2ce..954571f4a22 100644
--- a/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.rs
+++ b/src/tools/miri/tests/fail/uninit/uninit_alloc_diagnostic_with_provenance.rs
@@ -6,7 +6,7 @@
 
 // Test printing allocations that contain single-byte provenance.
 
-use std::alloc::{alloc, dealloc, Layout};
+use std::alloc::{Layout, alloc, dealloc};
 use std::mem::{self, MaybeUninit};
 use std::slice::from_raw_parts;
 
diff --git a/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs b/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs
index e84ffee367f..255a93226a9 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/linux-futex.rs
@@ -1,6 +1,9 @@
 //@only-target: linux
 //@compile-flags: -Zmiri-disable-isolation
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use std::mem::MaybeUninit;
 use std::ptr::{self, addr_of};
 use std::sync::atomic::AtomicI32;
diff --git a/src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs b/src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs
index 87c8a2e1063..2dc09709b8e 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/tls_pthread_drop_order.rs
@@ -5,6 +5,9 @@
 //! the fallback path in `guard::key::enable`, which uses a *single* pthread_key
 //! to manage a thread-local list of dtors to call.
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use std::mem;
 use std::ptr;
 
diff --git a/src/tools/miri/tests/pass-dep/concurrency/windows_init_once.rs b/src/tools/miri/tests/pass-dep/concurrency/windows_init_once.rs
index afcab7a702d..6853395686a 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/windows_init_once.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/windows_init_once.rs
@@ -7,7 +7,7 @@ use std::thread;
 
 use windows_sys::Win32::Foundation::{FALSE, TRUE};
 use windows_sys::Win32::System::Threading::{
-    InitOnceBeginInitialize, InitOnceComplete, INIT_ONCE, INIT_ONCE_INIT_FAILED,
+    INIT_ONCE, INIT_ONCE_INIT_FAILED, InitOnceBeginInitialize, InitOnceComplete,
 };
 
 // not in windows-sys
diff --git a/src/tools/miri/tests/pass-dep/concurrency/windows_join_multiple.rs b/src/tools/miri/tests/pass-dep/concurrency/windows_join_multiple.rs
index 67e77663110..ce829eee227 100644
--- a/src/tools/miri/tests/pass-dep/concurrency/windows_join_multiple.rs
+++ b/src/tools/miri/tests/pass-dep/concurrency/windows_join_multiple.rs
@@ -7,7 +7,7 @@ use std::sync::atomic::{AtomicBool, Ordering};
 use std::thread;
 
 use windows_sys::Win32::Foundation::{HANDLE, WAIT_OBJECT_0};
-use windows_sys::Win32::System::Threading::{WaitForSingleObject, INFINITE};
+use windows_sys::Win32::System::Threading::{INFINITE, WaitForSingleObject};
 
 fn main() {
     static FLAG: AtomicBool = AtomicBool::new(false);
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs b/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs
index 2f65ce13d64..3ea34513376 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-epoll-no-blocking.rs
@@ -231,10 +231,10 @@ fn test_two_same_fd_in_same_epoll_instance() {
     //Two notification should be received.
     let expected_event = u32::try_from(libc::EPOLLIN | libc::EPOLLOUT).unwrap();
     let expected_value = 5 as u64;
-    check_epoll_wait::<8>(
-        epfd,
-        &[(expected_event, expected_value), (expected_event, expected_value)],
-    );
+    check_epoll_wait::<8>(epfd, &[
+        (expected_event, expected_value),
+        (expected_event, expected_value),
+    ]);
 }
 
 fn test_epoll_eventfd() {
@@ -291,10 +291,10 @@ fn test_epoll_socketpair_both_sides() {
     let expected_value0 = fds[0] as u64;
     let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap();
     let expected_value1 = fds[1] as u64;
-    check_epoll_wait::<8>(
-        epfd,
-        &[(expected_event0, expected_value0), (expected_event1, expected_value1)],
-    );
+    check_epoll_wait::<8>(epfd, &[
+        (expected_event0, expected_value0),
+        (expected_event1, expected_value1),
+    ]);
 
     // Read from fds[0].
     let mut buf: [u8; 5] = [0; 5];
@@ -454,10 +454,10 @@ fn test_socketpair_read() {
     let expected_value0 = fds[0] as u64;
     let expected_event1 = u32::try_from(libc::EPOLLOUT).unwrap();
     let expected_value1 = fds[1] as u64;
-    check_epoll_wait::<8>(
-        epfd,
-        &[(expected_event0, expected_value0), (expected_event1, expected_value1)],
-    );
+    check_epoll_wait::<8>(epfd, &[
+        (expected_event0, expected_value0),
+        (expected_event1, expected_value1),
+    ]);
 
     // Read 3 bytes from fds[0].
     let mut buf: [u8; 3] = [0; 3];
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs b/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs
index 1e3d486233a..1d084194658 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-eventfd.rs
@@ -2,6 +2,9 @@
 // test_race depends on a deterministic schedule.
 //@compile-flags: -Zmiri-preemption-rate=0
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use std::thread;
 
 fn main() {
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs
index 11809613749..17e6e507c27 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-fs.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-fs.rs
@@ -5,7 +5,7 @@
 #![feature(io_error_uncategorized)]
 
 use std::ffi::{CStr, CString, OsString};
-use std::fs::{canonicalize, remove_file, File};
+use std::fs::{File, canonicalize, remove_file};
 use std::io::{Error, ErrorKind, Write};
 use std::os::unix::ffi::OsStrExt;
 use std::os::unix::io::AsRawFd;
@@ -169,7 +169,7 @@ fn test_ftruncate<T: From<i32>>(
 
 #[cfg(target_os = "linux")]
 fn test_o_tmpfile_flag() {
-    use std::fs::{create_dir, OpenOptions};
+    use std::fs::{OpenOptions, create_dir};
     use std::os::unix::fs::OpenOptionsExt;
     let dir_path = utils::prepare_dir("miri_test_fs_dir");
     create_dir(&dir_path).unwrap();
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs b/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs
index c6e8355c3f5..76f883e5d8d 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-pipe.rs
@@ -72,6 +72,8 @@ fn test_pipe_threaded() {
     thread2.join().unwrap();
 }
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#[allow(static_mut_refs)]
 fn test_race() {
     static mut VAL: u8 = 0;
     let mut fds = [-1, -1];
diff --git a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs
index c3d6af5a1ef..64819e57679 100644
--- a/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs
+++ b/src/tools/miri/tests/pass-dep/libc/libc-socketpair.rs
@@ -1,6 +1,10 @@
 //@ignore-target: windows # No libc socketpair on Windows
 // test_race depends on a deterministic schedule.
 //@compile-flags: -Zmiri-preemption-rate=0
+
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use std::thread;
 fn main() {
     test_socketpair();
diff --git a/src/tools/miri/tests/pass-dep/tokio/sleep.rs b/src/tools/miri/tests/pass-dep/tokio/sleep.rs
index 38f2cdde115..3c409a641f2 100644
--- a/src/tools/miri/tests/pass-dep/tokio/sleep.rs
+++ b/src/tools/miri/tests/pass-dep/tokio/sleep.rs
@@ -1,6 +1,6 @@
 //@only-target: linux # We only support tokio on Linux
 
-use tokio::time::{sleep, Duration, Instant};
+use tokio::time::{Duration, Instant, sleep};
 
 #[tokio::main]
 async fn main() {
diff --git a/src/tools/miri/tests/pass/0weak_memory_consistency.rs b/src/tools/miri/tests/pass/0weak_memory_consistency.rs
index 1cbccb2eebd..10f7aed9418 100644
--- a/src/tools/miri/tests/pass/0weak_memory_consistency.rs
+++ b/src/tools/miri/tests/pass/0weak_memory_consistency.rs
@@ -22,7 +22,7 @@
 // Available: https://ss265.host.cs.st-andrews.ac.uk/papers/n3132.pdf.
 
 use std::sync::atomic::Ordering::*;
-use std::sync::atomic::{fence, AtomicBool, AtomicI32};
+use std::sync::atomic::{AtomicBool, AtomicI32, fence};
 use std::thread::spawn;
 
 #[derive(Copy, Clone)]
diff --git a/src/tools/miri/tests/pass/async-drop.rs b/src/tools/miri/tests/pass/async-drop.rs
index 92ecbdd29fd..53e3476f620 100644
--- a/src/tools/miri/tests/pass/async-drop.rs
+++ b/src/tools/miri/tests/pass/async-drop.rs
@@ -10,10 +10,10 @@
 #![allow(incomplete_features, dead_code)]
 
 // FIXME(zetanumbers): consider AsyncDestruct::async_drop cleanup tests
-use core::future::{async_drop_in_place, AsyncDrop, Future};
+use core::future::{AsyncDrop, Future, async_drop_in_place};
 use core::hint::black_box;
 use core::mem::{self, ManuallyDrop};
-use core::pin::{pin, Pin};
+use core::pin::{Pin, pin};
 use core::task::{Context, Poll, Waker};
 
 async fn test_async_drop<T>(x: T) {
@@ -125,7 +125,10 @@ struct AsyncReference<'a> {
 }
 
 impl AsyncDrop for AsyncReference<'_> {
-    type Dropper<'a> = impl Future<Output = ()> where Self: 'a;
+    type Dropper<'a>
+        = impl Future<Output = ()>
+    where
+        Self: 'a;
 
     fn async_drop(self: Pin<&mut Self>) -> Self::Dropper<'_> {
         async move {
diff --git a/src/tools/miri/tests/pass/atomic.rs b/src/tools/miri/tests/pass/atomic.rs
index dfdc9b42f81..781cc9bd309 100644
--- a/src/tools/miri/tests/pass/atomic.rs
+++ b/src/tools/miri/tests/pass/atomic.rs
@@ -1,9 +1,13 @@
 //@revisions: stack tree
 //@[tree]compile-flags: -Zmiri-tree-borrows
 //@compile-flags: -Zmiri-strict-provenance
+
 #![feature(strict_provenance, strict_provenance_atomic_ptr)]
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use std::sync::atomic::{
-    compiler_fence, fence, AtomicBool, AtomicIsize, AtomicPtr, AtomicU64, Ordering::*,
+    AtomicBool, AtomicIsize, AtomicPtr, AtomicU64, Ordering::*, compiler_fence, fence,
 };
 
 fn main() {
diff --git a/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs b/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs
index 18980932f31..a1371242f60 100644
--- a/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs
+++ b/src/tools/miri/tests/pass/box-custom-alloc-aliasing.rs
@@ -11,7 +11,7 @@ use std::{
     alloc::{AllocError, Allocator, Layout},
     cell::{Cell, UnsafeCell},
     mem,
-    ptr::{self, addr_of, NonNull},
+    ptr::{self, NonNull, addr_of},
     thread::{self, ThreadId},
 };
 
diff --git a/src/tools/miri/tests/pass/catch.rs b/src/tools/miri/tests/pass/catch.rs
index 4ede23e68ce..bedabf3eb28 100644
--- a/src/tools/miri/tests/pass/catch.rs
+++ b/src/tools/miri/tests/pass/catch.rs
@@ -1,4 +1,4 @@
-use std::panic::{catch_unwind, AssertUnwindSafe};
+use std::panic::{AssertUnwindSafe, catch_unwind};
 
 fn main() {
     let mut i = 3;
diff --git a/src/tools/miri/tests/pass/drop_on_array_elements.rs b/src/tools/miri/tests/pass/drop_on_array_elements.rs
index ae1ef036267..4bf241fee2b 100644
--- a/src/tools/miri/tests/pass/drop_on_array_elements.rs
+++ b/src/tools/miri/tests/pass/drop_on_array_elements.rs
@@ -1,3 +1,5 @@
+#![allow(static_mut_refs)]
+
 struct Bar(u16); // ZSTs are tested separately
 
 static mut DROP_COUNT: usize = 0;
diff --git a/src/tools/miri/tests/pass/drop_on_fat_ptr_array_elements.rs b/src/tools/miri/tests/pass/drop_on_fat_ptr_array_elements.rs
index 40025cd07f7..04723af94c3 100644
--- a/src/tools/miri/tests/pass/drop_on_fat_ptr_array_elements.rs
+++ b/src/tools/miri/tests/pass/drop_on_fat_ptr_array_elements.rs
@@ -1,3 +1,5 @@
+#![allow(static_mut_refs)]
+
 trait Foo {}
 
 struct Bar;
diff --git a/src/tools/miri/tests/pass/drop_on_zst_array_elements.rs b/src/tools/miri/tests/pass/drop_on_zst_array_elements.rs
index babe098e4e6..71398724f2c 100644
--- a/src/tools/miri/tests/pass/drop_on_zst_array_elements.rs
+++ b/src/tools/miri/tests/pass/drop_on_zst_array_elements.rs
@@ -1,3 +1,5 @@
+#![allow(static_mut_refs)]
+
 struct Bar;
 
 static mut DROP_COUNT: usize = 0;
diff --git a/src/tools/miri/tests/pass/drop_through_owned_slice.rs b/src/tools/miri/tests/pass/drop_through_owned_slice.rs
index 8cdeb57d02f..2d1d876e6f2 100644
--- a/src/tools/miri/tests/pass/drop_through_owned_slice.rs
+++ b/src/tools/miri/tests/pass/drop_through_owned_slice.rs
@@ -1,3 +1,5 @@
+#![allow(static_mut_refs)]
+
 struct Bar;
 
 static mut DROP_COUNT: usize = 0;
diff --git a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
index 4c0d6f52425..cd606a5282a 100644
--- a/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
+++ b/src/tools/miri/tests/pass/intrinsics/portable-simd.rs
@@ -11,7 +11,7 @@
 #![allow(incomplete_features, internal_features)]
 use std::intrinsics::simd as intrinsics;
 use std::ptr;
-use std::simd::{prelude::*, StdFloat};
+use std::simd::{StdFloat, prelude::*};
 
 extern "rust-intrinsic" {
     #[rustc_nounwind]
diff --git a/src/tools/miri/tests/pass/panic/catch_panic.rs b/src/tools/miri/tests/pass/panic/catch_panic.rs
index b83902a8b19..06d15a1a7f9 100644
--- a/src/tools/miri/tests/pass/panic/catch_panic.rs
+++ b/src/tools/miri/tests/pass/panic/catch_panic.rs
@@ -2,7 +2,7 @@
 #![allow(unconditional_panic, non_fmt_panics)]
 
 use std::cell::Cell;
-use std::panic::{catch_unwind, AssertUnwindSafe};
+use std::panic::{AssertUnwindSafe, catch_unwind};
 use std::process;
 
 thread_local! {
diff --git a/src/tools/miri/tests/pass/panic/concurrent-panic.rs b/src/tools/miri/tests/pass/panic/concurrent-panic.rs
index 7cc1e2a973f..e804df90977 100644
--- a/src/tools/miri/tests/pass/panic/concurrent-panic.rs
+++ b/src/tools/miri/tests/pass/panic/concurrent-panic.rs
@@ -5,7 +5,7 @@
 //! that separate threads have their own panicking state.
 
 use std::sync::{Arc, Condvar, Mutex};
-use std::thread::{spawn, JoinHandle};
+use std::thread::{JoinHandle, spawn};
 
 struct BlockOnDrop(Option<JoinHandle<()>>);
 
diff --git a/src/tools/miri/tests/pass/path.rs b/src/tools/miri/tests/pass/path.rs
index fe99d38e073..299ee6cfe9d 100644
--- a/src/tools/miri/tests/pass/path.rs
+++ b/src/tools/miri/tests/pass/path.rs
@@ -1,5 +1,5 @@
 //@compile-flags: -Zmiri-disable-isolation
-use std::path::{absolute, Path, PathBuf};
+use std::path::{Path, PathBuf, absolute};
 
 #[path = "../utils/mod.rs"]
 mod utils;
diff --git a/src/tools/miri/tests/pass/shims/fs-symlink.rs b/src/tools/miri/tests/pass/shims/fs-symlink.rs
index 01bb713926c..30cf234e7a0 100644
--- a/src/tools/miri/tests/pass/shims/fs-symlink.rs
+++ b/src/tools/miri/tests/pass/shims/fs-symlink.rs
@@ -3,7 +3,7 @@
 //@ignore-target: windows # File handling is not implemented yet
 //@compile-flags: -Zmiri-disable-isolation
 
-use std::fs::{read_link, remove_file, File};
+use std::fs::{File, read_link, remove_file};
 use std::io::{Read, Result};
 use std::path::Path;
 
diff --git a/src/tools/miri/tests/pass/shims/fs.rs b/src/tools/miri/tests/pass/shims/fs.rs
index 761164a4ba3..62424ca26b1 100644
--- a/src/tools/miri/tests/pass/shims/fs.rs
+++ b/src/tools/miri/tests/pass/shims/fs.rs
@@ -7,8 +7,8 @@
 use std::collections::HashMap;
 use std::ffi::OsString;
 use std::fs::{
-    canonicalize, create_dir, read_dir, remove_dir, remove_dir_all, remove_file, rename, File,
-    OpenOptions,
+    File, OpenOptions, canonicalize, create_dir, read_dir, remove_dir, remove_dir_all, remove_file,
+    rename,
 };
 use std::io::{Error, ErrorKind, IsTerminal, Read, Result, Seek, SeekFrom, Write};
 use std::path::Path;
diff --git a/src/tools/miri/tests/pass/static_memory_modification.rs b/src/tools/miri/tests/pass/static_memory_modification.rs
index 84a524b1ed1..1900250bf4f 100644
--- a/src/tools/miri/tests/pass/static_memory_modification.rs
+++ b/src/tools/miri/tests/pass/static_memory_modification.rs
@@ -1,3 +1,6 @@
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use std::sync::atomic::{AtomicUsize, Ordering};
 
 static mut X: usize = 5;
diff --git a/src/tools/miri/tests/pass/static_mut.rs b/src/tools/miri/tests/pass/static_mut.rs
index 4488b5a09d5..f88c7a16e6d 100644
--- a/src/tools/miri/tests/pass/static_mut.rs
+++ b/src/tools/miri/tests/pass/static_mut.rs
@@ -1,3 +1,6 @@
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use std::ptr::addr_of;
 
 static mut FOO: i32 = 42;
diff --git a/src/tools/miri/tests/pass/tls/tls_static.rs b/src/tools/miri/tests/pass/tls/tls_static.rs
index 8d0e5089d40..cc4eaca72ab 100644
--- a/src/tools/miri/tests/pass/tls/tls_static.rs
+++ b/src/tools/miri/tests/pass/tls/tls_static.rs
@@ -7,6 +7,8 @@
 //! dereferencing the pointer on `t2` resolves to `t1`'s thread-local. In this
 //! test, we also check that thread-locals act as per-thread statics.
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
 #![feature(thread_local)]
 
 use std::ptr::addr_of_mut;
diff --git a/src/tools/miri/tests/pass/weak_memory/weak.rs b/src/tools/miri/tests/pass/weak_memory/weak.rs
index 1b5c98cd518..5d636431d86 100644
--- a/src/tools/miri/tests/pass/weak_memory/weak.rs
+++ b/src/tools/miri/tests/pass/weak_memory/weak.rs
@@ -8,7 +8,7 @@
 // the RNG and always read the latest value from the store buffer.
 
 use std::sync::atomic::Ordering::*;
-use std::sync::atomic::{fence, AtomicUsize};
+use std::sync::atomic::{AtomicUsize, fence};
 use std::thread::spawn;
 
 #[allow(dead_code)]
diff --git a/src/tools/miri/tests/ui.rs b/src/tools/miri/tests/ui.rs
index d405eb92ad1..2430140eea1 100644
--- a/src/tools/miri/tests/ui.rs
+++ b/src/tools/miri/tests/ui.rs
@@ -12,7 +12,7 @@ use ui_test::custom_flags::edition::Edition;
 use ui_test::dependencies::DependencyBuilder;
 use ui_test::per_test_config::TestConfig;
 use ui_test::spanned::Spanned;
-use ui_test::{status_emitter, CommandBuilder, Config, Format, Match, OutputConflictHandling};
+use ui_test::{CommandBuilder, Config, Format, Match, OutputConflictHandling, status_emitter};
 
 #[derive(Copy, Clone, Debug)]
 enum Mode {
@@ -118,24 +118,21 @@ fn miri_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) ->
     config.comment_defaults.base().add_custom("edition", Edition("2021".into()));
 
     if with_dependencies {
-        config.comment_defaults.base().set_custom(
-            "dependencies",
-            DependencyBuilder {
-                program: CommandBuilder {
-                    // Set the `cargo-miri` binary, which we expect to be in the same folder as the `miri` binary.
-                    // (It's a separate crate, so we don't get an env var from cargo.)
-                    program: miri_path()
-                        .with_file_name(format!("cargo-miri{}", env::consts::EXE_SUFFIX)),
-                    // There is no `cargo miri build` so we just use `cargo miri run`.
-                    args: ["miri", "run"].into_iter().map(Into::into).collect(),
-                    // Reset `RUSTFLAGS` to work around <https://github.com/rust-lang/rust/pull/119574#issuecomment-1876878344>.
-                    envs: vec![("RUSTFLAGS".into(), None)],
-                    ..CommandBuilder::cargo()
-                },
-                crate_manifest_path: Path::new("test_dependencies").join("Cargo.toml"),
-                build_std: None,
+        config.comment_defaults.base().set_custom("dependencies", DependencyBuilder {
+            program: CommandBuilder {
+                // Set the `cargo-miri` binary, which we expect to be in the same folder as the `miri` binary.
+                // (It's a separate crate, so we don't get an env var from cargo.)
+                program: miri_path()
+                    .with_file_name(format!("cargo-miri{}", env::consts::EXE_SUFFIX)),
+                // There is no `cargo miri build` so we just use `cargo miri run`.
+                args: ["miri", "run"].into_iter().map(Into::into).collect(),
+                // Reset `RUSTFLAGS` to work around <https://github.com/rust-lang/rust/pull/119574#issuecomment-1876878344>.
+                envs: vec![("RUSTFLAGS".into(), None)],
+                ..CommandBuilder::cargo()
             },
-        );
+            crate_manifest_path: Path::new("test_dependencies").join("Cargo.toml"),
+            build_std: None,
+        });
     }
     config
 }
diff --git a/src/tools/run-make-support/src/fs.rs b/src/tools/run-make-support/src/fs.rs
index 2c35ba52a62..2ca55ad3b3a 100644
--- a/src/tools/run-make-support/src/fs.rs
+++ b/src/tools/run-make-support/src/fs.rs
@@ -1,42 +1,6 @@
 use std::io;
 use std::path::{Path, PathBuf};
 
-// FIXME(jieyouxu): modify create_symlink to panic on windows.
-
-/// Creates a new symlink to a path on the filesystem, adjusting for Windows or Unix.
-#[cfg(target_family = "windows")]
-pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
-    if link.as_ref().exists() {
-        std::fs::remove_dir(link.as_ref()).unwrap();
-    }
-    if original.as_ref().is_file() {
-        std::os::windows::fs::symlink_file(original.as_ref(), link.as_ref()).expect(&format!(
-            "failed to create symlink {:?} for {:?}",
-            link.as_ref().display(),
-            original.as_ref().display(),
-        ));
-    } else {
-        std::os::windows::fs::symlink_dir(original.as_ref(), link.as_ref()).expect(&format!(
-            "failed to create symlink {:?} for {:?}",
-            link.as_ref().display(),
-            original.as_ref().display(),
-        ));
-    }
-}
-
-/// Creates a new symlink to a path on the filesystem, adjusting for Windows or Unix.
-#[cfg(target_family = "unix")]
-pub fn create_symlink<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
-    if link.as_ref().exists() {
-        std::fs::remove_dir(link.as_ref()).unwrap();
-    }
-    std::os::unix::fs::symlink(original.as_ref(), link.as_ref()).expect(&format!(
-        "failed to create symlink {:?} for {:?}",
-        link.as_ref().display(),
-        original.as_ref().display(),
-    ));
-}
-
 /// Copy a directory into another.
 pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
     fn copy_dir_all_inner(src: impl AsRef<Path>, dst: impl AsRef<Path>) -> io::Result<()> {
@@ -50,7 +14,31 @@ pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
             if ty.is_dir() {
                 copy_dir_all_inner(entry.path(), dst.join(entry.file_name()))?;
             } else if ty.is_symlink() {
-                copy_symlink(entry.path(), dst.join(entry.file_name()))?;
+                // Traverse symlink once to find path of target entity.
+                let target_path = std::fs::read_link(entry.path())?;
+
+                let new_symlink_path = dst.join(entry.file_name());
+                #[cfg(windows)]
+                {
+                    use std::os::windows::fs::FileTypeExt;
+                    if ty.is_symlink_dir() {
+                        std::os::windows::fs::symlink_dir(&target_path, new_symlink_path)?;
+                    } else {
+                        // Target may be a file or another symlink, in any case we can use
+                        // `symlink_file` here.
+                        std::os::windows::fs::symlink_file(&target_path, new_symlink_path)?;
+                    }
+                }
+                #[cfg(unix)]
+                {
+                    std::os::unix::fs::symlink(target_path, new_symlink_path)?;
+                }
+                #[cfg(not(any(windows, unix)))]
+                {
+                    // Technically there's also wasi, but I have no clue about wasi symlink
+                    // semantics and which wasi targets / environment support symlinks.
+                    unimplemented!("unsupported target");
+                }
             } else {
                 std::fs::copy(entry.path(), dst.join(entry.file_name()))?;
             }
@@ -69,12 +57,6 @@ pub fn copy_dir_all(src: impl AsRef<Path>, dst: impl AsRef<Path>) {
     }
 }
 
-fn copy_symlink<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()> {
-    let target_path = std::fs::read_link(from).unwrap();
-    create_symlink(target_path, to);
-    Ok(())
-}
-
 /// Helper for reading entries in a given directory.
 pub fn read_dir_entries<P: AsRef<Path>, F: FnMut(&Path)>(dir: P, mut callback: F) {
     for entry in read_dir(dir) {
@@ -85,8 +67,17 @@ pub fn read_dir_entries<P: AsRef<Path>, F: FnMut(&Path)>(dir: P, mut callback: F
 /// A wrapper around [`std::fs::remove_file`] which includes the file path in the panic message.
 #[track_caller]
 pub fn remove_file<P: AsRef<Path>>(path: P) {
-    std::fs::remove_file(path.as_ref())
-        .expect(&format!("the file in path \"{}\" could not be removed", path.as_ref().display()));
+    if let Err(e) = std::fs::remove_file(path.as_ref()) {
+        panic!("failed to remove file at `{}`: {e}", path.as_ref().display());
+    }
+}
+
+/// A wrapper around [`std::fs::remove_dir`] which includes the directory path in the panic message.
+#[track_caller]
+pub fn remove_dir<P: AsRef<Path>>(path: P) {
+    if let Err(e) = std::fs::remove_dir(path.as_ref()) {
+        panic!("failed to remove directory at `{}`: {e}", path.as_ref().display());
+    }
 }
 
 /// A wrapper around [`std::fs::copy`] which includes the file path in the panic message.
@@ -165,13 +156,32 @@ pub fn create_dir_all<P: AsRef<Path>>(path: P) {
     ));
 }
 
-/// A wrapper around [`std::fs::metadata`] which includes the file path in the panic message.
+/// A wrapper around [`std::fs::metadata`] which includes the file path in the panic message. Note
+/// that this will traverse symlinks and will return metadata about the target file. Use
+/// [`symlink_metadata`] if you don't want to traverse symlinks.
+///
+/// See [`std::fs::metadata`] docs for more details.
 #[track_caller]
 pub fn metadata<P: AsRef<Path>>(path: P) -> std::fs::Metadata {
-    std::fs::metadata(path.as_ref()).expect(&format!(
-        "the file's metadata in path \"{}\" could not be read",
-        path.as_ref().display()
-    ))
+    match std::fs::metadata(path.as_ref()) {
+        Ok(m) => m,
+        Err(e) => panic!("failed to read file metadata at `{}`: {e}", path.as_ref().display()),
+    }
+}
+
+/// A wrapper around [`std::fs::symlink_metadata`] which includes the file path in the panic
+/// message. Note that this will not traverse symlinks and will return metadata about the filesystem
+/// entity itself. Use [`metadata`] if you want to traverse symlinks.
+///
+/// See [`std::fs::symlink_metadata`] docs for more details.
+#[track_caller]
+pub fn symlink_metadata<P: AsRef<Path>>(path: P) -> std::fs::Metadata {
+    match std::fs::symlink_metadata(path.as_ref()) {
+        Ok(m) => m,
+        Err(e) => {
+            panic!("failed to read file metadata (shallow) at `{}`: {e}", path.as_ref().display())
+        }
+    }
 }
 
 /// A wrapper around [`std::fs::rename`] which includes the file path in the panic message.
@@ -205,3 +215,73 @@ pub fn shallow_find_dir_entries<P: AsRef<Path>>(dir: P) -> Vec<PathBuf> {
     }
     output
 }
+
+/// Create a new symbolic link to a directory.
+///
+/// # Removing the symlink
+///
+/// - On Windows, a symlink-to-directory needs to be removed with a corresponding [`fs::remove_dir`]
+///   and not [`fs::remove_file`].
+/// - On Unix, remove the symlink with [`fs::remove_file`].
+///
+/// [`fs::remove_dir`]: crate::fs::remove_dir
+/// [`fs::remove_file`]: crate::fs::remove_file
+pub fn symlink_dir<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
+    #[cfg(unix)]
+    {
+        if let Err(e) = std::os::unix::fs::symlink(original.as_ref(), link.as_ref()) {
+            panic!(
+                "failed to create symlink: original=`{}`, link=`{}`: {e}",
+                original.as_ref().display(),
+                link.as_ref().display()
+            );
+        }
+    }
+    #[cfg(windows)]
+    {
+        if let Err(e) = std::os::windows::fs::symlink_dir(original.as_ref(), link.as_ref()) {
+            panic!(
+                "failed to create symlink-to-directory: original=`{}`, link=`{}`: {e}",
+                original.as_ref().display(),
+                link.as_ref().display()
+            );
+        }
+    }
+    #[cfg(not(any(windows, unix)))]
+    {
+        unimplemented!("target family not currently supported")
+    }
+}
+
+/// Create a new symbolic link to a file.
+///
+/// # Removing the symlink
+///
+/// On both Windows and Unix, a symlink-to-file needs to be removed with a corresponding
+/// [`fs::remove_file`](crate::fs::remove_file) and not [`fs::remove_dir`](crate::fs::remove_dir).
+pub fn symlink_file<P: AsRef<Path>, Q: AsRef<Path>>(original: P, link: Q) {
+    #[cfg(unix)]
+    {
+        if let Err(e) = std::os::unix::fs::symlink(original.as_ref(), link.as_ref()) {
+            panic!(
+                "failed to create symlink: original=`{}`, link=`{}`: {e}",
+                original.as_ref().display(),
+                link.as_ref().display()
+            );
+        }
+    }
+    #[cfg(windows)]
+    {
+        if let Err(e) = std::os::windows::fs::symlink_file(original.as_ref(), link.as_ref()) {
+            panic!(
+                "failed to create symlink-to-file: original=`{}`, link=`{}`: {e}",
+                original.as_ref().display(),
+                link.as_ref().display()
+            );
+        }
+    }
+    #[cfg(not(any(windows, unix)))]
+    {
+        unimplemented!("target family not currently supported")
+    }
+}
diff --git a/src/tools/rustfmt/.github/workflows/check_diff.yml b/src/tools/rustfmt/.github/workflows/check_diff.yml
index 2f2beb76915..99daa0addf5 100644
--- a/src/tools/rustfmt/.github/workflows/check_diff.yml
+++ b/src/tools/rustfmt/.github/workflows/check_diff.yml
@@ -21,7 +21,7 @@ jobs:
 
     steps:
     - name: checkout
-      uses: actions/checkout@v3
+      uses: actions/checkout@v4
 
     - name: install rustup
       run: |
diff --git a/src/tools/rustfmt/.github/workflows/integration.yml b/src/tools/rustfmt/.github/workflows/integration.yml
index f0dd0cf73bb..bda374562bc 100644
--- a/src/tools/rustfmt/.github/workflows/integration.yml
+++ b/src/tools/rustfmt/.github/workflows/integration.yml
@@ -64,7 +64,7 @@ jobs:
 
     steps:
     - name: checkout
-      uses: actions/checkout@v3
+      uses: actions/checkout@v4
 
       # Run build
     - name: install rustup
diff --git a/src/tools/rustfmt/.github/workflows/linux.yml b/src/tools/rustfmt/.github/workflows/linux.yml
index bce9b0c8d5a..3a5e6ab5404 100644
--- a/src/tools/rustfmt/.github/workflows/linux.yml
+++ b/src/tools/rustfmt/.github/workflows/linux.yml
@@ -26,7 +26,7 @@ jobs:
 
     steps:
     - name: checkout
-      uses: actions/checkout@v3
+      uses: actions/checkout@v4
 
       # Run build
     - name: install rustup
diff --git a/src/tools/rustfmt/.github/workflows/mac.yml b/src/tools/rustfmt/.github/workflows/mac.yml
index 89a980c42c5..2c766d0573b 100644
--- a/src/tools/rustfmt/.github/workflows/mac.yml
+++ b/src/tools/rustfmt/.github/workflows/mac.yml
@@ -8,7 +8,6 @@ on:
 jobs:
   test:
     # https://help.github.com/en/actions/automating-your-workflow-with-github-actions/virtual-environments-for-github-hosted-runners#supported-runners-and-hardware-resources
-    # macOS Catalina 10.15
     runs-on: macos-latest
     name: (${{ matrix.target }}, ${{ matrix.cfg_release_channel }})
     env:
@@ -23,7 +22,7 @@ jobs:
 
     steps:
     - name: checkout
-      uses: actions/checkout@v3
+      uses: actions/checkout@v4
 
       # Run build
     - name: install rustup
diff --git a/src/tools/rustfmt/.github/workflows/rustdoc_check.yml b/src/tools/rustfmt/.github/workflows/rustdoc_check.yml
index cd0c3218971..6e8a7ecd7ad 100644
--- a/src/tools/rustfmt/.github/workflows/rustdoc_check.yml
+++ b/src/tools/rustfmt/.github/workflows/rustdoc_check.yml
@@ -11,7 +11,7 @@ jobs:
     name: rustdoc check
     steps:
     - name: checkout
-      uses: actions/checkout@v3
+      uses: actions/checkout@v4
 
     - name: install rustup
       run: |
diff --git a/src/tools/rustfmt/.github/workflows/upload-assets.yml b/src/tools/rustfmt/.github/workflows/upload-assets.yml
index 7dfaa4b9204..7a639b469e8 100644
--- a/src/tools/rustfmt/.github/workflows/upload-assets.yml
+++ b/src/tools/rustfmt/.github/workflows/upload-assets.yml
@@ -31,7 +31,7 @@ jobs:
             target: x86_64-pc-windows-msvc
     runs-on: ${{ matrix.os }}
     steps:
-      - uses: actions/checkout@v3
+      - uses: actions/checkout@v4
 
         # Run build
       - name: install rustup
diff --git a/src/tools/rustfmt/.github/workflows/windows.yml b/src/tools/rustfmt/.github/workflows/windows.yml
index ec37c714b08..728f1b90b13 100644
--- a/src/tools/rustfmt/.github/workflows/windows.yml
+++ b/src/tools/rustfmt/.github/workflows/windows.yml
@@ -33,7 +33,7 @@ jobs:
     - name: disable git eol translation
       run: git config --global core.autocrlf false
     - name: checkout
-      uses: actions/checkout@v3
+      uses: actions/checkout@v4
 
       # Run build
     - name: Install Rustup using win.rustup.rs
diff --git a/src/tools/rustfmt/CHANGELOG.md b/src/tools/rustfmt/CHANGELOG.md
index 89e90fb17dd..8af60f60dc6 100644
--- a/src/tools/rustfmt/CHANGELOG.md
+++ b/src/tools/rustfmt/CHANGELOG.md
@@ -1,6 +1,66 @@
 # Changelog
 
-## [Unreleased]
+## [1.8.0] 2024-09-20
+
+### Fixed
+- Fix issue where rustfmt would crash on Windows when using the `ignore` option [#6178](https://github.com/rust-lang/rustfmt/issues/6178)
+
+### Changed
+- `rustfmt --version` now prints a commit hash that is 10 characters long [#6258](https://github.com/rust-lang/rustfmt/pull/6258)
+- `rustfmt --version` will no longer print empty git information when git information isn't available at build time.
+  For example, git information is not available when building rustfmt from a source tarball [#6266](https://github.com/rust-lang/rustfmt/pull/6266)
+- `version` has been soft deprecated and replaced by `style_edition`.
+  `style_edition=2024` is equivalent to `version=Two` and `style_edition={2015|2018|2021}`
+  are equivalent to `version=One` [#6247](https://github.com/rust-lang/rustfmt/pull/6247)
+- When `style_edition=2024` is configured `overflow_delimited_expr` will default to `true` [#6260](https://github.com/rust-lang/rustfmt/pull/6260).
+  ```rust
+  // with style_edition=2015
+  do_thing(
+      x,
+      Bar {
+          x: value,
+          y: value2,
+      },
+  );
+
+  // with style_edition=2024
+  do_thing(x, Bar {
+      x: value,
+      y: value2,
+  });
+  ```
+- When `style_edition=2024` is configured rustfmt will apply the [style guide's version sorting algorithm]
+  when sorting imports [#6284](https://github.com/rust-lang/rustfmt/pull/6284)
+  ```rust
+  // with style_edition=2015
+  use std::num::{NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8};
+
+  // with style_edition=2024
+  use std::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64};
+  ```
+  [style guide's version sorting algorithm]: https://doc.rust-lang.org/nightly/style-guide/#sorting
+- When parsing rustfmt configurations fails, rustfmt will now include the path to the toml file in the erorr message [#6302](https://github.com/rust-lang/rustfmt/issues/6302)
+
+### Added
+- rustfmt now formats trailing where clauses in type aliases [#5887](https://github.com/rust-lang/rustfmt/pull/5887)
+  ```rust
+  type Foo
+      = Bar
+  where
+      A: B,
+      C: D;
+  ```
+- Users can now configure which `style_edition` rustfmt uses when formatting their code as specified
+  in [RFC 3338](https://rust-lang.github.io/rfcs/3338-style-evolution.html). Users are encouraged to configure `style_edition`
+  in their `rustfmt.toml` files, but the value can also be specified via the cli with `--unstable-features --style-edition={style_edition}`.
+  When `style_edition` is not explicitly configured it will be inferred from the `edition` configuration.
+  When neither `style_edition` nor `edition` are configured `style_edition` defaults to `2015` [#6247](https://github.com/rust-lang/rustfmt/pull/6247)
+
+### Misc
+- Removed `tracing-attributes` dependency [#6208](https://github.com/rust-lang/rustfmt/pull/6208)
+- Reduced syn's features in the internal `config_proc_macro` crate [#6237](https://github.com/rust-lang/rustfmt/pull/6237)
+
+## [1.7.1] 2024-06-24
 
 ### Fixed
 
@@ -238,7 +298,7 @@
 
 ### Added
 
-- New configuration option (`skip_macro_invocations`)[https://rust-lang.github.io/rustfmt/?version=master&search=#skip_macro_invocations] [#5347](https://github.com/rust-lang/rustfmt/pull/5347) that can be used to globally define a single enumerated list of macro calls that rustfmt should skip formatting. rustfmt [currently also supports this via a custom tool attribute](https://github.com/rust-lang/rustfmt#tips), however, these cannot be used in all contexts because [custom inner attributes are unstable](https://github.com/rust-lang/rust/issues/54726)
+- New configuration option [`skip_macro_invocations`](https://rust-lang.github.io/rustfmt/?version=master&search=#skip_macro_invocations) [#5347](https://github.com/rust-lang/rustfmt/pull/5347) that can be used to globally define a single enumerated list of macro calls that rustfmt should skip formatting. rustfmt [currently also supports this via a custom tool attribute](https://github.com/rust-lang/rustfmt#tips), however, these cannot be used in all contexts because [custom inner attributes are unstable](https://github.com/rust-lang/rust/issues/54726)
 
 ### Misc
 
diff --git a/src/tools/rustfmt/Cargo.lock b/src/tools/rustfmt/Cargo.lock
index 2a1fffa50fe..e2ceb668ebd 100644
--- a/src/tools/rustfmt/Cargo.lock
+++ b/src/tools/rustfmt/Cargo.lock
@@ -499,7 +499,7 @@ dependencies = [
 
 [[package]]
 name = "rustfmt-nightly"
-version = "1.7.1"
+version = "1.8.0"
 dependencies = [
  "annotate-snippets",
  "anyhow",
@@ -710,22 +710,10 @@ checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8"
 dependencies = [
  "cfg-if",
  "pin-project-lite",
- "tracing-attributes",
  "tracing-core",
 ]
 
 [[package]]
-name = "tracing-attributes"
-version = "0.1.26"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn",
-]
-
-[[package]]
 name = "tracing-core"
 version = "0.1.31"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/tools/rustfmt/Cargo.toml b/src/tools/rustfmt/Cargo.toml
index a16620ed99b..e497b792342 100644
--- a/src/tools/rustfmt/Cargo.toml
+++ b/src/tools/rustfmt/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 
 name = "rustfmt-nightly"
-version = "1.7.1"
+version = "1.8.0"
 description = "Tool to find and fix Rust formatting issues"
 repository = "https://github.com/rust-lang/rustfmt"
 readme = "README.md"
@@ -50,7 +50,7 @@ serde_json = "1.0"
 term = "0.7"
 thiserror = "1.0.40"
 toml = "0.7.4"
-tracing = "0.1.37"
+tracing = { version = "0.1.37", default-features = false, features = ["std"] }
 tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
 unicode-segmentation = "1.9"
 unicode-width = "0.1"
diff --git a/src/tools/rustfmt/Configurations.md b/src/tools/rustfmt/Configurations.md
index f52c2573154..b1f54060392 100644
--- a/src/tools/rustfmt/Configurations.md
+++ b/src/tools/rustfmt/Configurations.md
@@ -534,7 +534,7 @@ Note that this option may be soft-deprecated in the future once the [ignore](#ig
 Specifies which edition is used by the parser.
 
 - **Default value**: `"2015"`
-- **Possible values**: `"2015"`, `"2018"`, `"2021"`
+- **Possible values**: `"2015"`, `"2018"`, `"2021"`, `"2024"`
 - **Stable**: Yes
 
 Rustfmt is able to pick up the edition used by reading the `Cargo.toml` file if executed
@@ -2692,6 +2692,17 @@ By default this option is set as a percentage of [`max_width`](#max_width) provi
 
 See also [`max_width`](#max_width) and [`use_small_heuristics`](#use_small_heuristics)
 
+## `style_edition`
+
+Controls the edition of the [Rust Style Guide] to use for formatting ([RFC 3338])
+
+- **Default value**: `"2015"`
+- **Possible values**: `"2015"`, `"2018"`, `"2021"`, `"2024"` (unstable variant)
+- **Stable**: No
+
+[Rust Style Guide]: https://doc.rust-lang.org/nightly/style-guide/
+[RFC 3338]: https://rust-lang.github.io/rfcs/3338-style-evolution.html
+
 ## `tab_spaces`
 
 Number of spaces per tab
@@ -3051,9 +3062,7 @@ fn main() {
 
 ## `version`
 
-Which version of the formatting rules to use. `Version::One` is backwards-compatible
-with Rustfmt 1.0. Other versions are only backwards compatible within a major
-version number.
+This option is deprecated and has been replaced by [`style_edition`](#style_edition)
 
 - **Default value**: `One`
 - **Possible values**: `One`, `Two`
diff --git a/src/tools/rustfmt/Contributing.md b/src/tools/rustfmt/Contributing.md
index 2f2ccfb175a..85754a8658a 100644
--- a/src/tools/rustfmt/Contributing.md
+++ b/src/tools/rustfmt/Contributing.md
@@ -109,17 +109,17 @@ If you want to test modified `cargo-fmt`, or run `rustfmt` on the whole project
 RUSTFMT="./target/debug/rustfmt" cargo run --bin cargo-fmt -- --manifest-path path/to/project/you/want2test/Cargo.toml
 ```
 
-### Version-gate formatting changes
+### Gate formatting changes
 
-A change that introduces a different code-formatting should be gated on the
-`version` configuration. This is to ensure the formatting of the current major
-release is preserved, while allowing fixes to be implemented for the next
-release.
+A change that introduces a different code-formatting must be gated on the
+`style_edition` configuration. This is to ensure rustfmt upholds its formatting
+stability guarantees and adheres to the Style Edition process set in [RFC 3338]
 
-This is done by conditionally guarding the change like so:
+This can be done by conditionally guarding the formatting change, e.g.:
 
 ```rust
-if config.version() == Version::One { // if the current major release is 1.x
+// if the current stable Style Edition is Edition 2024
+if config.style_edition() <= StyleEdition::Edition2024 {
     // current formatting
 } else {
     // new formatting
@@ -129,13 +129,14 @@ if config.version() == Version::One { // if the current major release is 1.x
 This allows the user to apply the next formatting explicitly via the
 configuration, while being stable by default.
 
-When the next major release is done, the code block of the previous formatting
-can be deleted, e.g., the first block in the example above when going from `1.x`
-to `2.x`.
+This can then be enhanced as needed if and when there are
+new Style Editions with differing formatting prescriptions.
 
 | Note: Only formatting changes with default options need to be gated. |
 | --- |
 
+[RFC 3338]: https://rust-lang.github.io/rfcs/3338-style-evolution.html
+
 ### A quick tour of Rustfmt
 
 Rustfmt is basically a pretty printer - that is, its mode of operation is to
diff --git a/src/tools/rustfmt/build.rs b/src/tools/rustfmt/build.rs
index 9a8bb77a8ed..696c713d726 100644
--- a/src/tools/rustfmt/build.rs
+++ b/src/tools/rustfmt/build.rs
@@ -25,7 +25,7 @@ fn main() {
 // (git not installed or if this is not a git repository) just return an empty string.
 fn commit_info() -> String {
     match (channel(), commit_hash(), commit_date()) {
-        (channel, Some(hash), Some(date)) => format!("{} ({} {})", channel, hash.trim_end(), date),
+        (channel, Some(hash), Some(date)) => format!("{} ({} {})", channel, hash, date),
         _ => String::new(),
     }
 }
@@ -39,17 +39,20 @@ fn channel() -> String {
 }
 
 fn commit_hash() -> Option<String> {
-    Command::new("git")
-        .args(["rev-parse", "--short", "HEAD"])
+    let output = Command::new("git")
+        .args(["rev-parse", "HEAD"])
         .output()
-        .ok()
-        .and_then(|r| String::from_utf8(r.stdout).ok())
+        .ok()?;
+    let mut stdout = output.status.success().then_some(output.stdout)?;
+    stdout.truncate(10);
+    String::from_utf8(stdout).ok()
 }
 
 fn commit_date() -> Option<String> {
-    Command::new("git")
+    let output = Command::new("git")
         .args(["log", "-1", "--date=short", "--pretty=format:%cd"])
         .output()
-        .ok()
-        .and_then(|r| String::from_utf8(r.stdout).ok())
+        .ok()?;
+    let stdout = output.status.success().then_some(output.stdout)?;
+    String::from_utf8(stdout).ok()
 }
diff --git a/src/tools/rustfmt/check_diff/Cargo.lock b/src/tools/rustfmt/check_diff/Cargo.lock
index 6716ccdf9a0..2abf5af2f98 100644
--- a/src/tools/rustfmt/check_diff/Cargo.lock
+++ b/src/tools/rustfmt/check_diff/Cargo.lock
@@ -3,6 +3,15 @@
 version = 3
 
 [[package]]
+name = "aho-corasick"
+version = "1.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
+dependencies = [
+ "memchr",
+]
+
+[[package]]
 name = "anstream"
 version = "0.6.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -52,10 +61,25 @@ dependencies = [
 ]
 
 [[package]]
+name = "bitflags"
+version = "2.6.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de"
+
+[[package]]
+name = "cfg-if"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
+
+[[package]]
 name = "check_diff"
 version = "0.1.0"
 dependencies = [
  "clap",
+ "tempfile",
+ "tracing",
+ "tracing-subscriber",
 ]
 
 [[package]]
@@ -105,6 +129,22 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0b6a852b24ab71dffc585bcb46eaf7959d175cb865a7152e35b348d1b2960422"
 
 [[package]]
+name = "errno"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba"
+dependencies = [
+ "libc",
+ "windows-sys",
+]
+
+[[package]]
+name = "fastrand"
+version = "2.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a"
+
+[[package]]
 name = "heck"
 version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -117,6 +157,73 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f8478577c03552c21db0e2724ffb8986a5ce7af88107e6be5d2ee6e158c12800"
 
 [[package]]
+name = "lazy_static"
+version = "1.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
+
+[[package]]
+name = "libc"
+version = "0.2.155"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
+
+[[package]]
+name = "linux-raw-sys"
+version = "0.4.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89"
+
+[[package]]
+name = "log"
+version = "0.4.21"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "90ed8c1e510134f979dbc4f070f87d4313098b704861a105fe34231c70a3901c"
+
+[[package]]
+name = "matchers"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558"
+dependencies = [
+ "regex-automata 0.1.10",
+]
+
+[[package]]
+name = "memchr"
+version = "2.7.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
+
+[[package]]
+name = "nu-ansi-term"
+version = "0.46.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "77a8165726e8236064dbb45459242600304b42a5ea24ee2948e18e023bf7ba84"
+dependencies = [
+ "overload",
+ "winapi",
+]
+
+[[package]]
+name = "once_cell"
+version = "1.19.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
+
+[[package]]
+name = "overload"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39"
+
+[[package]]
+name = "pin-project-lite"
+version = "0.2.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02"
+
+[[package]]
 name = "proc-macro2"
 version = "1.0.83"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -135,6 +242,78 @@ dependencies = [
 ]
 
 [[package]]
+name = "regex"
+version = "1.10.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-automata 0.4.7",
+ "regex-syntax 0.8.4",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.1.10"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132"
+dependencies = [
+ "regex-syntax 0.6.29",
+]
+
+[[package]]
+name = "regex-automata"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df"
+dependencies = [
+ "aho-corasick",
+ "memchr",
+ "regex-syntax 0.8.4",
+]
+
+[[package]]
+name = "regex-syntax"
+version = "0.6.29"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f162c6dd7b008981e4d40210aca20b4bd0f9b60ca9271061b07f78537722f2e1"
+
+[[package]]
+name = "regex-syntax"
+version = "0.8.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b"
+
+[[package]]
+name = "rustix"
+version = "0.38.34"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f"
+dependencies = [
+ "bitflags",
+ "errno",
+ "libc",
+ "linux-raw-sys",
+ "windows-sys",
+]
+
+[[package]]
+name = "sharded-slab"
+version = "0.1.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6"
+dependencies = [
+ "lazy_static",
+]
+
+[[package]]
+name = "smallvec"
+version = "1.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
+
+[[package]]
 name = "strsim"
 version = "0.11.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -152,6 +331,89 @@ dependencies = [
 ]
 
 [[package]]
+name = "tempfile"
+version = "3.10.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "85b77fafb263dd9d05cbeac119526425676db3784113aa9295c88498cbf8bff1"
+dependencies = [
+ "cfg-if",
+ "fastrand",
+ "rustix",
+ "windows-sys",
+]
+
+[[package]]
+name = "thread_local"
+version = "1.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+]
+
+[[package]]
+name = "tracing"
+version = "0.1.40"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef"
+dependencies = [
+ "pin-project-lite",
+ "tracing-attributes",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-attributes"
+version = "0.1.27"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "tracing-core"
+version = "0.1.32"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54"
+dependencies = [
+ "once_cell",
+ "valuable",
+]
+
+[[package]]
+name = "tracing-log"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
+dependencies = [
+ "log",
+ "once_cell",
+ "tracing-core",
+]
+
+[[package]]
+name = "tracing-subscriber"
+version = "0.3.18"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
+dependencies = [
+ "matchers",
+ "nu-ansi-term",
+ "once_cell",
+ "regex",
+ "sharded-slab",
+ "smallvec",
+ "thread_local",
+ "tracing",
+ "tracing-core",
+ "tracing-log",
+]
+
+[[package]]
 name = "unicode-ident"
 version = "1.0.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -164,6 +426,34 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
 
 [[package]]
+name = "valuable"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d"
+
+[[package]]
+name = "winapi"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
+dependencies = [
+ "winapi-i686-pc-windows-gnu",
+ "winapi-x86_64-pc-windows-gnu",
+]
+
+[[package]]
+name = "winapi-i686-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+
+[[package]]
+name = "winapi-x86_64-pc-windows-gnu"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
+
+[[package]]
 name = "windows-sys"
 version = "0.52.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/tools/rustfmt/check_diff/Cargo.toml b/src/tools/rustfmt/check_diff/Cargo.toml
index a1ed154481a..4ae8a5f1f3a 100644
--- a/src/tools/rustfmt/check_diff/Cargo.toml
+++ b/src/tools/rustfmt/check_diff/Cargo.toml
@@ -7,3 +7,7 @@ edition = "2021"
 
 [dependencies]
 clap = { version = "4.4.2", features = ["derive"] }
+tracing = "0.1.37"
+tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
+[dev-dependencies]
+tempfile = "3"
diff --git a/src/tools/rustfmt/check_diff/src/lib.rs b/src/tools/rustfmt/check_diff/src/lib.rs
new file mode 100644
index 00000000000..b83d67c8b6e
--- /dev/null
+++ b/src/tools/rustfmt/check_diff/src/lib.rs
@@ -0,0 +1,58 @@
+use std::env;
+use std::io;
+use std::path::Path;
+use std::process::Command;
+use tracing::info;
+
+pub enum GitError {
+    FailedClone { stdout: Vec<u8>, stderr: Vec<u8> },
+    IO(std::io::Error),
+}
+
+impl From<io::Error> for GitError {
+    fn from(error: io::Error) -> Self {
+        GitError::IO(error)
+    }
+}
+
+/// Clone a git repository
+///
+/// Parameters:
+/// url: git clone url
+/// dest: directory where the repo should be cloned
+pub fn clone_git_repo(url: &str, dest: &Path) -> Result<(), GitError> {
+    let git_cmd = Command::new("git")
+        .env("GIT_TERMINAL_PROMPT", "0")
+        .args([
+            "clone",
+            "--quiet",
+            url,
+            "--depth",
+            "1",
+            dest.to_str().unwrap(),
+        ])
+        .output()?;
+
+    // if the git command does not return successfully,
+    // any command on the repo will fail. So fail fast.
+    if !git_cmd.status.success() {
+        let error = GitError::FailedClone {
+            stdout: git_cmd.stdout,
+            stderr: git_cmd.stderr,
+        };
+        return Err(error);
+    }
+
+    info!("Successfully clone repository.");
+    return Ok(());
+}
+
+pub fn change_directory_to_path(dest: &Path) -> io::Result<()> {
+    let dest_path = Path::new(&dest);
+    env::set_current_dir(&dest_path)?;
+    info!(
+        "Current directory: {}",
+        env::current_dir().unwrap().display()
+    );
+    return Ok(());
+}
diff --git a/src/tools/rustfmt/check_diff/src/main.rs b/src/tools/rustfmt/check_diff/src/main.rs
index 6d07c1b0df6..01c5926c490 100644
--- a/src/tools/rustfmt/check_diff/src/main.rs
+++ b/src/tools/rustfmt/check_diff/src/main.rs
@@ -1,4 +1,5 @@
 use clap::Parser;
+
 /// Inputs for the check_diff script
 #[derive(Parser)]
 struct CliInputs {
@@ -16,10 +17,5 @@ struct CliInputs {
 }
 
 fn main() {
-    let args = CliInputs::parse();
-    println!(
-        "remote_repo_url: {:?}, feature_branch: {:?},
-        optional_commit_hash: {:?}, optional_rustfmt_config: {:?}",
-        args.remote_repo_url, args.feature_branch, args.commit_hash, args.rustfmt_config
-    );
+    let _args = CliInputs::parse();
 }
diff --git a/src/tools/rustfmt/check_diff/tests/bash_commands.rs b/src/tools/rustfmt/check_diff/tests/bash_commands.rs
new file mode 100644
index 00000000000..38ee34ef503
--- /dev/null
+++ b/src/tools/rustfmt/check_diff/tests/bash_commands.rs
@@ -0,0 +1,12 @@
+use check_diff::change_directory_to_path;
+use std::env;
+use tempfile::Builder;
+
+#[test]
+fn cd_test() {
+    // Creates an empty directory in the current working directory
+    let dir = Builder::new().tempdir_in("").unwrap();
+    let dest_path = dir.path();
+    change_directory_to_path(dest_path).unwrap();
+    assert_eq!(env::current_dir().unwrap(), dest_path);
+}
diff --git a/src/tools/rustfmt/check_diff/tests/git.rs b/src/tools/rustfmt/check_diff/tests/git.rs
new file mode 100644
index 00000000000..677c3840e1e
--- /dev/null
+++ b/src/tools/rustfmt/check_diff/tests/git.rs
@@ -0,0 +1,16 @@
+use check_diff::clone_git_repo;
+
+use tempfile::Builder;
+
+#[test]
+fn clone_repo_test() {
+    // Creates an empty directory in the current working directory
+    let dir = Builder::new().tempdir_in("").unwrap();
+    let sample_repo = "https://github.com/rust-lang/rustfmt.git";
+    let dest_path = dir.path();
+    let result = clone_git_repo(sample_repo, dest_path);
+    assert!(result.is_ok());
+    // check whether a .git folder exists after cloning the repo
+    let git_repo = dest_path.join(".git");
+    assert!(git_repo.exists());
+}
diff --git a/src/tools/rustfmt/ci/build_and_test.bat b/src/tools/rustfmt/ci/build_and_test.bat
index 16608a4aaa7..b6b5ca21364 100755
--- a/src/tools/rustfmt/ci/build_and_test.bat
+++ b/src/tools/rustfmt/ci/build_and_test.bat
@@ -13,7 +13,13 @@ if "%CFG_RELEASE_CHANNEL%"=="nightly" (
 )
 cargo test || exit /b 1
 
-:: Build and test other crates
+:: Build and test config_proc_macro
 cd config_proc_macro || exit /b 1
 cargo build --locked || exit /b 1
 cargo test || exit /b 1
+
+:: Build and test check_diff
+cd ..
+cd check_diff || exit /b 1
+cargo build --locked || exit /b 1
+cargo test || exit /b 1
diff --git a/src/tools/rustfmt/ci/build_and_test.sh b/src/tools/rustfmt/ci/build_and_test.sh
index 207da362fd6..dd9a0c0fd9b 100755
--- a/src/tools/rustfmt/ci/build_and_test.sh
+++ b/src/tools/rustfmt/ci/build_and_test.sh
@@ -17,7 +17,13 @@ else
 fi
 cargo test
 
-# Build and test other crates
+# Build and test config_proc_macro
 cd config_proc_macro
 cargo build --locked
 cargo test
+
+# Build and test check_diff
+cd ..
+cd check_diff
+cargo build --locked
+cargo test
diff --git a/src/tools/rustfmt/config_proc_macro/Cargo.toml b/src/tools/rustfmt/config_proc_macro/Cargo.toml
index eda8a7fce81..ec0db49d71c 100644
--- a/src/tools/rustfmt/config_proc_macro/Cargo.toml
+++ b/src/tools/rustfmt/config_proc_macro/Cargo.toml
@@ -1,7 +1,7 @@
 [package]
 name = "rustfmt-config_proc_macro"
 version = "0.3.0"
-edition = "2018"
+edition = "2021"
 description = "A collection of procedural macros for rustfmt"
 license = "Apache-2.0 OR MIT"
 categories = ["development-tools::procedural-macro-helpers"]
@@ -13,7 +13,7 @@ proc-macro = true
 [dependencies]
 proc-macro2 = "1.0"
 quote = "1.0"
-syn = { version = "2.0", features = ["full", "visit"] }
+syn = { version = "2.0", default-features = false, features = ["full", "parsing", "proc-macro", "printing"] }
 
 [dev-dependencies]
 serde = { version = "1.0.160", features = ["derive"] }
diff --git a/src/tools/rustfmt/config_proc_macro/src/utils.rs b/src/tools/rustfmt/config_proc_macro/src/utils.rs
index f5cba87b07b..1f5b5cdb604 100644
--- a/src/tools/rustfmt/config_proc_macro/src/utils.rs
+++ b/src/tools/rustfmt/config_proc_macro/src/utils.rs
@@ -1,5 +1,5 @@
 use proc_macro2::TokenStream;
-use quote::{quote, ToTokens};
+use quote::{ToTokens, quote};
 
 pub fn fold_quote<F, I, T>(input: impl Iterator<Item = I>, f: F) -> TokenStream
 where
diff --git a/src/tools/rustfmt/rust-toolchain b/src/tools/rustfmt/rust-toolchain
index 25e3961d32a..80723123274 100644
--- a/src/tools/rustfmt/rust-toolchain
+++ b/src/tools/rustfmt/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2024-06-13"
+channel = "nightly-2024-09-10"
 components = ["llvm-tools", "rustc-dev"]
diff --git a/src/tools/rustfmt/rustfmt.toml b/src/tools/rustfmt/rustfmt.toml
index eccd5f9bd19..86447eac2e6 100644
--- a/src/tools/rustfmt/rustfmt.toml
+++ b/src/tools/rustfmt/rustfmt.toml
@@ -1,3 +1,4 @@
 error_on_line_overflow = true
 error_on_unformatted = true
-version = "Two"
+style_edition = "2024"
+overflow_delimited_expr = false
diff --git a/src/tools/rustfmt/src/attr.rs b/src/tools/rustfmt/src/attr.rs
index a2c0a28d66e..5c2068b6a22 100644
--- a/src/tools/rustfmt/src/attr.rs
+++ b/src/tools/rustfmt/src/attr.rs
@@ -1,21 +1,21 @@
 //! Format attributes and meta items.
 
-use rustc_ast::ast;
 use rustc_ast::HasAttrs;
-use rustc_span::{symbol::sym, Span};
+use rustc_ast::ast;
+use rustc_span::{Span, symbol::sym};
 use tracing::debug;
 
 use self::doc_comment::DocCommentFormatter;
-use crate::comment::{contains_comment, rewrite_doc_comment, CommentStyle};
-use crate::config::lists::*;
+use crate::comment::{CommentStyle, contains_comment, rewrite_doc_comment};
 use crate::config::IndentStyle;
+use crate::config::lists::*;
 use crate::expr::rewrite_literal;
-use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
+use crate::lists::{ListFormatting, Separator, definitive_tactic, itemize_list, write_list};
 use crate::overflow;
-use crate::rewrite::{Rewrite, RewriteContext};
+use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
 use crate::shape::Shape;
 use crate::source_map::SpanUtils;
-use crate::types::{rewrite_path, PathContext};
+use crate::types::{PathContext, rewrite_path};
 use crate::utils::{count_newlines, mk_sp};
 
 mod doc_comment;
@@ -100,7 +100,7 @@ fn format_derive(
                 ",",
                 |span| span.lo(),
                 |span| span.hi(),
-                |span| Some(context.snippet(*span).to_owned()),
+                |span| Ok(context.snippet(*span).to_owned()),
                 // We update derive attribute spans to start after the opening '('
                 // This helps us focus parsing to just what's inside #[derive(...)]
                 context.snippet_provider.span_after(attr.span, "("),
@@ -148,7 +148,7 @@ fn format_derive(
         .tactic(tactic)
         .trailing_separator(trailing_separator)
         .ends_with_newline(false);
-    let item_str = write_list(&all_items, &fmt)?;
+    let item_str = write_list(&all_items, &fmt).ok()?;
 
     debug!("item_str: '{}'", item_str);
 
@@ -218,9 +218,9 @@ fn rewrite_initial_doc_comments(
     context: &RewriteContext<'_>,
     attrs: &[ast::Attribute],
     shape: Shape,
-) -> Option<(usize, Option<String>)> {
+) -> Result<(usize, Option<String>), RewriteError> {
     if attrs.is_empty() {
-        return Some((0, None));
+        return Ok((0, None));
     }
     // Rewrite doc comments
     let sugared_docs = take_while_with_pred(context, attrs, |a| a.is_doc_comment());
@@ -230,7 +230,7 @@ fn rewrite_initial_doc_comments(
             .map(|a| context.snippet(a.span))
             .collect::<Vec<_>>()
             .join("\n");
-        return Some((
+        return Ok((
             sugared_docs.len(),
             Some(rewrite_doc_comment(
                 &snippet,
@@ -240,13 +240,19 @@ fn rewrite_initial_doc_comments(
         ));
     }
 
-    Some((0, None))
+    Ok((0, None))
 }
 
 impl Rewrite for ast::NestedMetaItem {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         match self {
-            ast::NestedMetaItem::MetaItem(ref meta_item) => meta_item.rewrite(context, shape),
+            ast::NestedMetaItem::MetaItem(ref meta_item) => {
+                meta_item.rewrite_result(context, shape)
+            }
             ast::NestedMetaItem::Lit(ref l) => {
                 rewrite_literal(context, l.as_token_lit(), l.span, shape)
             }
@@ -275,7 +281,11 @@ fn has_newlines_before_after_comment(comment: &str) -> (&str, &str) {
 
 impl Rewrite for ast::MetaItem {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
-        Some(match self.kind {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
+        Ok(match self.kind {
             ast::MetaItemKind::Word => {
                 rewrite_path(context, PathContext::Type, &None, &self.path, shape)?
             }
@@ -287,7 +297,7 @@ impl Rewrite for ast::MetaItem {
                     &path,
                     list.iter(),
                     // 1 = "]"
-                    shape.sub_width(1)?,
+                    shape.sub_width(1).max_width_error(shape.width, self.span)?,
                     self.span,
                     context.config.attr_fn_like_width(),
                     Some(if has_trailing_comma {
@@ -300,7 +310,9 @@ impl Rewrite for ast::MetaItem {
             ast::MetaItemKind::NameValue(ref lit) => {
                 let path = rewrite_path(context, PathContext::Type, &None, &self.path, shape)?;
                 // 3 = ` = `
-                let lit_shape = shape.shrink_left(path.len() + 3)?;
+                let lit_shape = shape
+                    .shrink_left(path.len() + 3)
+                    .max_width_error(shape.width, self.span)?;
                 // `rewrite_literal` returns `None` when `lit` exceeds max
                 // width. Since a literal is basically unformattable unless it
                 // is a string literal (and only if `format_strings` is set),
@@ -308,7 +320,7 @@ impl Rewrite for ast::MetaItem {
                 // is longer than the max width and continue on formatting.
                 // See #2479 for example.
                 let value = rewrite_literal(context, lit.as_token_lit(), lit.span, lit_shape)
-                    .unwrap_or_else(|| context.snippet(lit.span).to_owned());
+                    .unwrap_or_else(|_| context.snippet(lit.span).to_owned());
                 format!("{path} = {value}")
             }
         })
@@ -317,6 +329,10 @@ impl Rewrite for ast::MetaItem {
 
 impl Rewrite for ast::Attribute {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         let snippet = context.snippet(self.span);
         if self.is_doc_comment() {
             rewrite_doc_comment(snippet, shape.comment(context.config), context.config)
@@ -328,7 +344,7 @@ impl Rewrite for ast::Attribute {
             let prefix = attr_prefix(self);
 
             if should_skip || contains_comment(snippet) {
-                return Some(snippet.to_owned());
+                return Ok(snippet.to_owned());
             }
 
             if let Some(ref meta) = self.meta() {
@@ -353,9 +369,11 @@ impl Rewrite for ast::Attribute {
                 }
 
                 // 1 = `[`
-                let shape = shape.offset_left(prefix.len() + 1)?;
-                Some(meta.rewrite(context, shape).map_or_else(
-                    || snippet.to_owned(),
+                let shape = shape
+                    .offset_left(prefix.len() + 1)
+                    .max_width_error(shape.width, self.span)?;
+                Ok(meta.rewrite_result(context, shape).map_or_else(
+                    |_| snippet.to_owned(),
                     |rw| match &self.kind {
                         ast::AttrKind::Normal(normal_attr) => match normal_attr.item.unsafety {
                             // For #![feature(unsafe_attributes)]
@@ -367,7 +385,7 @@ impl Rewrite for ast::Attribute {
                     },
                 ))
             } else {
-                Some(snippet.to_owned())
+                Ok(snippet.to_owned())
             }
         }
     }
@@ -375,8 +393,12 @@ impl Rewrite for ast::Attribute {
 
 impl Rewrite for [ast::Attribute] {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         if self.is_empty() {
-            return Some(String::new());
+            return Ok(String::new());
         }
 
         // The current remaining attributes.
@@ -392,7 +414,7 @@ impl Rewrite for [ast::Attribute] {
         // merging derives into a single attribute.
         loop {
             if attrs.is_empty() {
-                return Some(result);
+                return Ok(result);
             }
 
             // Handle doc comments.
@@ -431,7 +453,7 @@ impl Rewrite for [ast::Attribute] {
             // Handle derives if we will merge them.
             if !skip_derives && context.config.merge_derives() && is_derive(&attrs[0]) {
                 let derives = take_while_with_pred(context, attrs, is_derive);
-                let derive_str = format_derive(derives, shape, context)?;
+                let derive_str = format_derive(derives, shape, context).unknown_error()?;
                 result.push_str(&derive_str);
 
                 let missing_span = attrs
@@ -464,7 +486,7 @@ impl Rewrite for [ast::Attribute] {
             // If we get here, then we have a regular attribute, just handle one
             // at a time.
 
-            let formatted_attr = attrs[0].rewrite(context, shape)?;
+            let formatted_attr = attrs[0].rewrite_result(context, shape)?;
             result.push_str(&formatted_attr);
 
             let missing_span = attrs
diff --git a/src/tools/rustfmt/src/bin/main.rs b/src/tools/rustfmt/src/bin/main.rs
index 88281d296be..c7d3a060d54 100644
--- a/src/tools/rustfmt/src/bin/main.rs
+++ b/src/tools/rustfmt/src/bin/main.rs
@@ -1,6 +1,6 @@
 #![feature(rustc_private)]
 
-use anyhow::{format_err, Result};
+use anyhow::{Result, format_err};
 
 use io::Error as IoError;
 use thiserror::Error;
@@ -11,15 +11,15 @@ use tracing_subscriber::EnvFilter;
 use std::collections::HashMap;
 use std::env;
 use std::fs::File;
-use std::io::{self, stdout, Read, Write};
+use std::io::{self, Read, Write, stdout};
 use std::path::{Path, PathBuf};
 use std::str::FromStr;
 
 use getopts::{Matches, Options};
 
 use crate::rustfmt::{
-    load_config, CliOptions, Color, Config, Edition, EmitMode, FileLines, FileName,
-    FormatReportFormatterBuilder, Input, Session, Verbosity,
+    CliOptions, Color, Config, Edition, EmitMode, FileLines, FileName,
+    FormatReportFormatterBuilder, Input, Session, StyleEdition, Verbosity, Version, load_config,
 };
 
 const BUG_REPORT_URL: &str = "https://github.com/rust-lang/rustfmt/issues/new?labels=bug";
@@ -129,7 +129,12 @@ fn make_opts() -> Options {
          found reverts to the input file path",
         "[Path for the configuration file]",
     );
-    opts.optopt("", "edition", "Rust edition to use", "[2015|2018|2021]");
+    opts.optopt(
+        "",
+        "edition",
+        "Rust edition to use",
+        "[2015|2018|2021|2024]",
+    );
     opts.optopt(
         "",
         "color",
@@ -181,6 +186,12 @@ fn make_opts() -> Options {
             "skip-children",
             "Don't reformat child modules (unstable).",
         );
+        opts.optopt(
+            "",
+            "style-edition",
+            "The edition of the Style Guide (unstable).",
+            "[2015|2018|2021|2024]",
+        );
     }
 
     opts.optflag("v", "verbose", "Print verbose output");
@@ -263,24 +274,35 @@ fn format_string(input: String, options: GetOptsOptions) -> Result<i32> {
     let (mut config, _) = load_config(Some(Path::new(".")), Some(options.clone()))?;
 
     if options.check {
-        config.set().emit_mode(EmitMode::Diff);
+        config.set_cli().emit_mode(EmitMode::Diff);
     } else {
         match options.emit_mode {
             // Emit modes which work with standard input
             // None means default, which is Stdout.
-            None | Some(EmitMode::Stdout) | Some(EmitMode::Checkstyle) | Some(EmitMode::Json) => {}
+            None => {
+                config
+                    .set()
+                    .emit_mode(options.emit_mode.unwrap_or(EmitMode::Stdout));
+            }
+            Some(EmitMode::Stdout) | Some(EmitMode::Checkstyle) | Some(EmitMode::Json) => {
+                config
+                    .set_cli()
+                    .emit_mode(options.emit_mode.unwrap_or(EmitMode::Stdout));
+            }
             Some(emit_mode) => {
                 return Err(OperationError::StdinBadEmit(emit_mode).into());
             }
         }
-        config
-            .set()
-            .emit_mode(options.emit_mode.unwrap_or(EmitMode::Stdout));
     }
     config.set().verbose(Verbosity::Quiet);
 
     // parse file_lines
-    config.set().file_lines(options.file_lines);
+    if options.file_lines.is_all() {
+        config.set().file_lines(options.file_lines);
+    } else {
+        config.set_cli().file_lines(options.file_lines);
+    }
+
     for f in config.file_lines().files() {
         match *f {
             FileName::Stdin => {}
@@ -319,10 +341,10 @@ fn format(
 
     for file in files {
         if !file.exists() {
-            eprintln!("Error: file `{}` does not exist", file.to_str().unwrap());
+            eprintln!("Error: file `{}` does not exist", file.display());
             session.add_operational_error();
         } else if file.is_dir() {
-            eprintln!("Error: `{}` is a directory", file.to_str().unwrap());
+            eprintln!("Error: `{}` is a directory", file.display());
             session.add_operational_error();
         } else {
             // Check the file directory if the config-path could not be read or not provided
@@ -428,27 +450,27 @@ are included as out of line modules from `src/lib.rs`."
 }
 
 fn print_version() {
-    let version_info = format!(
-        "{}-{}",
-        option_env!("CARGO_PKG_VERSION").unwrap_or("unknown"),
-        include_str!(concat!(env!("OUT_DIR"), "/commit-info.txt"))
-    );
+    let version_number = option_env!("CARGO_PKG_VERSION").unwrap_or("unknown");
+    let commit_info = include_str!(concat!(env!("OUT_DIR"), "/commit-info.txt"));
 
-    println!("rustfmt {version_info}");
+    if commit_info.is_empty() {
+        println!("rustfmt {version_number}");
+    } else {
+        println!("rustfmt {version_number}-{commit_info}");
+    }
 }
 
 fn determine_operation(matches: &Matches) -> Result<Operation, OperationError> {
     if matches.opt_present("h") {
-        let topic = matches.opt_str("h");
-        if topic.is_none() {
+        let Some(topic) = matches.opt_str("h") else {
             return Ok(Operation::Help(HelpOp::None));
-        } else if topic == Some("config".to_owned()) {
-            return Ok(Operation::Help(HelpOp::Config));
-        } else if topic == Some("file-lines".to_owned()) && is_nightly() {
-            return Ok(Operation::Help(HelpOp::FileLines));
-        } else {
-            return Err(OperationError::UnknownHelpTopic(topic.unwrap()));
-        }
+        };
+
+        return match topic.as_str() {
+            "config" => Ok(Operation::Help(HelpOp::Config)),
+            "file-lines" if is_nightly() => Ok(Operation::Help(HelpOp::FileLines)),
+            _ => Err(OperationError::UnknownHelpTopic(topic)),
+        };
     }
     let mut free_matches = matches.free.iter();
 
@@ -514,6 +536,7 @@ struct GetOptsOptions {
     backup: bool,
     check: bool,
     edition: Option<Edition>,
+    style_edition: Option<StyleEdition>,
     color: Option<Color>,
     file_lines: FileLines, // Default is all lines in all files.
     unstable_features: bool,
@@ -545,6 +568,10 @@ impl GetOptsOptions {
                 if let Some(ref file_lines) = matches.opt_str("file-lines") {
                     options.file_lines = file_lines.parse()?;
                 }
+                if let Some(ref edition_str) = matches.opt_str("style-edition") {
+                    options.style_edition =
+                        Some(style_edition_from_style_edition_str(edition_str)?);
+                }
             } else {
                 let mut unstable_options = vec![];
                 if matches.opt_present("skip-children") {
@@ -556,6 +583,9 @@ impl GetOptsOptions {
                 if matches.opt_present("file-lines") {
                     unstable_options.push("`--file-lines`");
                 }
+                if matches.opt_present("style-edition") {
+                    unstable_options.push("`--style-edition`");
+                }
                 if !unstable_options.is_empty() {
                     let s = if unstable_options.len() == 1 { "" } else { "s" };
                     return Err(format_err!(
@@ -650,36 +680,49 @@ impl GetOptsOptions {
 impl CliOptions for GetOptsOptions {
     fn apply_to(self, config: &mut Config) {
         if self.verbose {
-            config.set().verbose(Verbosity::Verbose);
+            config.set_cli().verbose(Verbosity::Verbose);
         } else if self.quiet {
-            config.set().verbose(Verbosity::Quiet);
+            config.set_cli().verbose(Verbosity::Quiet);
         } else {
             config.set().verbose(Verbosity::Normal);
         }
-        config.set().file_lines(self.file_lines);
-        config.set().unstable_features(self.unstable_features);
+
+        if self.file_lines.is_all() {
+            config.set().file_lines(self.file_lines);
+        } else {
+            config.set_cli().file_lines(self.file_lines);
+        }
+
+        if self.unstable_features {
+            config.set_cli().unstable_features(self.unstable_features);
+        } else {
+            config.set().unstable_features(self.unstable_features);
+        }
         if let Some(skip_children) = self.skip_children {
-            config.set().skip_children(skip_children);
+            config.set_cli().skip_children(skip_children);
         }
         if let Some(error_on_unformatted) = self.error_on_unformatted {
-            config.set().error_on_unformatted(error_on_unformatted);
+            config.set_cli().error_on_unformatted(error_on_unformatted);
         }
         if let Some(edition) = self.edition {
-            config.set().edition(edition);
+            config.set_cli().edition(edition);
+        }
+        if let Some(edition) = self.style_edition {
+            config.set_cli().style_edition(edition);
         }
         if self.check {
-            config.set().emit_mode(EmitMode::Diff);
+            config.set_cli().emit_mode(EmitMode::Diff);
         } else if let Some(emit_mode) = self.emit_mode {
-            config.set().emit_mode(emit_mode);
+            config.set_cli().emit_mode(emit_mode);
         }
         if self.backup {
-            config.set().make_backup(true);
+            config.set_cli().make_backup(true);
         }
         if let Some(color) = self.color {
-            config.set().color(color);
+            config.set_cli().color(color);
         }
         if self.print_misformatted_file_names {
-            config.set().print_misformatted_file_names(true);
+            config.set_cli().print_misformatted_file_names(true);
         }
 
         for (key, val) in self.inline_config {
@@ -690,6 +733,25 @@ impl CliOptions for GetOptsOptions {
     fn config_path(&self) -> Option<&Path> {
         self.config_path.as_deref()
     }
+
+    fn edition(&self) -> Option<Edition> {
+        self.inline_config
+            .get("edition")
+            .map_or(self.edition, |e| Edition::from_str(e).ok())
+    }
+
+    fn style_edition(&self) -> Option<StyleEdition> {
+        self.inline_config
+            .get("style_edition")
+            .map_or(self.style_edition, |se| StyleEdition::from_str(se).ok())
+    }
+
+    fn version(&self) -> Option<Version> {
+        self.inline_config
+            .get("version")
+            .map(|version| Version::from_str(version).ok())
+            .flatten()
+    }
 }
 
 fn edition_from_edition_str(edition_str: &str) -> Result<Edition> {
@@ -702,6 +764,16 @@ fn edition_from_edition_str(edition_str: &str) -> Result<Edition> {
     }
 }
 
+fn style_edition_from_style_edition_str(edition_str: &str) -> Result<StyleEdition> {
+    match edition_str {
+        "2015" => Ok(StyleEdition::Edition2015),
+        "2018" => Ok(StyleEdition::Edition2018),
+        "2021" => Ok(StyleEdition::Edition2021),
+        "2024" => Ok(StyleEdition::Edition2024),
+        _ => Err(format_err!("Invalid value for `--style-edition`")),
+    }
+}
+
 fn emit_mode_from_emit_str(emit_str: &str) -> Result<EmitMode> {
     match emit_str {
         "files" => Ok(EmitMode::Files),
@@ -712,3 +784,185 @@ fn emit_mode_from_emit_str(emit_str: &str) -> Result<EmitMode> {
         _ => Err(format_err!("Invalid value for `--emit`")),
     }
 }
+
+#[cfg(test)]
+#[allow(dead_code)]
+mod test {
+    use super::*;
+    use rustfmt_config_proc_macro::nightly_only_test;
+
+    fn get_config<O: CliOptions>(path: Option<&Path>, options: Option<O>) -> Config {
+        load_config(path, options).unwrap().0
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn flag_sets_style_edition_override_correctly() {
+        let mut options = GetOptsOptions::default();
+        options.style_edition = Some(StyleEdition::Edition2024);
+        let config = get_config(None, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2024);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn edition_sets_style_edition_override_correctly() {
+        let mut options = GetOptsOptions::default();
+        options.edition = Some(Edition::Edition2024);
+        let config = get_config(None, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2024);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn version_sets_style_edition_override_correctly() {
+        let mut options = GetOptsOptions::default();
+        options.inline_config = HashMap::from([("version".to_owned(), "Two".to_owned())]);
+        let config = get_config(None, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2024);
+        assert_eq!(config.overflow_delimited_expr(), true);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn version_config_file_sets_style_edition_override_correctly() {
+        let options = GetOptsOptions::default();
+        let config_file = Some(Path::new("tests/config/style-edition/just-version"));
+        let config = get_config(config_file, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2024);
+        assert_eq!(config.overflow_delimited_expr(), true);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn style_edition_flag_has_correct_precedence_over_edition() {
+        let mut options = GetOptsOptions::default();
+        options.style_edition = Some(StyleEdition::Edition2021);
+        options.edition = Some(Edition::Edition2024);
+        let config = get_config(None, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2021);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn style_edition_flag_has_correct_precedence_over_version() {
+        let mut options = GetOptsOptions::default();
+        options.style_edition = Some(StyleEdition::Edition2018);
+        options.inline_config = HashMap::from([("version".to_owned(), "Two".to_owned())]);
+        let config = get_config(None, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2018);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn style_edition_flag_has_correct_precedence_over_edition_version() {
+        let mut options = GetOptsOptions::default();
+        options.style_edition = Some(StyleEdition::Edition2021);
+        options.edition = Some(Edition::Edition2018);
+        options.inline_config = HashMap::from([("version".to_owned(), "Two".to_owned())]);
+        let config = get_config(None, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2021);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn style_edition_inline_has_correct_precedence_over_edition_version() {
+        let mut options = GetOptsOptions::default();
+        options.edition = Some(Edition::Edition2018);
+        options.inline_config = HashMap::from([
+            ("version".to_owned(), "One".to_owned()),
+            ("style_edition".to_owned(), "2024".to_owned()),
+        ]);
+        let config = get_config(None, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2024);
+        assert_eq!(config.overflow_delimited_expr(), true);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn style_edition_config_file_trumps_edition_flag_version_inline() {
+        let mut options = GetOptsOptions::default();
+        let config_file = Some(Path::new("tests/config/style-edition/just-style-edition"));
+        options.edition = Some(Edition::Edition2018);
+        options.inline_config = HashMap::from([("version".to_owned(), "One".to_owned())]);
+        let config = get_config(config_file, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2024);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn style_edition_config_file_trumps_edition_config_and_version_inline() {
+        let mut options = GetOptsOptions::default();
+        let config_file = Some(Path::new(
+            "tests/config/style-edition/style-edition-and-edition",
+        ));
+        options.inline_config = HashMap::from([("version".to_owned(), "Two".to_owned())]);
+        let config = get_config(config_file, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2021);
+        assert_eq!(config.edition(), Edition::Edition2024);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn version_config_trumps_edition_config_and_flag() {
+        let mut options = GetOptsOptions::default();
+        let config_file = Some(Path::new("tests/config/style-edition/version-edition"));
+        options.edition = Some(Edition::Edition2018);
+        let config = get_config(config_file, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2024);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn style_edition_config_file_trumps_version_config() {
+        let options = GetOptsOptions::default();
+        let config_file = Some(Path::new(
+            "tests/config/style-edition/version-style-edition",
+        ));
+        let config = get_config(config_file, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2021);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn style_edition_config_file_trumps_edition_version_config() {
+        let options = GetOptsOptions::default();
+        let config_file = Some(Path::new(
+            "tests/config/style-edition/version-style-edition-and-edition",
+        ));
+        let config = get_config(config_file, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2021);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn correct_defaults_for_style_edition_loaded() {
+        let mut options = GetOptsOptions::default();
+        options.style_edition = Some(StyleEdition::Edition2024);
+        let config = get_config(None, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2024);
+        assert_eq!(config.overflow_delimited_expr(), true);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn style_edition_defaults_overridden_from_config() {
+        let options = GetOptsOptions::default();
+        let config_file = Some(Path::new("tests/config/style-edition/overrides"));
+        let config = get_config(config_file, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2024);
+        assert_eq!(config.overflow_delimited_expr(), false);
+    }
+
+    #[nightly_only_test]
+    #[test]
+    fn style_edition_defaults_overridden_from_cli() {
+        let mut options = GetOptsOptions::default();
+        let config_file = Some(Path::new("tests/config/style-edition/just-style-edition"));
+        options.inline_config =
+            HashMap::from([("overflow_delimited_expr".to_owned(), "false".to_owned())]);
+        let config = get_config(config_file, Some(options));
+        assert_eq!(config.style_edition(), StyleEdition::Edition2024);
+        assert_eq!(config.overflow_delimited_expr(), false);
+    }
+}
diff --git a/src/tools/rustfmt/src/chains.rs b/src/tools/rustfmt/src/chains.rs
index 96fbe7a963a..fd2ef9cb1db 100644
--- a/src/tools/rustfmt/src/chains.rs
+++ b/src/tools/rustfmt/src/chains.rs
@@ -59,15 +59,15 @@ use std::borrow::Cow;
 use std::cmp::min;
 
 use rustc_ast::{ast, ptr};
-use rustc_span::{symbol, BytePos, Span};
+use rustc_span::{BytePos, Span, symbol};
 use tracing::debug;
 
-use crate::comment::{rewrite_comment, CharClasses, FullCodeCharKind, RichChar};
-use crate::config::{IndentStyle, Version};
+use crate::comment::{CharClasses, FullCodeCharKind, RichChar, rewrite_comment};
+use crate::config::{IndentStyle, StyleEdition};
 use crate::expr::rewrite_call;
 use crate::lists::extract_pre_comment;
 use crate::macros::convert_try_mac;
-use crate::rewrite::{Rewrite, RewriteContext};
+use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
 use crate::shape::Shape;
 use crate::source_map::SpanUtils;
 use crate::utils::{
@@ -80,6 +80,9 @@ use thin_vec::ThinVec;
 /// Provides the original input contents from the span
 /// of a chain element with trailing spaces trimmed.
 fn format_overflow_style(span: Span, context: &RewriteContext<'_>) -> Option<String> {
+    // TODO(ding-young): Currently returning None when the given span is out of the range
+    // covered by the snippet provider. If this is a common cause for internal
+    // rewrite failure, add a new enum variant and return RewriteError instead of None
     context.snippet_provider.span_to_snippet(span).map(|s| {
         s.lines()
             .map(|l| l.trim_end())
@@ -93,12 +96,16 @@ fn format_chain_item(
     context: &RewriteContext<'_>,
     rewrite_shape: Shape,
     allow_overflow: bool,
-) -> Option<String> {
+) -> RewriteResult {
     if allow_overflow {
-        item.rewrite(context, rewrite_shape)
-            .or_else(|| format_overflow_style(item.span, context))
+        // TODO(ding-young): Consider calling format_overflow_style()
+        // only when item.rewrite_result() returns RewriteError::ExceedsMaxWidth.
+        // It may be inappropriate to call format_overflow_style on other RewriteError
+        // since the current approach retries formatting if allow_overflow is true
+        item.rewrite_result(context, rewrite_shape)
+            .or_else(|_| format_overflow_style(item.span, context).unknown_error())
     } else {
-        item.rewrite(context, rewrite_shape)
+        item.rewrite_result(context, rewrite_shape)
     }
 }
 
@@ -135,17 +142,17 @@ pub(crate) fn rewrite_chain(
     expr: &ast::Expr,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     let chain = Chain::from_ast(expr, context);
     debug!("rewrite_chain {:?} {:?}", chain, shape);
 
     // If this is just an expression with some `?`s, then format it trivially and
     // return early.
     if chain.children.is_empty() {
-        return chain.parent.rewrite(context, shape);
+        return chain.parent.rewrite_result(context, shape);
     }
 
-    chain.rewrite(context, shape)
+    chain.rewrite_result(context, shape)
 }
 
 #[derive(Debug)]
@@ -203,7 +210,7 @@ impl ChainItemKind {
     fn is_tup_field_access(expr: &ast::Expr) -> bool {
         match expr.kind {
             ast::ExprKind::Field(_, ref field) => {
-                field.name.to_string().chars().all(|c| c.is_digit(10))
+                field.name.as_str().chars().all(|c| c.is_digit(10))
             }
             _ => false,
         }
@@ -269,7 +276,13 @@ impl ChainItemKind {
 
 impl Rewrite for ChainItem {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
-        let shape = shape.sub_width(self.tries)?;
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
+        let shape = shape
+            .sub_width(self.tries)
+            .max_width_error(shape.width, self.span)?;
         let rewrite = match self.kind {
             ChainItemKind::Parent {
                 ref expr,
@@ -278,14 +291,14 @@ impl Rewrite for ChainItem {
             ChainItemKind::Parent {
                 ref expr,
                 parens: false,
-            } => expr.rewrite(context, shape)?,
+            } => expr.rewrite_result(context, shape)?,
             ChainItemKind::MethodCall(ref segment, ref types, ref exprs) => {
                 Self::rewrite_method_call(segment.ident, types, exprs, self.span, context, shape)?
             }
             ChainItemKind::StructField(ident) => format!(".{}", rewrite_ident(context, ident)),
             ChainItemKind::TupleField(ident, nested) => format!(
                 "{}.{}",
-                if nested && context.config.version() == Version::One {
+                if nested && context.config.style_edition() <= StyleEdition::Edition2021 {
                     " "
                 } else {
                     ""
@@ -297,7 +310,7 @@ impl Rewrite for ChainItem {
                 rewrite_comment(comment, false, shape, context.config)?
             }
         };
-        Some(format!("{rewrite}{}", "?".repeat(self.tries)))
+        Ok(format!("{rewrite}{}", "?".repeat(self.tries)))
     }
 }
 
@@ -327,14 +340,14 @@ impl ChainItem {
         span: Span,
         context: &RewriteContext<'_>,
         shape: Shape,
-    ) -> Option<String> {
+    ) -> RewriteResult {
         let type_str = if types.is_empty() {
             String::new()
         } else {
             let type_list = types
                 .iter()
-                .map(|ty| ty.rewrite(context, shape))
-                .collect::<Option<Vec<_>>>()?;
+                .map(|ty| ty.rewrite_result(context, shape))
+                .collect::<Result<Vec<_>, RewriteError>>()?;
 
             format!("::<{}>", type_list.join(", "))
         };
@@ -519,6 +532,10 @@ impl Chain {
 
 impl Rewrite for Chain {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         debug!("rewrite chain {:?} {:?}", self, shape);
 
         let mut formatter = match context.config.indent_style() {
@@ -532,17 +549,25 @@ impl Rewrite for Chain {
 
         formatter.format_root(&self.parent, context, shape)?;
         if let Some(result) = formatter.pure_root() {
-            return wrap_str(result, context.config.max_width(), shape);
+            return wrap_str(result, context.config.max_width(), shape)
+                .max_width_error(shape.width, self.parent.span);
         }
 
+        let first = self.children.first().unwrap_or(&self.parent);
+        let last = self.children.last().unwrap_or(&self.parent);
+        let children_span = mk_sp(first.span.lo(), last.span.hi());
+        let full_span = self.parent.span.with_hi(children_span.hi());
+
         // Decide how to layout the rest of the chain.
-        let child_shape = formatter.child_shape(context, shape)?;
+        let child_shape = formatter
+            .child_shape(context, shape)
+            .max_width_error(shape.width, children_span)?;
 
         formatter.format_children(context, child_shape)?;
         formatter.format_last_child(context, shape, child_shape)?;
 
         let result = formatter.join_rewrites(context, child_shape)?;
-        wrap_str(result, context.config.max_width(), shape)
+        wrap_str(result, context.config.max_width(), shape).max_width_error(shape.width, full_span)
     }
 }
 
@@ -564,16 +589,20 @@ trait ChainFormatter {
         parent: &ChainItem,
         context: &RewriteContext<'_>,
         shape: Shape,
-    ) -> Option<()>;
+    ) -> Result<(), RewriteError>;
     fn child_shape(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<Shape>;
-    fn format_children(&mut self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<()>;
+    fn format_children(
+        &mut self,
+        context: &RewriteContext<'_>,
+        child_shape: Shape,
+    ) -> Result<(), RewriteError>;
     fn format_last_child(
         &mut self,
         context: &RewriteContext<'_>,
         shape: Shape,
         child_shape: Shape,
-    ) -> Option<()>;
-    fn join_rewrites(&self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<String>;
+    ) -> Result<(), RewriteError>;
+    fn join_rewrites(&self, context: &RewriteContext<'_>, child_shape: Shape) -> RewriteResult;
     // Returns `Some` if the chain is only a root, None otherwise.
     fn pure_root(&mut self) -> Option<String>;
 }
@@ -616,12 +645,16 @@ impl<'a> ChainFormatterShared<'a> {
         }
     }
 
-    fn format_children(&mut self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<()> {
+    fn format_children(
+        &mut self,
+        context: &RewriteContext<'_>,
+        child_shape: Shape,
+    ) -> Result<(), RewriteError> {
         for item in &self.children[..self.children.len() - 1] {
             let rewrite = format_chain_item(item, context, child_shape, self.allow_overflow)?;
             self.rewrites.push(rewrite);
         }
-        Some(())
+        Ok(())
     }
 
     // Rewrite the last child. The last child of a chain requires special treatment. We need to
@@ -662,8 +695,8 @@ impl<'a> ChainFormatterShared<'a> {
         context: &RewriteContext<'_>,
         shape: Shape,
         child_shape: Shape,
-    ) -> Option<()> {
-        let last = self.children.last()?;
+    ) -> Result<(), RewriteError> {
+        let last = self.children.last().unknown_error()?;
         let extendable = may_extend && last_line_extendable(&self.rewrites[0]);
         let prev_last_line_width = last_line_width(&self.rewrites[0]);
 
@@ -687,11 +720,17 @@ impl<'a> ChainFormatterShared<'a> {
             && self.rewrites.iter().all(|s| !s.contains('\n'))
             && one_line_budget > 0;
         let last_shape = if all_in_one_line {
-            shape.sub_width(last.tries)?
+            shape
+                .sub_width(last.tries)
+                .max_width_error(shape.width, last.span)?
         } else if extendable {
-            child_shape.sub_width(last.tries)?
+            child_shape
+                .sub_width(last.tries)
+                .max_width_error(child_shape.width, last.span)?
         } else {
-            child_shape.sub_width(shape.rhs_overhead(context.config) + last.tries)?
+            child_shape
+                .sub_width(shape.rhs_overhead(context.config) + last.tries)
+                .max_width_error(child_shape.width, last.span)?
         };
 
         let mut last_subexpr_str = None;
@@ -707,7 +746,7 @@ impl<'a> ChainFormatterShared<'a> {
             };
 
             if let Some(one_line_shape) = one_line_shape {
-                if let Some(rw) = last.rewrite(context, one_line_shape) {
+                if let Ok(rw) = last.rewrite_result(context, one_line_shape) {
                     // We allow overflowing here only if both of the following conditions match:
                     // 1. The entire chain fits in a single line except the last child.
                     // 2. `last_child_str.lines().count() >= 5`.
@@ -722,17 +761,18 @@ impl<'a> ChainFormatterShared<'a> {
                         // last child on its own line, and compare two rewrites to choose which is
                         // better.
                         let last_shape = child_shape
-                            .sub_width(shape.rhs_overhead(context.config) + last.tries)?;
-                        match last.rewrite(context, last_shape) {
-                            Some(ref new_rw) if !could_fit_single_line => {
+                            .sub_width(shape.rhs_overhead(context.config) + last.tries)
+                            .max_width_error(child_shape.width, last.span)?;
+                        match last.rewrite_result(context, last_shape) {
+                            Ok(ref new_rw) if !could_fit_single_line => {
                                 last_subexpr_str = Some(new_rw.clone());
                             }
-                            Some(ref new_rw) if new_rw.lines().count() >= line_count => {
+                            Ok(ref new_rw) if new_rw.lines().count() >= line_count => {
                                 last_subexpr_str = Some(rw);
                                 self.fits_single_line = could_fit_single_line && all_in_one_line;
                             }
-                            new_rw @ Some(..) => {
-                                last_subexpr_str = new_rw;
+                            Ok(new_rw) => {
+                                last_subexpr_str = Some(new_rw);
                             }
                             _ => {
                                 last_subexpr_str = Some(rw);
@@ -747,22 +787,28 @@ impl<'a> ChainFormatterShared<'a> {
         let last_shape = if context.use_block_indent() {
             last_shape
         } else {
-            child_shape.sub_width(shape.rhs_overhead(context.config) + last.tries)?
+            child_shape
+                .sub_width(shape.rhs_overhead(context.config) + last.tries)
+                .max_width_error(child_shape.width, last.span)?
         };
 
-        last_subexpr_str = last_subexpr_str.or_else(|| last.rewrite(context, last_shape));
-        self.rewrites.push(last_subexpr_str?);
-        Some(())
+        let last_subexpr_str =
+            last_subexpr_str.unwrap_or(last.rewrite_result(context, last_shape)?);
+        self.rewrites.push(last_subexpr_str);
+        Ok(())
     }
 
-    fn join_rewrites(&self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<String> {
+    fn join_rewrites(&self, context: &RewriteContext<'_>, child_shape: Shape) -> RewriteResult {
         let connector = if self.fits_single_line {
             // Yay, we can put everything on one line.
             Cow::from("")
         } else {
             // Use new lines.
             if context.force_one_line_chain.get() {
-                return None;
+                return Err(RewriteError::ExceedsMaxWidth {
+                    configured_width: child_shape.width,
+                    span: self.children.last().unknown_error()?.span,
+                });
             }
             child_shape.to_string_with_newline(context.config)
         };
@@ -781,7 +827,7 @@ impl<'a> ChainFormatterShared<'a> {
             result.push_str(rewrite);
         }
 
-        Some(result)
+        Ok(result)
     }
 }
 
@@ -806,8 +852,8 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
         parent: &ChainItem,
         context: &RewriteContext<'_>,
         shape: Shape,
-    ) -> Option<()> {
-        let mut root_rewrite: String = parent.rewrite(context, shape)?;
+    ) -> Result<(), RewriteError> {
+        let mut root_rewrite: String = parent.rewrite_result(context, shape)?;
 
         let mut root_ends_with_block = parent.kind.is_block_like(context, &root_rewrite);
         let tab_width = context.config.tab_spaces().saturating_sub(shape.offset);
@@ -817,10 +863,12 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
             if let ChainItemKind::Comment(..) = item.kind {
                 break;
             }
-            let shape = shape.offset_left(root_rewrite.len())?;
-            match &item.rewrite(context, shape) {
-                Some(rewrite) => root_rewrite.push_str(rewrite),
-                None => break,
+            let shape = shape
+                .offset_left(root_rewrite.len())
+                .max_width_error(shape.width, item.span)?;
+            match &item.rewrite_result(context, shape) {
+                Ok(rewrite) => root_rewrite.push_str(rewrite),
+                Err(_) => break,
             }
 
             root_ends_with_block = last_line_extendable(&root_rewrite);
@@ -832,7 +880,7 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
         }
         self.shared.rewrites.push(root_rewrite);
         self.root_ends_with_block = root_ends_with_block;
-        Some(())
+        Ok(())
     }
 
     fn child_shape(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<Shape> {
@@ -840,7 +888,11 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
         Some(get_block_child_shape(block_end, context, shape))
     }
 
-    fn format_children(&mut self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<()> {
+    fn format_children(
+        &mut self,
+        context: &RewriteContext<'_>,
+        child_shape: Shape,
+    ) -> Result<(), RewriteError> {
         self.shared.format_children(context, child_shape)
     }
 
@@ -849,12 +901,12 @@ impl<'a> ChainFormatter for ChainFormatterBlock<'a> {
         context: &RewriteContext<'_>,
         shape: Shape,
         child_shape: Shape,
-    ) -> Option<()> {
+    ) -> Result<(), RewriteError> {
         self.shared
             .format_last_child(true, context, shape, child_shape)
     }
 
-    fn join_rewrites(&self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<String> {
+    fn join_rewrites(&self, context: &RewriteContext<'_>, child_shape: Shape) -> RewriteResult {
         self.shared.join_rewrites(context, child_shape)
     }
 
@@ -885,9 +937,9 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
         parent: &ChainItem,
         context: &RewriteContext<'_>,
         shape: Shape,
-    ) -> Option<()> {
+    ) -> Result<(), RewriteError> {
         let parent_shape = shape.visual_indent(0);
-        let mut root_rewrite = parent.rewrite(context, parent_shape)?;
+        let mut root_rewrite = parent.rewrite_result(context, parent_shape)?;
         let multiline = root_rewrite.contains('\n');
         self.offset = if multiline {
             last_line_width(&root_rewrite).saturating_sub(shape.used_width())
@@ -899,18 +951,19 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
             let item = &self.shared.children[0];
             if let ChainItemKind::Comment(..) = item.kind {
                 self.shared.rewrites.push(root_rewrite);
-                return Some(());
+                return Ok(());
             }
             let child_shape = parent_shape
                 .visual_indent(self.offset)
-                .sub_width(self.offset)?;
-            let rewrite = item.rewrite(context, child_shape)?;
+                .sub_width(self.offset)
+                .max_width_error(parent_shape.width, item.span)?;
+            let rewrite = item.rewrite_result(context, child_shape)?;
             if filtered_str_fits(&rewrite, context.config.max_width(), shape) {
                 root_rewrite.push_str(&rewrite);
             } else {
                 // We couldn't fit in at the visual indent, try the last
                 // indent.
-                let rewrite = item.rewrite(context, parent_shape)?;
+                let rewrite = item.rewrite_result(context, parent_shape)?;
                 root_rewrite.push_str(&rewrite);
                 self.offset = 0;
             }
@@ -919,7 +972,7 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
         }
 
         self.shared.rewrites.push(root_rewrite);
-        Some(())
+        Ok(())
     }
 
     fn child_shape(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<Shape> {
@@ -932,7 +985,11 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
         )
     }
 
-    fn format_children(&mut self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<()> {
+    fn format_children(
+        &mut self,
+        context: &RewriteContext<'_>,
+        child_shape: Shape,
+    ) -> Result<(), RewriteError> {
         self.shared.format_children(context, child_shape)
     }
 
@@ -941,12 +998,12 @@ impl<'a> ChainFormatter for ChainFormatterVisual<'a> {
         context: &RewriteContext<'_>,
         shape: Shape,
         child_shape: Shape,
-    ) -> Option<()> {
+    ) -> Result<(), RewriteError> {
         self.shared
             .format_last_child(false, context, shape, child_shape)
     }
 
-    fn join_rewrites(&self, context: &RewriteContext<'_>, child_shape: Shape) -> Option<String> {
+    fn join_rewrites(&self, context: &RewriteContext<'_>, child_shape: Shape) -> RewriteResult {
         self.shared.join_rewrites(context, child_shape)
     }
 
diff --git a/src/tools/rustfmt/src/closures.rs b/src/tools/rustfmt/src/closures.rs
index b5c26235e77..a37b47e3bc9 100644
--- a/src/tools/rustfmt/src/closures.rs
+++ b/src/tools/rustfmt/src/closures.rs
@@ -4,17 +4,17 @@ use thin_vec::thin_vec;
 use tracing::debug;
 
 use crate::attr::get_attrs_from_stmt;
+use crate::config::StyleEdition;
 use crate::config::lists::*;
-use crate::config::Version;
 use crate::expr::{block_contains_comment, is_simple_block, is_unsafe_block, rewrite_cond};
 use crate::items::{span_hi_for_param, span_lo_for_param};
-use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
+use crate::lists::{ListFormatting, Separator, definitive_tactic, itemize_list, write_list};
 use crate::overflow::OverflowableItem;
-use crate::rewrite::{Rewrite, RewriteContext};
+use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
 use crate::shape::Shape;
 use crate::source_map::SpanUtils;
 use crate::types::rewrite_bound_params;
-use crate::utils::{last_line_width, left_most_sub_expr, stmt_expr, NodeIdExt};
+use crate::utils::{NodeIdExt, last_line_width, left_most_sub_expr, stmt_expr};
 
 // This module is pretty messy because of the rules around closures and blocks:
 // FIXME - the below is probably no longer true in full.
@@ -37,7 +37,7 @@ pub(crate) fn rewrite_closure(
     span: Span,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     debug!("rewrite_closure {:?}", body);
 
     let (prefix, extra_offset) = rewrite_closure_fn_decl(
@@ -53,13 +53,15 @@ pub(crate) fn rewrite_closure(
         shape,
     )?;
     // 1 = space between `|...|` and body.
-    let body_shape = shape.offset_left(extra_offset)?;
+    let body_shape = shape
+        .offset_left(extra_offset)
+        .max_width_error(shape.width, span)?;
 
     if let ast::ExprKind::Block(ref block, _) = body.kind {
         // The body of the closure is an empty block.
         if block.stmts.is_empty() && !block_contains_comment(context, block) {
             return body
-                .rewrite(context, shape)
+                .rewrite_result(context, shape)
                 .map(|s| format!("{} {}", prefix, s));
         }
 
@@ -67,15 +69,15 @@ pub(crate) fn rewrite_closure(
             ast::FnRetTy::Default(_) if !context.inside_macro() => {
                 try_rewrite_without_block(body, &prefix, context, shape, body_shape)
             }
-            _ => None,
+            _ => Err(RewriteError::Unknown),
         };
 
-        result.or_else(|| {
+        result.or_else(|_| {
             // Either we require a block, or tried without and failed.
             rewrite_closure_block(block, &prefix, context, body_shape)
         })
     } else {
-        rewrite_closure_expr(body, &prefix, context, body_shape).or_else(|| {
+        rewrite_closure_expr(body, &prefix, context, body_shape).or_else(|_| {
             // The closure originally had a non-block expression, but we can't fit on
             // one line, so we'll insert a block.
             rewrite_closure_with_block(body, &prefix, context, body_shape)
@@ -89,7 +91,7 @@ fn try_rewrite_without_block(
     context: &RewriteContext<'_>,
     shape: Shape,
     body_shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     let expr = get_inner_expr(expr, prefix, context);
 
     if is_block_closure_forced(context, expr) {
@@ -153,11 +155,11 @@ fn rewrite_closure_with_block(
     prefix: &str,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     let left_most = left_most_sub_expr(body);
     let veto_block = veto_block(body) && !expr_requires_semi_to_be_stmt(left_most);
     if veto_block {
-        return None;
+        return Err(RewriteError::Unknown);
     }
 
     let block = ast::Block {
@@ -185,7 +187,7 @@ fn rewrite_closure_with_block(
         shape,
         false,
     )?;
-    Some(format!("{prefix} {block}"))
+    Ok(format!("{prefix} {block}"))
 }
 
 // Rewrite closure with a single expression without wrapping its body with block.
@@ -194,7 +196,7 @@ fn rewrite_closure_expr(
     prefix: &str,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     fn allow_multi_line(expr: &ast::Expr) -> bool {
         match expr.kind {
             ast::ExprKind::Match(..)
@@ -217,12 +219,12 @@ fn rewrite_closure_expr(
     // unless it is a block-like expression or we are inside macro call.
     let veto_multiline = (!allow_multi_line(expr) && !context.inside_macro())
         || context.config.force_multiline_blocks();
-    expr.rewrite(context, shape)
+    expr.rewrite_result(context, shape)
         .and_then(|rw| {
             if veto_multiline && rw.contains('\n') {
-                None
+                Err(RewriteError::Unknown)
             } else {
-                Some(rw)
+                Ok(rw)
             }
         })
         .map(|rw| format!("{} {}", prefix, rw))
@@ -234,8 +236,12 @@ fn rewrite_closure_block(
     prefix: &str,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
-    Some(format!("{} {}", prefix, block.rewrite(context, shape)?))
+) -> RewriteResult {
+    Ok(format!(
+        "{} {}",
+        prefix,
+        block.rewrite_result(context, shape)?
+    ))
 }
 
 // Return type is (prefix, extra_offset)
@@ -250,13 +256,14 @@ fn rewrite_closure_fn_decl(
     span: Span,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<(String, usize)> {
+) -> Result<(String, usize), RewriteError> {
     let binder = match binder {
         ast::ClosureBinder::For { generic_params, .. } if generic_params.is_empty() => {
             "for<> ".to_owned()
         }
         ast::ClosureBinder::For { generic_params, .. } => {
-            let lifetime_str = rewrite_bound_params(context, shape, generic_params)?;
+            let lifetime_str =
+                rewrite_bound_params(context, shape, generic_params).unknown_error()?;
             format!("for<{lifetime_str}> ")
         }
         ast::ClosureBinder::NotPresent => "".to_owned(),
@@ -287,13 +294,17 @@ fn rewrite_closure_fn_decl(
     // 4 = "|| {".len(), which is overconservative when the closure consists of
     // a single expression.
     let nested_shape = shape
-        .shrink_left(binder.len() + const_.len() + immovable.len() + coro.len() + mover.len())?
-        .sub_width(4)?;
+        .shrink_left(binder.len() + const_.len() + immovable.len() + coro.len() + mover.len())
+        .and_then(|shape| shape.sub_width(4))
+        .max_width_error(shape.width, span)?;
 
     // 1 = |
     let param_offset = nested_shape.indent + 1;
-    let param_shape = nested_shape.offset_left(1)?.visual_indent(0);
-    let ret_str = fn_decl.output.rewrite(context, param_shape)?;
+    let param_shape = nested_shape
+        .offset_left(1)
+        .max_width_error(nested_shape.width, span)?
+        .visual_indent(0);
+    let ret_str = fn_decl.output.rewrite_result(context, param_shape)?;
 
     let param_items = itemize_list(
         context.snippet_provider,
@@ -302,7 +313,7 @@ fn rewrite_closure_fn_decl(
         ",",
         |param| span_lo_for_param(param),
         |param| span_hi_for_param(context, param),
-        |param| param.rewrite(context, param_shape),
+        |param| param.rewrite_result(context, param_shape),
         context.snippet_provider.span_after(span, "|"),
         body.span.lo(),
         false,
@@ -317,7 +328,9 @@ fn rewrite_closure_fn_decl(
         horizontal_budget,
     );
     let param_shape = match tactic {
-        DefinitiveListTactic::Horizontal => param_shape.sub_width(ret_str.len() + 1)?,
+        DefinitiveListTactic::Horizontal => param_shape
+            .sub_width(ret_str.len() + 1)
+            .max_width_error(param_shape.width, span)?,
         _ => param_shape,
     };
 
@@ -339,7 +352,7 @@ fn rewrite_closure_fn_decl(
     // 1 = space between `|...|` and body.
     let extra_offset = last_line_width(&prefix) + 1;
 
-    Some((prefix, extra_offset))
+    Ok((prefix, extra_offset))
 }
 
 // Rewriting closure which is placed at the end of the function call's arg.
@@ -348,7 +361,7 @@ pub(crate) fn rewrite_last_closure(
     context: &RewriteContext<'_>,
     expr: &ast::Expr,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     if let ast::ExprKind::Closure(ref closure) = expr.kind {
         let ast::Closure {
             ref binder,
@@ -385,10 +398,12 @@ pub(crate) fn rewrite_last_closure(
         )?;
         // If the closure goes multi line before its body, do not overflow the closure.
         if prefix.contains('\n') {
-            return None;
+            return Err(RewriteError::Unknown);
         }
 
-        let body_shape = shape.offset_left(extra_offset)?;
+        let body_shape = shape
+            .offset_left(extra_offset)
+            .max_width_error(shape.width, expr.span)?;
 
         // We force to use block for the body of the closure for certain kinds of expressions.
         if is_block_closure_forced(context, body) {
@@ -400,7 +415,7 @@ pub(crate) fn rewrite_last_closure(
                             // closure.  However, if the closure has a return type, then we must
                             // keep the blocks.
                             match rewrite_closure_expr(body, &prefix, context, shape) {
-                                Some(single_line_body_str)
+                                Ok(single_line_body_str)
                                     if !single_line_body_str.contains('\n') =>
                                 {
                                     single_line_body_str
@@ -424,9 +439,9 @@ pub(crate) fn rewrite_last_closure(
         }
 
         // Seems fine, just format the closure in usual manner.
-        return expr.rewrite(context, shape);
+        return expr.rewrite_result(context, shape);
     }
-    None
+    Err(RewriteError::Unknown)
 }
 
 /// Returns `true` if the given vector of arguments has more than one `ast::ExprKind::Closure`.
@@ -443,18 +458,18 @@ fn is_block_closure_forced(context: &RewriteContext<'_>, expr: &ast::Expr) -> bo
     if context.inside_macro() {
         false
     } else {
-        is_block_closure_forced_inner(expr, context.config.version())
+        is_block_closure_forced_inner(expr, context.config.style_edition())
     }
 }
 
-fn is_block_closure_forced_inner(expr: &ast::Expr, version: Version) -> bool {
+fn is_block_closure_forced_inner(expr: &ast::Expr, style_edition: StyleEdition) -> bool {
     match expr.kind {
         ast::ExprKind::If(..) | ast::ExprKind::While(..) | ast::ExprKind::ForLoop { .. } => true,
-        ast::ExprKind::Loop(..) if version == Version::Two => true,
+        ast::ExprKind::Loop(..) if style_edition >= StyleEdition::Edition2024 => true,
         ast::ExprKind::AddrOf(_, _, ref expr)
         | ast::ExprKind::Try(ref expr)
         | ast::ExprKind::Unary(_, ref expr)
-        | ast::ExprKind::Cast(ref expr, _) => is_block_closure_forced_inner(expr, version),
+        | ast::ExprKind::Cast(ref expr, _) => is_block_closure_forced_inner(expr, style_edition),
         _ => false,
     }
 }
diff --git a/src/tools/rustfmt/src/comment.rs b/src/tools/rustfmt/src/comment.rs
index e76be0fd162..b7d7a396a67 100644
--- a/src/tools/rustfmt/src/comment.rs
+++ b/src/tools/rustfmt/src/comment.rs
@@ -2,14 +2,14 @@
 
 use std::{borrow::Cow, iter};
 
-use itertools::{multipeek, MultiPeek};
+use itertools::{Itertools as _, MultiPeek, multipeek};
 use rustc_span::Span;
 use tracing::{debug, trace};
 
 use crate::config::Config;
-use crate::rewrite::RewriteContext;
+use crate::rewrite::{RewriteContext, RewriteErrorExt, RewriteResult};
 use crate::shape::{Indent, Shape};
-use crate::string::{rewrite_string, StringFormat};
+use crate::string::{StringFormat, rewrite_string};
 use crate::utils::{
     count_newlines, first_line_width, last_line_width, trim_left_preserve_layout,
     trimmed_last_line_width, unicode_str_width,
@@ -158,7 +158,7 @@ pub(crate) fn combine_strs_with_missing_comments(
     span: Span,
     shape: Shape,
     allow_extend: bool,
-) -> Option<String> {
+) -> RewriteResult {
     trace!(
         "combine_strs_with_missing_comments `{}` `{}` {:?} {:?}",
         prev_str, next_str, span, shape
@@ -188,7 +188,7 @@ pub(crate) fn combine_strs_with_missing_comments(
             result.push_str(&indent.to_string_with_newline(config))
         }
         result.push_str(next_str);
-        return Some(result);
+        return Ok(result);
     }
 
     // We have a missing comment between the first expression and the second expression.
@@ -233,10 +233,10 @@ pub(crate) fn combine_strs_with_missing_comments(
     result.push_str(&second_sep);
     result.push_str(next_str);
 
-    Some(result)
+    Ok(result)
 }
 
-pub(crate) fn rewrite_doc_comment(orig: &str, shape: Shape, config: &Config) -> Option<String> {
+pub(crate) fn rewrite_doc_comment(orig: &str, shape: Shape, config: &Config) -> RewriteResult {
     identify_comment(orig, false, shape, config, true)
 }
 
@@ -245,7 +245,7 @@ pub(crate) fn rewrite_comment(
     block_style: bool,
     shape: Shape,
     config: &Config,
-) -> Option<String> {
+) -> RewriteResult {
     identify_comment(orig, block_style, shape, config, false)
 }
 
@@ -255,7 +255,7 @@ fn identify_comment(
     shape: Shape,
     config: &Config,
     is_doc_comment: bool,
-) -> Option<String> {
+) -> RewriteResult {
     let style = comment_style(orig, false);
 
     // Computes the byte length of line taking into account a newline if the line is part of a
@@ -347,7 +347,7 @@ fn identify_comment(
     let (first_group, rest) = orig.split_at(first_group_ending);
     let rewritten_first_group =
         if !config.normalize_comments() && has_bare_lines && style.is_block_comment() {
-            trim_left_preserve_layout(first_group, shape.indent, config)?
+            trim_left_preserve_layout(first_group, shape.indent, config).unknown_error()?
         } else if !config.normalize_comments()
             && !config.wrap_comments()
             && !(
@@ -368,7 +368,7 @@ fn identify_comment(
             )?
         };
     if rest.is_empty() {
-        Some(rewritten_first_group)
+        Ok(rewritten_first_group)
     } else {
         identify_comment(
             rest.trim_start(),
@@ -534,10 +534,11 @@ impl ItemizedBlock {
 
     /// Returns the block as a string, with each line trimmed at the start.
     fn trimmed_block_as_string(&self) -> String {
-        self.lines
-            .iter()
-            .map(|line| format!("{} ", line.trim_start()))
-            .collect::<String>()
+        self.lines.iter().fold(String::new(), |mut acc, line| {
+            acc.push_str(line.trim_start());
+            acc.push(' ');
+            acc
+        })
     }
 
     /// Returns the block as a string under its original form.
@@ -900,7 +901,7 @@ fn rewrite_comment_inner(
     shape: Shape,
     config: &Config,
     is_doc_comment: bool,
-) -> Option<String> {
+) -> RewriteResult {
     let mut rewriter = CommentRewrite::new(orig, block_style, shape, config);
 
     let line_breaks = count_newlines(orig.trim_end());
@@ -934,7 +935,7 @@ fn rewrite_comment_inner(
         }
     }
 
-    Some(rewriter.finish())
+    Ok(rewriter.finish())
 }
 
 const RUSTFMT_CUSTOM_COMMENT_PREFIX: &str = "//#### ";
@@ -999,7 +1000,7 @@ pub(crate) fn rewrite_missing_comment(
     span: Span,
     shape: Shape,
     context: &RewriteContext<'_>,
-) -> Option<String> {
+) -> RewriteResult {
     let missing_snippet = context.snippet(span);
     let trimmed_snippet = missing_snippet.trim();
     // check the span starts with a comment
@@ -1007,7 +1008,7 @@ pub(crate) fn rewrite_missing_comment(
     if !trimmed_snippet.is_empty() && pos.is_some() {
         rewrite_comment(trimmed_snippet, false, shape, context.config)
     } else {
-        Some(String::new())
+        Ok(String::new())
     }
 }
 
@@ -1019,13 +1020,13 @@ pub(crate) fn recover_missing_comment_in_span(
     shape: Shape,
     context: &RewriteContext<'_>,
     used_width: usize,
-) -> Option<String> {
+) -> RewriteResult {
     let missing_comment = rewrite_missing_comment(span, shape, context)?;
     if missing_comment.is_empty() {
-        Some(String::new())
+        Ok(String::new())
     } else {
         let missing_snippet = context.snippet(span);
-        let pos = missing_snippet.find('/')?;
+        let pos = missing_snippet.find('/').unknown_error()?;
         // 1 = ` `
         let total_width = missing_comment.len() + used_width + 1;
         let force_new_line_before_comment =
@@ -1035,7 +1036,7 @@ pub(crate) fn recover_missing_comment_in_span(
         } else {
             Cow::from(" ")
         };
-        Some(format!("{sep}{missing_comment}"))
+        Ok(format!("{sep}{missing_comment}"))
     }
 }
 
@@ -1055,8 +1056,7 @@ fn light_rewrite_comment(
     config: &Config,
     is_doc_comment: bool,
 ) -> String {
-    let lines: Vec<&str> = orig
-        .lines()
+    orig.lines()
         .map(|l| {
             // This is basically just l.trim(), but in the case that a line starts
             // with `*` we want to leave one space before it, so it aligns with the
@@ -1074,8 +1074,7 @@ fn light_rewrite_comment(
             // Preserve markdown's double-space line break syntax in doc comment.
             trim_end_unless_two_whitespaces(left_trimmed, is_doc_comment)
         })
-        .collect();
-    lines.join(&format!("\n{}", offset.to_string(config)))
+        .join(&format!("\n{}", offset.to_string(config)))
 }
 
 /// Trims comment characters and possibly a single space from the left of a string.
@@ -1704,12 +1703,11 @@ impl<'a> Iterator for CommentCodeSlices<'a> {
 }
 
 /// Checks is `new` didn't miss any comment from `span`, if it removed any, return previous text
-/// (if it fits in the width/offset, else return `None`), else return `new`
 pub(crate) fn recover_comment_removed(
     new: String,
     span: Span,
     context: &RewriteContext<'_>,
-) -> Option<String> {
+) -> String {
     let snippet = context.snippet(span);
     if snippet != new && changed_comment_content(snippet, &new) {
         // We missed some comments. Warn and keep the original text.
@@ -1723,9 +1721,9 @@ pub(crate) fn recover_comment_removed(
                 )],
             );
         }
-        Some(snippet.to_owned())
+        snippet.to_owned()
     } else {
-        Some(new)
+        new
     }
 }
 
diff --git a/src/tools/rustfmt/src/config/config_type.rs b/src/tools/rustfmt/src/config/config_type.rs
index f7cff1a1729..14217caba0a 100644
--- a/src/tools/rustfmt/src/config/config_type.rs
+++ b/src/tools/rustfmt/src/config/config_type.rs
@@ -70,15 +70,15 @@ macro_rules! create_config {
     //
     // - $i: the ident name of the option
     // - $ty: the type of the option value
-    // - $def: the default value of the option
     // - $stb: true if the option is stable
     // - $dstring: description of the option
-    ($($i:ident: $ty:ty, $def:expr, $stb:expr, $( $dstring:expr ),+ );+ $(;)*) => (
+    ($($i:ident: $ty:ty, $stb:expr, $( $dstring:expr ),+ );+ $(;)*) => (
         #[cfg(test)]
         use std::collections::HashSet;
         use std::io::Write;
 
         use serde::{Deserialize, Serialize};
+        use $crate::config::style_edition::StyleEditionDefault;
 
         #[derive(Clone)]
         #[allow(unreachable_pub)]
@@ -89,7 +89,10 @@ macro_rules! create_config {
             // - 1: true if the option was manually initialized
             // - 2: the option value
             // - 3: true if the option is unstable
-            $($i: (Cell<bool>, bool, $ty, bool)),+
+            // - 4: true if the option was set manually from a CLI flag
+            // FIXME: 4 is probably unnecessary and duplicative
+            // https://github.com/rust-lang/rustfmt/issues/6252
+            $($i: (Cell<bool>, bool, <$ty as StyleEditionDefault>::ConfigType, bool, bool)),+
         }
 
         // Just like the Config struct but with each property wrapped
@@ -100,7 +103,7 @@ macro_rules! create_config {
         #[derive(Deserialize, Serialize, Clone)]
         #[allow(unreachable_pub)]
         pub struct PartialConfig {
-            $(pub $i: Option<$ty>),+
+            $(pub $i: Option<<$ty as StyleEditionDefault>::ConfigType>),+
         }
 
         // Macro hygiene won't allow us to make `set_$i()` methods on Config
@@ -114,7 +117,7 @@ macro_rules! create_config {
         impl<'a> ConfigSetter<'a> {
             $(
             #[allow(unreachable_pub)]
-            pub fn $i(&mut self, value: $ty) {
+            pub fn $i(&mut self, value: <$ty as StyleEditionDefault>::ConfigType) {
                 (self.0).$i.2 = value;
                 match stringify!($i) {
                     "max_width"
@@ -130,6 +133,37 @@ macro_rules! create_config {
                     "merge_imports" => self.0.set_merge_imports(),
                     "fn_args_layout" => self.0.set_fn_args_layout(),
                     "hide_parse_errors" => self.0.set_hide_parse_errors(),
+                    "version" => self.0.set_version(),
+                    &_ => (),
+                }
+            }
+            )+
+        }
+
+        #[allow(unreachable_pub)]
+        pub struct CliConfigSetter<'a>(&'a mut Config);
+
+        impl<'a> CliConfigSetter<'a> {
+            $(
+            #[allow(unreachable_pub)]
+            pub fn $i(&mut self, value: <$ty as StyleEditionDefault>::ConfigType) {
+                (self.0).$i.2 = value;
+                (self.0).$i.4 = true;
+                match stringify!($i) {
+                    "max_width"
+                    | "use_small_heuristics"
+                    | "fn_call_width"
+                    | "single_line_if_else_max_width"
+                    | "single_line_let_else_max_width"
+                    | "attr_fn_like_width"
+                    | "struct_lit_width"
+                    | "struct_variant_width"
+                    | "array_width"
+                    | "chain_width" => self.0.set_heuristics(),
+                    "merge_imports" => self.0.set_merge_imports(),
+                    "fn_args_layout" => self.0.set_fn_args_layout(),
+                    "hide_parse_errors" => self.0.set_hide_parse_errors(),
+                    "version" => self.0.set_version(),
                     &_ => (),
                 }
             }
@@ -150,25 +184,66 @@ macro_rules! create_config {
             )+
         }
 
+        // Query each option, returns true if the user set the option via a CLI flag,
+        // false if a default was used.
+        #[allow(unreachable_pub)]
+        pub struct CliConfigWasSet<'a>(&'a Config);
+
+        impl<'a> CliConfigWasSet<'a> {
+            $(
+            #[allow(unreachable_pub)]
+            pub fn $i(&self) -> bool {
+                (self.0).$i.4
+            }
+            )+
+        }
+
         impl Config {
             $(
             #[allow(unreachable_pub)]
-            pub fn $i(&self) -> $ty {
+            pub fn $i(&self) -> <$ty as StyleEditionDefault>::ConfigType {
                 self.$i.0.set(true);
                 self.$i.2.clone()
             }
             )+
 
             #[allow(unreachable_pub)]
+            pub(super) fn default_with_style_edition(style_edition: StyleEdition) -> Config {
+                Config {
+                    $(
+                        $i: (
+                                Cell::new(false),
+                                false,
+                                <$ty as StyleEditionDefault>::style_edition_default(
+                                    style_edition
+                                ),
+                                $stb,
+                                false,
+                            ),
+                    )+
+                }
+            }
+
+            #[allow(unreachable_pub)]
             pub fn set(&mut self) -> ConfigSetter<'_> {
                 ConfigSetter(self)
             }
 
             #[allow(unreachable_pub)]
+            pub fn set_cli(&mut self) -> CliConfigSetter<'_> {
+                CliConfigSetter(self)
+            }
+
+            #[allow(unreachable_pub)]
             pub fn was_set(&self) -> ConfigWasSet<'_> {
                 ConfigWasSet(self)
             }
 
+            #[allow(unreachable_pub)]
+            pub fn was_set_cli(&self) -> CliConfigWasSet<'_> {
+                CliConfigWasSet(self)
+            }
+
             fn fill_from_parsed_config(mut self, parsed: PartialConfig, dir: &Path) -> Config {
             $(
                 if let Some(option_value) = parsed.$i {
@@ -186,6 +261,7 @@ macro_rules! create_config {
                 self.set_merge_imports();
                 self.set_fn_args_layout();
                 self.set_hide_parse_errors();
+                self.set_version();
                 self
             }
 
@@ -212,7 +288,9 @@ macro_rules! create_config {
             pub fn is_valid_key_val(key: &str, val: &str) -> bool {
                 match key {
                     $(
-                        stringify!($i) => val.parse::<$ty>().is_ok(),
+                        stringify!($i) => {
+                            val.parse::<<$ty as StyleEditionDefault>::ConfigType>().is_ok()
+                        }
                     )+
                         _ => false,
                 }
@@ -246,11 +324,15 @@ macro_rules! create_config {
                 match key {
                     $(
                         stringify!($i) => {
-                            let option_value = val.parse::<$ty>()
-                                .expect(&format!("Failed to parse override for {} (\"{}\") as a {}",
-                                                 stringify!($i),
-                                                 val,
-                                                 stringify!($ty)));
+                            let value = val.parse::<<$ty as StyleEditionDefault>::ConfigType>()
+                                .expect(
+                                    &format!(
+                                        "Failed to parse override for {} (\"{}\") as a {}",
+                                        stringify!($i),
+                                        val,
+                                        stringify!(<$ty as StyleEditionDefault>::ConfigType)
+                                    )
+                                );
 
                             // Users are currently allowed to set unstable
                             // options/variants via the `--config` options override.
@@ -261,7 +343,7 @@ macro_rules! create_config {
                             // For now, do not validate whether the option or value is stable,
                             // just always set it.
                             self.$i.1 = true;
-                            self.$i.2 = option_value;
+                            self.$i.2 = value;
                         }
                     )+
                     _ => panic!("Unknown config key in override: {}", key)
@@ -281,6 +363,7 @@ macro_rules! create_config {
                     "merge_imports" => self.set_merge_imports(),
                     "fn_args_layout" => self.set_fn_args_layout(),
                     "hide_parse_errors" => self.set_hide_parse_errors(),
+                    "version" => self.set_version(),
                     &_ => (),
                 }
             }
@@ -301,6 +384,7 @@ macro_rules! create_config {
 
             #[allow(unreachable_pub)]
             pub fn print_docs(out: &mut dyn Write, include_unstable: bool) {
+                let style_edition = StyleEdition::Edition2015;
                 use std::cmp;
                 let max = 0;
                 $( let max = cmp::max(max, stringify!($i).len()+1); )+
@@ -317,14 +401,17 @@ macro_rules! create_config {
                             }
                             name_out.push_str(name_raw);
                             name_out.push(' ');
-                            let mut default_str = format!("{}", $def);
+                            let default_value = <$ty as StyleEditionDefault>::style_edition_default(
+                                style_edition
+                            );
+                            let mut default_str = format!("{}", default_value);
                             if default_str.is_empty() {
                                 default_str = String::from("\"\"");
                             }
                             writeln!(out,
                                     "{}{} Default: {}{}",
                                     name_out,
-                                    <$ty>::doc_hint(),
+                                    <<$ty as StyleEditionDefault>::ConfigType>::doc_hint(),
                                     default_str,
                                     if !$stb { " (unstable)" } else { "" }).unwrap();
                             $(
@@ -477,12 +564,36 @@ macro_rules! create_config {
                 }
             }
 
+            fn set_version(&mut self) {
+                if !self.was_set().version() {
+                    return;
+                }
+
+                eprintln!(
+                    "Warning: the `version` option is deprecated. \
+                    Use `style_edition` instead."
+                );
+
+                if self.was_set().style_edition() || self.was_set_cli().style_edition() {
+                    eprintln!(
+                        "Warning: the deprecated `version` option was \
+                        used in conjunction with the `style_edition` \
+                        option which takes precedence. \
+                        The value of the `version` option will be ignored."
+                    );
+                }
+            }
+
             #[allow(unreachable_pub)]
             /// Returns `true` if the config key was explicitly set and is the default value.
             pub fn is_default(&self, key: &str) -> bool {
+                let style_edition = StyleEdition::Edition2015;
                 $(
+                    let default_value = <$ty as StyleEditionDefault>::style_edition_default(
+                        style_edition
+                    );
                     if let stringify!($i) = key {
-                        return self.$i.1 && self.$i.2 == $def;
+                        return self.$i.1 && self.$i.2 == default_value;
                     }
                  )+
                 false
@@ -492,11 +603,7 @@ macro_rules! create_config {
         // Template for the default configuration
         impl Default for Config {
             fn default() -> Config {
-                Config {
-                    $(
-                        $i: (Cell::new(false), false, $def, $stb),
-                    )+
-                }
+                Config::default_with_style_edition(StyleEdition::Edition2015)
             }
         }
     )
diff --git a/src/tools/rustfmt/src/config/file_lines.rs b/src/tools/rustfmt/src/config/file_lines.rs
index 224864393d3..c53ec6371e9 100644
--- a/src/tools/rustfmt/src/config/file_lines.rs
+++ b/src/tools/rustfmt/src/config/file_lines.rs
@@ -7,7 +7,7 @@ use std::{cmp, fmt, iter, str};
 
 use rustc_data_structures::sync::Lrc;
 use rustc_span::SourceFile;
-use serde::{ser, Deserialize, Deserializer, Serialize, Serializer};
+use serde::{Deserialize, Deserializer, Serialize, Serializer, ser};
 use serde_json as json;
 use thiserror::Error;
 
@@ -38,7 +38,7 @@ impl From<rustc_span::FileName> for FileName {
 impl fmt::Display for FileName {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match self {
-            FileName::Real(p) => write!(f, "{}", p.to_str().unwrap()),
+            FileName::Real(p) => write!(f, "{}", p.display()),
             FileName::Stdin => write!(f, "<stdin>"),
         }
     }
@@ -201,7 +201,7 @@ impl FileLines {
     }
 
     /// Returns `true` if this `FileLines` contains all lines in all files.
-    pub(crate) fn is_all(&self) -> bool {
+    pub fn is_all(&self) -> bool {
         self.0.is_none()
     }
 
diff --git a/src/tools/rustfmt/src/config/mod.rs b/src/tools/rustfmt/src/config/mod.rs
index 9484b2e5829..ea257c0a8ba 100644
--- a/src/tools/rustfmt/src/config/mod.rs
+++ b/src/tools/rustfmt/src/config/mod.rs
@@ -10,9 +10,7 @@ use crate::config::config_type::ConfigType;
 #[allow(unreachable_pub)]
 pub use crate::config::file_lines::{FileLines, FileName, Range};
 #[allow(unreachable_pub)]
-pub use crate::config::lists::*;
-#[allow(unreachable_pub)]
-pub use crate::config::macro_names::{MacroSelector, MacroSelectors};
+pub use crate::config::macro_names::MacroSelector;
 #[allow(unreachable_pub)]
 pub use crate::config::options::*;
 
@@ -34,161 +32,169 @@ pub(crate) mod style_edition;
 // `name: value type, default value, is stable, description;`
 create_config! {
     // Fundamental stuff
-    max_width: usize, 100, true, "Maximum width of each line";
-    hard_tabs: bool, false, true, "Use tab characters for indentation, spaces for alignment";
-    tab_spaces: usize, 4, true, "Number of spaces per tab";
-    newline_style: NewlineStyle, NewlineStyle::Auto, true, "Unix or Windows line endings";
-    indent_style: IndentStyle, IndentStyle::Block, false, "How do we indent expressions or items";
+    max_width: MaxWidth, true, "Maximum width of each line";
+    hard_tabs: HardTabs, true, "Use tab characters for indentation, spaces for alignment";
+    tab_spaces: TabSpaces, true, "Number of spaces per tab";
+    newline_style: NewlineStyleConfig, true, "Unix or Windows line endings";
+    indent_style: IndentStyleConfig, false, "How do we indent expressions or items";
 
     // Width Heuristics
-    use_small_heuristics: Heuristics, Heuristics::Default, true, "Whether to use different \
+    use_small_heuristics: UseSmallHeuristics, true, "Whether to use different \
         formatting for items and expressions if they satisfy a heuristic notion of 'small'";
-    width_heuristics: WidthHeuristics, WidthHeuristics::scaled(100), false,
-        "'small' heuristic values";
-    fn_call_width: usize, 60, true, "Maximum width of the args of a function call before \
+    width_heuristics: WidthHeuristicsConfig, false, "'small' heuristic values";
+    fn_call_width: FnCallWidth, true, "Maximum width of the args of a function call before \
         falling back to vertical formatting.";
-    attr_fn_like_width: usize, 70, true, "Maximum width of the args of a function-like \
+    attr_fn_like_width: AttrFnLikeWidth, true, "Maximum width of the args of a function-like \
         attributes before falling back to vertical formatting.";
-    struct_lit_width: usize, 18, true, "Maximum width in the body of a struct lit before \
-        falling back to vertical formatting.";
-    struct_variant_width: usize, 35, true, "Maximum width in the body of a struct variant before \
+    struct_lit_width: StructLitWidth, true, "Maximum width in the body of a struct lit before \
         falling back to vertical formatting.";
-    array_width: usize, 60, true,  "Maximum width of an array literal before falling \
+    struct_variant_width: StructVariantWidth, true, "Maximum width in the body of a struct variant \
+        before falling back to vertical formatting.";
+    array_width: ArrayWidth, true,  "Maximum width of an array literal before falling \
         back to vertical formatting.";
-    chain_width: usize, 60, true, "Maximum length of a chain to fit on a single line.";
-    single_line_if_else_max_width: usize, 50, true, "Maximum line length for single line if-else \
-        expressions. A value of zero means always break if-else expressions.";
-    single_line_let_else_max_width: usize, 50, true, "Maximum line length for single line \
-        let-else statements. A value of zero means always format the divergent `else` block \
-        over multiple lines.";
+    chain_width: ChainWidth, true, "Maximum length of a chain to fit on a single line.";
+    single_line_if_else_max_width: SingleLineIfElseMaxWidth, true, "Maximum line length for single \
+        line if-else expressions. A value of zero means always break if-else expressions.";
+    single_line_let_else_max_width: SingleLineLetElseMaxWidth, true, "Maximum line length for \
+        single line let-else statements. A value of zero means always format the divergent `else` \
+        block over multiple lines.";
 
     // Comments. macros, and strings
-    wrap_comments: bool, false, false, "Break comments to fit on the line";
-    format_code_in_doc_comments: bool, false, false, "Format the code snippet in doc comments.";
-    doc_comment_code_block_width: usize, 100, false, "Maximum width for code snippets in doc \
-        comments. No effect unless format_code_in_doc_comments = true";
-    comment_width: usize, 80, false,
+    wrap_comments: WrapComments, false, "Break comments to fit on the line";
+    format_code_in_doc_comments: FormatCodeInDocComments, false, "Format the code snippet in \
+        doc comments.";
+    doc_comment_code_block_width: DocCommentCodeBlockWidth, false, "Maximum width for code \
+        snippets in doc comments. No effect unless format_code_in_doc_comments = true";
+    comment_width: CommentWidth, false,
         "Maximum length of comments. No effect unless wrap_comments = true";
-    normalize_comments: bool, false, false, "Convert /* */ comments to // comments where possible";
-    normalize_doc_attributes: bool, false, false, "Normalize doc attributes as doc comments";
-    format_strings: bool, false, false, "Format string literals where necessary";
-    format_macro_matchers: bool, false, false,
+    normalize_comments: NormalizeComments, false, "Convert /* */ comments to // comments where \
+        possible";
+    normalize_doc_attributes: NormalizeDocAttributes, false, "Normalize doc attributes as doc \
+        comments";
+    format_strings: FormatStrings, false, "Format string literals where necessary";
+    format_macro_matchers: FormatMacroMatchers, false,
         "Format the metavariable matching patterns in macros";
-    format_macro_bodies: bool, true, false, "Format the bodies of declarative macro definitions";
-    skip_macro_invocations: MacroSelectors, MacroSelectors::default(), false,
+    format_macro_bodies: FormatMacroBodies, false,
+        "Format the bodies of declarative macro definitions";
+    skip_macro_invocations: SkipMacroInvocations, false,
         "Skip formatting the bodies of macros invoked with the following names.";
-    hex_literal_case: HexLiteralCase, HexLiteralCase::Preserve, false,
-        "Format hexadecimal integer literals";
+    hex_literal_case: HexLiteralCaseConfig, false, "Format hexadecimal integer literals";
 
     // Single line expressions and items
-    empty_item_single_line: bool, true, false,
+    empty_item_single_line: EmptyItemSingleLine, false,
         "Put empty-body functions and impls on a single line";
-    struct_lit_single_line: bool, true, false,
+    struct_lit_single_line: StructLitSingleLine, false,
         "Put small struct literals on a single line";
-    fn_single_line: bool, false, false, "Put single-expression functions on a single line";
-    where_single_line: bool, false, false, "Force where-clauses to be on a single line";
+    fn_single_line: FnSingleLine, false, "Put single-expression functions on a single line";
+    where_single_line: WhereSingleLine, false, "Force where-clauses to be on a single line";
 
     // Imports
-    imports_indent: IndentStyle, IndentStyle::Block, false, "Indent of imports";
-    imports_layout: ListTactic, ListTactic::Mixed, false, "Item layout inside a import block";
-    imports_granularity: ImportGranularity, ImportGranularity::Preserve, false,
+    imports_indent: ImportsIndent, false, "Indent of imports";
+    imports_layout: ImportsLayout, false, "Item layout inside a import block";
+    imports_granularity: ImportsGranularityConfig, false,
         "Merge or split imports to the provided granularity";
-    group_imports: GroupImportsTactic, GroupImportsTactic::Preserve, false,
+    group_imports: GroupImportsTacticConfig, false,
         "Controls the strategy for how imports are grouped together";
-    merge_imports: bool, false, false, "(deprecated: use imports_granularity instead)";
+    merge_imports: MergeImports, false, "(deprecated: use imports_granularity instead)";
 
     // Ordering
-    reorder_imports: bool, true, true, "Reorder import and extern crate statements alphabetically";
-    reorder_modules: bool, true, true, "Reorder module statements alphabetically in group";
-    reorder_impl_items: bool, false, false, "Reorder impl items";
+    reorder_imports: ReorderImports, true, "Reorder import and extern crate statements \
+        alphabetically";
+    reorder_modules: ReorderModules, true, "Reorder module statements alphabetically in group";
+    reorder_impl_items: ReorderImplItems, false, "Reorder impl items";
 
     // Spaces around punctuation
-    type_punctuation_density: TypeDensity, TypeDensity::Wide, false,
+    type_punctuation_density: TypePunctuationDensity, false,
         "Determines if '+' or '=' are wrapped in spaces in the punctuation of types";
-    space_before_colon: bool, false, false, "Leave a space before the colon";
-    space_after_colon: bool, true, false, "Leave a space after the colon";
-    spaces_around_ranges: bool, false, false, "Put spaces around the  .. and ..= range operators";
-    binop_separator: SeparatorPlace, SeparatorPlace::Front, false,
+    space_before_colon: SpaceBeforeColon, false, "Leave a space before the colon";
+    space_after_colon: SpaceAfterColon, false, "Leave a space after the colon";
+    spaces_around_ranges: SpacesAroundRanges, false, "Put spaces around the  .. and ..= range \
+        operators";
+    binop_separator: BinopSeparator, false,
         "Where to put a binary operator when a binary expression goes multiline";
 
     // Misc.
-    remove_nested_parens: bool, true, true, "Remove nested parens";
-    combine_control_expr: bool, true, false, "Combine control expressions with function calls";
-    short_array_element_width_threshold: usize, 10, true,
+    remove_nested_parens: RemoveNestedParens, true, "Remove nested parens";
+    combine_control_expr: CombineControlExpr, false, "Combine control expressions with function \
+        calls";
+    short_array_element_width_threshold: ShortArrayElementWidthThreshold, true,
         "Width threshold for an array element to be considered short";
-    overflow_delimited_expr: bool, false, false,
+    overflow_delimited_expr: OverflowDelimitedExpr, false,
         "Allow trailing bracket/brace delimited expressions to overflow";
-    struct_field_align_threshold: usize, 0, false,
+    struct_field_align_threshold: StructFieldAlignThreshold, false,
         "Align struct fields if their diffs fits within threshold";
-    enum_discrim_align_threshold: usize, 0, false,
+    enum_discrim_align_threshold: EnumDiscrimAlignThreshold, false,
         "Align enum variants discrims, if their diffs fit within threshold";
-    match_arm_blocks: bool, true, false, "Wrap the body of arms in blocks when it does not fit on \
-        the same line with the pattern of arms";
-    match_arm_leading_pipes: MatchArmLeadingPipe, MatchArmLeadingPipe::Never, true,
+    match_arm_blocks: MatchArmBlocks, false, "Wrap the body of arms in blocks when it does not fit \
+        on the same line with the pattern of arms";
+    match_arm_leading_pipes: MatchArmLeadingPipeConfig, true,
         "Determines whether leading pipes are emitted on match arms";
-    force_multiline_blocks: bool, false, false,
+    force_multiline_blocks: ForceMultilineBlocks, false,
         "Force multiline closure bodies and match arms to be wrapped in a block";
-    fn_args_layout: Density, Density::Tall, true,
+    fn_args_layout: FnArgsLayout, true,
         "(deprecated: use fn_params_layout instead)";
-    fn_params_layout: Density, Density::Tall, true,
+    fn_params_layout: FnParamsLayout, true,
         "Control the layout of parameters in function signatures.";
-    brace_style: BraceStyle, BraceStyle::SameLineWhere, false, "Brace style for items";
-    control_brace_style: ControlBraceStyle, ControlBraceStyle::AlwaysSameLine, false,
+    brace_style: BraceStyleConfig, false, "Brace style for items";
+    control_brace_style: ControlBraceStyleConfig, false,
         "Brace style for control flow constructs";
-    trailing_semicolon: bool, true, false,
+    trailing_semicolon: TrailingSemicolon, false,
         "Add trailing semicolon after break, continue and return";
-    trailing_comma: SeparatorTactic, SeparatorTactic::Vertical, false,
+    trailing_comma: TrailingComma, false,
         "How to handle trailing commas for lists";
-    match_block_trailing_comma: bool, false, true,
+    match_block_trailing_comma: MatchBlockTrailingComma, true,
         "Put a trailing comma after a block based match arm (non-block arms are not affected)";
-    blank_lines_upper_bound: usize, 1, false,
+    blank_lines_upper_bound: BlankLinesUpperBound, false,
         "Maximum number of blank lines which can be put between items";
-    blank_lines_lower_bound: usize, 0, false,
+    blank_lines_lower_bound: BlankLinesLowerBound, false,
         "Minimum number of blank lines which must be put between items";
-    edition: Edition, Edition::Edition2015, true, "The edition of the parser (RFC 2052)";
-    version: Version, Version::One, false, "Version of formatting rules";
-    inline_attribute_width: usize, 0, false,
+    edition: EditionConfig, true, "The edition of the parser (RFC 2052)";
+    style_edition: StyleEditionConfig, false, "The edition of the Style Guide (RFC 3338)";
+    version: VersionConfig, false, "Version of formatting rules";
+    inline_attribute_width: InlineAttributeWidth, false,
         "Write an item and its attribute on the same line \
         if their combined width is below a threshold";
-    format_generated_files: bool, true, false, "Format generated files";
-    generated_marker_line_search_limit: usize, 5, false, "Number of lines to check for a \
-        `@generated` marker when `format_generated_files` is enabled";
+    format_generated_files: FormatGeneratedFiles, false, "Format generated files";
+    generated_marker_line_search_limit: GeneratedMarkerLineSearchLimit, false, "Number of lines to \
+        check for a `@generated` marker when `format_generated_files` is enabled";
 
     // Options that can change the source code beyond whitespace/blocks (somewhat linty things)
-    merge_derives: bool, true, true, "Merge multiple `#[derive(...)]` into a single one";
-    use_try_shorthand: bool, false, true, "Replace uses of the try! macro by the ? shorthand";
-    use_field_init_shorthand: bool, false, true, "Use field initialization shorthand if possible";
-    force_explicit_abi: bool, true, true, "Always print the abi for extern items";
-    condense_wildcard_suffixes: bool, false, false, "Replace strings of _ wildcards by a single .. \
-                                                     in tuple patterns";
+    merge_derives: MergeDerives, true, "Merge multiple `#[derive(...)]` into a single one";
+    use_try_shorthand: UseTryShorthand, true, "Replace uses of the try! macro by the ? shorthand";
+    use_field_init_shorthand: UseFieldInitShorthand, true, "Use field initialization shorthand if \
+        possible";
+    force_explicit_abi: ForceExplicitAbi, true, "Always print the abi for extern items";
+    condense_wildcard_suffixes: CondenseWildcardSuffixes, false, "Replace strings of _ wildcards \
+        by a single .. in tuple patterns";
 
     // Control options (changes the operation of rustfmt, rather than the formatting)
-    color: Color, Color::Auto, false,
+    color: ColorConfig, false,
         "What Color option to use when none is supplied: Always, Never, Auto";
-    required_version: String, env!("CARGO_PKG_VERSION").to_owned(), false,
+    required_version: RequiredVersion, false,
         "Require a specific version of rustfmt";
-    unstable_features: bool, false, false,
+    unstable_features: UnstableFeatures, false,
             "Enables unstable features. Only available on nightly channel";
-    disable_all_formatting: bool, false, true, "Don't reformat anything";
-    skip_children: bool, false, false, "Don't reformat out of line modules";
-    hide_parse_errors: bool, false, false, "(deprecated: use show_parse_errors instead)";
-    show_parse_errors: bool, true, false, "Show errors from the parser (unstable)";
-    error_on_line_overflow: bool, false, false, "Error if unable to get all lines within max_width";
-    error_on_unformatted: bool, false, false,
+    disable_all_formatting: DisableAllFormatting, true, "Don't reformat anything";
+    skip_children: SkipChildren, false, "Don't reformat out of line modules";
+    hide_parse_errors: HideParseErrors, false, "Hide errors from the parser";
+    show_parse_errors: ShowParseErrors, false, "Show errors from the parser (unstable)";
+    error_on_line_overflow: ErrorOnLineOverflow, false, "Error if unable to get all lines within \
+        max_width";
+    error_on_unformatted: ErrorOnUnformatted, false,
         "Error if unable to get comments or string literals within max_width, \
          or they are left with trailing whitespaces";
-    ignore: IgnoreList, IgnoreList::default(), false,
+    ignore: Ignore, false,
         "Skip formatting the specified files and directories";
 
     // Not user-facing
-    verbose: Verbosity, Verbosity::Normal, false, "How much to information to emit to the user";
-    file_lines: FileLines, FileLines::all(), false,
+    verbose: Verbose, false, "How much to information to emit to the user";
+    file_lines: FileLinesConfig, false,
         "Lines to format; this is not supported in rustfmt.toml, and can only be specified \
          via the --file-lines option";
-    emit_mode: EmitMode, EmitMode::Files, false,
+    emit_mode: EmitModeConfig, false,
         "What emit Mode to use when none is supplied";
-    make_backup: bool, false, false, "Backup changed files";
-    print_misformatted_file_names: bool, false, true,
+    make_backup: MakeBackup, false, "Backup changed files";
+    print_misformatted_file_names: PrintMisformattedFileNames, true,
         "Prints the names of mismatched files that were formatted. Prints the names of \
          files that would be formatted when used with `--check` mode. ";
 }
@@ -211,9 +217,48 @@ impl PartialConfig {
 
         ::toml::to_string(&cloned).map_err(ToTomlError)
     }
+
+    pub(super) fn to_parsed_config(
+        self,
+        style_edition_override: Option<StyleEdition>,
+        edition_override: Option<Edition>,
+        version_override: Option<Version>,
+        dir: &Path,
+    ) -> Config {
+        Config::default_for_possible_style_edition(
+            style_edition_override.or(self.style_edition),
+            edition_override.or(self.edition),
+            version_override.or(self.version),
+        )
+        .fill_from_parsed_config(self, dir)
+    }
 }
 
 impl Config {
+    pub fn default_for_possible_style_edition(
+        style_edition: Option<StyleEdition>,
+        edition: Option<Edition>,
+        version: Option<Version>,
+    ) -> Config {
+        // Ensures the configuration defaults associated with Style Editions
+        // follow the precedence set in
+        // https://rust-lang.github.io/rfcs/3338-style-evolution.html
+        // 'version' is a legacy alias for 'style_edition' that we'll support
+        // for some period of time
+        // FIXME(calebcartwright) - remove 'version' at some point
+        match (style_edition, version, edition) {
+            (Some(se), _, _) => Self::default_with_style_edition(se),
+            (None, Some(Version::Two), _) => {
+                Self::default_with_style_edition(StyleEdition::Edition2024)
+            }
+            (None, Some(Version::One), _) => {
+                Self::default_with_style_edition(StyleEdition::Edition2015)
+            }
+            (None, None, Some(e)) => Self::default_with_style_edition(e.into()),
+            (None, None, None) => Config::default(),
+        }
+    }
+
     pub(crate) fn version_meets_requirement(&self) -> bool {
         if self.was_set().required_version() {
             let version = env!("CARGO_PKG_VERSION");
@@ -237,11 +282,16 @@ impl Config {
     ///
     /// Returns a `Config` if the config could be read and parsed from
     /// the file, otherwise errors.
-    pub(super) fn from_toml_path(file_path: &Path) -> Result<Config, Error> {
+    pub(super) fn from_toml_path(
+        file_path: &Path,
+        edition: Option<Edition>,
+        style_edition: Option<StyleEdition>,
+        version: Option<Version>,
+    ) -> Result<Config, Error> {
         let mut file = File::open(&file_path)?;
         let mut toml = String::new();
         file.read_to_string(&mut toml)?;
-        Config::from_toml(&toml, file_path.parent().unwrap())
+        Config::from_toml_for_style_edition(&toml, file_path, edition, style_edition, version)
             .map_err(|err| Error::new(ErrorKind::InvalidData, err))
     }
 
@@ -254,9 +304,14 @@ impl Config {
     ///
     /// Returns the `Config` to use, and the path of the project file if there was
     /// one.
-    pub(super) fn from_resolved_toml_path(dir: &Path) -> Result<(Config, Option<PathBuf>), Error> {
+    pub(super) fn from_resolved_toml_path(
+        dir: &Path,
+        edition: Option<Edition>,
+        style_edition: Option<StyleEdition>,
+        version: Option<Version>,
+    ) -> Result<(Config, Option<PathBuf>), Error> {
         /// Try to find a project file in the given directory and its parents.
-        /// Returns the path of a the nearest project file if one exists,
+        /// Returns the path of the nearest project file if one exists,
         /// or `None` if no project file was found.
         fn resolve_project_file(dir: &Path) -> Result<Option<PathBuf>, Error> {
             let mut current = if dir.is_relative() {
@@ -299,12 +354,27 @@ impl Config {
         }
 
         match resolve_project_file(dir)? {
-            None => Ok((Config::default(), None)),
-            Some(path) => Config::from_toml_path(&path).map(|config| (config, Some(path))),
+            None => Ok((
+                Config::default_for_possible_style_edition(style_edition, edition, version),
+                None,
+            )),
+            Some(path) => Config::from_toml_path(&path, edition, style_edition, version)
+                .map(|config| (config, Some(path))),
         }
     }
 
-    pub(crate) fn from_toml(toml: &str, dir: &Path) -> Result<Config, String> {
+    #[allow(dead_code)]
+    pub(super) fn from_toml(toml: &str, file_path: &Path) -> Result<Config, String> {
+        Self::from_toml_for_style_edition(toml, file_path, None, None, None)
+    }
+
+    pub(crate) fn from_toml_for_style_edition(
+        toml: &str,
+        file_path: &Path,
+        edition: Option<Edition>,
+        style_edition: Option<StyleEdition>,
+        version: Option<Version>,
+    ) -> Result<Config, String> {
         let parsed: ::toml::Value = toml
             .parse()
             .map_err(|e| format!("Could not parse TOML: {}", e))?;
@@ -318,18 +388,25 @@ impl Config {
                 err.push_str(msg)
             }
         }
-        match parsed.try_into() {
+
+        match parsed.try_into::<PartialConfig>() {
             Ok(parsed_config) => {
                 if !err.is_empty() {
                     eprint!("{err}");
                 }
-                Ok(Config::default().fill_from_parsed_config(parsed_config, dir))
+                let dir = file_path.parent().ok_or_else(|| {
+                    format!("failed to get parent directory for {}", file_path.display())
+                })?;
+
+                Ok(parsed_config.to_parsed_config(style_edition, edition, version, dir))
             }
             Err(e) => {
-                err.push_str("Error: Decoding config file failed:\n");
-                err.push_str(format!("{e}\n").as_str());
-                err.push_str("Please check your config file.");
-                Err(err)
+                let err_msg = format!(
+                    "The file `{}` failed to parse.\nError details: {e}",
+                    file_path.display()
+                );
+                err.push_str(&err_msg);
+                Err(err_msg)
             }
         }
     }
@@ -341,17 +418,26 @@ pub fn load_config<O: CliOptions>(
     file_path: Option<&Path>,
     options: Option<O>,
 ) -> Result<(Config, Option<PathBuf>), Error> {
-    let over_ride = match options {
-        Some(ref opts) => config_path(opts)?,
-        None => None,
+    let (over_ride, edition, style_edition, version) = match options {
+        Some(ref opts) => (
+            config_path(opts)?,
+            opts.edition(),
+            opts.style_edition(),
+            opts.version(),
+        ),
+        None => (None, None, None, None),
     };
 
     let result = if let Some(over_ride) = over_ride {
-        Config::from_toml_path(over_ride.as_ref()).map(|p| (p, Some(over_ride.to_owned())))
+        Config::from_toml_path(over_ride.as_ref(), edition, style_edition, version)
+            .map(|p| (p, Some(over_ride.to_owned())))
     } else if let Some(file_path) = file_path {
-        Config::from_resolved_toml_path(file_path)
+        Config::from_resolved_toml_path(file_path, edition, style_edition, version)
     } else {
-        Ok((Config::default(), None))
+        Ok((
+            Config::default_for_possible_style_edition(style_edition, edition, version),
+            None,
+        ))
     };
 
     result.map(|(mut c, p)| {
@@ -362,7 +448,7 @@ pub fn load_config<O: CliOptions>(
     })
 }
 
-// Check for the presence of known config file names (`rustfmt.toml, `.rustfmt.toml`) in `dir`
+// Check for the presence of known config file names (`rustfmt.toml`, `.rustfmt.toml`) in `dir`
 //
 // Return the path if a config file exists, empty if no file exists, and Error for IO errors
 fn get_toml_path(dir: &Path) -> Result<Option<PathBuf>, Error> {
@@ -372,7 +458,7 @@ fn get_toml_path(dir: &Path) -> Result<Option<PathBuf>, Error> {
         match fs::metadata(&config_file) {
             // Only return if it's a file to handle the unlikely situation of a directory named
             // `rustfmt.toml`.
-            Ok(ref md) if md.is_file() => return Ok(Some(config_file)),
+            Ok(ref md) if md.is_file() => return Ok(Some(config_file.canonicalize()?)),
             // Return the error if it's something other than `NotFound`; otherwise we didn't
             // find the project file yet, and continue searching.
             Err(e) => {
@@ -411,7 +497,11 @@ fn config_path(options: &dyn CliOptions) -> Result<Option<PathBuf>, Error> {
                 config_path_not_found(path.to_str().unwrap())
             }
         }
-        path => Ok(path.map(ToOwned::to_owned)),
+        Some(path) => Ok(Some(
+            // Canonicalize only after checking above that the `path.exists()`.
+            path.canonicalize()?,
+        )),
+        None => Ok(None),
     }
 }
 
@@ -420,12 +510,13 @@ mod test {
     use super::*;
     use std::str;
 
-    use crate::config::macro_names::MacroName;
+    use crate::config::macro_names::{MacroName, MacroSelectors};
     use rustfmt_config_proc_macro::{nightly_only_test, stable_only_test};
 
     #[allow(dead_code)]
     mod mock {
         use super::super::*;
+        use crate::config_option_with_style_edition_default;
         use rustfmt_config_proc_macro::config_type;
 
         #[config_type]
@@ -436,66 +527,69 @@ mod test {
             V3,
         }
 
+        config_option_with_style_edition_default!(
+            StableOption, bool, _ => false;
+            UnstableOption, bool, _ => false;
+            PartiallyUnstable, PartiallyUnstableOption, _ => PartiallyUnstableOption::V1;
+        );
+
         create_config! {
             // Options that are used by the generated functions
-            max_width: usize, 100, true, "Maximum width of each line";
-            required_version: String, env!("CARGO_PKG_VERSION").to_owned(), false,
-                "Require a specific version of rustfmt.";
-            ignore: IgnoreList, IgnoreList::default(), false,
-                "Skip formatting the specified files and directories.";
-            verbose: Verbosity, Verbosity::Normal, false,
-                "How much to information to emit to the user";
-            file_lines: FileLines, FileLines::all(), false,
+            max_width: MaxWidth, true, "Maximum width of each line";
+            required_version: RequiredVersion, false, "Require a specific version of rustfmt.";
+            ignore: Ignore, false, "Skip formatting the specified files and directories.";
+            verbose: Verbose, false, "How much to information to emit to the user";
+            file_lines: FileLinesConfig, false,
                 "Lines to format; this is not supported in rustfmt.toml, and can only be specified \
                     via the --file-lines option";
 
             // merge_imports deprecation
-            imports_granularity: ImportGranularity, ImportGranularity::Preserve, false,
-                "Merge imports";
-            merge_imports: bool, false, false, "(deprecated: use imports_granularity instead)";
+            imports_granularity: ImportsGranularityConfig, false, "Merge imports";
+            merge_imports: MergeImports, false, "(deprecated: use imports_granularity instead)";
 
             // fn_args_layout renamed to fn_params_layout
-            fn_args_layout: Density, Density::Tall, true,
-                "(deprecated: use fn_params_layout instead)";
-            fn_params_layout: Density, Density::Tall, true,
+            fn_args_layout: FnArgsLayout, true, "(deprecated: use fn_params_layout instead)";
+            fn_params_layout: FnParamsLayout, true,
                 "Control the layout of parameters in a function signatures.";
 
             // hide_parse_errors renamed to show_parse_errors
-            hide_parse_errors: bool, false, false,
+            hide_parse_errors: HideParseErrors, false,
                 "(deprecated: use show_parse_errors instead)";
-            show_parse_errors: bool, true, false,
+            show_parse_errors: ShowParseErrors, false,
                 "Show errors from the parser (unstable)";
 
 
             // Width Heuristics
-            use_small_heuristics: Heuristics, Heuristics::Default, true,
+            use_small_heuristics: UseSmallHeuristics, true,
                 "Whether to use different formatting for items and \
                  expressions if they satisfy a heuristic notion of 'small'.";
-            width_heuristics: WidthHeuristics, WidthHeuristics::scaled(100), false,
-                "'small' heuristic values";
+            width_heuristics: WidthHeuristicsConfig, false, "'small' heuristic values";
 
-            fn_call_width: usize, 60, true, "Maximum width of the args of a function call before \
+            fn_call_width: FnCallWidth, true, "Maximum width of the args of a function call before \
                 falling back to vertical formatting.";
-            attr_fn_like_width: usize, 70, true, "Maximum width of the args of a function-like \
-                attributes before falling back to vertical formatting.";
-            struct_lit_width: usize, 18, true, "Maximum width in the body of a struct lit before \
-                falling back to vertical formatting.";
-            struct_variant_width: usize, 35, true, "Maximum width in the body of a struct \
+            attr_fn_like_width: AttrFnLikeWidth, true, "Maximum width of the args of a \
+                function-like attributes before falling back to vertical formatting.";
+            struct_lit_width: StructLitWidth, true, "Maximum width in the body of a struct lit \
+                before falling back to vertical formatting.";
+            struct_variant_width: StructVariantWidth, true, "Maximum width in the body of a struct \
                 variant before falling back to vertical formatting.";
-            array_width: usize, 60, true,  "Maximum width of an array literal before falling \
+            array_width: ArrayWidth, true,  "Maximum width of an array literal before falling \
                 back to vertical formatting.";
-            chain_width: usize, 60, true, "Maximum length of a chain to fit on a single line.";
-            single_line_if_else_max_width: usize, 50, true, "Maximum line length for single \
-                line if-else expressions. A value of zero means always break if-else expressions.";
-            single_line_let_else_max_width: usize, 50, false, "Maximum line length for single \
-                line let-else statements. A value of zero means always format the divergent \
-                `else` block over multiple lines.";
+            chain_width: ChainWidth, true, "Maximum length of a chain to fit on a single line.";
+            single_line_if_else_max_width: SingleLineIfElseMaxWidth, true, "Maximum line length \
+                for single line if-else expressions. A value of zero means always break if-else \
+                expressions.";
+            single_line_let_else_max_width: SingleLineLetElseMaxWidth, false, "Maximum line length \
+                for single line let-else statements. A value of zero means always format the \
+                divergent `else` block over multiple lines.";
 
             // Options that are used by the tests
-            stable_option: bool, false, true, "A stable option";
-            unstable_option: bool, false, false, "An unstable option";
-            partially_unstable_option: PartiallyUnstableOption, PartiallyUnstableOption::V1, true,
-                "A partially unstable option";
+            stable_option: StableOption, true, "A stable option";
+            unstable_option: UnstableOption, false, "An unstable option";
+            partially_unstable_option: PartiallyUnstable, true, "A partially unstable option";
+            edition: EditionConfig, true, "blah";
+            style_edition: StyleEditionConfig, true, "blah";
+            version: VersionConfig, false, "blah blah"
         }
 
         #[cfg(test)]
@@ -580,7 +674,7 @@ mod test {
 
     #[test]
     fn test_was_set() {
-        let config = Config::from_toml("hard_tabs = true", Path::new("")).unwrap();
+        let config = Config::from_toml("hard_tabs = true", Path::new("./rustfmt.toml")).unwrap();
 
         assert_eq!(config.was_set().hard_tabs(), true);
         assert_eq!(config.was_set().verbose(), false);
@@ -679,6 +773,7 @@ match_block_trailing_comma = false
 blank_lines_upper_bound = 1
 blank_lines_lower_bound = 0
 edition = "2015"
+style_edition = "2015"
 version = "One"
 inline_attribute_width = 0
 format_generated_files = true
@@ -706,6 +801,114 @@ make_backup = false
         assert_eq!(&toml, &default_config);
     }
 
+    #[test]
+    fn test_dump_style_edition_2024_config() {
+        let edition_2024_config = format!(
+            r#"max_width = 100
+hard_tabs = false
+tab_spaces = 4
+newline_style = "Auto"
+indent_style = "Block"
+use_small_heuristics = "Default"
+fn_call_width = 60
+attr_fn_like_width = 70
+struct_lit_width = 18
+struct_variant_width = 35
+array_width = 60
+chain_width = 60
+single_line_if_else_max_width = 50
+single_line_let_else_max_width = 50
+wrap_comments = false
+format_code_in_doc_comments = false
+doc_comment_code_block_width = 100
+comment_width = 80
+normalize_comments = false
+normalize_doc_attributes = false
+format_strings = false
+format_macro_matchers = false
+format_macro_bodies = true
+skip_macro_invocations = []
+hex_literal_case = "Preserve"
+empty_item_single_line = true
+struct_lit_single_line = true
+fn_single_line = false
+where_single_line = false
+imports_indent = "Block"
+imports_layout = "Mixed"
+imports_granularity = "Preserve"
+group_imports = "Preserve"
+reorder_imports = true
+reorder_modules = true
+reorder_impl_items = false
+type_punctuation_density = "Wide"
+space_before_colon = false
+space_after_colon = true
+spaces_around_ranges = false
+binop_separator = "Front"
+remove_nested_parens = true
+combine_control_expr = true
+short_array_element_width_threshold = 10
+overflow_delimited_expr = true
+struct_field_align_threshold = 0
+enum_discrim_align_threshold = 0
+match_arm_blocks = true
+match_arm_leading_pipes = "Never"
+force_multiline_blocks = false
+fn_params_layout = "Tall"
+brace_style = "SameLineWhere"
+control_brace_style = "AlwaysSameLine"
+trailing_semicolon = true
+trailing_comma = "Vertical"
+match_block_trailing_comma = false
+blank_lines_upper_bound = 1
+blank_lines_lower_bound = 0
+edition = "2015"
+style_edition = "2024"
+version = "Two"
+inline_attribute_width = 0
+format_generated_files = true
+generated_marker_line_search_limit = 5
+merge_derives = true
+use_try_shorthand = false
+use_field_init_shorthand = false
+force_explicit_abi = true
+condense_wildcard_suffixes = false
+color = "Auto"
+required_version = "{}"
+unstable_features = false
+disable_all_formatting = false
+skip_children = false
+show_parse_errors = true
+error_on_line_overflow = false
+error_on_unformatted = false
+ignore = []
+emit_mode = "Files"
+make_backup = false
+"#,
+            env!("CARGO_PKG_VERSION")
+        );
+        let toml = Config::default_with_style_edition(StyleEdition::Edition2024)
+            .all_options()
+            .to_toml()
+            .unwrap();
+        assert_eq!(&toml, &edition_2024_config);
+    }
+
+    #[test]
+    fn test_editions_2015_2018_2021_identical() {
+        let get_edition_toml = |style_edition: StyleEdition| {
+            Config::default_with_style_edition(style_edition)
+                .all_options()
+                .to_toml()
+                .unwrap()
+        };
+        let edition2015 = get_edition_toml(StyleEdition::Edition2015);
+        let edition2018 = get_edition_toml(StyleEdition::Edition2018);
+        let edition2021 = get_edition_toml(StyleEdition::Edition2021);
+        assert_eq!(edition2015, edition2018);
+        assert_eq!(edition2018, edition2021);
+    }
+
     #[stable_only_test]
     #[test]
     fn test_as_not_nightly_channel() {
@@ -730,11 +933,26 @@ make_backup = false
     #[nightly_only_test]
     #[test]
     fn test_unstable_from_toml() {
-        let config = Config::from_toml("unstable_features = true", Path::new("")).unwrap();
+        let config =
+            Config::from_toml("unstable_features = true", Path::new("./rustfmt.toml")).unwrap();
         assert_eq!(config.was_set().unstable_features(), true);
         assert_eq!(config.unstable_features(), true);
     }
 
+    #[test]
+    fn test_set_cli() {
+        let mut config = Config::default();
+        assert_eq!(config.was_set().edition(), false);
+        assert_eq!(config.was_set_cli().edition(), false);
+        config.set().edition(Edition::Edition2021);
+        assert_eq!(config.was_set().edition(), false);
+        assert_eq!(config.was_set_cli().edition(), false);
+        config.set_cli().edition(Edition::Edition2021);
+        assert_eq!(config.was_set().edition(), false);
+        assert_eq!(config.was_set_cli().edition(), true);
+        assert_eq!(config.was_set_cli().emit_mode(), false);
+    }
+
     #[cfg(test)]
     mod deprecated_option_merge_imports {
         use super::*;
@@ -746,7 +964,7 @@ make_backup = false
                 unstable_features = true
                 merge_imports = true
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             assert_eq!(config.imports_granularity(), ImportGranularity::Crate);
         }
 
@@ -758,7 +976,7 @@ make_backup = false
                 merge_imports = true
                 imports_granularity = "Preserve"
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             assert_eq!(config.imports_granularity(), ImportGranularity::Preserve);
         }
 
@@ -769,7 +987,7 @@ make_backup = false
                 unstable_features = true
                 merge_imports = true
             "#;
-            let mut config = Config::from_toml(toml, Path::new("")).unwrap();
+            let mut config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             config.override_value("imports_granularity", "Preserve");
             assert_eq!(config.imports_granularity(), ImportGranularity::Preserve);
         }
@@ -781,7 +999,7 @@ make_backup = false
                 unstable_features = true
                 imports_granularity = "Module"
             "#;
-            let mut config = Config::from_toml(toml, Path::new("")).unwrap();
+            let mut config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             config.override_value("merge_imports", "true");
             // no effect: the new option always takes precedence
             assert_eq!(config.imports_granularity(), ImportGranularity::Module);
@@ -798,7 +1016,7 @@ make_backup = false
                 use_small_heuristics = "Default"
                 max_width = 200
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             assert_eq!(config.array_width(), 120);
             assert_eq!(config.attr_fn_like_width(), 140);
             assert_eq!(config.chain_width(), 120);
@@ -814,7 +1032,7 @@ make_backup = false
                 use_small_heuristics = "Max"
                 max_width = 120
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             assert_eq!(config.array_width(), 120);
             assert_eq!(config.attr_fn_like_width(), 120);
             assert_eq!(config.chain_width(), 120);
@@ -830,11 +1048,11 @@ make_backup = false
                 use_small_heuristics = "Off"
                 max_width = 100
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
-            assert_eq!(config.array_width(), usize::max_value());
-            assert_eq!(config.attr_fn_like_width(), usize::max_value());
-            assert_eq!(config.chain_width(), usize::max_value());
-            assert_eq!(config.fn_call_width(), usize::max_value());
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
+            assert_eq!(config.array_width(), usize::MAX);
+            assert_eq!(config.attr_fn_like_width(), usize::MAX);
+            assert_eq!(config.chain_width(), usize::MAX);
+            assert_eq!(config.fn_call_width(), usize::MAX);
             assert_eq!(config.single_line_if_else_max_width(), 0);
             assert_eq!(config.struct_lit_width(), 0);
             assert_eq!(config.struct_variant_width(), 0);
@@ -852,7 +1070,7 @@ make_backup = false
                 struct_lit_width = 30
                 struct_variant_width = 34
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             assert_eq!(config.array_width(), 20);
             assert_eq!(config.attr_fn_like_width(), 40);
             assert_eq!(config.chain_width(), 20);
@@ -874,7 +1092,7 @@ make_backup = false
                 struct_lit_width = 30
                 struct_variant_width = 34
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             assert_eq!(config.array_width(), 20);
             assert_eq!(config.attr_fn_like_width(), 40);
             assert_eq!(config.chain_width(), 20);
@@ -896,7 +1114,7 @@ make_backup = false
                 struct_lit_width = 30
                 struct_variant_width = 34
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             assert_eq!(config.array_width(), 20);
             assert_eq!(config.attr_fn_like_width(), 40);
             assert_eq!(config.chain_width(), 20);
@@ -912,7 +1130,7 @@ make_backup = false
                 max_width = 90
                 fn_call_width = 95
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             assert_eq!(config.fn_call_width(), 90);
         }
 
@@ -922,7 +1140,7 @@ make_backup = false
                 max_width = 80
                 attr_fn_like_width = 90
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             assert_eq!(config.attr_fn_like_width(), 80);
         }
 
@@ -932,7 +1150,7 @@ make_backup = false
                 max_width = 78
                 struct_lit_width = 90
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             assert_eq!(config.struct_lit_width(), 78);
         }
 
@@ -942,7 +1160,7 @@ make_backup = false
                 max_width = 80
                 struct_variant_width = 90
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             assert_eq!(config.struct_variant_width(), 80);
         }
 
@@ -952,7 +1170,7 @@ make_backup = false
                 max_width = 60
                 array_width = 80
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             assert_eq!(config.array_width(), 60);
         }
 
@@ -962,7 +1180,7 @@ make_backup = false
                 max_width = 80
                 chain_width = 90
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             assert_eq!(config.chain_width(), 80);
         }
 
@@ -972,7 +1190,7 @@ make_backup = false
                 max_width = 70
                 single_line_if_else_max_width = 90
             "#;
-            let config = Config::from_toml(toml, Path::new("")).unwrap();
+            let config = Config::from_toml(toml, Path::new("./rustfmt.toml")).unwrap();
             assert_eq!(config.single_line_if_else_max_width(), 70);
         }
 
diff --git a/src/tools/rustfmt/src/config/options.rs b/src/tools/rustfmt/src/config/options.rs
index 3c5c713a33a..c526b5c678f 100644
--- a/src/tools/rustfmt/src/config/options.rs
+++ b/src/tools/rustfmt/src/config/options.rs
@@ -1,6 +1,6 @@
 #![allow(unused_imports)]
 
-use std::collections::{hash_set, HashSet};
+use std::collections::{HashSet, hash_set};
 use std::fmt;
 use std::path::{Path, PathBuf};
 use std::str::FromStr;
@@ -11,8 +11,10 @@ use serde::de::{SeqAccess, Visitor};
 use serde::ser::SerializeSeq;
 use serde::{Deserialize, Deserializer, Serialize, Serializer};
 
-use crate::config::lists::*;
 use crate::config::Config;
+use crate::config::file_lines::FileLines;
+use crate::config::lists::*;
+use crate::config::macro_names::MacroSelectors;
 
 #[config_type]
 pub enum NewlineStyle {
@@ -253,12 +255,12 @@ impl WidthHeuristics {
     // Using this WidthHeuristics means we ignore heuristics.
     pub fn null() -> WidthHeuristics {
         WidthHeuristics {
-            fn_call_width: usize::max_value(),
-            attr_fn_like_width: usize::max_value(),
+            fn_call_width: usize::MAX,
+            attr_fn_like_width: usize::MAX,
             struct_lit_width: 0,
             struct_variant_width: 0,
-            array_width: usize::max_value(),
-            chain_width: usize::max_value(),
+            array_width: usize::MAX,
+            chain_width: usize::MAX,
             single_line_if_else_max_width: 0,
             single_line_let_else_max_width: 0,
         }
@@ -413,7 +415,13 @@ impl FromStr for IgnoreList {
 /// values in a config with values from the command line.
 pub trait CliOptions {
     fn apply_to(self, config: &mut Config);
+
+    /// It is ok if the returned path doesn't exist or is not canonicalized
+    /// (i.e. the callers are expected to handle such cases).
     fn config_path(&self) -> Option<&Path>;
+    fn edition(&self) -> Option<Edition>;
+    fn style_edition(&self) -> Option<StyleEdition>;
+    fn version(&self) -> Option<Version>;
 }
 
 /// The edition of the syntax and semantics of code (RFC 2052).
@@ -454,6 +462,17 @@ impl From<Edition> for rustc_span::edition::Edition {
     }
 }
 
+impl From<Edition> for StyleEdition {
+    fn from(edition: Edition) -> Self {
+        match edition {
+            Edition::Edition2015 => StyleEdition::Edition2015,
+            Edition::Edition2018 => StyleEdition::Edition2018,
+            Edition::Edition2021 => StyleEdition::Edition2021,
+            Edition::Edition2024 => StyleEdition::Edition2024,
+        }
+    }
+}
+
 impl PartialOrd for Edition {
     fn partial_cmp(&self, other: &Edition) -> Option<std::cmp::Ordering> {
         rustc_span::edition::Edition::partial_cmp(&(*self).into(), &(*other).into())
@@ -471,10 +490,11 @@ pub enum MatchArmLeadingPipe {
     Preserve,
 }
 
-/// Defines the default values for each config according to [the style guide].
-/// rustfmt output may differ between style editions.
+/// Defines the default values for each config according to the edition of the
+/// [Style Guide] as per [RFC 3338]. Rustfmt output may differ between Style editions.
 ///
-/// [the style guide]: https://doc.rust-lang.org/nightly/style-guide/
+/// [Style Guide]: https://doc.rust-lang.org/nightly/style-guide/
+/// [RFC 3338]: https://rust-lang.github.io/rfcs/3338-style-evolution.html
 #[config_type]
 pub enum StyleEdition {
     #[value = "2015"]
@@ -491,6 +511,169 @@ pub enum StyleEdition {
     Edition2021,
     #[value = "2024"]
     #[doc_hint = "2024"]
+    #[unstable_variant]
     /// [Edition 2024]().
     Edition2024,
 }
+
+impl From<StyleEdition> for rustc_span::edition::Edition {
+    fn from(edition: StyleEdition) -> Self {
+        match edition {
+            StyleEdition::Edition2015 => Self::Edition2015,
+            StyleEdition::Edition2018 => Self::Edition2018,
+            StyleEdition::Edition2021 => Self::Edition2021,
+            StyleEdition::Edition2024 => Self::Edition2024,
+        }
+    }
+}
+
+impl PartialOrd for StyleEdition {
+    fn partial_cmp(&self, other: &StyleEdition) -> Option<std::cmp::Ordering> {
+        rustc_span::edition::Edition::partial_cmp(&(*self).into(), &(*other).into())
+    }
+}
+
+/// Defines unit structs to implement `StyleEditionDefault` for.
+#[macro_export]
+macro_rules! config_option_with_style_edition_default {
+    ($name:ident, $config_ty:ty, _ => $default:expr) => {
+        #[allow(unreachable_pub)]
+        pub struct $name;
+        $crate::style_edition_default!($name, $config_ty, _ => $default);
+    };
+    ($name:ident, $config_ty:ty, Edition2024 => $default_2024:expr, _ => $default_2015:expr) => {
+        pub struct $name;
+        $crate::style_edition_default!(
+            $name,
+            $config_ty,
+            Edition2024 => $default_2024,
+            _ => $default_2015
+        );
+    };
+    (
+        $($name:ident, $config_ty:ty, $(Edition2024 => $default_2024:expr,)? _ => $default:expr);*
+        $(;)*
+    ) => {
+        $(
+            config_option_with_style_edition_default!(
+                $name, $config_ty, $(Edition2024 => $default_2024,)? _ => $default
+            );
+        )*
+    };
+}
+
+// TODO(ytmimi) Some of the configuration values have a `Config` suffix, while others don't.
+// I chose to add a `Config` suffix in cases where a type for the config option was already
+// defined. For example, `NewlineStyle` and `NewlineStyleConfig`. There was some discussion
+// about using the `Config` suffix more consistently.
+config_option_with_style_edition_default!(
+    // Fundamental stuff
+    MaxWidth, usize, _ => 100;
+    HardTabs, bool, _ => false;
+    TabSpaces, usize, _ => 4;
+    NewlineStyleConfig, NewlineStyle, _ => NewlineStyle::Auto;
+    IndentStyleConfig, IndentStyle, _ => IndentStyle::Block;
+
+    // Width Heuristics
+    UseSmallHeuristics, Heuristics, _ => Heuristics::Default;
+    WidthHeuristicsConfig, WidthHeuristics, _ => WidthHeuristics::scaled(100);
+    FnCallWidth, usize, _ => 60;
+    AttrFnLikeWidth, usize, _ => 70;
+    StructLitWidth, usize, _ => 18;
+    StructVariantWidth, usize, _ => 35;
+    ArrayWidth, usize, _ => 60;
+    ChainWidth, usize, _ => 60;
+    SingleLineIfElseMaxWidth, usize, _ => 50;
+    SingleLineLetElseMaxWidth, usize, _ => 50;
+
+    // Comments. macros, and strings
+    WrapComments, bool, _ => false;
+    FormatCodeInDocComments, bool, _ => false;
+    DocCommentCodeBlockWidth, usize, _ => 100;
+    CommentWidth, usize, _ => 80;
+    NormalizeComments, bool, _ => false;
+    NormalizeDocAttributes, bool, _ => false;
+    FormatStrings, bool, _ => false;
+    FormatMacroMatchers, bool, _ => false;
+    FormatMacroBodies, bool, _ => true;
+    SkipMacroInvocations, MacroSelectors, _ => MacroSelectors::default();
+    HexLiteralCaseConfig, HexLiteralCase, _ => HexLiteralCase::Preserve;
+
+    // Single line expressions and items
+    EmptyItemSingleLine, bool, _ => true;
+    StructLitSingleLine, bool, _ => true;
+    FnSingleLine, bool, _ => false;
+    WhereSingleLine, bool, _ => false;
+
+    // Imports
+    ImportsIndent, IndentStyle, _ => IndentStyle::Block;
+    ImportsLayout, ListTactic, _ => ListTactic::Mixed;
+    ImportsGranularityConfig, ImportGranularity, _ => ImportGranularity::Preserve;
+    GroupImportsTacticConfig, GroupImportsTactic, _ => GroupImportsTactic::Preserve;
+    MergeImports, bool, _ => false;
+
+    // Ordering
+    ReorderImports, bool, _ => true;
+    ReorderModules, bool, _ => true;
+    ReorderImplItems, bool, _ => false;
+
+    // Spaces around punctuation
+    TypePunctuationDensity, TypeDensity, _ => TypeDensity::Wide;
+    SpaceBeforeColon, bool, _ => false;
+    SpaceAfterColon, bool, _ => true;
+    SpacesAroundRanges, bool, _ => false;
+    BinopSeparator, SeparatorPlace, _ => SeparatorPlace::Front;
+
+    // Misc.
+    RemoveNestedParens, bool, _ => true;
+    CombineControlExpr, bool, _ => true;
+    ShortArrayElementWidthThreshold, usize, _ => 10;
+    OverflowDelimitedExpr, bool, Edition2024 => true, _ => false;
+    StructFieldAlignThreshold, usize, _ => 0;
+    EnumDiscrimAlignThreshold, usize, _ => 0;
+    MatchArmBlocks, bool, _ => true;
+    MatchArmLeadingPipeConfig, MatchArmLeadingPipe, _ => MatchArmLeadingPipe::Never;
+    ForceMultilineBlocks, bool, _ => false;
+    FnArgsLayout, Density, _ => Density::Tall;
+    FnParamsLayout, Density, _ => Density::Tall;
+    BraceStyleConfig, BraceStyle, _ => BraceStyle::SameLineWhere;
+    ControlBraceStyleConfig, ControlBraceStyle, _ => ControlBraceStyle::AlwaysSameLine;
+    TrailingSemicolon, bool, _ => true;
+    TrailingComma, SeparatorTactic, _ => SeparatorTactic::Vertical;
+    MatchBlockTrailingComma, bool, _ => false;
+    BlankLinesUpperBound, usize, _ => 1;
+    BlankLinesLowerBound, usize, _ => 0;
+    EditionConfig, Edition, _ => Edition::Edition2015;
+    StyleEditionConfig, StyleEdition,
+        Edition2024 =>  StyleEdition::Edition2024, _ => StyleEdition::Edition2015;
+    VersionConfig, Version, Edition2024 => Version::Two, _ => Version::One;
+    InlineAttributeWidth, usize, _ => 0;
+    FormatGeneratedFiles, bool, _ => true;
+    GeneratedMarkerLineSearchLimit, usize, _ => 5;
+
+    // Options that can change the source code beyond whitespace/blocks (somewhat linty things)
+    MergeDerives, bool, _ => true;
+    UseTryShorthand, bool, _ => false;
+    UseFieldInitShorthand, bool, _ => false;
+    ForceExplicitAbi, bool, _ => true;
+    CondenseWildcardSuffixes, bool, _ => false;
+
+    // Control options (changes the operation of rustfmt, rather than the formatting)
+    ColorConfig, Color, _ => Color::Auto;
+    RequiredVersion, String, _ => env!("CARGO_PKG_VERSION").to_owned();
+    UnstableFeatures, bool, _ => false;
+    DisableAllFormatting, bool, _ => false;
+    SkipChildren, bool, _ => false;
+    HideParseErrors, bool, _ => false;
+    ShowParseErrors, bool, _ => true;
+    ErrorOnLineOverflow, bool, _ => false;
+    ErrorOnUnformatted, bool, _ => false;
+    Ignore, IgnoreList, _ => IgnoreList::default();
+
+    // Not user-facing
+    Verbose, Verbosity, _ => Verbosity::Normal;
+    FileLinesConfig, FileLines, _ => FileLines::all();
+    EmitModeConfig, EmitMode, _ => EmitMode::Files;
+    MakeBackup, bool, _ => false;
+    PrintMisformattedFileNames, bool, _ => false;
+);
diff --git a/src/tools/rustfmt/src/config/style_edition.rs b/src/tools/rustfmt/src/config/style_edition.rs
index 7b3ea3bc119..c34eca9c8e1 100644
--- a/src/tools/rustfmt/src/config/style_edition.rs
+++ b/src/tools/rustfmt/src/config/style_edition.rs
@@ -2,7 +2,7 @@ use crate::config::StyleEdition;
 
 /// Defines the default value for the given style edition
 #[allow(dead_code)]
-pub(crate) trait StyleEditionDefault {
+pub trait StyleEditionDefault {
     type ConfigType;
     fn style_edition_default(style_edition: StyleEdition) -> Self::ConfigType;
 }
diff --git a/src/tools/rustfmt/src/emitter/checkstyle.rs b/src/tools/rustfmt/src/emitter/checkstyle.rs
index 9385ae59a06..c320c16bd1d 100644
--- a/src/tools/rustfmt/src/emitter/checkstyle.rs
+++ b/src/tools/rustfmt/src/emitter/checkstyle.rs
@@ -1,6 +1,6 @@
 use self::xml::XmlEscaped;
 use super::*;
-use crate::rustfmt_diff::{make_diff, DiffLine, Mismatch};
+use crate::rustfmt_diff::{DiffLine, Mismatch, make_diff};
 
 mod xml;
 
diff --git a/src/tools/rustfmt/src/emitter/json.rs b/src/tools/rustfmt/src/emitter/json.rs
index 084f565804c..a99626f783d 100644
--- a/src/tools/rustfmt/src/emitter/json.rs
+++ b/src/tools/rustfmt/src/emitter/json.rs
@@ -1,5 +1,5 @@
 use super::*;
-use crate::rustfmt_diff::{make_diff, DiffLine, Mismatch};
+use crate::rustfmt_diff::{DiffLine, Mismatch, make_diff};
 use serde::Serialize;
 use serde_json::to_string as to_json_string;
 
diff --git a/src/tools/rustfmt/src/emitter/modified_lines.rs b/src/tools/rustfmt/src/emitter/modified_lines.rs
index 81f0a31b974..0d5124bc33e 100644
--- a/src/tools/rustfmt/src/emitter/modified_lines.rs
+++ b/src/tools/rustfmt/src/emitter/modified_lines.rs
@@ -1,5 +1,5 @@
 use super::*;
-use crate::rustfmt_diff::{make_diff, ModifiedLines};
+use crate::rustfmt_diff::{ModifiedLines, make_diff};
 
 #[derive(Debug, Default)]
 pub(crate) struct ModifiedLinesEmitter;
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index 75c75c523b0..77c9818b66b 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -3,33 +3,33 @@ use std::cmp::min;
 
 use itertools::Itertools;
 use rustc_ast::token::{Delimiter, Lit, LitKind};
-use rustc_ast::{ast, ptr, token, ForLoopKind, MatchKind};
+use rustc_ast::{ForLoopKind, MatchKind, ast, ptr, token};
 use rustc_span::{BytePos, Span};
 use tracing::debug;
 
 use crate::chains::rewrite_chain;
 use crate::closures;
 use crate::comment::{
-    combine_strs_with_missing_comments, contains_comment, recover_comment_removed, rewrite_comment,
-    rewrite_missing_comment, CharClasses, FindUncommented,
+    CharClasses, FindUncommented, combine_strs_with_missing_comments, contains_comment,
+    recover_comment_removed, rewrite_comment, rewrite_missing_comment,
 };
 use crate::config::lists::*;
-use crate::config::{Config, ControlBraceStyle, HexLiteralCase, IndentStyle, Version};
+use crate::config::{Config, ControlBraceStyle, HexLiteralCase, IndentStyle, StyleEdition};
 use crate::lists::{
-    definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape,
-    struct_lit_tactic, write_list, ListFormatting, Separator,
+    ListFormatting, Separator, definitive_tactic, itemize_list, shape_for_tactic,
+    struct_lit_formatting, struct_lit_shape, struct_lit_tactic, write_list,
 };
-use crate::macros::{rewrite_macro, MacroPosition};
+use crate::macros::{MacroPosition, rewrite_macro};
 use crate::matches::rewrite_match;
 use crate::overflow::{self, IntoOverflowableItem, OverflowableItem};
-use crate::pairs::{rewrite_all_pairs, rewrite_pair, PairParts};
-use crate::rewrite::{Rewrite, RewriteContext};
+use crate::pairs::{PairParts, rewrite_all_pairs, rewrite_pair};
+use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
 use crate::shape::{Indent, Shape};
 use crate::source_map::{LineRangeUtils, SpanUtils};
 use crate::spanned::Spanned;
 use crate::stmt;
-use crate::string::{rewrite_string, StringFormat};
-use crate::types::{rewrite_path, PathContext};
+use crate::string::{StringFormat, rewrite_string};
+use crate::types::{PathContext, rewrite_path};
 use crate::utils::{
     colon_spaces, contains_skip, count_newlines, filtered_str_fits, first_line_ends_with,
     inner_attributes, last_line_extendable, last_line_width, mk_sp, outer_attributes,
@@ -40,6 +40,10 @@ use crate::visitor::FmtVisitor;
 
 impl Rewrite for ast::Expr {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         format_expr(self, ExprType::SubExpression, context, shape)
     }
 }
@@ -59,14 +63,14 @@ pub(crate) fn format_expr(
     expr_type: ExprType,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
-    skip_out_of_file_lines_range!(context, expr.span);
+) -> RewriteResult {
+    skip_out_of_file_lines_range_err!(context, expr.span);
 
     if contains_skip(&*expr.attrs) {
-        return Some(context.snippet(expr.span()).to_owned());
+        return Ok(context.snippet(expr.span()).to_owned());
     }
     let shape = if expr_type == ExprType::Statement && semicolon_for_expr(context, expr) {
-        shape.sub_width(1)?
+        shape.sub_width(1).max_width_error(shape.width, expr.span)?
     } else {
         shape
     };
@@ -82,25 +86,25 @@ pub(crate) fn format_expr(
             None,
         ),
         ast::ExprKind::Lit(token_lit) => {
-            if let Some(expr_rw) = rewrite_literal(context, token_lit, expr.span, shape) {
-                Some(expr_rw)
+            if let Ok(expr_rw) = rewrite_literal(context, token_lit, expr.span, shape) {
+                Ok(expr_rw)
             } else {
                 if let LitKind::StrRaw(_) = token_lit.kind {
-                    Some(context.snippet(expr.span).trim().into())
+                    Ok(context.snippet(expr.span).trim().into())
                 } else {
-                    None
+                    Err(RewriteError::Unknown)
                 }
             }
         }
         ast::ExprKind::Call(ref callee, ref args) => {
             let inner_span = mk_sp(callee.span.hi(), expr.span.hi());
-            let callee_str = callee.rewrite(context, shape)?;
+            let callee_str = callee.rewrite_result(context, shape)?;
             rewrite_call(context, &callee_str, args, inner_span, shape)
         }
         ast::ExprKind::Paren(ref subexpr) => rewrite_paren(context, subexpr, shape, expr.span),
         ast::ExprKind::Binary(op, ref lhs, ref rhs) => {
             // FIXME: format comments between operands and operator
-            rewrite_all_pairs(expr, shape, context).or_else(|| {
+            rewrite_all_pairs(expr, shape, context).or_else(|_| {
                 rewrite_pair(
                     &**lhs,
                     &**rhs,
@@ -138,7 +142,8 @@ pub(crate) fn format_expr(
         | ast::ExprKind::ForLoop { .. }
         | ast::ExprKind::Loop(..)
         | ast::ExprKind::While(..) => to_control_flow(expr, expr_type)
-            .and_then(|control_flow| control_flow.rewrite(context, shape)),
+            .unknown_error()
+            .and_then(|control_flow| control_flow.rewrite_result(context, shape)),
         ast::ExprKind::ConstBlock(ref anon_const) => {
             let rewrite = match anon_const.value.kind {
                 ast::ExprKind::Block(ref block, opt_label) => {
@@ -148,20 +153,20 @@ pub(crate) fn format_expr(
                     // See https://github.com/rust-lang/rustfmt/issues/6158
                     rewrite_block(block, Some(&expr.attrs), opt_label, context, shape)?
                 }
-                _ => anon_const.rewrite(context, shape)?,
+                _ => anon_const.rewrite_result(context, shape)?,
             };
-            Some(format!("const {}", rewrite))
+            Ok(format!("const {}", rewrite))
         }
         ast::ExprKind::Block(ref block, opt_label) => {
             match expr_type {
                 ExprType::Statement => {
                     if is_unsafe_block(block) {
                         rewrite_block(block, Some(&expr.attrs), opt_label, context, shape)
-                    } else if let rw @ Some(_) =
+                    } else if let Some(rw) =
                         rewrite_empty_block(context, block, Some(&expr.attrs), opt_label, "", shape)
                     {
                         // Rewrite block without trying to put it in a single line.
-                        rw
+                        Ok(rw)
                     } else {
                         let prefix = block_prefix(context, block, shape)?;
 
@@ -198,7 +203,7 @@ pub(crate) fn format_expr(
                 Some(label) => format!(" {}", label.ident),
                 None => String::new(),
             };
-            Some(format!("continue{id_str}"))
+            Ok(format!("continue{id_str}"))
         }
         ast::ExprKind::Break(ref opt_label, ref opt_expr) => {
             let id_str = match *opt_label {
@@ -209,14 +214,14 @@ pub(crate) fn format_expr(
             if let Some(ref expr) = *opt_expr {
                 rewrite_unary_prefix(context, &format!("break{id_str} "), &**expr, shape)
             } else {
-                Some(format!("break{id_str}"))
+                Ok(format!("break{id_str}"))
             }
         }
         ast::ExprKind::Yield(ref opt_expr) => {
             if let Some(ref expr) = *opt_expr {
                 rewrite_unary_prefix(context, "yield ", &**expr, shape)
             } else {
-                Some("yield".to_string())
+                Ok("yield".to_string())
             }
         }
         ast::ExprKind::Closure(ref cl) => closures::rewrite_closure(
@@ -236,20 +241,21 @@ pub(crate) fn format_expr(
         | ast::ExprKind::MethodCall(..)
         | ast::ExprKind::Await(_, _) => rewrite_chain(expr, context, shape),
         ast::ExprKind::MacCall(ref mac) => {
-            rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|| {
+            rewrite_macro(mac, None, context, shape, MacroPosition::Expression).or_else(|_| {
                 wrap_str(
                     context.snippet(expr.span).to_owned(),
                     context.config.max_width(),
                     shape,
                 )
+                .max_width_error(shape.width, expr.span)
             })
         }
-        ast::ExprKind::Ret(None) => Some("return".to_owned()),
+        ast::ExprKind::Ret(None) => Ok("return".to_owned()),
         ast::ExprKind::Ret(Some(ref expr)) => {
             rewrite_unary_prefix(context, "return ", &**expr, shape)
         }
         ast::ExprKind::Become(ref expr) => rewrite_unary_prefix(context, "become ", &**expr, shape),
-        ast::ExprKind::Yeet(None) => Some("do yeet".to_owned()),
+        ast::ExprKind::Yeet(None) => Ok("do yeet".to_owned()),
         ast::ExprKind::Yeet(Some(ref expr)) => {
             rewrite_unary_prefix(context, "do yeet ", &**expr, shape)
         }
@@ -344,23 +350,23 @@ pub(crate) fn format_expr(
                     };
                     rewrite_unary_suffix(context, &sp_delim, &*lhs, shape)
                 }
-                (None, None) => Some(delim.to_owned()),
+                (None, None) => Ok(delim.to_owned()),
             }
         }
         // We do not format these expressions yet, but they should still
         // satisfy our width restrictions.
         // Style Guide RFC for InlineAsm variant pending
         // https://github.com/rust-dev-tools/fmt-rfcs/issues/152
-        ast::ExprKind::InlineAsm(..) => Some(context.snippet(expr.span).to_owned()),
+        ast::ExprKind::InlineAsm(..) => Ok(context.snippet(expr.span).to_owned()),
         ast::ExprKind::TryBlock(ref block) => {
-            if let rw @ Some(_) =
+            if let rw @ Ok(_) =
                 rewrite_single_line_block(context, "try ", block, Some(&expr.attrs), None, shape)
             {
                 rw
             } else {
                 // 9 = `try `
                 let budget = shape.width.saturating_sub(9);
-                Some(format!(
+                Ok(format!(
                     "{}{}",
                     "try ",
                     rewrite_block(
@@ -379,7 +385,7 @@ pub(crate) fn format_expr(
             } else {
                 ""
             };
-            if let rw @ Some(_) = rewrite_single_line_block(
+            if let rw @ Ok(_) = rewrite_single_line_block(
                 context,
                 format!("{kind} {mover}").as_str(),
                 block,
@@ -391,7 +397,7 @@ pub(crate) fn format_expr(
             } else {
                 // 6 = `async `
                 let budget = shape.width.saturating_sub(6);
-                Some(format!(
+                Ok(format!(
                     "{kind} {mover}{}",
                     rewrite_block(
                         block,
@@ -403,7 +409,7 @@ pub(crate) fn format_expr(
                 ))
             }
         }
-        ast::ExprKind::Underscore => Some("_".to_owned()),
+        ast::ExprKind::Underscore => Ok("_".to_owned()),
         ast::ExprKind::FormatArgs(..)
         | ast::ExprKind::Type(..)
         | ast::ExprKind::IncludedBytes(..)
@@ -412,16 +418,16 @@ pub(crate) fn format_expr(
             // rustfmt tries to parse macro arguments when formatting macros, so it's not totally
             // impossible for rustfmt to come across one of these nodes when formatting a file.
             // Also, rustfmt might get passed the output from `-Zunpretty=expanded`.
-            None
+            Err(RewriteError::Unknown)
         }
-        ast::ExprKind::Err(_) | ast::ExprKind::Dummy => None,
+        ast::ExprKind::Err(_) | ast::ExprKind::Dummy => Err(RewriteError::Unknown),
     };
 
     expr_rw
-        .and_then(|expr_str| recover_comment_removed(expr_str, expr.span, context))
+        .map(|expr_str| recover_comment_removed(expr_str, expr.span, context))
         .and_then(|expr_str| {
             let attrs = outer_attributes(&expr.attrs);
-            let attrs_str = attrs.rewrite(context, shape)?;
+            let attrs_str = attrs.rewrite_result(context, shape)?;
             let span = mk_sp(
                 attrs.last().map_or(expr.span.lo(), |attr| attr.span.hi()),
                 expr.span.lo(),
@@ -438,7 +444,7 @@ pub(crate) fn rewrite_array<'a, T: 'a + IntoOverflowableItem<'a>>(
     shape: Shape,
     force_separator_tactic: Option<SeparatorTactic>,
     delim_token: Option<Delimiter>,
-) -> Option<String> {
+) -> RewriteResult {
     overflow::rewrite_with_square_brackets(
         context,
         name,
@@ -488,17 +494,20 @@ fn rewrite_empty_block(
     None
 }
 
-fn block_prefix(context: &RewriteContext<'_>, block: &ast::Block, shape: Shape) -> Option<String> {
-    Some(match block.rules {
+fn block_prefix(context: &RewriteContext<'_>, block: &ast::Block, shape: Shape) -> RewriteResult {
+    Ok(match block.rules {
         ast::BlockCheckMode::Unsafe(..) => {
             let snippet = context.snippet(block.span);
-            let open_pos = snippet.find_uncommented("{")?;
+            let open_pos = snippet.find_uncommented("{").unknown_error()?;
             // Extract comment between unsafe and block start.
             let trimmed = &snippet[6..open_pos].trim();
 
             if !trimmed.is_empty() {
                 // 9 = "unsafe  {".len(), 7 = "unsafe ".len()
-                let budget = shape.width.checked_sub(9)?;
+                let budget = shape
+                    .width
+                    .checked_sub(9)
+                    .max_width_error(shape.width, block.span)?;
                 format!(
                     "unsafe {} ",
                     rewrite_comment(
@@ -523,17 +532,19 @@ fn rewrite_single_line_block(
     attrs: Option<&[ast::Attribute]>,
     label: Option<ast::Label>,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     if let Some(block_expr) = stmt::Stmt::from_simple_block(context, block, attrs) {
-        let expr_shape = shape.offset_left(last_line_width(prefix))?;
-        let expr_str = block_expr.rewrite(context, expr_shape)?;
+        let expr_shape = shape
+            .offset_left(last_line_width(prefix))
+            .max_width_error(shape.width, block_expr.span())?;
+        let expr_str = block_expr.rewrite_result(context, expr_shape)?;
         let label_str = rewrite_label(context, label);
         let result = format!("{prefix}{label_str}{{ {expr_str} }}");
         if result.len() <= shape.width && !result.contains('\n') {
-            return Some(result);
+            return Ok(result);
         }
     }
-    None
+    Err(RewriteError::Unknown)
 }
 
 pub(crate) fn rewrite_block_with_visitor(
@@ -544,9 +555,9 @@ pub(crate) fn rewrite_block_with_visitor(
     label: Option<ast::Label>,
     shape: Shape,
     has_braces: bool,
-) -> Option<String> {
-    if let rw @ Some(_) = rewrite_empty_block(context, block, attrs, label, prefix, shape) {
-        return rw;
+) -> RewriteResult {
+    if let Some(rw_str) = rewrite_empty_block(context, block, attrs, label, prefix, shape) {
+        return Ok(rw_str);
     }
 
     let mut visitor = FmtVisitor::from_context(context);
@@ -555,7 +566,7 @@ pub(crate) fn rewrite_block_with_visitor(
     match (block.rules, label) {
         (ast::BlockCheckMode::Unsafe(..), _) | (ast::BlockCheckMode::Default, Some(_)) => {
             let snippet = context.snippet(block.span);
-            let open_pos = snippet.find_uncommented("{")?;
+            let open_pos = snippet.find_uncommented("{").unknown_error()?;
             visitor.last_pos = block.span.lo() + BytePos(open_pos as u32)
         }
         (ast::BlockCheckMode::Default, None) => visitor.last_pos = block.span.lo(),
@@ -569,11 +580,15 @@ pub(crate) fn rewrite_block_with_visitor(
         .skipped_range
         .borrow_mut()
         .append(&mut visitor_context.skipped_range.borrow_mut());
-    Some(format!("{}{}{}", prefix, label_str, visitor.buffer))
+    Ok(format!("{}{}{}", prefix, label_str, visitor.buffer))
 }
 
 impl Rewrite for ast::Block {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         rewrite_block(self, None, None, context, shape)
     }
 }
@@ -584,7 +599,7 @@ fn rewrite_block(
     label: Option<ast::Label>,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     rewrite_block_inner(block, attrs, label, true, context, shape)
 }
 
@@ -595,27 +610,24 @@ fn rewrite_block_inner(
     allow_single_line: bool,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     let prefix = block_prefix(context, block, shape)?;
 
     // shape.width is used only for the single line case: either the empty block `{}`,
     // or an unsafe expression `unsafe { e }`.
-    if let rw @ Some(_) = rewrite_empty_block(context, block, attrs, label, &prefix, shape) {
-        return rw;
+    if let Some(rw_str) = rewrite_empty_block(context, block, attrs, label, &prefix, shape) {
+        return Ok(rw_str);
     }
 
-    let result = rewrite_block_with_visitor(context, &prefix, block, attrs, label, shape, true);
-    if let Some(ref result_str) = result {
-        if allow_single_line && result_str.lines().count() <= 3 {
-            if let rw @ Some(_) =
-                rewrite_single_line_block(context, &prefix, block, attrs, label, shape)
-            {
-                return rw;
-            }
+    let result_str =
+        rewrite_block_with_visitor(context, &prefix, block, attrs, label, shape, true)?;
+    if allow_single_line && result_str.lines().count() <= 3 {
+        if let rw @ Ok(_) = rewrite_single_line_block(context, &prefix, block, attrs, label, shape)
+        {
+            return rw;
         }
     }
-
-    result
+    Ok(result_str)
 }
 
 /// Rewrite the divergent block of a `let-else` statement.
@@ -624,7 +636,7 @@ pub(crate) fn rewrite_let_else_block(
     allow_single_line: bool,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     rewrite_block_inner(block, None, None, allow_single_line, context, shape)
 }
 
@@ -648,6 +660,7 @@ pub(crate) fn rewrite_cond(
                 String::from("\n") + &shape.indent.block_only().to_string(context.config);
             control_flow
                 .rewrite_cond(context, shape, &alt_block_sep)
+                .ok()
                 .map(|rw| rw.0)
         }),
     }
@@ -872,10 +885,12 @@ impl<'a> ControlFlow<'a> {
         expr: &ast::Expr,
         shape: Shape,
         offset: usize,
-    ) -> Option<String> {
+    ) -> RewriteResult {
         debug!("rewrite_pat_expr {:?} {:?} {:?}", shape, self.pat, expr);
 
-        let cond_shape = shape.offset_left(offset)?;
+        let cond_shape = shape
+            .offset_left(offset)
+            .max_width_error(shape.width, expr.span)?;
         if let Some(pat) = self.pat {
             let matcher = if self.matcher.is_empty() {
                 self.matcher.to_owned()
@@ -883,9 +898,10 @@ impl<'a> ControlFlow<'a> {
                 format!("{} ", self.matcher)
             };
             let pat_shape = cond_shape
-                .offset_left(matcher.len())?
-                .sub_width(self.connector.len())?;
-            let pat_string = pat.rewrite(context, pat_shape)?;
+                .offset_left(matcher.len())
+                .and_then(|s| s.sub_width(self.connector.len()))
+                .max_width_error(cond_shape.width, pat.span)?;
+            let pat_string = pat.rewrite_result(context, pat_shape)?;
             let comments_lo = context
                 .snippet_provider
                 .span_after(self.span.with_lo(pat.span.hi()), self.connector.trim());
@@ -902,10 +918,10 @@ impl<'a> ControlFlow<'a> {
             );
         }
 
-        let expr_rw = expr.rewrite(context, cond_shape);
+        let expr_rw = expr.rewrite_result(context, cond_shape);
         // The expression may (partially) fit on the current line.
         // We do not allow splitting between `if` and condition.
-        if self.keyword == "if" || expr_rw.is_some() {
+        if self.keyword == "if" || expr_rw.is_ok() {
             return expr_rw;
         }
 
@@ -914,7 +930,7 @@ impl<'a> ControlFlow<'a> {
             .block_indent(context.config.tab_spaces())
             .with_max_width(context.config);
         let nested_indent_str = nested_shape.indent.to_string_with_newline(context.config);
-        expr.rewrite(context, nested_shape)
+        expr.rewrite_result(context, nested_shape)
             .map(|expr_rw| format!("{}{}", nested_indent_str, expr_rw))
     }
 
@@ -923,7 +939,7 @@ impl<'a> ControlFlow<'a> {
         context: &RewriteContext<'_>,
         shape: Shape,
         alt_block_sep: &str,
-    ) -> Option<(String, usize)> {
+    ) -> Result<(String, usize), RewriteError> {
         // Do not take the rhs overhead from the upper expressions into account
         // when rewriting pattern.
         let new_width = context.budget(shape.used_width());
@@ -934,7 +950,9 @@ impl<'a> ControlFlow<'a> {
         let constr_shape = if self.nested_if {
             // We are part of an if-elseif-else chain. Our constraints are tightened.
             // 7 = "} else " .len()
-            fresh_shape.offset_left(7)?
+            fresh_shape
+                .offset_left(7)
+                .max_width_error(fresh_shape.width, self.span)?
         } else {
             fresh_shape
         };
@@ -970,7 +988,7 @@ impl<'a> ControlFlow<'a> {
 
             if let Some(cond_str) = trial {
                 if cond_str.len() <= context.config.single_line_if_else_max_width() {
-                    return Some((cond_str, 0));
+                    return Ok((cond_str, 0));
                 }
             }
         }
@@ -1023,7 +1041,7 @@ impl<'a> ControlFlow<'a> {
             label_string.len() + self.keyword.len() + pat_expr_string.len() + 2
         };
 
-        Some((
+        Ok((
             format!(
                 "{}{}{}{}{}",
                 label_string,
@@ -1089,13 +1107,17 @@ pub(crate) fn rewrite_else_kw_with_comments(
 
 impl<'a> Rewrite for ControlFlow<'a> {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         debug!("ControlFlow::rewrite {:?} {:?}", self, shape);
 
         let alt_block_sep = &shape.indent.to_string_with_newline(context.config);
         let (cond_str, used_width) = self.rewrite_cond(context, shape, alt_block_sep)?;
         // If `used_width` is 0, it indicates that whole control flow is written in a single line.
         if used_width == 0 {
-            return Some(cond_str);
+            return Ok(cond_str);
         }
 
         let block_width = shape.width.saturating_sub(used_width);
@@ -1139,7 +1161,7 @@ impl<'a> Rewrite for ControlFlow<'a> {
                         true,
                         mk_sp(else_block.span.lo(), self.span.hi()),
                     )
-                    .rewrite(context, shape)
+                    .rewrite_result(context, shape)
                 }
                 _ => {
                     last_in_chain = true;
@@ -1164,7 +1186,7 @@ impl<'a> Rewrite for ControlFlow<'a> {
             result.push_str(&rewrite?);
         }
 
-        Some(result)
+        Ok(result)
     }
 }
 
@@ -1177,7 +1199,7 @@ fn rewrite_label(context: &RewriteContext<'_>, opt_label: Option<ast::Label>) ->
 
 fn extract_comment(span: Span, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
     match rewrite_missing_comment(span, shape, context) {
-        Some(ref comment) if !comment.is_empty() => Some(format!(
+        Ok(ref comment) if !comment.is_empty() => Some(format!(
             "{indent}{comment}{indent}",
             indent = shape.indent.to_string_with_newline(context.config)
         )),
@@ -1248,7 +1270,7 @@ pub(crate) fn rewrite_literal(
     token_lit: token::Lit,
     span: Span,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     match token_lit.kind {
         token::LitKind::Str => rewrite_string_lit(context, span, shape),
         token::LitKind::Integer => rewrite_int_lit(context, token_lit, span, shape),
@@ -1256,11 +1278,12 @@ pub(crate) fn rewrite_literal(
             context.snippet(span).to_owned(),
             context.config.max_width(),
             shape,
-        ),
+        )
+        .max_width_error(shape.width, span),
     }
 }
 
-fn rewrite_string_lit(context: &RewriteContext<'_>, span: Span, shape: Shape) -> Option<String> {
+fn rewrite_string_lit(context: &RewriteContext<'_>, span: Span, shape: Shape) -> RewriteResult {
     let string_lit = context.snippet(span);
 
     if !context.config.format_strings() {
@@ -1268,11 +1291,12 @@ fn rewrite_string_lit(context: &RewriteContext<'_>, span: Span, shape: Shape) ->
             .lines()
             .dropping_back(1)
             .all(|line| line.ends_with('\\'))
-            && context.config.version() == Version::Two
+            && context.config.style_edition() >= StyleEdition::Edition2024
         {
-            return Some(string_lit.to_owned());
+            return Ok(string_lit.to_owned());
         } else {
-            return wrap_str(string_lit.to_owned(), context.config.max_width(), shape);
+            return wrap_str(string_lit.to_owned(), context.config.max_width(), shape)
+                .max_width_error(shape.width, span);
         }
     }
 
@@ -1284,6 +1308,7 @@ fn rewrite_string_lit(context: &RewriteContext<'_>, span: Span, shape: Shape) ->
         &StringFormat::new(shape.visual_indent(0), context.config),
         shape.width.saturating_sub(2),
     )
+    .max_width_error(shape.width, span)
 }
 
 fn rewrite_int_lit(
@@ -1291,7 +1316,7 @@ fn rewrite_int_lit(
     token_lit: token::Lit,
     span: Span,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     let symbol = token_lit.symbol.as_str();
 
     if let Some(symbol_stripped) = symbol.strip_prefix("0x") {
@@ -1305,11 +1330,12 @@ fn rewrite_int_lit(
                 format!(
                     "0x{}{}",
                     hex_lit,
-                    token_lit.suffix.map_or(String::new(), |s| s.to_string())
+                    token_lit.suffix.as_ref().map_or("", |s| s.as_str())
                 ),
                 context.config.max_width(),
                 shape,
-            );
+            )
+            .max_width_error(shape.width, span);
         }
     }
 
@@ -1318,6 +1344,7 @@ fn rewrite_int_lit(
         context.config.max_width(),
         shape,
     )
+    .max_width_error(shape.width, span)
 }
 
 fn choose_separator_tactic(context: &RewriteContext<'_>, span: Span) -> Option<SeparatorTactic> {
@@ -1338,7 +1365,7 @@ pub(crate) fn rewrite_call(
     args: &[ptr::P<ast::Expr>],
     span: Span,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     overflow::rewrite_with_parens(
         context,
         callee,
@@ -1458,7 +1485,7 @@ pub(crate) fn rewrite_paren(
     mut subexpr: &ast::Expr,
     shape: Shape,
     mut span: Span,
-) -> Option<String> {
+) -> RewriteResult {
     debug!("rewrite_paren, shape: {:?}", shape);
 
     // Extract comments within parens.
@@ -1487,11 +1514,14 @@ pub(crate) fn rewrite_paren(
     }
 
     // 1 = `(` and `)`
-    let sub_shape = shape.offset_left(1)?.sub_width(1)?;
-    let subexpr_str = subexpr.rewrite(context, sub_shape)?;
+    let sub_shape = shape
+        .offset_left(1)
+        .and_then(|s| s.sub_width(1))
+        .max_width_error(shape.width, span)?;
+    let subexpr_str = subexpr.rewrite_result(context, sub_shape)?;
     let fits_single_line = !pre_comment.contains("//") && !post_comment.contains("//");
     if fits_single_line {
-        Some(format!("({pre_comment}{subexpr_str}{post_comment})"))
+        Ok(format!("({pre_comment}{subexpr_str}{post_comment})"))
     } else {
         rewrite_paren_in_multi_line(context, subexpr, shape, pre_span, post_span)
     }
@@ -1503,12 +1533,12 @@ fn rewrite_paren_in_multi_line(
     shape: Shape,
     pre_span: Span,
     post_span: Span,
-) -> Option<String> {
+) -> RewriteResult {
     let nested_indent = shape.indent.block_indent(context.config);
     let nested_shape = Shape::indented(nested_indent, context.config);
     let pre_comment = rewrite_missing_comment(pre_span, nested_shape, context)?;
     let post_comment = rewrite_missing_comment(post_span, nested_shape, context)?;
-    let subexpr_str = subexpr.rewrite(context, nested_shape)?;
+    let subexpr_str = subexpr.rewrite_result(context, nested_shape)?;
 
     let mut result = String::with_capacity(subexpr_str.len() * 2);
     result.push('(');
@@ -1525,7 +1555,7 @@ fn rewrite_paren_in_multi_line(
     result.push_str(&shape.indent.to_string_with_newline(context.config));
     result.push(')');
 
-    Some(result)
+    Ok(result)
 }
 
 fn rewrite_index(
@@ -1533,8 +1563,8 @@ fn rewrite_index(
     index: &ast::Expr,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
-    let expr_str = expr.rewrite(context, shape)?;
+) -> RewriteResult {
+    let expr_str = expr.rewrite_result(context, shape)?;
 
     let offset = last_line_width(&expr_str) + 1;
     let rhs_overhead = shape.rhs_overhead(context.config);
@@ -1549,37 +1579,45 @@ fn rewrite_index(
                 .and_then(|shape| shape.sub_width(1)),
             IndentStyle::Visual => shape.visual_indent(offset).sub_width(offset + 1),
         }
-    };
-    let orig_index_rw = index_shape.and_then(|s| index.rewrite(context, s));
+    }
+    .max_width_error(shape.width, index.span());
+    let orig_index_rw = index_shape.and_then(|s| index.rewrite_result(context, s));
 
     // Return if index fits in a single line.
     match orig_index_rw {
-        Some(ref index_str) if !index_str.contains('\n') => {
-            return Some(format!("{expr_str}[{index_str}]"));
+        Ok(ref index_str) if !index_str.contains('\n') => {
+            return Ok(format!("{expr_str}[{index_str}]"));
         }
         _ => (),
     }
 
     // Try putting index on the next line and see if it fits in a single line.
     let indent = shape.indent.block_indent(context.config);
-    let index_shape = Shape::indented(indent, context.config).offset_left(1)?;
-    let index_shape = index_shape.sub_width(1 + rhs_overhead)?;
-    let new_index_rw = index.rewrite(context, index_shape);
+    let index_shape = Shape::indented(indent, context.config)
+        .offset_left(1)
+        .max_width_error(shape.width, index.span())?;
+    let index_shape = index_shape
+        .sub_width(1 + rhs_overhead)
+        .max_width_error(index_shape.width, index.span())?;
+    let new_index_rw = index.rewrite_result(context, index_shape);
     match (orig_index_rw, new_index_rw) {
-        (_, Some(ref new_index_str)) if !new_index_str.contains('\n') => Some(format!(
+        (_, Ok(ref new_index_str)) if !new_index_str.contains('\n') => Ok(format!(
             "{}{}[{}]",
             expr_str,
             indent.to_string_with_newline(context.config),
             new_index_str,
         )),
-        (None, Some(ref new_index_str)) => Some(format!(
+        (Err(_), Ok(ref new_index_str)) => Ok(format!(
             "{}{}[{}]",
             expr_str,
             indent.to_string_with_newline(context.config),
             new_index_str,
         )),
-        (Some(ref index_str), _) => Some(format!("{expr_str}[{index_str}]")),
-        _ => None,
+        (Ok(ref index_str), _) => Ok(format!("{expr_str}[{index_str}]")),
+        // When both orig_index_rw and new_index_rw result in errors, we currently propagate the
+        // error from the second attempt since it is more generous with width constraints.
+        // This decision is somewhat arbitrary and is open to change.
+        (Err(_), Err(new_index_rw_err)) => Err(new_index_rw_err),
     }
 }
 
@@ -1596,7 +1634,7 @@ fn rewrite_struct_lit<'a>(
     attrs: &[ast::Attribute],
     span: Span,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     debug!("rewrite_struct_lit: shape {:?}", shape);
 
     enum StructLitField<'a> {
@@ -1606,20 +1644,21 @@ fn rewrite_struct_lit<'a>(
     }
 
     // 2 = " {".len()
-    let path_shape = shape.sub_width(2)?;
+    let path_shape = shape.sub_width(2).max_width_error(shape.width, span)?;
     let path_str = rewrite_path(context, PathContext::Expr, qself, path, path_shape)?;
 
     let has_base_or_rest = match struct_rest {
-        ast::StructRest::None if fields.is_empty() => return Some(format!("{path_str} {{}}")),
+        ast::StructRest::None if fields.is_empty() => return Ok(format!("{path_str} {{}}")),
         ast::StructRest::Rest(_) if fields.is_empty() => {
-            return Some(format!("{path_str} {{ .. }}"));
+            return Ok(format!("{path_str} {{ .. }}"));
         }
         ast::StructRest::Rest(_) | ast::StructRest::Base(_) => true,
         _ => false,
     };
 
     // Foo { a: Foo } - indent is +3, width is -5.
-    let (h_shape, v_shape) = struct_lit_shape(shape, context, path_str.len() + 3, 2)?;
+    let (h_shape, v_shape) = struct_lit_shape(shape, context, path_str.len() + 3, 2)
+        .max_width_error(shape.width, span)?;
 
     let one_line_width = h_shape.map_or(0, |shape| shape.width);
     let body_lo = context.snippet_provider.span_after(span, "{");
@@ -1632,7 +1671,8 @@ fn rewrite_struct_lit<'a>(
             v_shape,
             mk_sp(body_lo, span.hi()),
             one_line_width,
-        )?
+        )
+        .unknown_error()?
     } else {
         let field_iter = fields.iter().map(StructLitField::Regular).chain(
             match struct_rest {
@@ -1661,14 +1701,24 @@ fn rewrite_struct_lit<'a>(
         let rewrite = |item: &StructLitField<'_>| match *item {
             StructLitField::Regular(field) => {
                 // The 1 taken from the v_budget is for the comma.
-                rewrite_field(context, field, v_shape.sub_width(1)?, 0)
+                rewrite_field(
+                    context,
+                    field,
+                    v_shape.sub_width(1).max_width_error(v_shape.width, span)?,
+                    0,
+                )
             }
             StructLitField::Base(expr) => {
                 // 2 = ..
-                expr.rewrite(context, v_shape.offset_left(2)?)
-                    .map(|s| format!("..{}", s))
+                expr.rewrite_result(
+                    context,
+                    v_shape
+                        .offset_left(2)
+                        .max_width_error(v_shape.width, span)?,
+                )
+                .map(|s| format!("..{}", s))
             }
-            StructLitField::Rest(_) => Some("..".to_owned()),
+            StructLitField::Rest(_) => Ok("..".to_owned()),
         };
 
         let items = itemize_list(
@@ -1703,7 +1753,7 @@ fn rewrite_struct_lit<'a>(
 
     let fields_str =
         wrap_struct_field(context, attrs, &fields_str, shape, v_shape, one_line_width)?;
-    Some(format!("{path_str} {{{fields_str}}}"))
+    Ok(format!("{path_str} {{{fields_str}}}"))
 
     // FIXME if context.config.indent_style() == Visual, but we run out
     // of space, we should fall back to BlockIndent.
@@ -1716,7 +1766,7 @@ pub(crate) fn wrap_struct_field(
     shape: Shape,
     nested_shape: Shape,
     one_line_width: usize,
-) -> Option<String> {
+) -> RewriteResult {
     let should_vertical = context.config.indent_style() == IndentStyle::Block
         && (fields_str.contains('\n')
             || !context.config.struct_lit_single_line()
@@ -1725,7 +1775,7 @@ pub(crate) fn wrap_struct_field(
     let inner_attrs = &inner_attributes(attrs);
     if inner_attrs.is_empty() {
         if should_vertical {
-            Some(format!(
+            Ok(format!(
                 "{}{}{}",
                 nested_shape.indent.to_string_with_newline(context.config),
                 fields_str,
@@ -1733,13 +1783,13 @@ pub(crate) fn wrap_struct_field(
             ))
         } else {
             // One liner or visual indent.
-            Some(format!(" {fields_str} "))
+            Ok(format!(" {fields_str} "))
         }
     } else {
-        Some(format!(
+        Ok(format!(
             "{}{}{}{}{}",
             nested_shape.indent.to_string_with_newline(context.config),
-            inner_attrs.rewrite(context, shape)?,
+            inner_attrs.rewrite_result(context, shape)?,
             nested_shape.indent.to_string_with_newline(context.config),
             fields_str,
             shape.indent.to_string_with_newline(context.config)
@@ -1756,38 +1806,40 @@ pub(crate) fn rewrite_field(
     field: &ast::ExprField,
     shape: Shape,
     prefix_max_width: usize,
-) -> Option<String> {
+) -> RewriteResult {
     if contains_skip(&field.attrs) {
-        return Some(context.snippet(field.span()).to_owned());
+        return Ok(context.snippet(field.span()).to_owned());
     }
-    let mut attrs_str = field.attrs.rewrite(context, shape)?;
+    let mut attrs_str = field.attrs.rewrite_result(context, shape)?;
     if !attrs_str.is_empty() {
         attrs_str.push_str(&shape.indent.to_string_with_newline(context.config));
     };
     let name = context.snippet(field.ident.span);
     if field.is_shorthand {
-        Some(attrs_str + name)
+        Ok(attrs_str + name)
     } else {
         let mut separator = String::from(struct_lit_field_separator(context.config));
         for _ in 0..prefix_max_width.saturating_sub(name.len()) {
             separator.push(' ');
         }
         let overhead = name.len() + separator.len();
-        let expr_shape = shape.offset_left(overhead)?;
-        let expr = field.expr.rewrite(context, expr_shape);
+        let expr_shape = shape
+            .offset_left(overhead)
+            .max_width_error(shape.width, field.span)?;
+        let expr = field.expr.rewrite_result(context, expr_shape);
         let is_lit = matches!(field.expr.kind, ast::ExprKind::Lit(_));
         match expr {
-            Some(ref e)
+            Ok(ref e)
                 if !is_lit && e.as_str() == name && context.config.use_field_init_shorthand() =>
             {
-                Some(attrs_str + name)
+                Ok(attrs_str + name)
             }
-            Some(e) => Some(format!("{attrs_str}{name}{separator}{e}")),
-            None => {
+            Ok(e) => Ok(format!("{attrs_str}{name}{separator}{e}")),
+            Err(_) => {
                 let expr_offset = shape.indent.block_indent(context.config);
                 let expr = field
                     .expr
-                    .rewrite(context, Shape::indented(expr_offset, context.config));
+                    .rewrite_result(context, Shape::indented(expr_offset, context.config));
                 expr.map(|s| {
                     format!(
                         "{}{}:\n{}{}",
@@ -1808,21 +1860,27 @@ fn rewrite_tuple_in_visual_indent_style<'a, T: 'a + IntoOverflowableItem<'a>>(
     span: Span,
     shape: Shape,
     is_singleton_tuple: bool,
-) -> Option<String> {
+) -> RewriteResult {
     // In case of length 1, need a trailing comma
     debug!("rewrite_tuple_in_visual_indent_style {:?}", shape);
     if is_singleton_tuple {
         // 3 = "(" + ",)"
-        let nested_shape = shape.sub_width(3)?.visual_indent(1);
+        let nested_shape = shape
+            .sub_width(3)
+            .max_width_error(shape.width, span)?
+            .visual_indent(1);
         return items
             .next()
             .unwrap()
-            .rewrite(context, nested_shape)
+            .rewrite_result(context, nested_shape)
             .map(|s| format!("({},)", s));
     }
 
     let list_lo = context.snippet_provider.span_after(span, "(");
-    let nested_shape = shape.sub_width(2)?.visual_indent(1);
+    let nested_shape = shape
+        .sub_width(2)
+        .max_width_error(shape.width, span)?
+        .visual_indent(1);
     let items = itemize_list(
         context.snippet_provider,
         items,
@@ -1830,7 +1888,7 @@ fn rewrite_tuple_in_visual_indent_style<'a, T: 'a + IntoOverflowableItem<'a>>(
         ",",
         |item| item.span().lo(),
         |item| item.span().hi(),
-        |item| item.rewrite(context, nested_shape),
+        |item| item.rewrite_result(context, nested_shape),
         list_lo,
         span.hi() - BytePos(1),
         false,
@@ -1847,7 +1905,7 @@ fn rewrite_tuple_in_visual_indent_style<'a, T: 'a + IntoOverflowableItem<'a>>(
         .ends_with_newline(false);
     let list_str = write_list(&item_vec, &fmt)?;
 
-    Some(format!("({list_str})"))
+    Ok(format!("({list_str})"))
 }
 
 fn rewrite_let(
@@ -1855,14 +1913,16 @@ fn rewrite_let(
     shape: Shape,
     pat: &ast::Pat,
     expr: &ast::Expr,
-) -> Option<String> {
+) -> RewriteResult {
     let mut result = "let ".to_owned();
 
     // TODO(ytmimi) comments could appear between `let` and the `pat`
 
     // 4 = "let ".len()
-    let pat_shape = shape.offset_left(4)?;
-    let pat_str = pat.rewrite(context, pat_shape)?;
+    let pat_shape = shape
+        .offset_left(4)
+        .max_width_error(shape.width, pat.span)?;
+    let pat_str = pat.rewrite_result(context, pat_shape)?;
     result.push_str(&pat_str);
 
     // TODO(ytmimi) comments could appear between `pat` and `=`
@@ -1890,7 +1950,7 @@ pub(crate) fn rewrite_tuple<'a, T: 'a + IntoOverflowableItem<'a>>(
     span: Span,
     shape: Shape,
     is_singleton_tuple: bool,
-) -> Option<String> {
+) -> RewriteResult {
     debug!("rewrite_tuple {:?}", shape);
     if context.use_block_indent() {
         // We use the same rule as function calls for rewriting tuples.
@@ -1919,31 +1979,35 @@ pub(crate) fn rewrite_tuple<'a, T: 'a + IntoOverflowableItem<'a>>(
     }
 }
 
-pub(crate) fn rewrite_unary_prefix<R: Rewrite>(
+pub(crate) fn rewrite_unary_prefix<R: Rewrite + Spanned>(
     context: &RewriteContext<'_>,
     prefix: &str,
     rewrite: &R,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
+    let shape = shape
+        .offset_left(prefix.len())
+        .max_width_error(shape.width, rewrite.span())?;
     rewrite
-        .rewrite(context, shape.offset_left(prefix.len())?)
+        .rewrite_result(context, shape)
         .map(|r| format!("{}{}", prefix, r))
 }
 
 // FIXME: this is probably not correct for multi-line Rewrites. we should
 // subtract suffix.len() from the last line budget, not the first!
-pub(crate) fn rewrite_unary_suffix<R: Rewrite>(
+pub(crate) fn rewrite_unary_suffix<R: Rewrite + Spanned>(
     context: &RewriteContext<'_>,
     suffix: &str,
     rewrite: &R,
     shape: Shape,
-) -> Option<String> {
-    rewrite
-        .rewrite(context, shape.sub_width(suffix.len())?)
-        .map(|mut r| {
-            r.push_str(suffix);
-            r
-        })
+) -> RewriteResult {
+    let shape = shape
+        .sub_width(suffix.len())
+        .max_width_error(shape.width, rewrite.span())?;
+    rewrite.rewrite_result(context, shape).map(|mut r| {
+        r.push_str(suffix);
+        r
+    })
 }
 
 fn rewrite_unary_op(
@@ -1951,7 +2015,7 @@ fn rewrite_unary_op(
     op: ast::UnOp,
     expr: &ast::Expr,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     // For some reason, an UnOp is not spanned like BinOp!
     rewrite_unary_prefix(context, op.as_str(), expr, shape)
 }
@@ -1990,15 +2054,21 @@ fn rewrite_assignment(
     rhs: &ast::Expr,
     op: Option<&ast::BinOp>,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     let operator_str = match op {
         Some(op) => context.snippet(op.span),
         None => "=",
     };
 
     // 1 = space between lhs and operator.
-    let lhs_shape = shape.sub_width(operator_str.len() + 1)?;
-    let lhs_str = format!("{} {}", lhs.rewrite(context, lhs_shape)?, operator_str);
+    let lhs_shape = shape
+        .sub_width(operator_str.len() + 1)
+        .max_width_error(shape.width, lhs.span())?;
+    let lhs_str = format!(
+        "{} {}",
+        lhs.rewrite_result(context, lhs_shape)?,
+        operator_str
+    );
 
     rewrite_assign_rhs(
         context,
@@ -2029,7 +2099,7 @@ pub(crate) fn rewrite_assign_rhs<S: Into<String>, R: Rewrite>(
     ex: &R,
     rhs_kind: &RhsAssignKind<'_>,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     rewrite_assign_rhs_with(context, lhs, ex, shape, rhs_kind, RhsTactics::Default)
 }
 
@@ -2040,7 +2110,7 @@ pub(crate) fn rewrite_assign_rhs_expr<R: Rewrite>(
     shape: Shape,
     rhs_kind: &RhsAssignKind<'_>,
     rhs_tactics: RhsTactics,
-) -> Option<String> {
+) -> RewriteResult {
     let last_line_width = last_line_width(lhs).saturating_sub(if lhs.contains('\n') {
         shape.indent.width()
     } else {
@@ -2062,7 +2132,7 @@ pub(crate) fn rewrite_assign_rhs_expr<R: Rewrite>(
         context,
         ex,
         orig_shape,
-        ex.rewrite(context, orig_shape),
+        ex.rewrite_result(context, orig_shape),
         rhs_kind,
         rhs_tactics,
         has_rhs_comment,
@@ -2076,13 +2146,13 @@ pub(crate) fn rewrite_assign_rhs_with<S: Into<String>, R: Rewrite>(
     shape: Shape,
     rhs_kind: &RhsAssignKind<'_>,
     rhs_tactics: RhsTactics,
-) -> Option<String> {
+) -> RewriteResult {
     let lhs = lhs.into();
     let rhs = rewrite_assign_rhs_expr(context, &lhs, ex, shape, rhs_kind, rhs_tactics)?;
-    Some(lhs + &rhs)
+    Ok(lhs + &rhs)
 }
 
-pub(crate) fn rewrite_assign_rhs_with_comments<S: Into<String>, R: Rewrite>(
+pub(crate) fn rewrite_assign_rhs_with_comments<S: Into<String>, R: Rewrite + Spanned>(
     context: &RewriteContext<'_>,
     lhs: S,
     ex: &R,
@@ -2091,21 +2161,22 @@ pub(crate) fn rewrite_assign_rhs_with_comments<S: Into<String>, R: Rewrite>(
     rhs_tactics: RhsTactics,
     between_span: Span,
     allow_extend: bool,
-) -> Option<String> {
+) -> RewriteResult {
     let lhs = lhs.into();
     let contains_comment = contains_comment(context.snippet(between_span));
     let shape = if contains_comment {
-        shape.block_left(context.config.tab_spaces())?
+        shape
+            .block_left(context.config.tab_spaces())
+            .max_width_error(shape.width, between_span.with_hi(ex.span().hi()))?
     } else {
         shape
     };
     let rhs = rewrite_assign_rhs_expr(context, &lhs, ex, shape, rhs_kind, rhs_tactics)?;
-
     if contains_comment {
         let rhs = rhs.trim_start();
         combine_strs_with_missing_comments(context, &lhs, rhs, between_span, shape, allow_extend)
     } else {
-        Some(lhs + &rhs)
+        Ok(lhs + &rhs)
     }
 }
 
@@ -2113,23 +2184,25 @@ fn choose_rhs<R: Rewrite>(
     context: &RewriteContext<'_>,
     expr: &R,
     shape: Shape,
-    orig_rhs: Option<String>,
+    orig_rhs: RewriteResult,
     _rhs_kind: &RhsAssignKind<'_>,
     rhs_tactics: RhsTactics,
     has_rhs_comment: bool,
-) -> Option<String> {
+) -> RewriteResult {
     match orig_rhs {
-        Some(ref new_str) if new_str.is_empty() => Some(String::new()),
-        Some(ref new_str)
-            if !new_str.contains('\n') && unicode_str_width(new_str) <= shape.width =>
-        {
-            Some(format!(" {new_str}"))
+        Ok(ref new_str) if new_str.is_empty() => Ok(String::new()),
+        Ok(ref new_str) if !new_str.contains('\n') && unicode_str_width(new_str) <= shape.width => {
+            Ok(format!(" {new_str}"))
         }
         _ => {
             // Expression did not fit on the same line as the identifier.
             // Try splitting the line and see if that works better.
-            let new_shape = shape_from_rhs_tactic(context, shape, rhs_tactics)?;
-            let new_rhs = expr.rewrite(context, new_shape);
+            let new_shape = shape_from_rhs_tactic(context, shape, rhs_tactics)
+                // TODO(ding-young) Ideally, we can replace unknown_error() with max_width_error(),
+                // but this requires either implementing the Spanned trait for ast::GenericBounds
+                // or grabbing the span from the call site.
+                .unknown_error()?;
+            let new_rhs = expr.rewrite_result(context, new_shape);
             let new_indent_str = &shape
                 .indent
                 .block_indent(context.config)
@@ -2137,24 +2210,27 @@ fn choose_rhs<R: Rewrite>(
             let before_space_str = if has_rhs_comment { "" } else { " " };
 
             match (orig_rhs, new_rhs) {
-                (Some(ref orig_rhs), Some(ref new_rhs))
+                (Ok(ref orig_rhs), Ok(ref new_rhs))
                     if !filtered_str_fits(&new_rhs, context.config.max_width(), new_shape) =>
                 {
-                    Some(format!("{before_space_str}{orig_rhs}"))
+                    Ok(format!("{before_space_str}{orig_rhs}"))
                 }
-                (Some(ref orig_rhs), Some(ref new_rhs))
+                (Ok(ref orig_rhs), Ok(ref new_rhs))
                     if prefer_next_line(orig_rhs, new_rhs, rhs_tactics) =>
                 {
-                    Some(format!("{new_indent_str}{new_rhs}"))
+                    Ok(format!("{new_indent_str}{new_rhs}"))
                 }
-                (None, Some(ref new_rhs)) => Some(format!("{new_indent_str}{new_rhs}")),
-                (None, None) if rhs_tactics == RhsTactics::AllowOverflow => {
+                (Err(_), Ok(ref new_rhs)) => Ok(format!("{new_indent_str}{new_rhs}")),
+                (Err(_), Err(_)) if rhs_tactics == RhsTactics::AllowOverflow => {
                     let shape = shape.infinite_width();
-                    expr.rewrite(context, shape)
+                    expr.rewrite_result(context, shape)
                         .map(|s| format!("{}{}", before_space_str, s))
                 }
-                (None, None) => None,
-                (Some(orig_rhs), _) => Some(format!("{before_space_str}{orig_rhs}")),
+                // When both orig_rhs and new_rhs result in errors, we currently propagate
+                // the error from the second attempt since it is more generous with
+                // width constraints. This decision is somewhat arbitrary and is open to change.
+                (Err(_), Err(new_rhs_err)) => Err(new_rhs_err),
+                (Ok(orig_rhs), _) => Ok(format!("{before_space_str}{orig_rhs}")),
             }
         }
     }
@@ -2204,7 +2280,7 @@ fn rewrite_expr_addrof(
     mutability: ast::Mutability,
     expr: &ast::Expr,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     let operator_str = match (mutability, borrow_kind) {
         (ast::Mutability::Not, ast::BorrowKind::Ref) => "&",
         (ast::Mutability::Not, ast::BorrowKind::Raw) => "&raw const ",
diff --git a/src/tools/rustfmt/src/formatting.rs b/src/tools/rustfmt/src/formatting.rs
index 5e71fe107eb..1e1e329f624 100644
--- a/src/tools/rustfmt/src/formatting.rs
+++ b/src/tools/rustfmt/src/formatting.rs
@@ -17,7 +17,7 @@ use crate::parse::parser::{DirectoryOwnership, Parser, ParserError};
 use crate::parse::session::ParseSess;
 use crate::utils::{contains_skip, count_newlines};
 use crate::visitor::FmtVisitor;
-use crate::{modules, source_file, ErrorKind, FormatReport, Input, Session};
+use crate::{ErrorKind, FormatReport, Input, Session, modules, source_file};
 
 mod generated;
 mod newline_style;
diff --git a/src/tools/rustfmt/src/git-rustfmt/main.rs b/src/tools/rustfmt/src/git-rustfmt/main.rs
index b8b0432aa95..64458420f59 100644
--- a/src/tools/rustfmt/src/git-rustfmt/main.rs
+++ b/src/tools/rustfmt/src/git-rustfmt/main.rs
@@ -13,7 +13,9 @@ use rustfmt_nightly as rustfmt;
 use tracing::debug;
 use tracing_subscriber::EnvFilter;
 
-use crate::rustfmt::{load_config, CliOptions, FormatReportFormatterBuilder, Input, Session};
+use crate::rustfmt::{
+    CliOptions, FormatReportFormatterBuilder, Input, Session, Version, load_config,
+};
 
 fn prune_files(files: Vec<&str>) -> Vec<&str> {
     let prefixes: Vec<_> = files
@@ -87,6 +89,15 @@ impl CliOptions for NullOptions {
     fn config_path(&self) -> Option<&Path> {
         unreachable!();
     }
+    fn edition(&self) -> Option<rustfmt_nightly::Edition> {
+        unreachable!();
+    }
+    fn style_edition(&self) -> Option<rustfmt_nightly::StyleEdition> {
+        unreachable!();
+    }
+    fn version(&self) -> Option<Version> {
+        unreachable!();
+    }
 }
 
 fn uncommitted_files() -> Vec<String> {
diff --git a/src/tools/rustfmt/src/ignore_path.rs b/src/tools/rustfmt/src/ignore_path.rs
index 5c25f233ce3..2f804ef5a25 100644
--- a/src/tools/rustfmt/src/ignore_path.rs
+++ b/src/tools/rustfmt/src/ignore_path.rs
@@ -41,8 +41,11 @@ mod test {
         use crate::ignore_path::IgnorePathSet;
         use std::path::{Path, PathBuf};
 
-        let config =
-            Config::from_toml(r#"ignore = ["foo.rs", "bar_dir/*"]"#, Path::new("")).unwrap();
+        let config = Config::from_toml(
+            r#"ignore = ["foo.rs", "bar_dir/*"]"#,
+            Path::new("./rustfmt.toml"),
+        )
+        .unwrap();
         let ignore_path_set = IgnorePathSet::from_ignore_list(&config.ignore()).unwrap();
 
         assert!(ignore_path_set.is_match(&FileName::Real(PathBuf::from("src/foo.rs"))));
@@ -59,7 +62,7 @@ mod test {
 
         let config = Config::from_toml(
             r#"ignore = ["foo.rs", "bar_dir/*", "!bar_dir/*/what.rs"]"#,
-            Path::new(""),
+            Path::new("./rustfmt.toml"),
         )
         .unwrap();
         let ignore_path_set = IgnorePathSet::from_ignore_list(&config.ignore()).unwrap();
diff --git a/src/tools/rustfmt/src/imports.rs b/src/tools/rustfmt/src/imports.rs
index 12c178e136f..b741dd9b5da 100644
--- a/src/tools/rustfmt/src/imports.rs
+++ b/src/tools/rustfmt/src/imports.rs
@@ -8,19 +8,20 @@ use itertools::Itertools;
 
 use rustc_ast::ast::{self, UseTreeKind};
 use rustc_span::{
+    BytePos, DUMMY_SP, Span,
     symbol::{self, sym},
-    BytePos, Span, DUMMY_SP,
 };
 
 use crate::comment::combine_strs_with_missing_comments;
-use crate::config::lists::*;
 use crate::config::ImportGranularity;
-use crate::config::{Edition, IndentStyle, Version};
+use crate::config::lists::*;
+use crate::config::{Edition, IndentStyle, StyleEdition};
 use crate::lists::{
-    definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
+    ListFormatting, ListItem, Separator, definitive_tactic, itemize_list, write_list,
 };
-use crate::rewrite::{Rewrite, RewriteContext};
+use crate::rewrite::{Rewrite, RewriteContext, RewriteErrorExt, RewriteResult};
 use crate::shape::Shape;
+use crate::sort::version_sort;
 use crate::source_map::SpanUtils;
 use crate::spanned::Spanned;
 use crate::utils::{is_same_visibility, mk_sp, rewrite_ident};
@@ -44,7 +45,8 @@ impl<'a> FmtVisitor<'a> {
             Some(item.span.lo()),
             Some(item.attrs.clone()),
         )
-        .rewrite_top_level(&self.get_context(), shape);
+        .rewrite_top_level(&self.get_context(), shape)
+        .ok();
         match rw {
             Some(ref s) if s.is_empty() => {
                 // Format up to last newline
@@ -104,7 +106,7 @@ pub(crate) enum UseSegmentKind {
 #[derive(Clone, Eq, PartialEq)]
 pub(crate) struct UseSegment {
     pub(crate) kind: UseSegmentKind,
-    pub(crate) version: Version,
+    pub(crate) style_edition: StyleEdition,
 }
 
 #[derive(Clone)]
@@ -149,7 +151,7 @@ impl UseSegment {
         };
         UseSegment {
             kind,
-            version: self.version,
+            style_edition: self.style_edition,
         }
     }
 
@@ -197,7 +199,7 @@ impl UseSegment {
 
         Some(UseSegment {
             kind,
-            version: context.config.version(),
+            style_edition: context.config.style_edition(),
         })
     }
 
@@ -331,12 +333,17 @@ impl UseTree {
         &self,
         context: &RewriteContext<'_>,
         shape: Shape,
-    ) -> Option<String> {
+    ) -> RewriteResult {
         let vis = self.visibility.as_ref().map_or(Cow::from(""), |vis| {
             crate::utils::format_visibility(context, vis)
         });
         let use_str = self
-            .rewrite(context, shape.offset_left(vis.len())?)
+            .rewrite_result(
+                context,
+                shape
+                    .offset_left(vis.len())
+                    .max_width_error(shape.width, self.span())?,
+            )
             .map(|s| {
                 if s.is_empty() {
                     s
@@ -346,8 +353,8 @@ impl UseTree {
             })?;
         match self.attrs {
             Some(ref attrs) if !attrs.is_empty() => {
-                let attr_str = attrs.rewrite(context, shape)?;
-                let lo = attrs.last().as_ref()?.span.hi();
+                let attr_str = attrs.rewrite_result(context, shape)?;
+                let lo = attrs.last().unknown_error()?.span.hi();
                 let hi = self.span.lo();
                 let span = mk_sp(lo, hi);
 
@@ -368,7 +375,7 @@ impl UseTree {
                     allow_extend,
                 )
             }
-            _ => Some(use_str),
+            _ => Ok(use_str),
         }
     }
 
@@ -444,18 +451,21 @@ impl UseTree {
             }
         }
 
-        let version = context.config.version();
+        let style_edition = context.config.style_edition();
 
         match a.kind {
             UseTreeKind::Glob => {
                 // in case of a global path and the glob starts at the root, e.g., "::*"
                 if a.prefix.segments.len() == 1 && leading_modsep {
                     let kind = UseSegmentKind::Ident("".to_owned(), None);
-                    result.path.push(UseSegment { kind, version });
+                    result.path.push(UseSegment {
+                        kind,
+                        style_edition,
+                    });
                 }
                 result.path.push(UseSegment {
                     kind: UseSegmentKind::Glob,
-                    version,
+                    style_edition,
                 });
             }
             UseTreeKind::Nested {
@@ -470,7 +480,7 @@ impl UseTree {
                     ",",
                     |tree| tree.span.lo(),
                     |tree| tree.span.hi(),
-                    |_| Some("".to_owned()), // We only need comments for now.
+                    |_| Ok("".to_owned()), // We only need comments for now.
                     context.snippet_provider.span_after(a.span, "{"),
                     a.span.hi(),
                     false,
@@ -480,7 +490,10 @@ impl UseTree {
                 // e.g., "::{foo, bar}"
                 if a.prefix.segments.len() == 1 && leading_modsep {
                     let kind = UseSegmentKind::Ident("".to_owned(), None);
-                    result.path.push(UseSegment { kind, version });
+                    result.path.push(UseSegment {
+                        kind,
+                        style_edition,
+                    });
                 }
                 let kind = UseSegmentKind::List(
                     list.iter()
@@ -490,7 +503,10 @@ impl UseTree {
                         })
                         .collect(),
                 );
-                result.path.push(UseSegment { kind, version });
+                result.path.push(UseSegment {
+                    kind,
+                    style_edition,
+                });
             }
             UseTreeKind::Simple(ref rename) => {
                 // If the path has leading double colons and is composed of only 2 segments, then we
@@ -519,7 +535,10 @@ impl UseTree {
                     _ => UseSegmentKind::Ident(name, alias),
                 };
 
-                let segment = UseSegment { kind, version };
+                let segment = UseSegment {
+                    kind,
+                    style_edition,
+                };
 
                 // `name` is already in result.
                 result.path.pop();
@@ -614,7 +633,7 @@ impl UseTree {
             list.sort();
             last = UseSegment {
                 kind: UseSegmentKind::List(list),
-                version: last.version,
+                style_edition: last.style_edition,
             };
         }
 
@@ -732,9 +751,12 @@ impl UseTree {
         }) = self.path.last()
         {
             let self_segment = self.path.pop().unwrap();
-            let version = self_segment.version;
+            let style_edition = self_segment.style_edition;
             let kind = UseSegmentKind::List(vec![UseTree::from_path(vec![self_segment], DUMMY_SP)]);
-            self.path.push(UseSegment { kind, version });
+            self.path.push(UseSegment {
+                kind,
+                style_edition,
+            });
         }
         self
     }
@@ -750,7 +772,7 @@ fn merge_rest(
         return None;
     }
     if a.len() != len && b.len() != len {
-        let version = a[len].version;
+        let style_edition = a[len].style_edition;
         if let UseSegmentKind::List(ref list) = a[len].kind {
             let mut list = list.clone();
             merge_use_trees_inner(
@@ -760,7 +782,10 @@ fn merge_rest(
             );
             let mut new_path = b[..len].to_vec();
             let kind = UseSegmentKind::List(list);
-            new_path.push(UseSegment { kind, version });
+            new_path.push(UseSegment {
+                kind,
+                style_edition,
+            });
             return Some(new_path);
         }
     } else if len == 1 {
@@ -770,9 +795,12 @@ fn merge_rest(
             (&b[0], &a[1..])
         };
         let kind = UseSegmentKind::Slf(common.get_alias().map(ToString::to_string));
-        let version = a[0].version;
+        let style_edition = a[0].style_edition;
         let mut list = vec![UseTree::from_path(
-            vec![UseSegment { kind, version }],
+            vec![UseSegment {
+                kind,
+                style_edition,
+            }],
             DUMMY_SP,
         )];
         match rest {
@@ -788,7 +816,7 @@ fn merge_rest(
             b[0].clone(),
             UseSegment {
                 kind: UseSegmentKind::List(list),
-                version,
+                style_edition,
             },
         ]);
     } else {
@@ -801,8 +829,11 @@ fn merge_rest(
     list.sort();
     let mut new_path = b[..len].to_vec();
     let kind = UseSegmentKind::List(list);
-    let version = a[0].version;
-    new_path.push(UseSegment { kind, version });
+    let style_edition = a[0].style_edition;
+    new_path.push(UseSegment {
+        kind,
+        style_edition,
+    });
     Some(new_path)
 }
 
@@ -892,8 +923,8 @@ impl Ord for UseSegment {
             | (Super(ref a), Super(ref b))
             | (Crate(ref a), Crate(ref b)) => match (a, b) {
                 (Some(sa), Some(sb)) => {
-                    if self.version == Version::Two {
-                        sa.trim_start_matches("r#").cmp(sb.trim_start_matches("r#"))
+                    if self.style_edition >= StyleEdition::Edition2024 {
+                        version_sort(sa.trim_start_matches("r#"), sb.trim_start_matches("r#"))
                     } else {
                         a.cmp(b)
                     }
@@ -902,25 +933,31 @@ impl Ord for UseSegment {
             },
             (Glob, Glob) => Ordering::Equal,
             (Ident(ref pia, ref aa), Ident(ref pib, ref ab)) => {
-                let (ia, ib) = if self.version == Version::Two {
+                let (ia, ib) = if self.style_edition >= StyleEdition::Edition2024 {
                     (pia.trim_start_matches("r#"), pib.trim_start_matches("r#"))
                 } else {
                     (pia.as_str(), pib.as_str())
                 };
-                // snake_case < CamelCase < UPPER_SNAKE_CASE
-                if ia.starts_with(char::is_uppercase) && ib.starts_with(char::is_lowercase) {
-                    return Ordering::Greater;
-                }
-                if ia.starts_with(char::is_lowercase) && ib.starts_with(char::is_uppercase) {
-                    return Ordering::Less;
-                }
-                if is_upper_snake_case(ia) && !is_upper_snake_case(ib) {
-                    return Ordering::Greater;
-                }
-                if !is_upper_snake_case(ia) && is_upper_snake_case(ib) {
-                    return Ordering::Less;
-                }
-                let ident_ord = ia.cmp(ib);
+
+                let ident_ord = if self.style_edition >= StyleEdition::Edition2024 {
+                    version_sort(ia, ib)
+                } else {
+                    // snake_case < CamelCase < UPPER_SNAKE_CASE
+                    if ia.starts_with(char::is_uppercase) && ib.starts_with(char::is_lowercase) {
+                        return Ordering::Greater;
+                    }
+                    if ia.starts_with(char::is_lowercase) && ib.starts_with(char::is_uppercase) {
+                        return Ordering::Less;
+                    }
+                    if is_upper_snake_case(ia) && !is_upper_snake_case(ib) {
+                        return Ordering::Greater;
+                    }
+                    if !is_upper_snake_case(ia) && is_upper_snake_case(ib) {
+                        return Ordering::Less;
+                    }
+                    ia.cmp(ib)
+                };
+
                 if ident_ord != Ordering::Equal {
                     return ident_ord;
                 }
@@ -928,9 +965,8 @@ impl Ord for UseSegment {
                     (None, Some(_)) => Ordering::Less,
                     (Some(_), None) => Ordering::Greater,
                     (Some(aas), Some(abs)) => {
-                        if self.version == Version::Two {
-                            aas.trim_start_matches("r#")
-                                .cmp(abs.trim_start_matches("r#"))
+                        if self.style_edition >= StyleEdition::Edition2024 {
+                            version_sort(aas.trim_start_matches("r#"), abs.trim_start_matches("r#"))
                         } else {
                             aas.cmp(abs)
                         }
@@ -982,21 +1018,24 @@ fn rewrite_nested_use_tree(
     context: &RewriteContext<'_>,
     use_tree_list: &[UseTree],
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     let mut list_items = Vec::with_capacity(use_tree_list.len());
     let nested_shape = match context.config.imports_indent() {
         IndentStyle::Block => shape
             .block_indent(context.config.tab_spaces())
             .with_max_width(context.config)
-            .sub_width(1)?,
+            .sub_width(1)
+            .unknown_error()?,
         IndentStyle::Visual => shape.visual_indent(0),
     };
     for use_tree in use_tree_list {
         if let Some(mut list_item) = use_tree.list_item.clone() {
-            list_item.item = use_tree.rewrite(context, nested_shape);
+            list_item.item = use_tree.rewrite_result(context, nested_shape);
             list_items.push(list_item);
         } else {
-            list_items.push(ListItem::from_str(use_tree.rewrite(context, nested_shape)?));
+            list_items.push(ListItem::from_str(
+                use_tree.rewrite_result(context, nested_shape)?,
+            ));
         }
     }
     let has_nested_list = use_tree_list.iter().any(|use_segment| {
@@ -1049,12 +1088,16 @@ fn rewrite_nested_use_tree(
         format!("{{{list_str}}}")
     };
 
-    Some(result)
+    Ok(result)
 }
 
 impl Rewrite for UseSegment {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
-        Some(match self.kind {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
+        Ok(match self.kind {
             UseSegmentKind::Ident(ref ident, Some(ref rename)) => {
                 format!("{ident} as {rename}")
             }
@@ -1066,31 +1109,42 @@ impl Rewrite for UseSegment {
             UseSegmentKind::Crate(Some(ref rename)) => format!("crate as {rename}"),
             UseSegmentKind::Crate(None) => "crate".to_owned(),
             UseSegmentKind::Glob => "*".to_owned(),
-            UseSegmentKind::List(ref use_tree_list) => rewrite_nested_use_tree(
-                context,
-                use_tree_list,
-                // 1 = "{" and "}"
-                shape.offset_left(1)?.sub_width(1)?,
-            )?,
+            UseSegmentKind::List(ref use_tree_list) => {
+                rewrite_nested_use_tree(
+                    context,
+                    use_tree_list,
+                    // 1 = "{" and "}"
+                    shape
+                        .offset_left(1)
+                        .and_then(|s| s.sub_width(1))
+                        .unknown_error()?,
+                )?
+            }
         })
     }
 }
 
 impl Rewrite for UseTree {
+    fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
     // This does NOT format attributes and visibility or add a trailing `;`.
-    fn rewrite(&self, context: &RewriteContext<'_>, mut shape: Shape) -> Option<String> {
+    fn rewrite_result(&self, context: &RewriteContext<'_>, mut shape: Shape) -> RewriteResult {
         let mut result = String::with_capacity(256);
         let mut iter = self.path.iter().peekable();
         while let Some(segment) = iter.next() {
-            let segment_str = segment.rewrite(context, shape)?;
+            let segment_str = segment.rewrite_result(context, shape)?;
             result.push_str(&segment_str);
             if iter.peek().is_some() {
                 result.push_str("::");
                 // 2 = "::"
-                shape = shape.offset_left(2 + segment_str.len())?;
+                shape = shape
+                    .offset_left(2 + segment_str.len())
+                    .max_width_error(shape.width, self.span())?;
             }
         }
-        Some(result)
+        Ok(result)
     }
 }
 
@@ -1114,7 +1168,7 @@ mod test {
 
         struct Parser<'a> {
             input: Peekable<Chars<'a>>,
-            version: Version,
+            style_edition: StyleEdition,
         }
 
         impl<'a> Parser<'a> {
@@ -1132,7 +1186,7 @@ mod test {
                 buf: &mut String,
                 alias_buf: &mut Option<String>,
             ) {
-                let version = self.version;
+                let style_edition = self.style_edition;
                 if !buf.is_empty() {
                     let mut alias = None;
                     swap(alias_buf, &mut alias);
@@ -1140,19 +1194,28 @@ mod test {
                     match buf.as_ref() {
                         "self" => {
                             let kind = UseSegmentKind::Slf(alias);
-                            result.push(UseSegment { kind, version });
+                            result.push(UseSegment {
+                                kind,
+                                style_edition,
+                            });
                             *buf = String::new();
                             *alias_buf = None;
                         }
                         "super" => {
                             let kind = UseSegmentKind::Super(alias);
-                            result.push(UseSegment { kind, version });
+                            result.push(UseSegment {
+                                kind,
+                                style_edition,
+                            });
                             *buf = String::new();
                             *alias_buf = None;
                         }
                         "crate" => {
                             let kind = UseSegmentKind::Crate(alias);
-                            result.push(UseSegment { kind, version });
+                            result.push(UseSegment {
+                                kind,
+                                style_edition,
+                            });
                             *buf = String::new();
                             *alias_buf = None;
                         }
@@ -1160,7 +1223,10 @@ mod test {
                             let mut name = String::new();
                             swap(buf, &mut name);
                             let kind = UseSegmentKind::Ident(name, alias);
-                            result.push(UseSegment { kind, version });
+                            result.push(UseSegment {
+                                kind,
+                                style_edition,
+                            });
                         }
                     }
                 }
@@ -1178,7 +1244,7 @@ mod test {
                             let kind = UseSegmentKind::List(self.parse_list());
                             result.push(UseSegment {
                                 kind,
-                                version: self.version,
+                                style_edition: self.style_edition,
                             });
                             self.eat('}');
                         }
@@ -1188,7 +1254,7 @@ mod test {
                             let kind = UseSegmentKind::Glob;
                             result.push(UseSegment {
                                 kind,
-                                version: self.version,
+                                style_edition: self.style_edition,
                             });
                         }
                         ':' => {
@@ -1249,7 +1315,7 @@ mod test {
 
         let mut parser = Parser {
             input: s.chars().peekable(),
-            version: Version::One,
+            style_edition: StyleEdition::Edition2015,
         };
         parser.parse_in_list()
     }
diff --git a/src/tools/rustfmt/src/items.rs b/src/tools/rustfmt/src/items.rs
index cbf7ce90e37..fc043a697e0 100644
--- a/src/tools/rustfmt/src/items.rs
+++ b/src/tools/rustfmt/src/items.rs
@@ -1,31 +1,30 @@
 // Formatting top-level items - functions, structs, enums, traits, impls.
 
 use std::borrow::Cow;
-use std::cmp::{max, min, Ordering};
+use std::cmp::{Ordering, max, min};
 
 use regex::Regex;
 use rustc_ast::visit;
 use rustc_ast::{ast, ptr};
-use rustc_span::{symbol, BytePos, Span, DUMMY_SP};
+use rustc_span::{BytePos, DUMMY_SP, Span, symbol};
 use tracing::debug;
 
 use crate::attr::filter_inline_attrs;
 use crate::comment::{
-    combine_strs_with_missing_comments, contains_comment, is_last_comment_block,
+    FindUncommented, combine_strs_with_missing_comments, contains_comment, is_last_comment_block,
     recover_comment_removed, recover_missing_comment_in_span, rewrite_missing_comment,
-    FindUncommented,
 };
 use crate::config::lists::*;
-use crate::config::{BraceStyle, Config, IndentStyle, Version};
+use crate::config::{BraceStyle, Config, IndentStyle, StyleEdition};
 use crate::expr::{
-    is_empty_block, is_simple_block_stmt, rewrite_assign_rhs, rewrite_assign_rhs_with,
-    rewrite_assign_rhs_with_comments, rewrite_else_kw_with_comments, rewrite_let_else_block,
-    RhsAssignKind, RhsTactics,
+    RhsAssignKind, RhsTactics, is_empty_block, is_simple_block_stmt, rewrite_assign_rhs,
+    rewrite_assign_rhs_with, rewrite_assign_rhs_with_comments, rewrite_else_kw_with_comments,
+    rewrite_let_else_block,
 };
-use crate::lists::{definitive_tactic, itemize_list, write_list, ListFormatting, Separator};
-use crate::macros::{rewrite_macro, MacroPosition};
+use crate::lists::{ListFormatting, Separator, definitive_tactic, itemize_list, write_list};
+use crate::macros::{MacroPosition, rewrite_macro};
 use crate::overflow;
-use crate::rewrite::{Rewrite, RewriteContext};
+use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
 use crate::shape::{Indent, Shape};
 use crate::source_map::{LineRangeUtils, SpanUtils};
 use crate::spanned::Spanned;
@@ -49,18 +48,22 @@ fn type_annotation_separator(config: &Config) -> &str {
 // let pat: ty = init; or let pat: ty = init else { .. };
 impl Rewrite for ast::Local {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         debug!(
             "Local::rewrite {:?} {} {:?}",
             self, shape.width, shape.indent
         );
 
-        skip_out_of_file_lines_range!(context, self.span);
+        skip_out_of_file_lines_range_err!(context, self.span);
 
         if contains_skip(&self.attrs) {
-            return None;
+            return Err(RewriteError::SkipFormatting);
         }
 
-        let attrs_str = self.attrs.rewrite(context, shape)?;
+        let attrs_str = self.attrs.rewrite_result(context, shape)?;
         let mut result = if attrs_str.is_empty() {
             "let ".to_owned()
         } else {
@@ -79,10 +82,15 @@ impl Rewrite for ast::Local {
         let let_kw_offset = result.len() - "let ".len();
 
         // 4 = "let ".len()
-        let pat_shape = shape.offset_left(4)?;
+        let pat_shape = shape
+            .offset_left(4)
+            .max_width_error(shape.width, self.span())?;
         // 1 = ;
-        let pat_shape = pat_shape.sub_width(1)?;
-        let pat_str = self.pat.rewrite(context, pat_shape)?;
+        let pat_shape = pat_shape
+            .sub_width(1)
+            .max_width_error(shape.width, self.span())?;
+        let pat_str = self.pat.rewrite_result(context, pat_shape)?;
+
         result.push_str(&pat_str);
 
         // String that is placed within the assignment pattern and expression.
@@ -96,11 +104,13 @@ impl Rewrite for ast::Local {
                 } else {
                     shape
                 }
-                .offset_left(last_line_width(&result) + separator.len())?
+                .offset_left(last_line_width(&result) + separator.len())
+                .max_width_error(shape.width, self.span())?
                 // 2 = ` =`
-                .sub_width(2)?;
+                .sub_width(2)
+                .max_width_error(shape.width, self.span())?;
 
-                let rewrite = ty.rewrite(context, ty_shape)?;
+                let rewrite = ty.rewrite_result(context, ty_shape)?;
 
                 infix.push_str(separator);
                 infix.push_str(&rewrite);
@@ -117,7 +127,9 @@ impl Rewrite for ast::Local {
 
         if let Some((init, else_block)) = self.kind.init_else_opt() {
             // 1 = trailing semicolon;
-            let nested_shape = shape.sub_width(1)?;
+            let nested_shape = shape
+                .sub_width(1)
+                .max_width_error(shape.width, self.span())?;
 
             result = rewrite_assign_rhs(
                 context,
@@ -131,7 +143,8 @@ impl Rewrite for ast::Local {
                 let else_kw_span = init.span.between(block.span);
                 // Strip attributes and comments to check if newline is needed before the else
                 // keyword from the initializer part. (#5901)
-                let init_str = if context.config.version() == Version::Two {
+                let style_edition = context.config.style_edition();
+                let init_str = if style_edition >= StyleEdition::Edition2024 {
                     &result[let_kw_offset..]
                 } else {
                     result.as_str()
@@ -155,7 +168,8 @@ impl Rewrite for ast::Local {
                     std::cmp::min(shape.width, context.config.single_line_let_else_max_width());
 
                 // If available_space hits zero we know for sure this will be a multi-lined block
-                let assign_str_with_else_kw = if context.config.version() == Version::Two {
+                let style_edition = context.config.style_edition();
+                let assign_str_with_else_kw = if style_edition >= StyleEdition::Edition2024 {
                     &result[let_kw_offset..]
                 } else {
                     result.as_str()
@@ -184,7 +198,7 @@ impl Rewrite for ast::Local {
         }
 
         result.push(';');
-        Some(result)
+        Ok(result)
     }
 }
 
@@ -420,7 +434,7 @@ impl<'a> FmtVisitor<'a> {
 
         let mut fn_brace_style = newline_for_brace(self.config, &fn_sig.generics.where_clause);
         let (result, _, force_newline_brace) =
-            rewrite_fn_base(&context, indent, ident, fn_sig, span, fn_brace_style)?;
+            rewrite_fn_base(&context, indent, ident, fn_sig, span, fn_brace_style).ok()?;
 
         // 2 = ` {`
         if self.config.brace_style() == BraceStyle::AlwaysNextLine
@@ -441,7 +455,7 @@ impl<'a> FmtVisitor<'a> {
         vis: &ast::Visibility,
         generics: &ast::Generics,
         span: Span,
-    ) -> Option<String> {
+    ) -> RewriteResult {
         // Drop semicolon or it will be interpreted as comment.
         let span = mk_sp(span.lo(), span.hi() - BytePos(1));
         let context = self.get_context();
@@ -463,7 +477,7 @@ impl<'a> FmtVisitor<'a> {
         // Re-attach semicolon
         result.push(';');
 
-        Some(result)
+        Ok(result)
     }
 
     pub(crate) fn single_line_fn(
@@ -615,7 +629,10 @@ impl<'a> FmtVisitor<'a> {
                     }
                 },
                 |f| f.span.hi(),
-                |f| self.format_variant(f, one_line_width, pad_discrim_ident_to),
+                |f| {
+                    self.format_variant(f, one_line_width, pad_discrim_ident_to)
+                        .unknown_error()
+                },
                 body_lo,
                 body_hi,
                 false,
@@ -636,7 +653,7 @@ impl<'a> FmtVisitor<'a> {
             .trailing_separator(self.config.trailing_comma())
             .preserve_newline(true);
 
-        let list = write_list(&items, &fmt)?;
+        let list = write_list(&items, &fmt).ok()?;
         result.push_str(&list);
         result.push_str(&original_offset.to_string_with_newline(self.config));
         result.push('}');
@@ -658,10 +675,10 @@ impl<'a> FmtVisitor<'a> {
 
         let context = self.get_context();
         let shape = self.shape();
-        let attrs_str = if context.config.version() == Version::Two {
+        let attrs_str = if context.config.style_edition() >= StyleEdition::Edition2024 {
             field.attrs.rewrite(&context, shape)?
         } else {
-            // Version::One formatting that was off by 1. See issue #5801
+            // StyleEdition::Edition20{15|18|21} formatting that was off by 1. See issue #5801
             field.attrs.rewrite(&context, shape.sub_width(1)?)?
         };
         // sub_width(1) to take the trailing comma into account
@@ -693,12 +710,14 @@ impl<'a> FmtVisitor<'a> {
                 shape,
                 &RhsAssignKind::Expr(&ex.kind, ex.span),
                 RhsTactics::AllowOverflow,
-            )?
+            )
+            .ok()?
         } else {
             variant_body
         };
 
         combine_strs_with_missing_comments(&context, &attrs_str, &variant_body, span, shape, false)
+            .ok()
     }
 
     fn visit_impl_items(&mut self, items: &[ptr::P<ast::AssocItem>]) {
@@ -822,7 +841,8 @@ pub(crate) fn format_impl(
         where_span_end,
         self_ty.span.hi(),
         option,
-    )?;
+    )
+    .ok()?;
 
     // If there is no where-clause, we may have missing comments between the trait name and
     // the opening brace.
@@ -834,7 +854,7 @@ pub(crate) fn format_impl(
                 context,
                 last_line_width(&result),
             ) {
-                Some(ref missing_comment) if !missing_comment.is_empty() => {
+                Ok(ref missing_comment) if !missing_comment.is_empty() => {
                     result.push_str(missing_comment);
                 }
                 _ => (),
@@ -949,7 +969,7 @@ fn format_impl_ref_and_type(
     result.push_str(format_defaultness(defaultness));
     result.push_str(format_safety(safety));
 
-    let shape = if context.config.version() == Version::Two {
+    let shape = if context.config.style_edition() >= StyleEdition::Edition2024 {
         Shape::indented(offset + last_line_width(&result), context.config)
     } else {
         generics_shape_from_config(
@@ -958,7 +978,7 @@ fn format_impl_ref_and_type(
             0,
         )?
     };
-    let generics_str = rewrite_generics(context, "impl", generics, shape)?;
+    let generics_str = rewrite_generics(context, "impl", generics, shape).ok()?;
     result.push_str(&generics_str);
     result.push_str(format_constness_right(constness));
 
@@ -1166,7 +1186,7 @@ pub(crate) fn format_trait(
 
     let shape = Shape::indented(offset, context.config).offset_left(result.len())?;
     let generics_str =
-        rewrite_generics(context, rewrite_ident(context, item.ident), generics, shape)?;
+        rewrite_generics(context, rewrite_ident(context, item.ident), generics, shape).ok()?;
     result.push_str(&generics_str);
 
     // FIXME(#2055): rustfmt fails to format when there are comments between trait bounds.
@@ -1187,7 +1207,8 @@ pub(crate) fn format_trait(
             shape,
             &RhsAssignKind::Bounds,
             RhsTactics::ForceNextLineWithoutIndent,
-        )?;
+        )
+        .ok()?;
     }
 
     // Rewrite where-clause.
@@ -1212,7 +1233,8 @@ pub(crate) fn format_trait(
             None,
             pos_before_where,
             option,
-        )?;
+        )
+        .ok()?;
         // If the where-clause cannot fit on the same line,
         // put the where-clause on a new line
         if !where_clause_str.contains('\n')
@@ -1241,7 +1263,7 @@ pub(crate) fn format_trait(
                     context,
                     last_line_width(&result),
                 ) {
-                    Some(ref missing_comment) if !missing_comment.is_empty() => {
+                    Ok(ref missing_comment) if !missing_comment.is_empty() => {
                         result.push_str(missing_comment);
                     }
                     _ => (),
@@ -1317,7 +1339,11 @@ pub(crate) struct TraitAliasBounds<'a> {
 
 impl<'a> Rewrite for TraitAliasBounds<'a> {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
-        let generic_bounds_str = self.generic_bounds.rewrite(context, shape)?;
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
+        let generic_bounds_str = self.generic_bounds.rewrite_result(context, shape)?;
 
         let mut option = WhereClauseOption::new(true, WhereClauseSpace::None);
         option.allow_single_line();
@@ -1346,7 +1372,7 @@ impl<'a> Rewrite for TraitAliasBounds<'a> {
             shape.indent.to_string_with_newline(context.config)
         };
 
-        Some(format!("{generic_bounds_str}{space}{where_str}"))
+        Ok(format!("{generic_bounds_str}{space}{where_str}"))
     }
 }
 
@@ -1361,7 +1387,7 @@ pub(crate) fn format_trait_alias(
     let alias = rewrite_ident(context, ident);
     // 6 = "trait ", 2 = " ="
     let g_shape = shape.offset_left(6)?.sub_width(2)?;
-    let generics_str = rewrite_generics(context, alias, generics, g_shape)?;
+    let generics_str = rewrite_generics(context, alias, generics, g_shape).ok()?;
     let vis_str = format_visibility(context, vis);
     let lhs = format!("{vis_str}trait {generics_str} =");
     // 1 = ";"
@@ -1377,6 +1403,7 @@ pub(crate) fn format_trait_alias(
         shape.sub_width(1)?,
     )
     .map(|s| s + ";")
+    .ok()
 }
 
 fn format_unit_struct(
@@ -1531,8 +1558,8 @@ fn format_empty_struct_or_tuple(
     // indented shape for proper indenting of multi-line comments
     let shape = Shape::indented(offset.block_indent(context.config), context.config);
     match rewrite_missing_comment(span, shape, context) {
-        Some(ref s) if s.is_empty() => (),
-        Some(ref s) => {
+        Ok(ref s) if s.is_empty() => (),
+        Ok(ref s) => {
             let is_multi_line = !is_single_line(s);
             if is_multi_line || first_line_contains_single_line_comment(s) {
                 let nested_indent_str = offset
@@ -1545,7 +1572,7 @@ fn format_empty_struct_or_tuple(
                 result.push_str(&offset.to_string_with_newline(context.config));
             }
         }
-        None => result.push_str(context.snippet(span)),
+        Err(_) => result.push_str(context.snippet(span)),
     }
     result.push_str(closer);
 }
@@ -1587,7 +1614,7 @@ fn format_tuple_struct(
         Some(generics) => {
             let budget = context.budget(last_line_width(&header_str));
             let shape = Shape::legacy(budget, offset);
-            let generics_str = rewrite_generics(context, "", generics, shape)?;
+            let generics_str = rewrite_generics(context, "", generics, shape).ok()?;
             result.push_str(&generics_str);
 
             let where_budget = context.budget(last_line_width(&result));
@@ -1603,7 +1630,8 @@ fn format_tuple_struct(
                 None,
                 body_hi,
                 option,
-            )?
+            )
+            .ok()?
         }
         None => "".to_owned(),
     };
@@ -1629,7 +1657,8 @@ fn format_tuple_struct(
             mk_sp(lo, span.hi()),
             context.config.fn_call_width(),
             None,
-        )?;
+        )
+        .ok()?;
     }
 
     if !where_clause_str.is_empty()
@@ -1672,7 +1701,7 @@ pub(crate) fn rewrite_type_alias<'a, 'b>(
     indent: Indent,
     visitor_kind: &ItemVisitorKind<'b>,
     span: Span,
-) -> Option<String> {
+) -> RewriteResult {
     use ItemVisitorKind::*;
 
     let ast::TyAlias {
@@ -1683,6 +1712,9 @@ pub(crate) fn rewrite_type_alias<'a, 'b>(
         where_clauses,
     } = *ty_alias_kind;
     let ty_opt = ty.as_ref();
+    let rhs_hi = ty
+        .as_ref()
+        .map_or(where_clauses.before.span.hi(), |ty| ty.span.hi());
     let (ident, vis) = match visitor_kind {
         Item(i) => (i.ident, &i.vis),
         AssocTraitItem(i) | AssocImplItem(i) => (i.ident, &i.vis),
@@ -1697,21 +1729,27 @@ pub(crate) fn rewrite_type_alias<'a, 'b>(
     match (visitor_kind, &op_ty) {
         (Item(_) | AssocTraitItem(_) | ForeignItem(_), Some(op_bounds)) => {
             let op = OpaqueType { bounds: op_bounds };
-            rewrite_ty(rw_info, Some(bounds), Some(&op), vis)
+            rewrite_ty(rw_info, Some(bounds), Some(&op), rhs_hi, vis)
         }
         (Item(_) | AssocTraitItem(_) | ForeignItem(_), None) => {
-            rewrite_ty(rw_info, Some(bounds), ty_opt, vis)
+            rewrite_ty(rw_info, Some(bounds), ty_opt, rhs_hi, vis)
         }
         (AssocImplItem(_), _) => {
             let result = if let Some(op_bounds) = op_ty {
                 let op = OpaqueType { bounds: op_bounds };
-                rewrite_ty(rw_info, Some(bounds), Some(&op), &DEFAULT_VISIBILITY)
+                rewrite_ty(
+                    rw_info,
+                    Some(bounds),
+                    Some(&op),
+                    rhs_hi,
+                    &DEFAULT_VISIBILITY,
+                )
             } else {
-                rewrite_ty(rw_info, Some(bounds), ty_opt, vis)
+                rewrite_ty(rw_info, Some(bounds), ty_opt, rhs_hi, vis)
             }?;
             match defaultness {
-                ast::Defaultness::Default(..) => Some(format!("default {result}")),
-                _ => Some(result),
+                ast::Defaultness::Default(..) => Ok(format!("default {result}")),
+                _ => Ok(result),
             }
         }
     }
@@ -1721,17 +1759,16 @@ fn rewrite_ty<R: Rewrite>(
     rw_info: &TyAliasRewriteInfo<'_, '_>,
     generic_bounds_opt: Option<&ast::GenericBounds>,
     rhs: Option<&R>,
+    // the span of the end of the RHS (or the end of the generics, if there is no RHS)
+    rhs_hi: BytePos,
     vis: &ast::Visibility,
-) -> Option<String> {
+) -> RewriteResult {
     let mut result = String::with_capacity(128);
     let TyAliasRewriteInfo(context, indent, generics, where_clauses, ident, span) = *rw_info;
     let (before_where_predicates, after_where_predicates) = generics
         .where_clause
         .predicates
         .split_at(where_clauses.split);
-    if !after_where_predicates.is_empty() {
-        return None;
-    }
     result.push_str(&format!("{}type ", format_visibility(context, vis)));
     let ident_str = rewrite_ident(context, ident);
 
@@ -1739,9 +1776,11 @@ fn rewrite_ty<R: Rewrite>(
         result.push_str(ident_str)
     } else {
         // 2 = `= `
-        let g_shape = Shape::indented(indent, context.config)
-            .offset_left(result.len())?
-            .sub_width(2)?;
+        let g_shape = Shape::indented(indent, context.config);
+        let g_shape = g_shape
+            .offset_left(result.len())
+            .and_then(|s| s.sub_width(2))
+            .max_width_error(g_shape.width, span)?;
         let generics_str = rewrite_generics(context, ident_str, generics, g_shape)?;
         result.push_str(&generics_str);
     }
@@ -1749,8 +1788,13 @@ fn rewrite_ty<R: Rewrite>(
     if let Some(bounds) = generic_bounds_opt {
         if !bounds.is_empty() {
             // 2 = `: `
-            let shape = Shape::indented(indent, context.config).offset_left(result.len() + 2)?;
-            let type_bounds = bounds.rewrite(context, shape).map(|s| format!(": {}", s))?;
+            let shape = Shape::indented(indent, context.config);
+            let shape = shape
+                .offset_left(result.len() + 2)
+                .max_width_error(shape.width, span)?;
+            let type_bounds = bounds
+                .rewrite_result(context, shape)
+                .map(|s| format!(": {}", s))?;
             result.push_str(&type_bounds);
         }
     }
@@ -1760,7 +1804,7 @@ fn rewrite_ty<R: Rewrite>(
     if rhs.is_none() {
         option.suppress_comma();
     }
-    let where_clause_str = rewrite_where_clause(
+    let before_where_clause_str = rewrite_where_clause(
         context,
         before_where_predicates,
         where_clauses.before.span,
@@ -1772,14 +1816,20 @@ fn rewrite_ty<R: Rewrite>(
         generics.span.hi(),
         option,
     )?;
-    result.push_str(&where_clause_str);
+    result.push_str(&before_where_clause_str);
 
-    if let Some(ty) = rhs {
-        // If there's a where clause, add a newline before the assignment. Otherwise just add a
-        // space.
-        let has_where = !before_where_predicates.is_empty();
-        if has_where {
+    let mut result = if let Some(ty) = rhs {
+        // If there are any where clauses, add a newline before the assignment.
+        // If there is a before where clause, do not indent, but if there is
+        // only an after where clause, additionally indent the type.
+        if !before_where_predicates.is_empty() {
             result.push_str(&indent.to_string_with_newline(context.config));
+        } else if !after_where_predicates.is_empty() {
+            result.push_str(
+                &indent
+                    .block_indent(context.config)
+                    .to_string_with_newline(context.config),
+            );
         } else {
             result.push(' ');
         }
@@ -1791,13 +1841,20 @@ fn rewrite_ty<R: Rewrite>(
 
         let lhs = match comment_span {
             Some(comment_span)
-                if contains_comment(context.snippet_provider.span_to_snippet(comment_span)?) =>
+                if contains_comment(
+                    context
+                        .snippet_provider
+                        .span_to_snippet(comment_span)
+                        .unknown_error()?,
+                ) =>
             {
-                let comment_shape = if has_where {
+                let comment_shape = if !before_where_predicates.is_empty() {
                     Shape::indented(indent, context.config)
                 } else {
-                    Shape::indented(indent, context.config)
-                        .block_left(context.config.tab_spaces())?
+                    let shape = Shape::indented(indent, context.config);
+                    shape
+                        .block_left(context.config.tab_spaces())
+                        .max_width_error(shape.width, span)?
                 };
 
                 combine_strs_with_missing_comments(
@@ -1812,12 +1869,39 @@ fn rewrite_ty<R: Rewrite>(
             _ => format!("{result}="),
         };
 
-        // 1 = `;`
-        let shape = Shape::indented(indent, context.config).sub_width(1)?;
-        rewrite_assign_rhs(context, lhs, &*ty, &RhsAssignKind::Ty, shape).map(|s| s + ";")
+        // 1 = `;` unless there's a trailing where clause
+        let shape = Shape::indented(indent, context.config);
+        let shape = if after_where_predicates.is_empty() {
+            Shape::indented(indent, context.config)
+                .sub_width(1)
+                .max_width_error(shape.width, span)?
+        } else {
+            shape
+        };
+        rewrite_assign_rhs(context, lhs, &*ty, &RhsAssignKind::Ty, shape)?
     } else {
-        Some(format!("{result};"))
+        result
+    };
+
+    if !after_where_predicates.is_empty() {
+        let option = WhereClauseOption::new(true, WhereClauseSpace::Newline);
+        let after_where_clause_str = rewrite_where_clause(
+            context,
+            after_where_predicates,
+            where_clauses.after.span,
+            context.config.brace_style(),
+            Shape::indented(indent, context.config),
+            false,
+            ";",
+            None,
+            rhs_hi,
+            option,
+        )?;
+        result.push_str(&after_where_clause_str);
     }
+
+    result += ";";
+    Ok(result)
 }
 
 fn type_annotation_spacing(config: &Config) -> (&str, &str) {
@@ -1830,10 +1914,10 @@ fn type_annotation_spacing(config: &Config) -> (&str, &str) {
 pub(crate) fn rewrite_struct_field_prefix(
     context: &RewriteContext<'_>,
     field: &ast::FieldDef,
-) -> Option<String> {
+) -> RewriteResult {
     let vis = format_visibility(context, &field.vis);
     let type_annotation_spacing = type_annotation_spacing(context.config);
-    Some(match field.ident {
+    Ok(match field.ident {
         Some(name) => format!(
             "{}{}{}:",
             vis,
@@ -1846,6 +1930,10 @@ pub(crate) fn rewrite_struct_field_prefix(
 
 impl Rewrite for ast::FieldDef {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         rewrite_struct_field(context, self, shape, 0)
     }
 }
@@ -1855,15 +1943,15 @@ pub(crate) fn rewrite_struct_field(
     field: &ast::FieldDef,
     shape: Shape,
     lhs_max_width: usize,
-) -> Option<String> {
+) -> RewriteResult {
     if contains_skip(&field.attrs) {
-        return Some(context.snippet(field.span()).to_owned());
+        return Ok(context.snippet(field.span()).to_owned());
     }
 
     let type_annotation_spacing = type_annotation_spacing(context.config);
     let prefix = rewrite_struct_field_prefix(context, field)?;
 
-    let attrs_str = field.attrs.rewrite(context, shape)?;
+    let attrs_str = field.attrs.rewrite_result(context, shape)?;
     let attrs_extendable = field.ident.is_none() && is_attributes_extendable(&attrs_str);
     let missing_span = if field.attrs.is_empty() {
         mk_sp(field.span.lo(), field.span.lo())
@@ -1893,12 +1981,14 @@ pub(crate) fn rewrite_struct_field(
     if prefix.is_empty() && !attrs_str.is_empty() && attrs_extendable && spacing.is_empty() {
         spacing.push(' ');
     }
+
     let orig_ty = shape
         .offset_left(overhead + spacing.len())
-        .and_then(|ty_shape| field.ty.rewrite(context, ty_shape));
+        .and_then(|ty_shape| field.ty.rewrite_result(context, ty_shape).ok());
+
     if let Some(ref ty) = orig_ty {
         if !ty.contains('\n') && !contains_comment(context.snippet(missing_span)) {
-            return Some(attr_prefix + &spacing + ty);
+            return Ok(attr_prefix + &spacing + ty);
         }
     }
 
@@ -2045,7 +2135,8 @@ fn rewrite_static(
             comments_span,
             true,
         )
-        .and_then(|res| recover_comment_removed(res, static_parts.span, context))
+        .ok()
+        .map(|res| recover_comment_removed(res, static_parts.span, context))
         .map(|s| if s.ends_with(';') { s } else { s + ";" })
     } else {
         Some(format!("{prefix}{ty_str};"))
@@ -2072,19 +2163,34 @@ impl<'a> Rewrite for OpaqueType<'a> {
 
 impl Rewrite for ast::FnRetTy {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         match *self {
-            ast::FnRetTy::Default(_) => Some(String::new()),
+            ast::FnRetTy::Default(_) => Ok(String::new()),
             ast::FnRetTy::Ty(ref ty) => {
-                if context.config.version() == Version::One
+                let arrow_width = "-> ".len();
+                if context.config.style_edition() <= StyleEdition::Edition2021
                     || context.config.indent_style() == IndentStyle::Visual
                 {
-                    let inner_width = shape.width.checked_sub(3)?;
+                    let inner_width = shape
+                        .width
+                        .checked_sub(arrow_width)
+                        .max_width_error(shape.width, self.span())?;
                     return ty
-                        .rewrite(context, Shape::legacy(inner_width, shape.indent + 3))
+                        .rewrite_result(
+                            context,
+                            Shape::legacy(inner_width, shape.indent + arrow_width),
+                        )
                         .map(|r| format!("-> {}", r));
                 }
 
-                ty.rewrite(context, shape.offset_left(3)?)
+                let shape = shape
+                    .offset_left(arrow_width)
+                    .max_width_error(shape.width, self.span())?;
+
+                ty.rewrite_result(context, shape)
                     .map(|s| format!("-> {}", s))
             }
         }
@@ -2126,9 +2232,11 @@ fn get_missing_param_comments(
     };
 
     let comment_before_colon = rewrite_missing_comment(span_before_colon, shape, context)
+        .ok()
         .filter(|comment| !comment.is_empty())
         .map_or(String::new(), |comment| format!(" {}", comment));
     let comment_after_colon = rewrite_missing_comment(span_after_colon, shape, context)
+        .ok()
         .filter(|comment| !comment.is_empty())
         .map_or(String::new(), |comment| format!("{} ", comment));
     (comment_before_colon, comment_after_colon)
@@ -2136,9 +2244,13 @@ fn get_missing_param_comments(
 
 impl Rewrite for ast::Param {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         let param_attrs_result = self
             .attrs
-            .rewrite(context, Shape::legacy(shape.width, shape.indent))?;
+            .rewrite_result(context, Shape::legacy(shape.width, shape.indent))?;
         // N.B. Doc comments aren't typically valid syntax, but could appear
         // in the presence of certain macros - https://github.com/rust-lang/rustfmt/issues/4936
         let (span, has_multiple_attr_lines, has_doc_comments) = if !self.attrs.is_empty() {
@@ -2164,7 +2276,7 @@ impl Rewrite for ast::Param {
         } else if is_named_param(self) {
             let param_name = &self
                 .pat
-                .rewrite(context, Shape::legacy(shape.width, shape.indent))?;
+                .rewrite_result(context, Shape::legacy(shape.width, shape.indent))?;
             let mut result = combine_strs_with_missing_comments(
                 context,
                 &param_attrs_result,
@@ -2181,10 +2293,13 @@ impl Rewrite for ast::Param {
                 result.push_str(colon_spaces(context.config));
                 result.push_str(&after_comment);
                 let overhead = last_line_width(&result);
-                let max_width = shape.width.checked_sub(overhead)?;
-                if let Some(ty_str) = self
+                let max_width = shape
+                    .width
+                    .checked_sub(overhead)
+                    .max_width_error(shape.width, self.span())?;
+                if let Ok(ty_str) = self
                     .ty
-                    .rewrite(context, Shape::legacy(max_width, shape.indent))
+                    .rewrite_result(context, Shape::legacy(max_width, shape.indent))
                 {
                     result.push_str(&ty_str);
                 } else {
@@ -2206,17 +2321,20 @@ impl Rewrite for ast::Param {
                     result.push_str(colon_spaces(context.config));
                     result.push_str(&after_comment);
                     let overhead = last_line_width(&result);
-                    let max_width = shape.width.checked_sub(overhead)?;
+                    let max_width = shape
+                        .width
+                        .checked_sub(overhead)
+                        .max_width_error(shape.width, self.span())?;
                     let ty_str = self
                         .ty
-                        .rewrite(context, Shape::legacy(max_width, shape.indent))?;
+                        .rewrite_result(context, Shape::legacy(max_width, shape.indent))?;
                     result.push_str(&ty_str);
                 }
             }
 
-            Some(result)
+            Ok(result)
         } else {
-            self.ty.rewrite(context, shape)
+            self.ty.rewrite_result(context, shape)
         }
     }
 }
@@ -2228,17 +2346,17 @@ fn rewrite_explicit_self(
     span: Span,
     shape: Shape,
     has_multiple_attr_lines: bool,
-) -> Option<String> {
+) -> RewriteResult {
     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(
+                    let lifetime_str = l.rewrite_result(
                         context,
                         Shape::legacy(context.config.max_width(), Indent::empty()),
                     )?;
-                    Some(combine_strs_with_missing_comments(
+                    Ok(combine_strs_with_missing_comments(
                         context,
                         param_attrs,
                         &format!("&{lifetime_str} {mut_str}self"),
@@ -2247,7 +2365,7 @@ fn rewrite_explicit_self(
                         !has_multiple_attr_lines,
                     )?)
                 }
-                None => Some(combine_strs_with_missing_comments(
+                None => Ok(combine_strs_with_missing_comments(
                     context,
                     param_attrs,
                     &format!("&{mut_str}self"),
@@ -2258,12 +2376,12 @@ fn rewrite_explicit_self(
             }
         }
         ast::SelfKind::Explicit(ref ty, mutability) => {
-            let type_str = ty.rewrite(
+            let type_str = ty.rewrite_result(
                 context,
                 Shape::legacy(context.config.max_width(), Indent::empty()),
             )?;
 
-            Some(combine_strs_with_missing_comments(
+            Ok(combine_strs_with_missing_comments(
                 context,
                 param_attrs,
                 &format!("{}self: {}", format_mutability(mutability), type_str),
@@ -2272,7 +2390,7 @@ fn rewrite_explicit_self(
                 !has_multiple_attr_lines,
             )?)
         }
-        ast::SelfKind::Value(mutability) => Some(combine_strs_with_missing_comments(
+        ast::SelfKind::Value(mutability) => Ok(combine_strs_with_missing_comments(
             context,
             param_attrs,
             &format!("{}self", format_mutability(mutability)),
@@ -2326,7 +2444,7 @@ fn rewrite_fn_base(
     fn_sig: &FnSig<'_>,
     span: Span,
     fn_brace_style: FnBraceStyle,
-) -> Option<(String, bool, bool)> {
+) -> Result<(String, bool, bool), RewriteError> {
     let mut force_new_line_for_brace = false;
 
     let where_clause = &fn_sig.generics.where_clause;
@@ -2370,7 +2488,7 @@ fn rewrite_fn_base(
     // return type later anyway.
     let ret_str = fd
         .output
-        .rewrite(context, Shape::indented(indent, context.config))?;
+        .rewrite_result(context, Shape::indented(indent, context.config))?;
 
     let multi_line_ret_str = ret_str.contains('\n');
     let ret_str_len = if multi_line_ret_str { 0 } else { ret_str.len() };
@@ -2383,7 +2501,7 @@ fn rewrite_fn_base(
         ret_str_len,
         fn_brace_style,
         multi_line_ret_str,
-    )?;
+    );
 
     debug!(
         "rewrite_fn_base: one_line_budget: {}, multi_line_budget: {}, param_indent: {:?}",
@@ -2452,7 +2570,7 @@ fn rewrite_fn_base(
             .last()
             .map_or(false, |last_line| last_line.contains("//"));
 
-        if context.config.version() == Version::Two {
+        if context.config.style_edition() >= StyleEdition::Edition2024 {
             if closing_paren_overflow_max_width {
                 result.push(')');
                 result.push_str(&indent.to_string_with_newline(context.config));
@@ -2495,7 +2613,7 @@ fn rewrite_fn_base(
             }
         };
         let ret_shape = if ret_should_indent {
-            if context.config.version() == Version::One
+            if context.config.style_edition() <= StyleEdition::Edition2021
                 || context.config.indent_style() == IndentStyle::Visual
             {
                 let indent = if param_str.is_empty() {
@@ -2528,7 +2646,7 @@ fn rewrite_fn_base(
                 ret_shape
             }
         } else {
-            if context.config.version() == Version::Two {
+            if context.config.style_edition() >= StyleEdition::Edition2024 {
                 if !param_str.is_empty() || !no_params_and_over_max_width {
                     result.push(' ');
                 }
@@ -2545,7 +2663,7 @@ fn rewrite_fn_base(
         if multi_line_ret_str || ret_should_indent {
             // Now that we know the proper indent and width, we need to
             // re-layout the return type.
-            let ret_str = fd.output.rewrite(context, ret_shape)?;
+            let ret_str = fd.output.rewrite_result(context, ret_shape)?;
             result.push_str(&ret_str);
         } else {
             result.push_str(&ret_str);
@@ -2617,7 +2735,7 @@ fn rewrite_fn_base(
                 context,
                 last_line_width(&result),
             ) {
-                Some(ref missing_comment) if !missing_comment.is_empty() => {
+                Ok(ref missing_comment) if !missing_comment.is_empty() => {
                     result.push_str(missing_comment);
                     force_new_line_for_brace = true;
                 }
@@ -2632,7 +2750,7 @@ fn rewrite_fn_base(
     force_new_line_for_brace |= ends_with_comment;
     force_new_line_for_brace |=
         is_params_multi_lined && context.config.where_single_line() && !where_clause_str.is_empty();
-    Some((result, ends_with_comment, force_new_line_for_brace))
+    Ok((result, ends_with_comment, force_new_line_for_brace))
 }
 
 /// Kind of spaces to put before `where`.
@@ -2703,7 +2821,7 @@ fn rewrite_params(
     param_indent: Indent,
     span: Span,
     variadic: bool,
-) -> Option<String> {
+) -> RewriteResult {
     if params.is_empty() {
         let comment = context
             .snippet(mk_sp(
@@ -2712,7 +2830,7 @@ fn rewrite_params(
                 span.hi() - BytePos(1),
             ))
             .trim();
-        return Some(comment.to_owned());
+        return Ok(comment.to_owned());
     }
     let param_items: Vec<_> = itemize_list(
         context.snippet_provider,
@@ -2723,8 +2841,8 @@ fn rewrite_params(
         |param| param.ty.span.hi(),
         |param| {
             param
-                .rewrite(context, Shape::legacy(multi_line_budget, param_indent))
-                .or_else(|| Some(context.snippet(param.span()).to_owned()))
+                .rewrite_result(context, Shape::legacy(multi_line_budget, param_indent))
+                .or_else(|_| Ok(context.snippet(param.span()).to_owned()))
         },
         span.lo(),
         span.hi(),
@@ -2772,7 +2890,7 @@ fn compute_budgets_for_params(
     ret_str_len: usize,
     fn_brace_style: FnBraceStyle,
     force_vertical_layout: bool,
-) -> Option<(usize, usize, Indent)> {
+) -> (usize, usize, Indent) {
     debug!(
         "compute_budgets_for_params {} {:?}, {}, {:?}",
         result.len(),
@@ -2809,7 +2927,7 @@ fn compute_budgets_for_params(
                 }
             };
 
-            return Some((one_line_budget, multi_line_budget, indent));
+            return (one_line_budget, multi_line_budget, indent);
         }
     }
 
@@ -2821,7 +2939,7 @@ fn compute_budgets_for_params(
         // Account for `)` and possibly ` {`.
         IndentStyle::Visual => new_indent.width() + if ret_str_len == 0 { 1 } else { 3 },
     };
-    Some((0, context.budget(used_space), new_indent))
+    (0, context.budget(used_space), new_indent)
 }
 
 fn newline_for_brace(config: &Config, where_clause: &ast::WhereClause) -> FnBraceStyle {
@@ -2846,12 +2964,12 @@ fn rewrite_generics(
     ident: &str,
     generics: &ast::Generics,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     // FIXME: convert bounds to where-clauses where they get too big or if
     // there is a where-clause at all.
 
     if generics.params.is_empty() {
-        return Some(ident.to_owned());
+        return Ok(ident.to_owned());
     }
 
     let params = generics.params.iter();
@@ -2881,7 +2999,7 @@ fn rewrite_where_clause_rfc_style(
     span_end: Option<BytePos>,
     span_end_before_where: BytePos,
     where_clause_option: WhereClauseOption,
-) -> Option<String> {
+) -> RewriteResult {
     let (where_keyword, allow_single_line) = rewrite_where_keyword(
         context,
         predicates,
@@ -2895,8 +3013,9 @@ fn rewrite_where_clause_rfc_style(
     let clause_shape = shape
         .block()
         .with_max_width(context.config)
-        .block_left(context.config.tab_spaces())?
-        .sub_width(1)?;
+        .block_left(context.config.tab_spaces())
+        .and_then(|s| s.sub_width(1))
+        .max_width_error(shape.width, where_span)?;
     let force_single_line = context.config.where_single_line()
         && predicates.len() == 1
         && !where_clause_option.veto_single_line;
@@ -2921,7 +3040,7 @@ fn rewrite_where_clause_rfc_style(
             clause_shape.indent.to_string_with_newline(context.config)
         };
 
-    Some(format!("{where_keyword}{clause_sep}{preds_str}"))
+    Ok(format!("{where_keyword}{clause_sep}{preds_str}"))
 }
 
 /// Rewrite `where` and comment around it.
@@ -2932,12 +3051,13 @@ fn rewrite_where_keyword(
     shape: Shape,
     span_end_before_where: BytePos,
     where_clause_option: WhereClauseOption,
-) -> Option<(String, bool)> {
+) -> Result<(String, bool), RewriteError> {
     let block_shape = shape.block().with_max_width(context.config);
     // 1 = `,`
     let clause_shape = block_shape
-        .block_left(context.config.tab_spaces())?
-        .sub_width(1)?;
+        .block_left(context.config.tab_spaces())
+        .and_then(|s| s.sub_width(1))
+        .max_width_error(block_shape.width, where_span)?;
 
     let comment_separator = |comment: &str, shape: Shape| {
         if comment.is_empty() {
@@ -2968,7 +3088,7 @@ fn rewrite_where_keyword(
         && comment_before.is_empty()
         && comment_after.is_empty();
 
-    Some((result, allow_single_line))
+    Ok((result, allow_single_line))
 }
 
 /// Rewrite bounds on a where clause.
@@ -2980,7 +3100,7 @@ fn rewrite_bounds_on_where_clause(
     span_end: Option<BytePos>,
     where_clause_option: WhereClauseOption,
     force_single_line: bool,
-) -> Option<String> {
+) -> RewriteResult {
     let span_start = predicates[0].span().lo();
     // If we don't have the start of the next span, then use the end of the
     // predicates, but that means we miss comments.
@@ -2994,7 +3114,7 @@ fn rewrite_bounds_on_where_clause(
         ",",
         |pred| pred.span().lo(),
         |pred| pred.span().hi(),
-        |pred| pred.rewrite(context, shape),
+        |pred| pred.rewrite_result(context, shape),
         span_start,
         span_end,
         false,
@@ -3013,7 +3133,7 @@ fn rewrite_bounds_on_where_clause(
         DefinitiveListTactic::Vertical
     };
 
-    let preserve_newline = context.config.version() == Version::One;
+    let preserve_newline = context.config.style_edition() <= StyleEdition::Edition2021;
 
     let fmt = ListFormatting::new(shape, context.config)
         .tactic(shape_tactic)
@@ -3033,9 +3153,9 @@ fn rewrite_where_clause(
     span_end: Option<BytePos>,
     span_end_before_where: BytePos,
     where_clause_option: WhereClauseOption,
-) -> Option<String> {
+) -> RewriteResult {
     if predicates.is_empty() {
-        return Some(String::new());
+        return Ok(String::new());
     }
 
     if context.config.indent_style() == IndentStyle::Block {
@@ -3075,7 +3195,7 @@ fn rewrite_where_clause(
         ",",
         |pred| pred.span().lo(),
         |pred| pred.span().hi(),
-        |pred| pred.rewrite(context, Shape::legacy(budget, offset)),
+        |pred| pred.rewrite_result(context, Shape::legacy(budget, offset)),
         span_start,
         span_end,
         false,
@@ -3113,13 +3233,13 @@ fn rewrite_where_clause(
         || preds_str.contains('\n')
         || shape.indent.width() + " where ".len() + preds_str.len() + end_length > shape.width
     {
-        Some(format!(
+        Ok(format!(
             "\n{}where {}",
             (shape.indent + extra_indent).to_string(context.config),
             preds_str
         ))
     } else {
-        Some(format!(" where {preds_str}"))
+        Ok(format!(" where {preds_str}"))
     }
 }
 
@@ -3140,14 +3260,14 @@ fn rewrite_comments_before_after_where(
     span_before_where: Span,
     span_after_where: Span,
     shape: Shape,
-) -> Option<(String, String)> {
+) -> Result<(String, String), RewriteError> {
     let before_comment = rewrite_missing_comment(span_before_where, shape, context)?;
     let after_comment = rewrite_missing_comment(
         span_after_where,
         shape.block_indent(context.config.tab_spaces()),
         context,
     )?;
-    Some((before_comment, after_comment))
+    Ok((before_comment, after_comment))
 }
 
 fn format_header(
@@ -3169,7 +3289,7 @@ fn format_header(
         .opt_span_before(mk_sp(vis.span.lo(), ident.span.hi()), item_name.trim())
     {
         let missing_span = mk_sp(after_vis, before_item_name);
-        if let Some(result_with_comment) = combine_strs_with_missing_comments(
+        if let Ok(result_with_comment) = combine_strs_with_missing_comments(
             context,
             &result,
             item_name,
@@ -3203,7 +3323,7 @@ fn format_generics(
     used_width: usize,
 ) -> Option<String> {
     let shape = Shape::legacy(context.budget(used_width + offset.width()), offset);
-    let mut result = rewrite_generics(context, "", generics, shape)?;
+    let mut result = rewrite_generics(context, "", generics, shape).ok()?;
 
     // If the generics are not parameterized then generics.span.hi() == 0,
     // so we use span.lo(), which is the position after `struct Foo`.
@@ -3229,7 +3349,8 @@ fn format_generics(
             Some(span.hi()),
             span_end_before_where,
             option,
-        )?;
+        )
+        .ok()?;
         result.push_str(&where_clause_str);
         (
             brace_pos == BracePos::ForceSameLine || brace_style == BraceStyle::PreferSameLine,
@@ -3253,7 +3374,8 @@ fn format_generics(
                 ),
                 shape,
                 context,
-            ),
+            )
+            .ok(),
         )
     };
     // add missing comments
@@ -3295,7 +3417,11 @@ fn format_generics(
 
 impl Rewrite for ast::ForeignItem {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
-        let attrs_str = self.attrs.rewrite(context, shape)?;
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
+        let attrs_str = self.attrs.rewrite_result(context, shape)?;
         // Drop semicolon or it will be interpreted as comment.
         // FIXME: this may be a faulty span from libsyntax.
         let span = mk_sp(self.span.lo(), self.span.hi() - BytePos(1));
@@ -3328,7 +3454,7 @@ impl Rewrite for ast::ForeignItem {
                         defaultness,
                         Some(&inner_attrs),
                     );
-                    Some(visitor.buffer.to_owned())
+                    Ok(visitor.buffer.to_owned())
                 } else {
                     rewrite_fn_base(
                         context,
@@ -3360,7 +3486,9 @@ impl Rewrite for ast::ForeignItem {
                     prefix,
                     &static_foreign_item.ty,
                     &RhsAssignKind::Ty,
-                    shape.sub_width(1)?,
+                    shape
+                        .sub_width(1)
+                        .max_width_error(shape.width, static_foreign_item.ty.span)?,
                 )
                 .map(|s| s + ";")
             }
@@ -3421,6 +3549,7 @@ fn rewrite_attrs(
         shape,
         allow_extend,
     )
+    .ok()
 }
 
 /// Rewrite an inline mod.
diff --git a/src/tools/rustfmt/src/lib.rs b/src/tools/rustfmt/src/lib.rs
index 4263a49fd72..08cda6913b9 100644
--- a/src/tools/rustfmt/src/lib.rs
+++ b/src/tools/rustfmt/src/lib.rs
@@ -5,9 +5,6 @@
 #![allow(clippy::match_like_matches_macro)]
 #![allow(unreachable_pub)]
 
-// #[macro_use]
-// extern crate tracing;
-
 // N.B. these crates are loaded from the sysroot, so they need extern crate.
 extern crate rustc_ast;
 extern crate rustc_ast_pretty;
@@ -48,8 +45,8 @@ use crate::shape::Indent;
 use crate::utils::indent_next_line;
 
 pub use crate::config::{
-    load_config, CliOptions, Color, Config, Edition, EmitMode, FileLines, FileName, NewlineStyle,
-    Range, Verbosity,
+    CliOptions, Color, Config, Edition, EmitMode, FileLines, FileName, NewlineStyle, Range,
+    StyleEdition, Verbosity, Version, load_config,
 };
 
 pub use crate::format_report_formatter::{FormatReportFormatter, FormatReportFormatterBuilder};
@@ -94,6 +91,7 @@ mod rewrite;
 pub(crate) mod rustfmt_diff;
 mod shape;
 mod skip;
+mod sort;
 pub(crate) mod source_file;
 pub(crate) mod source_map;
 mod spanned;
diff --git a/src/tools/rustfmt/src/lists.rs b/src/tools/rustfmt/src/lists.rs
index 41afef279e9..415144a8abc 100644
--- a/src/tools/rustfmt/src/lists.rs
+++ b/src/tools/rustfmt/src/lists.rs
@@ -5,10 +5,10 @@ use std::iter::Peekable;
 
 use rustc_span::BytePos;
 
-use crate::comment::{find_comment_end, rewrite_comment, FindUncommented};
+use crate::comment::{FindUncommented, find_comment_end, rewrite_comment};
 use crate::config::lists::*;
 use crate::config::{Config, IndentStyle};
-use crate::rewrite::RewriteContext;
+use crate::rewrite::{RewriteContext, RewriteError, RewriteResult};
 use crate::shape::{Indent, Shape};
 use crate::utils::{
     count_newlines, first_line_width, last_line_width, mk_sp, starts_with_newline,
@@ -125,18 +125,18 @@ pub(crate) struct ListItem {
     pub(crate) pre_comment_style: ListItemCommentStyle,
     // Item should include attributes and doc comments. None indicates a failed
     // rewrite.
-    pub(crate) item: Option<String>,
+    pub(crate) item: RewriteResult,
     pub(crate) post_comment: Option<String>,
     // Whether there is extra whitespace before this item.
     pub(crate) new_lines: bool,
 }
 
 impl ListItem {
-    pub(crate) fn empty() -> ListItem {
+    pub(crate) fn from_item(item: RewriteResult) -> ListItem {
         ListItem {
             pre_comment: None,
             pre_comment_style: ListItemCommentStyle::None,
-            item: None,
+            item: item,
             post_comment: None,
             new_lines: false,
         }
@@ -185,7 +185,7 @@ impl ListItem {
         ListItem {
             pre_comment: None,
             pre_comment_style: ListItemCommentStyle::None,
-            item: Some(s.into()),
+            item: Ok(s.into()),
             post_comment: None,
             new_lines: false,
         }
@@ -197,7 +197,11 @@ impl ListItem {
             !matches!(*s, Some(ref s) if !s.is_empty())
         }
 
-        !(empty(&self.pre_comment) && empty(&self.item) && empty(&self.post_comment))
+        fn empty_result(s: &RewriteResult) -> bool {
+            !matches!(*s, Ok(ref s) if !s.is_empty())
+        }
+
+        !(empty(&self.pre_comment) && empty_result(&self.item) && empty(&self.post_comment))
     }
 }
 
@@ -257,7 +261,7 @@ where
 }
 
 // Format a list of commented items into a string.
-pub(crate) fn write_list<I, T>(items: I, formatting: &ListFormatting<'_>) -> Option<String>
+pub(crate) fn write_list<I, T>(items: I, formatting: &ListFormatting<'_>) -> RewriteResult
 where
     I: IntoIterator<Item = T> + Clone,
     T: AsRef<ListItem>,
@@ -281,7 +285,7 @@ where
     let indent_str = &formatting.shape.indent.to_string(formatting.config);
     while let Some((i, item)) = iter.next() {
         let item = item.as_ref();
-        let inner_item = item.item.as_ref()?;
+        let inner_item = item.item.as_ref().or_else(|err| Err(err.clone()))?;
         let first = i == 0;
         let last = iter.peek().is_none();
         let mut separate = match sep_place {
@@ -516,7 +520,7 @@ where
         prev_item_is_nested_import = inner_item.contains("::");
     }
 
-    Some(result)
+    Ok(result)
 }
 
 fn max_width_of_item_with_post_comment<I, T>(
@@ -741,7 +745,7 @@ where
     I: Iterator<Item = T>,
     F1: Fn(&T) -> BytePos,
     F2: Fn(&T) -> BytePos,
-    F3: Fn(&T) -> Option<String>,
+    F3: Fn(&T) -> RewriteResult,
 {
     type Item = ListItem;
 
@@ -775,8 +779,9 @@ where
             ListItem {
                 pre_comment,
                 pre_comment_style,
+                // leave_last is set to true only for rewrite_items
                 item: if self.inner.peek().is_none() && self.leave_last {
-                    None
+                    Err(RewriteError::SkipFormatting)
                 } else {
                     (self.get_item_string)(&item)
                 },
@@ -805,7 +810,7 @@ where
     I: Iterator<Item = T>,
     F1: Fn(&T) -> BytePos,
     F2: Fn(&T) -> BytePos,
-    F3: Fn(&T) -> Option<String>,
+    F3: Fn(&T) -> RewriteResult,
 {
     ListItems {
         snippet_provider,
diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs
index 524fc666fae..5a35e115d8f 100644
--- a/src/tools/rustfmt/src/macros.rs
+++ b/src/tools/rustfmt/src/macros.rs
@@ -10,35 +10,37 @@
 // and those with brackets will be formatted as array literals.
 
 use std::collections::HashMap;
-use std::panic::{catch_unwind, AssertUnwindSafe};
+use std::panic::{AssertUnwindSafe, catch_unwind};
 
 use rustc_ast::token::{BinOpToken, Delimiter, Token, TokenKind};
 use rustc_ast::tokenstream::{RefTokenTreeCursor, TokenStream, TokenTree};
 use rustc_ast::{ast, ptr};
 use rustc_ast_pretty::pprust;
 use rustc_span::{
+    BytePos, DUMMY_SP, Span, Symbol,
     symbol::{self, kw},
-    BytePos, Span, Symbol, DUMMY_SP,
 };
 use tracing::debug;
 
 use crate::comment::{
-    contains_comment, CharClasses, FindUncommented, FullCodeCharKind, LineClasses,
+    CharClasses, FindUncommented, FullCodeCharKind, LineClasses, contains_comment,
 };
+use crate::config::StyleEdition;
 use crate::config::lists::*;
-use crate::config::Version;
-use crate::expr::{rewrite_array, rewrite_assign_rhs, RhsAssignKind};
-use crate::lists::{itemize_list, write_list, ListFormatting};
+use crate::expr::{RhsAssignKind, rewrite_array, rewrite_assign_rhs};
+use crate::lists::{ListFormatting, itemize_list, write_list};
 use crate::overflow;
 use crate::parse::macros::lazy_static::parse_lazy_static;
-use crate::parse::macros::{parse_expr, parse_macro_args, ParsedMacroArgs};
-use crate::rewrite::{Rewrite, RewriteContext};
+use crate::parse::macros::{ParsedMacroArgs, parse_expr, parse_macro_args};
+use crate::rewrite::{
+    MacroErrorKind, Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult,
+};
 use crate::shape::{Indent, Shape};
 use crate::source_map::SpanUtils;
 use crate::spanned::Spanned;
 use crate::utils::{
-    filtered_str_fits, format_visibility, indent_next_line, is_empty_line, mk_sp,
-    remove_trailing_white_spaces, rewrite_ident, trim_left_preserve_layout, NodeIdExt,
+    NodeIdExt, filtered_str_fits, format_visibility, indent_next_line, is_empty_line, mk_sp,
+    remove_trailing_white_spaces, rewrite_ident, trim_left_preserve_layout,
 };
 use crate::visitor::FmtVisitor;
 
@@ -72,22 +74,30 @@ impl MacroArg {
 
 impl Rewrite for ast::Item {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         let mut visitor = crate::visitor::FmtVisitor::from_context(context);
         visitor.block_indent = shape.indent;
         visitor.last_pos = self.span().lo();
         visitor.visit_item(self);
-        Some(visitor.buffer.to_owned())
+        Ok(visitor.buffer.to_owned())
     }
 }
 
 impl Rewrite for MacroArg {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         match *self {
-            MacroArg::Expr(ref expr) => expr.rewrite(context, shape),
-            MacroArg::Ty(ref ty) => ty.rewrite(context, shape),
-            MacroArg::Pat(ref pat) => pat.rewrite(context, shape),
-            MacroArg::Item(ref item) => item.rewrite(context, shape),
-            MacroArg::Keyword(ident, _) => Some(ident.name.to_string()),
+            MacroArg::Expr(ref expr) => expr.rewrite_result(context, shape),
+            MacroArg::Ty(ref ty) => ty.rewrite_result(context, shape),
+            MacroArg::Pat(ref pat) => pat.rewrite_result(context, shape),
+            MacroArg::Item(ref item) => item.rewrite_result(context, shape),
+            MacroArg::Keyword(ident, _) => Ok(ident.name.to_string()),
         }
     }
 }
@@ -111,12 +121,14 @@ fn rewrite_macro_name(
 }
 
 // Use this on failing to format the macro call.
+// TODO(ding-young) We should also report macro parse failure to tell users why given snippet
+// is left unformatted. One possible improvement is appending formatting error to context.report
 fn return_macro_parse_failure_fallback(
     context: &RewriteContext<'_>,
     indent: Indent,
     position: MacroPosition,
     span: Span,
-) -> Option<String> {
+) -> RewriteResult {
     // Mark this as a failure however we format it
     context.macro_rewrite_failure.replace(true);
 
@@ -134,7 +146,8 @@ fn return_macro_parse_failure_fallback(
         })
         .unwrap_or(false);
     if is_like_block_indent_style {
-        return trim_left_preserve_layout(context.snippet(span), indent, context.config);
+        return trim_left_preserve_layout(context.snippet(span), indent, context.config)
+            .macro_error(MacroErrorKind::Unknown, span);
     }
 
     context.skipped_range.borrow_mut().push((
@@ -147,7 +160,7 @@ fn return_macro_parse_failure_fallback(
     if position == MacroPosition::Item {
         snippet.push(';');
     }
-    Some(snippet)
+    Ok(snippet)
 }
 
 pub(crate) fn rewrite_macro(
@@ -156,13 +169,13 @@ pub(crate) fn rewrite_macro(
     context: &RewriteContext<'_>,
     shape: Shape,
     position: MacroPosition,
-) -> Option<String> {
+) -> RewriteResult {
     let should_skip = context
         .skip_context
         .macros
         .skip(context.snippet(mac.path.span));
     if should_skip {
-        None
+        Err(RewriteError::SkipFormatting)
     } else {
         let guard = context.enter_macro();
         let result = catch_unwind(AssertUnwindSafe(|| {
@@ -176,9 +189,16 @@ pub(crate) fn rewrite_macro(
             )
         }));
         match result {
-            Err(..) | Ok(None) => {
+            Err(..) => {
                 context.macro_rewrite_failure.replace(true);
-                None
+                Err(RewriteError::MacroFailure {
+                    kind: MacroErrorKind::Unknown,
+                    span: mac.span(),
+                })
+            }
+            Ok(Err(e)) => {
+                context.macro_rewrite_failure.replace(true);
+                Err(e)
             }
             Ok(rw) => rw,
         }
@@ -192,11 +212,11 @@ fn rewrite_macro_inner(
     shape: Shape,
     position: MacroPosition,
     is_nested_macro: bool,
-) -> Option<String> {
+) -> RewriteResult {
     if context.config.use_try_shorthand() {
         if let Some(expr) = convert_try_mac(mac, context) {
             context.leave_macro();
-            return expr.rewrite(context, shape);
+            return expr.rewrite_result(context, shape);
         }
     }
 
@@ -216,21 +236,27 @@ fn rewrite_macro_inner(
     if ts.is_empty() && !has_comment {
         return match style {
             Delimiter::Parenthesis if position == MacroPosition::Item => {
-                Some(format!("{macro_name}();"))
+                Ok(format!("{macro_name}();"))
             }
-            Delimiter::Bracket if position == MacroPosition::Item => {
-                Some(format!("{macro_name}[];"))
-            }
-            Delimiter::Parenthesis => Some(format!("{macro_name}()")),
-            Delimiter::Bracket => Some(format!("{macro_name}[]")),
-            Delimiter::Brace => Some(format!("{macro_name} {{}}")),
+            Delimiter::Bracket if position == MacroPosition::Item => Ok(format!("{macro_name}[];")),
+            Delimiter::Parenthesis => Ok(format!("{macro_name}()")),
+            Delimiter::Bracket => Ok(format!("{macro_name}[]")),
+            Delimiter::Brace => Ok(format!("{macro_name} {{}}")),
             _ => unreachable!(),
         };
     }
     // Format well-known macros which cannot be parsed as a valid AST.
     if macro_name == "lazy_static!" && !has_comment {
-        if let success @ Some(..) = format_lazy_static(context, shape, ts.clone()) {
-            return success;
+        match format_lazy_static(context, shape, ts.clone(), mac.span()) {
+            Ok(rw) => return Ok(rw),
+            Err(err) => match err {
+                // We will move on to parsing macro args just like other macros
+                // if we could not parse lazy_static! with known syntax
+                RewriteError::MacroFailure { kind, span: _ }
+                    if kind == MacroErrorKind::ParseFailure => {}
+                // If formatting fails even though parsing succeeds, return the err early
+                _ => return Err(err),
+            },
         }
     }
 
@@ -267,7 +293,7 @@ fn rewrite_macro_inner(
         Delimiter::Parenthesis => {
             // Handle special case: `vec!(expr; expr)`
             if vec_with_semi {
-                handle_vec_semi(context, shape, arg_vec, macro_name, style)
+                handle_vec_semi(context, shape, arg_vec, macro_name, style, mac.span())
             } else {
                 // Format macro invocation as function call, preserve the trailing
                 // comma because not all macros support them.
@@ -293,7 +319,7 @@ fn rewrite_macro_inner(
         Delimiter::Bracket => {
             // Handle special case: `vec![expr; expr]`
             if vec_with_semi {
-                handle_vec_semi(context, shape, arg_vec, macro_name, style)
+                handle_vec_semi(context, shape, arg_vec, macro_name, style, mac.span())
             } else {
                 // If we are rewriting `vec!` macro or other special macros,
                 // then we can rewrite this as a usual array literal.
@@ -323,7 +349,7 @@ fn rewrite_macro_inner(
                     _ => "",
                 };
 
-                Some(format!("{rewrite}{comma}"))
+                Ok(format!("{rewrite}{comma}"))
             }
         }
         Delimiter::Brace => {
@@ -332,8 +358,8 @@ fn rewrite_macro_inner(
             // anything in between the braces (for now).
             let snippet = context.snippet(mac.span()).trim_start_matches(|c| c != '{');
             match trim_left_preserve_layout(snippet, shape.indent, context.config) {
-                Some(macro_body) => Some(format!("{macro_name} {macro_body}")),
-                None => Some(format!("{macro_name} {snippet}")),
+                Some(macro_body) => Ok(format!("{macro_name} {macro_body}")),
+                None => Ok(format!("{macro_name} {snippet}")),
             }
         }
         _ => unreachable!(),
@@ -346,28 +372,32 @@ fn handle_vec_semi(
     arg_vec: Vec<MacroArg>,
     macro_name: String,
     delim_token: Delimiter,
-) -> Option<String> {
+    span: Span,
+) -> RewriteResult {
     let (left, right) = match delim_token {
         Delimiter::Parenthesis => ("(", ")"),
         Delimiter::Bracket => ("[", "]"),
         _ => unreachable!(),
     };
 
-    let mac_shape = shape.offset_left(macro_name.len())?;
+    // Should we return MaxWidthError, Or Macro failure
+    let mac_shape = shape
+        .offset_left(macro_name.len())
+        .max_width_error(shape.width, span)?;
     // 8 = `vec![]` + `; ` or `vec!()` + `; `
     let total_overhead = 8;
     let nested_shape = mac_shape.block_indent(context.config.tab_spaces());
-    let lhs = arg_vec[0].rewrite(context, nested_shape)?;
-    let rhs = arg_vec[1].rewrite(context, nested_shape)?;
+    let lhs = arg_vec[0].rewrite_result(context, nested_shape)?;
+    let rhs = arg_vec[1].rewrite_result(context, nested_shape)?;
     if !lhs.contains('\n')
         && !rhs.contains('\n')
         && lhs.len() + rhs.len() + total_overhead <= shape.width
     {
         // macro_name(lhs; rhs) or macro_name[lhs; rhs]
-        Some(format!("{macro_name}{left}{lhs}; {rhs}{right}"))
+        Ok(format!("{macro_name}{left}{lhs}; {rhs}{right}"))
     } else {
         // macro_name(\nlhs;\nrhs\n) or macro_name[\nlhs;\nrhs\n]
-        Some(format!(
+        Ok(format!(
             "{}{}{}{};{}{}{}{}",
             macro_name,
             left,
@@ -385,7 +415,7 @@ fn rewrite_empty_macro_def_body(
     context: &RewriteContext<'_>,
     span: Span,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     // Create an empty, dummy `ast::Block` representing an empty macro body
     let block = ast::Block {
         stmts: vec![].into(),
@@ -395,7 +425,7 @@ fn rewrite_empty_macro_def_body(
         tokens: None,
         could_be_bare_literal: false,
     };
-    block.rewrite(context, shape)
+    block.rewrite_result(context, shape)
 }
 
 pub(crate) fn rewrite_macro_def(
@@ -406,8 +436,8 @@ pub(crate) fn rewrite_macro_def(
     ident: symbol::Ident,
     vis: &ast::Visibility,
     span: Span,
-) -> Option<String> {
-    let snippet = Some(remove_trailing_white_spaces(context.snippet(span)));
+) -> RewriteResult {
+    let snippet = Ok(remove_trailing_white_spaces(context.snippet(span)));
     if snippet.as_ref().map_or(true, |s| s.ends_with(';')) {
         return snippet;
     }
@@ -442,7 +472,7 @@ pub(crate) fn rewrite_macro_def(
         let lo = context.snippet_provider.span_before(span, "{");
         result += " ";
         result += &rewrite_empty_macro_def_body(context, span.with_lo(lo), shape)?;
-        return Some(result);
+        return Ok(result);
     }
 
     let branch_items = itemize_list(
@@ -453,13 +483,14 @@ pub(crate) fn rewrite_macro_def(
         |branch| branch.span.lo(),
         |branch| branch.span.hi(),
         |branch| match branch.rewrite(context, arm_shape, multi_branch_style) {
-            Some(v) => Some(v),
+            Ok(v) => Ok(v),
             // if the rewrite returned None because a macro could not be rewritten, then return the
             // original body
-            None if context.macro_rewrite_failure.get() => {
-                Some(context.snippet(branch.body).trim().to_string())
+            // TODO(ding-young) report rewrite error even if we return Ok with original snippet
+            Err(_) if context.macro_rewrite_failure.get() => {
+                Ok(context.snippet(branch.body).trim().to_string())
             }
-            None => None,
+            Err(e) => Err(e),
         },
         context.snippet_provider.span_after(span, "{"),
         span.hi(),
@@ -478,8 +509,8 @@ pub(crate) fn rewrite_macro_def(
     }
 
     match write_list(&branch_items, &fmt) {
-        Some(ref s) => result += s,
-        None => return snippet,
+        Ok(ref s) => result += s,
+        Err(_) => return snippet,
     }
 
     if multi_branch_style {
@@ -487,7 +518,7 @@ pub(crate) fn rewrite_macro_def(
         result += "}";
     }
 
-    Some(result)
+    Ok(result)
 }
 
 fn register_metavariable(
@@ -639,12 +670,13 @@ impl MacroArgKind {
         context: &RewriteContext<'_>,
         shape: Shape,
         use_multiple_lines: bool,
-    ) -> Option<String> {
-        let rewrite_delimited_inner = |delim_tok, args| -> Option<(String, String, String)> {
+    ) -> RewriteResult {
+        type DelimitedArgsRewrite = Result<(String, String, String), RewriteError>;
+        let rewrite_delimited_inner = |delim_tok, args| -> DelimitedArgsRewrite {
             let inner = wrap_macro_args(context, args, shape)?;
             let (lhs, rhs) = delim_token_to_str(context, delim_tok, shape, false, inner.is_empty());
             if lhs.len() + inner.len() + rhs.len() <= shape.width {
-                return Some((lhs, inner, rhs));
+                return Ok((lhs, inner, rhs));
             }
 
             let (lhs, rhs) = delim_token_to_str(context, delim_tok, shape, true, false);
@@ -652,27 +684,27 @@ impl MacroArgKind {
                 .block_indent(context.config.tab_spaces())
                 .with_max_width(context.config);
             let inner = wrap_macro_args(context, args, nested_shape)?;
-            Some((lhs, inner, rhs))
+            Ok((lhs, inner, rhs))
         };
 
         match *self {
-            MacroArgKind::MetaVariable(ty, ref name) => Some(format!("${name}:{ty}")),
+            MacroArgKind::MetaVariable(ty, ref name) => Ok(format!("${name}:{ty}")),
             MacroArgKind::Repeat(delim_tok, ref args, ref another, ref tok) => {
                 let (lhs, inner, rhs) = rewrite_delimited_inner(delim_tok, args)?;
                 let another = another
                     .as_ref()
-                    .and_then(|a| a.rewrite(context, shape, use_multiple_lines))
+                    .and_then(|a| a.rewrite(context, shape, use_multiple_lines).ok())
                     .unwrap_or_else(|| "".to_owned());
                 let repeat_tok = pprust::token_to_string(tok);
 
-                Some(format!("${lhs}{inner}{rhs}{another}{repeat_tok}"))
+                Ok(format!("${lhs}{inner}{rhs}{another}{repeat_tok}"))
             }
             MacroArgKind::Delimited(delim_tok, ref args) => {
                 rewrite_delimited_inner(delim_tok, args)
                     .map(|(lhs, inner, rhs)| format!("{}{}{}", lhs, inner, rhs))
             }
-            MacroArgKind::Separator(ref sep, ref prefix) => Some(format!("{prefix}{sep} ")),
-            MacroArgKind::Other(ref inner, ref prefix) => Some(format!("{prefix}{inner}")),
+            MacroArgKind::Separator(ref sep, ref prefix) => Ok(format!("{prefix}{sep} ")),
+            MacroArgKind::Other(ref inner, ref prefix) => Ok(format!("{prefix}{inner}")),
         }
     }
 }
@@ -688,7 +720,7 @@ impl ParsedMacroArg {
         context: &RewriteContext<'_>,
         shape: Shape,
         use_multiple_lines: bool,
-    ) -> Option<String> {
+    ) -> RewriteResult {
         self.kind.rewrite(context, shape, use_multiple_lines)
     }
 }
@@ -966,9 +998,9 @@ fn wrap_macro_args(
     context: &RewriteContext<'_>,
     args: &[ParsedMacroArg],
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     wrap_macro_args_inner(context, args, shape, false)
-        .or_else(|| wrap_macro_args_inner(context, args, shape, true))
+        .or_else(|_| wrap_macro_args_inner(context, args, shape, true))
 }
 
 fn wrap_macro_args_inner(
@@ -976,7 +1008,7 @@ fn wrap_macro_args_inner(
     args: &[ParsedMacroArg],
     shape: Shape,
     use_multiple_lines: bool,
-) -> Option<String> {
+) -> RewriteResult {
     let mut result = String::with_capacity(128);
     let mut iter = args.iter().peekable();
     let indent_str = shape.indent.to_string_with_newline(context.config);
@@ -1002,9 +1034,9 @@ fn wrap_macro_args_inner(
     }
 
     if !use_multiple_lines && result.len() >= shape.width {
-        None
+        Err(RewriteError::Unknown)
     } else {
-        Some(result)
+        Ok(result)
     }
 }
 
@@ -1012,22 +1044,21 @@ fn wrap_macro_args_inner(
 // for some common cases. I hope the basic logic is sufficient. Note that the
 // meaning of some tokens is a bit different here from usual Rust, e.g., `*`
 // and `(`/`)` have special meaning.
-//
-// We always try and format on one line.
-// FIXME: Use multi-line when every thing does not fit on one line.
 fn format_macro_args(
     context: &RewriteContext<'_>,
     token_stream: TokenStream,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
+    let span = span_for_token_stream(&token_stream);
     if !context.config.format_macro_matchers() {
-        let span = span_for_token_stream(&token_stream);
-        return Some(match span {
+        return Ok(match span {
             Some(span) => context.snippet(span).to_owned(),
             None => String::new(),
         });
     }
-    let parsed_args = MacroArgParser::new().parse(token_stream)?;
+    let parsed_args = MacroArgParser::new()
+        .parse(token_stream)
+        .macro_error(MacroErrorKind::ParseFailure, span.unwrap())?;
     wrap_macro_args(context, &parsed_args, shape)
 }
 
@@ -1132,9 +1163,9 @@ pub(crate) fn convert_try_mac(
 
 pub(crate) fn macro_style(mac: &ast::MacCall, context: &RewriteContext<'_>) -> Delimiter {
     let snippet = context.snippet(mac.span());
-    let paren_pos = snippet.find_uncommented("(").unwrap_or(usize::max_value());
-    let bracket_pos = snippet.find_uncommented("[").unwrap_or(usize::max_value());
-    let brace_pos = snippet.find_uncommented("{").unwrap_or(usize::max_value());
+    let paren_pos = snippet.find_uncommented("(").unwrap_or(usize::MAX);
+    let bracket_pos = snippet.find_uncommented("[").unwrap_or(usize::MAX);
+    let brace_pos = snippet.find_uncommented("{").unwrap_or(usize::MAX);
 
     if paren_pos < bracket_pos && paren_pos < brace_pos {
         Delimiter::Parenthesis
@@ -1242,23 +1273,31 @@ impl MacroBranch {
         context: &RewriteContext<'_>,
         shape: Shape,
         multi_branch_style: bool,
-    ) -> Option<String> {
+    ) -> RewriteResult {
         // Only attempt to format function-like macros.
         if self.args_paren_kind != Delimiter::Parenthesis {
             // FIXME(#1539): implement for non-sugared macros.
-            return None;
+            return Err(RewriteError::MacroFailure {
+                kind: MacroErrorKind::Unknown,
+                span: self.span,
+            });
         }
 
         let old_body = context.snippet(self.body).trim();
         let has_block_body = old_body.starts_with('{');
         let mut prefix_width = 5; // 5 = " => {"
-        if context.config.version() == Version::Two {
+        if context.config.style_edition() >= StyleEdition::Edition2024 {
             if has_block_body {
                 prefix_width = 6; // 6 = " => {{"
             }
         }
-        let mut result =
-            format_macro_args(context, self.args.clone(), shape.sub_width(prefix_width)?)?;
+        let mut result = format_macro_args(
+            context,
+            self.args.clone(),
+            shape
+                .sub_width(prefix_width)
+                .max_width_error(shape.width, self.span)?,
+        )?;
 
         if multi_branch_style {
             result += " =>";
@@ -1267,7 +1306,7 @@ impl MacroBranch {
         if !context.config.format_macro_bodies() {
             result += " ";
             result += context.snippet(self.whole_body);
-            return Some(result);
+            return Ok(result);
         }
 
         // The macro body is the most interesting part. It might end up as various
@@ -1276,7 +1315,8 @@ impl MacroBranch {
         // `$$`). We'll try and format like an AST node, but we'll substitute
         // variables for new names with the same length first.
 
-        let (body_str, substs) = replace_names(old_body)?;
+        let (body_str, substs) =
+            replace_names(old_body).macro_error(MacroErrorKind::ReplaceMacroVariable, self.span)?;
 
         let mut config = context.config.clone();
         config.set().show_parse_errors(false);
@@ -1299,13 +1339,21 @@ impl MacroBranch {
                 config.set().max_width(new_width);
                 match crate::format_code_block(&body_str, &config, true) {
                     Some(new_body) => new_body,
-                    None => return None,
+                    None => {
+                        return Err(RewriteError::MacroFailure {
+                            kind: MacroErrorKind::Unknown,
+                            span: self.span,
+                        });
+                    }
                 }
             }
         };
 
         if !filtered_str_fits(&new_body_snippet.snippet, config.max_width(), shape) {
-            return None;
+            return Err(RewriteError::ExceedsMaxWidth {
+                configured_width: shape.width,
+                span: self.span,
+            });
         }
 
         // Indent the body since it is in a block.
@@ -1331,7 +1379,10 @@ impl MacroBranch {
         for (old, new) in &substs {
             if old_body.contains(new) {
                 debug!("rewrite_macro_def: bailing matching variable: `{}`", new);
-                return None;
+                return Err(RewriteError::MacroFailure {
+                    kind: MacroErrorKind::ReplaceMacroVariable,
+                    span: self.span,
+                });
             }
             new_body = new_body.replace(new, old);
         }
@@ -1346,7 +1397,7 @@ impl MacroBranch {
 
         result += "}";
 
-        Some(result)
+        Ok(result)
     }
 }
 
@@ -1366,7 +1417,8 @@ fn format_lazy_static(
     context: &RewriteContext<'_>,
     shape: Shape,
     ts: TokenStream,
-) -> Option<String> {
+    span: Span,
+) -> RewriteResult {
     let mut result = String::with_capacity(1024);
     let nested_shape = shape
         .block_indent(context.config.tab_spaces())
@@ -1375,7 +1427,8 @@ fn format_lazy_static(
     result.push_str("lazy_static! {");
     result.push_str(&nested_shape.indent.to_string_with_newline(context.config));
 
-    let parsed_elems = parse_lazy_static(context, ts)?;
+    let parsed_elems =
+        parse_lazy_static(context, ts).macro_error(MacroErrorKind::ParseFailure, span)?;
     let last = parsed_elems.len() - 1;
     for (i, (vis, id, ty, expr)) in parsed_elems.iter().enumerate() {
         // Rewrite as a static item.
@@ -1385,14 +1438,16 @@ fn format_lazy_static(
             "{}static ref {}: {} =",
             vis,
             id,
-            ty.rewrite(context, nested_shape)?
+            ty.rewrite_result(context, nested_shape)?
         ));
         result.push_str(&rewrite_assign_rhs(
             context,
             stmt,
             &*expr,
             &RhsAssignKind::Expr(&expr.kind, expr.span),
-            nested_shape.sub_width(1)?,
+            nested_shape
+                .sub_width(1)
+                .max_width_error(nested_shape.width, expr.span)?,
         )?);
         result.push(';');
         if i != last {
@@ -1403,7 +1458,7 @@ fn format_lazy_static(
     result.push_str(&shape.indent.to_string_with_newline(context.config));
     result.push('}');
 
-    Some(result)
+    Ok(result)
 }
 
 fn rewrite_macro_with_items(
@@ -1415,12 +1470,12 @@ fn rewrite_macro_with_items(
     original_style: Delimiter,
     position: MacroPosition,
     span: Span,
-) -> Option<String> {
+) -> RewriteResult {
     let style_to_delims = |style| match style {
-        Delimiter::Parenthesis => Some(("(", ")")),
-        Delimiter::Bracket => Some(("[", "]")),
-        Delimiter::Brace => Some((" {", "}")),
-        _ => None,
+        Delimiter::Parenthesis => Ok(("(", ")")),
+        Delimiter::Bracket => Ok(("[", "]")),
+        Delimiter::Brace => Ok((" {", "}")),
+        _ => Err(RewriteError::Unknown),
     };
 
     let (opener, closer) = style_to_delims(style)?;
@@ -1442,7 +1497,7 @@ fn rewrite_macro_with_items(
     for item in items {
         let item = match item {
             MacroArg::Item(item) => item,
-            _ => return None,
+            _ => return Err(RewriteError::Unknown),
         };
         visitor.visit_item(item);
     }
@@ -1455,5 +1510,5 @@ fn rewrite_macro_with_items(
     result.push_str(&shape.indent.to_string_with_newline(context.config));
     result.push_str(closer);
     result.push_str(trailing_semicolon);
-    Some(result)
+    Ok(result)
 }
diff --git a/src/tools/rustfmt/src/matches.rs b/src/tools/rustfmt/src/matches.rs
index 30bf6271b2e..8f62648e576 100644
--- a/src/tools/rustfmt/src/matches.rs
+++ b/src/tools/rustfmt/src/matches.rs
@@ -2,19 +2,19 @@
 
 use std::iter::repeat;
 
-use rustc_ast::{ast, ptr, MatchKind};
+use rustc_ast::{MatchKind, ast, ptr};
 use rustc_span::{BytePos, Span};
 use tracing::debug;
 
-use crate::comment::{combine_strs_with_missing_comments, rewrite_comment, FindUncommented};
+use crate::comment::{FindUncommented, combine_strs_with_missing_comments, rewrite_comment};
 use crate::config::lists::*;
-use crate::config::{Config, ControlBraceStyle, IndentStyle, MatchArmLeadingPipe, Version};
+use crate::config::{Config, ControlBraceStyle, IndentStyle, MatchArmLeadingPipe, StyleEdition};
 use crate::expr::{
-    format_expr, is_empty_block, is_simple_block, is_unsafe_block, prefer_next_line, rewrite_cond,
-    ExprType, RhsTactics,
+    ExprType, RhsTactics, format_expr, is_empty_block, is_simple_block, is_unsafe_block,
+    prefer_next_line, rewrite_cond,
 };
-use crate::lists::{itemize_list, write_list, ListFormatting};
-use crate::rewrite::{Rewrite, RewriteContext};
+use crate::lists::{ListFormatting, itemize_list, write_list};
+use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
 use crate::shape::Shape;
 use crate::source_map::SpanUtils;
 use crate::spanned::Spanned;
@@ -56,6 +56,10 @@ impl<'a> Spanned for ArmWrapper<'a> {
 
 impl<'a> Rewrite for ArmWrapper<'a> {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         rewrite_match_arm(
             context,
             self.arm,
@@ -74,7 +78,7 @@ pub(crate) fn rewrite_match(
     span: Span,
     attrs: &[ast::Attribute],
     match_kind: MatchKind,
-) -> Option<String> {
+) -> RewriteResult {
     // Do not take the rhs overhead from the upper expressions into account
     // when rewriting match condition.
     let cond_shape = Shape {
@@ -83,10 +87,14 @@ pub(crate) fn rewrite_match(
     };
     // 6 = `match `
     let cond_shape = match context.config.indent_style() {
-        IndentStyle::Visual => cond_shape.shrink_left(6)?,
-        IndentStyle::Block => cond_shape.offset_left(6)?,
+        IndentStyle::Visual => cond_shape
+            .shrink_left(6)
+            .max_width_error(shape.width, span)?,
+        IndentStyle::Block => cond_shape
+            .offset_left(6)
+            .max_width_error(shape.width, span)?,
     };
-    let cond_str = cond.rewrite(context, cond_shape)?;
+    let cond_str = cond.rewrite_result(context, cond_shape)?;
     let alt_block_sep = &shape.indent.to_string_with_newline(context.config);
     let block_sep = match context.config.control_brace_style() {
         ControlBraceStyle::AlwaysNextLine => alt_block_sep,
@@ -105,12 +113,13 @@ pub(crate) fn rewrite_match(
     let inner_attrs_str = if inner_attrs.is_empty() {
         String::new()
     } else {
-        let shape = match context.config.version() {
-            Version::One => shape,
-            _ => shape.block_indent(context.config.tab_spaces()),
+        let shape = if context.config.style_edition() <= StyleEdition::Edition2021 {
+            shape
+        } else {
+            shape.block_indent(context.config.tab_spaces())
         };
         inner_attrs
-            .rewrite(context, shape)
+            .rewrite_result(context, shape)
             .map(|s| format!("{}{}\n", nested_indent_str, s))?
     };
 
@@ -130,16 +139,16 @@ pub(crate) fn rewrite_match(
     if arms.is_empty() {
         let snippet = context.snippet(mk_sp(open_brace_pos, span.hi() - BytePos(1)));
         if snippet.trim().is_empty() {
-            Some(format!("match {cond_str} {{}}"))
+            Ok(format!("match {cond_str} {{}}"))
         } else {
             // Empty match with comments or inner attributes? We are not going to bother, sorry ;)
-            Some(context.snippet(span).to_owned())
+            Ok(context.snippet(span).to_owned())
         }
     } else {
         let span_after_cond = mk_sp(cond.span.hi(), span.hi());
 
         match match_kind {
-            MatchKind::Prefix => Some(format!(
+            MatchKind::Prefix => Ok(format!(
                 "match {}{}{{\n{}{}{}\n{}}}",
                 cond_str,
                 block_sep,
@@ -148,7 +157,7 @@ pub(crate) fn rewrite_match(
                 rewrite_match_arms(context, arms, shape, span_after_cond, open_brace_pos)?,
                 shape.indent.to_string(context.config),
             )),
-            MatchKind::Postfix => Some(format!(
+            MatchKind::Postfix => Ok(format!(
                 "{}.match{}{{\n{}{}{}\n{}}}",
                 cond_str,
                 block_sep,
@@ -198,7 +207,7 @@ fn rewrite_match_arms(
     shape: Shape,
     span: Span,
     open_brace_pos: BytePos,
-) -> Option<String> {
+) -> RewriteResult {
     let arm_shape = shape
         .block_indent(context.config.tab_spaces())
         .with_max_width(context.config);
@@ -218,7 +227,7 @@ fn rewrite_match_arms(
         "|",
         |arm| arm.span().lo(),
         |arm| arm.span().hi(),
-        |arm| arm.rewrite(context, arm_shape),
+        |arm| arm.rewrite_result(context, arm_shape),
         open_brace_pos,
         span.hi(),
         false,
@@ -238,19 +247,19 @@ fn rewrite_match_arm(
     shape: Shape,
     is_last: bool,
     has_leading_pipe: bool,
-) -> Option<String> {
+) -> RewriteResult {
     let (missing_span, attrs_str) = if !arm.attrs.is_empty() {
         if contains_skip(&arm.attrs) {
-            let (_, body) = flatten_arm_body(context, arm.body.as_deref()?, None);
+            let (_, body) = flatten_arm_body(context, arm.body.as_deref().unknown_error()?, None);
             // `arm.span()` does not include trailing comma, add it manually.
-            return Some(format!(
+            return Ok(format!(
                 "{}{}",
                 context.snippet(arm.span()),
                 arm_comma(context.config, body, is_last),
             ));
         }
         let missing_span = mk_sp(arm.attrs[arm.attrs.len() - 1].span.hi(), arm.pat.span.lo());
-        (missing_span, arm.attrs.rewrite(context, shape)?)
+        (missing_span, arm.attrs.rewrite_result(context, shape)?)
     } else {
         (mk_sp(arm.span().lo(), arm.span().lo()), String::new())
     };
@@ -264,19 +273,25 @@ fn rewrite_match_arm(
     };
 
     // Patterns
-    let pat_shape = match &arm.body.as_ref()?.kind {
+    let pat_shape = match &arm.body.as_ref().unknown_error()?.kind {
         ast::ExprKind::Block(_, Some(label)) => {
             // Some block with a label ` => 'label: {`
             // 7 = ` => : {`
             let label_len = label.ident.as_str().len();
-            shape.sub_width(7 + label_len)?.offset_left(pipe_offset)?
+            shape
+                .sub_width(7 + label_len)
+                .and_then(|s| s.offset_left(pipe_offset))
+                .max_width_error(shape.width, arm.span)?
         }
         _ => {
             // 5 = ` => {`
-            shape.sub_width(5)?.offset_left(pipe_offset)?
+            shape
+                .sub_width(5)
+                .and_then(|s| s.offset_left(pipe_offset))
+                .max_width_error(shape.width, arm.span)?
         }
     };
-    let pats_str = arm.pat.rewrite(context, pat_shape)?;
+    let pats_str = arm.pat.rewrite_result(context, pat_shape)?;
 
     // Guard
     let block_like_pat = trimmed_last_line_width(&pats_str) <= context.config.tab_spaces();
@@ -298,10 +313,13 @@ fn rewrite_match_arm(
         false,
     )?;
 
-    let arrow_span = mk_sp(arm.pat.span.hi(), arm.body.as_ref()?.span().lo());
+    let arrow_span = mk_sp(
+        arm.pat.span.hi(),
+        arm.body.as_ref().unknown_error()?.span().lo(),
+    );
     rewrite_match_body(
         context,
-        arm.body.as_ref()?,
+        arm.body.as_ref().unknown_error()?,
         &lhs_str,
         shape,
         guard_str.contains('\n'),
@@ -382,7 +400,7 @@ fn rewrite_match_body(
     has_guard: bool,
     arrow_span: Span,
     is_last: bool,
-) -> Option<String> {
+) -> RewriteResult {
     let (extend, body) = flatten_arm_body(
         context,
         body,
@@ -403,7 +421,7 @@ fn rewrite_match_body(
             _ => " ",
         };
 
-        Some(format!("{} =>{}{}{}", pats_str, block_sep, body_str, comma))
+        Ok(format!("{} =>{}{}{}", pats_str, block_sep, body_str, comma))
     };
 
     let next_line_indent = if !is_block || is_empty_block {
@@ -420,7 +438,7 @@ fn rewrite_match_body(
         let arrow_snippet = context.snippet(arrow_span).trim();
         // search for the arrow starting from the end of the snippet since there may be a match
         // expression within the guard
-        let arrow_index = if context.config.version() == Version::One {
+        let arrow_index = if context.config.style_edition() <= StyleEdition::Edition2021 {
             arrow_snippet.rfind("=>").unwrap()
         } else {
             arrow_snippet.find_last_uncommented("=>").unwrap()
@@ -447,7 +465,7 @@ fn rewrite_match_body(
             result.push_str(&nested_indent_str);
             result.push_str(body_str);
             result.push_str(comma);
-            return Some(result);
+            return Ok(result);
         }
 
         let indent_str = shape.indent.to_string_with_newline(context.config);
@@ -458,7 +476,7 @@ fn rewrite_match_body(
                 } else {
                     ""
                 };
-                let semicolon = if context.config.version() == Version::One {
+                let semicolon = if context.config.style_edition() <= StyleEdition::Edition2021 {
                     ""
                 } else {
                     if semicolon_for_expr(context, body) {
@@ -490,7 +508,7 @@ fn rewrite_match_body(
         result.push_str(&block_sep);
         result.push_str(body_str);
         result.push_str(&body_suffix);
-        Some(result)
+        Ok(result)
     };
 
     // Let's try and get the arm body on the same line as the condition.
@@ -499,7 +517,7 @@ fn rewrite_match_body(
         .offset_left(extra_offset(pats_str, shape) + 4)
         .and_then(|shape| shape.sub_width(comma.len()));
     let orig_body = if forbid_same_line || !arrow_comment.is_empty() {
-        None
+        Err(RewriteError::Unknown)
     } else if let Some(body_shape) = orig_body_shape {
         let rewrite = nop_block_collapse(
             format_expr(body, ExprType::Statement, context, body_shape),
@@ -507,7 +525,7 @@ fn rewrite_match_body(
         );
 
         match rewrite {
-            Some(ref body_str)
+            Ok(ref body_str)
                 if is_block
                     || (!body_str.contains('\n')
                         && unicode_str_width(body_str) <= body_shape.width) =>
@@ -517,7 +535,7 @@ fn rewrite_match_body(
             _ => rewrite,
         }
     } else {
-        None
+        Err(RewriteError::Unknown)
     };
     let orig_budget = orig_body_shape.map_or(0, |shape| shape.width);
 
@@ -528,20 +546,23 @@ fn rewrite_match_body(
         next_line_body_shape.width,
     );
     match (orig_body, next_line_body) {
-        (Some(ref orig_str), Some(ref next_line_str))
+        (Ok(ref orig_str), Ok(ref next_line_str))
             if prefer_next_line(orig_str, next_line_str, RhsTactics::Default) =>
         {
             combine_next_line_body(next_line_str)
         }
-        (Some(ref orig_str), _) if extend && first_line_width(orig_str) <= orig_budget => {
+        (Ok(ref orig_str), _) if extend && first_line_width(orig_str) <= orig_budget => {
             combine_orig_body(orig_str)
         }
-        (Some(ref orig_str), Some(ref next_line_str)) if orig_str.contains('\n') => {
+        (Ok(ref orig_str), Ok(ref next_line_str)) if orig_str.contains('\n') => {
             combine_next_line_body(next_line_str)
         }
-        (None, Some(ref next_line_str)) => combine_next_line_body(next_line_str),
-        (None, None) => None,
-        (Some(ref orig_str), _) => combine_orig_body(orig_str),
+        (Err(_), Ok(ref next_line_str)) => combine_next_line_body(next_line_str),
+        // When both orig_body and next_line_body result in errors, we currently propagate the
+        // error from the second attempt since it is more generous with width constraints.
+        // This decision is somewhat arbitrary and is open to change.
+        (Err(_), Err(next_line_err)) => Err(next_line_err),
+        (Ok(ref orig_str), _) => combine_orig_body(orig_str),
     }
 }
 
@@ -554,7 +575,7 @@ fn rewrite_guard(
     // the arm (excludes offset).
     pattern_width: usize,
     multiline_pattern: bool,
-) -> Option<String> {
+) -> RewriteResult {
     if let Some(ref guard) = *guard {
         // First try to fit the guard string on the same line as the pattern.
         // 4 = ` if `, 5 = ` => {`
@@ -563,9 +584,9 @@ fn rewrite_guard(
             .and_then(|s| s.sub_width(5));
         if !multiline_pattern {
             if let Some(cond_shape) = cond_shape {
-                if let Some(cond_str) = guard.rewrite(context, cond_shape) {
+                if let Ok(cond_str) = guard.rewrite_result(context, cond_shape) {
                     if !cond_str.contains('\n') || pattern_width <= context.config.tab_spaces() {
-                        return Some(format!(" if {cond_str}"));
+                        return Ok(format!(" if {cond_str}"));
                     }
                 }
             }
@@ -575,24 +596,20 @@ fn rewrite_guard(
         // 3 = `if `, 5 = ` => {`
         let cond_shape = Shape::indented(shape.indent.block_indent(context.config), context.config)
             .offset_left(3)
-            .and_then(|s| s.sub_width(5));
-        if let Some(cond_shape) = cond_shape {
-            if let Some(cond_str) = guard.rewrite(context, cond_shape) {
-                return Some(format!(
-                    "{}if {}",
-                    cond_shape.indent.to_string_with_newline(context.config),
-                    cond_str
-                ));
-            }
-        }
-
-        None
+            .and_then(|s| s.sub_width(5))
+            .max_width_error(shape.width, guard.span)?;
+        let cond_str = guard.rewrite_result(context, cond_shape)?;
+        Ok(format!(
+            "{}if {}",
+            cond_shape.indent.to_string_with_newline(context.config),
+            cond_str
+        ))
     } else {
-        Some(String::new())
+        Ok(String::new())
     }
 }
 
-fn nop_block_collapse(block_str: Option<String>, budget: usize) -> Option<String> {
+fn nop_block_collapse(block_str: RewriteResult, budget: usize) -> RewriteResult {
     debug!("nop_block_collapse {:?} {}", block_str, budget);
     block_str.map(|block_str| {
         if block_str.starts_with('{')
diff --git a/src/tools/rustfmt/src/missed_spans.rs b/src/tools/rustfmt/src/missed_spans.rs
index 56adb2e5e69..384de1ce9ae 100644
--- a/src/tools/rustfmt/src/missed_spans.rs
+++ b/src/tools/rustfmt/src/missed_spans.rs
@@ -1,10 +1,10 @@
 use rustc_span::{BytePos, Pos, Span};
 use tracing::debug;
 
-use crate::comment::{is_last_comment_block, rewrite_comment, CodeCharKind, CommentCodeSlices};
-use crate::config::file_lines::FileLines;
+use crate::comment::{CodeCharKind, CommentCodeSlices, is_last_comment_block, rewrite_comment};
 use crate::config::FileName;
-use crate::config::Version;
+use crate::config::StyleEdition;
+use crate::config::file_lines::FileLines;
 use crate::coverage::transform_missing_snippet;
 use crate::shape::{Indent, Shape};
 use crate::source_map::LineRangeUtils;
@@ -247,7 +247,9 @@ impl<'a> FmtVisitor<'a> {
             let indent_str = self.block_indent.to_string(self.config);
             self.push_str(&indent_str);
             self.block_indent
-        } else if self.config.version() == Version::Two && !snippet.starts_with('\n') {
+        } else if self.config.style_edition() >= StyleEdition::Edition2024
+            && !snippet.starts_with('\n')
+        {
             // The comment appears on the same line as the previous formatted code.
             // Assuming that comment is logically associated with that code, we want to keep it on
             // the same level and avoid mixing it with possible other comment.
@@ -283,13 +285,13 @@ impl<'a> FmtVisitor<'a> {
                     let other_lines = &subslice[offset + 1..];
                     let comment_str =
                         rewrite_comment(other_lines, false, comment_shape, self.config)
-                            .unwrap_or_else(|| String::from(other_lines));
+                            .unwrap_or_else(|_| String::from(other_lines));
                     self.push_str(&comment_str);
                 }
             }
         } else {
             let comment_str = rewrite_comment(subslice, false, comment_shape, self.config)
-                .unwrap_or_else(|| String::from(subslice));
+                .unwrap_or_else(|_| String::from(subslice));
             self.push_str(&comment_str);
         }
 
diff --git a/src/tools/rustfmt/src/modules.rs b/src/tools/rustfmt/src/modules.rs
index 0590f28ee05..493b04f16c6 100644
--- a/src/tools/rustfmt/src/modules.rs
+++ b/src/tools/rustfmt/src/modules.rs
@@ -4,8 +4,8 @@ use std::path::{Path, PathBuf};
 
 use rustc_ast::ast;
 use rustc_ast::visit::Visitor;
-use rustc_span::symbol::{self, sym, Symbol};
 use rustc_span::Span;
+use rustc_span::symbol::{self, Symbol, sym};
 use thin_vec::ThinVec;
 use thiserror::Error;
 
diff --git a/src/tools/rustfmt/src/overflow.rs b/src/tools/rustfmt/src/overflow.rs
index cdb735be8a4..fdc8e23e72b 100644
--- a/src/tools/rustfmt/src/overflow.rs
+++ b/src/tools/rustfmt/src/overflow.rs
@@ -9,22 +9,22 @@ use rustc_span::Span;
 use tracing::debug;
 
 use crate::closures;
-use crate::config::Version;
-use crate::config::{lists::*, Config};
+use crate::config::StyleEdition;
+use crate::config::{Config, lists::*};
 use crate::expr::{
     can_be_overflowed_expr, is_every_expr_simple, is_method_call, is_nested_call, is_simple_expr,
     rewrite_cond,
 };
 use crate::lists::{
-    definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
+    ListFormatting, ListItem, Separator, definitive_tactic, itemize_list, write_list,
 };
 use crate::macros::MacroArg;
-use crate::patterns::{can_be_overflowed_pat, TuplePatField};
-use crate::rewrite::{Rewrite, RewriteContext};
+use crate::patterns::{TuplePatField, can_be_overflowed_pat};
+use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
 use crate::shape::Shape;
 use crate::source_map::SpanUtils;
 use crate::spanned::Spanned;
-use crate::types::{can_be_overflowed_type, SegmentParam};
+use crate::types::{SegmentParam, can_be_overflowed_type};
 use crate::utils::{count_newlines, extra_offset, first_line_width, last_line_width, mk_sp};
 
 /// A list of `format!`-like macros, that take a long format string and a list of arguments to
@@ -91,6 +91,10 @@ impl<'a> Rewrite for OverflowableItem<'a> {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
         self.map(|item| item.rewrite(context, shape))
     }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
+        self.map(|item| item.rewrite_result(context, shape))
+    }
 }
 
 impl<'a> Spanned for OverflowableItem<'a> {
@@ -201,8 +205,12 @@ impl<'a> OverflowableItem<'a> {
             OverflowableItem::NestedMetaItem(..) => SPECIAL_CASE_ATTR,
             _ => &[],
         };
-        let additional_cases = match (self, config.version()) {
-            (OverflowableItem::MacroArg(..), Version::Two) => SPECIAL_CASE_MACROS_V2,
+        let additional_cases = match self {
+            OverflowableItem::MacroArg(..)
+                if config.style_edition() >= StyleEdition::Edition2024 =>
+            {
+                SPECIAL_CASE_MACROS_V2
+            }
             _ => &[],
         };
         base_cases.iter().chain(additional_cases)
@@ -278,7 +286,7 @@ pub(crate) fn rewrite_with_parens<'a, T: 'a + IntoOverflowableItem<'a>>(
     span: Span,
     item_max_width: usize,
     force_separator_tactic: Option<SeparatorTactic>,
-) -> Option<String> {
+) -> RewriteResult {
     Context::new(
         context,
         items,
@@ -300,7 +308,7 @@ pub(crate) fn rewrite_with_angle_brackets<'a, T: 'a + IntoOverflowableItem<'a>>(
     items: impl Iterator<Item = &'a T>,
     shape: Shape,
     span: Span,
-) -> Option<String> {
+) -> RewriteResult {
     Context::new(
         context,
         items,
@@ -324,7 +332,7 @@ pub(crate) fn rewrite_with_square_brackets<'a, T: 'a + IntoOverflowableItem<'a>>
     span: Span,
     force_separator_tactic: Option<SeparatorTactic>,
     delim_token: Option<Delimiter>,
-) -> Option<String> {
+) -> RewriteResult {
     let (lhs, rhs) = match delim_token {
         Some(Delimiter::Parenthesis) => ("(", ")"),
         Some(Delimiter::Brace) => ("{", "}"),
@@ -428,7 +436,7 @@ impl<'a> Context<'a> {
                         if closures::args_have_many_closure(&self.items) {
                             None
                         } else {
-                            closures::rewrite_last_closure(self.context, expr, shape)
+                            closures::rewrite_last_closure(self.context, expr, shape).ok()
                         }
                     }
 
@@ -457,7 +465,7 @@ impl<'a> Context<'a> {
 
         if let Some(rewrite) = rewrite {
             // splitn(2, *).next().unwrap() is always safe.
-            let rewrite_first_line = Some(rewrite.splitn(2, '\n').next().unwrap().to_owned());
+            let rewrite_first_line = Ok(rewrite.splitn(2, '\n').next().unwrap().to_owned());
             last_list_item.item = rewrite_first_line;
             Some(rewrite)
         } else {
@@ -495,7 +503,7 @@ impl<'a> Context<'a> {
                 Some(OverflowableItem::MacroArg(MacroArg::Expr(expr)))
                     if !combine_arg_with_callee
                         && is_method_call(expr)
-                        && self.context.config.version() == Version::Two =>
+                        && self.context.config.style_edition() >= StyleEdition::Edition2024 =>
                 {
                     self.context.force_one_line_chain.replace(true);
                 }
@@ -545,22 +553,23 @@ impl<'a> Context<'a> {
                         .and_then(|last_item| last_item.rewrite(self.context, self.nested_shape));
                     let no_newline = rw.as_ref().map_or(false, |s| !s.contains('\n'));
                     if no_newline {
-                        list_items[self.items.len() - 1].item = rw;
+                        list_items[self.items.len() - 1].item = rw.unknown_error();
                     } else {
-                        list_items[self.items.len() - 1].item = Some(overflowed.to_owned());
+                        list_items[self.items.len() - 1].item = Ok(overflowed.to_owned());
                     }
                 } else {
-                    list_items[self.items.len() - 1].item = Some(overflowed.to_owned());
+                    list_items[self.items.len() - 1].item = Ok(overflowed.to_owned());
                 }
             }
             (true, DefinitiveListTactic::Horizontal, placeholder @ Some(..)) => {
-                list_items[self.items.len() - 1].item = placeholder;
+                list_items[self.items.len() - 1].item = placeholder.unknown_error();
             }
             _ if !self.items.is_empty() => {
                 list_items[self.items.len() - 1].item = self
                     .items
                     .last()
-                    .and_then(|last_item| last_item.rewrite(self.context, self.nested_shape));
+                    .and_then(|last_item| last_item.rewrite(self.context, self.nested_shape))
+                    .unknown_error();
 
                 // Use horizontal layout for a function with a single argument as long as
                 // everything fits in a single line.
@@ -613,7 +622,7 @@ impl<'a> Context<'a> {
         tactic
     }
 
-    fn rewrite_items(&self) -> Option<(bool, String)> {
+    fn rewrite_items(&self) -> Result<(bool, String), RewriteError> {
         let span = self.items_span();
         debug!("items: {:?}", self.items);
 
@@ -624,7 +633,7 @@ impl<'a> Context<'a> {
             ",",
             |item| item.span().lo(),
             |item| item.span().hi(),
-            |item| item.rewrite(self.context, self.nested_shape),
+            |item| item.rewrite_result(self.context, self.nested_shape),
             span.lo(),
             span.hi(),
             true,
@@ -689,7 +698,8 @@ impl<'a> Context<'a> {
         );
         result.push_str(self.ident);
         result.push_str(prefix);
-        let force_single_line = if self.context.config.version() == Version::Two {
+        let force_single_line = if self.context.config.style_edition() >= StyleEdition::Edition2024
+        {
             !self.context.use_block_indent() || (is_extendable && extend_width <= shape.width)
         } else {
             // 2 = `()`
@@ -711,7 +721,7 @@ impl<'a> Context<'a> {
         result
     }
 
-    fn rewrite(&self, shape: Shape) -> Option<String> {
+    fn rewrite(&self, shape: Shape) -> RewriteResult {
         let (extendable, items_str) = self.rewrite_items()?;
 
         // If we are using visual indent style and failed to format, retry with block indent.
@@ -725,7 +735,7 @@ impl<'a> Context<'a> {
             return result;
         }
 
-        Some(self.wrap_items(&items_str, shape, extendable))
+        Ok(self.wrap_items(&items_str, shape, extendable))
     }
 }
 
diff --git a/src/tools/rustfmt/src/pairs.rs b/src/tools/rustfmt/src/pairs.rs
index bfc2ffed383..9c51298416b 100644
--- a/src/tools/rustfmt/src/pairs.rs
+++ b/src/tools/rustfmt/src/pairs.rs
@@ -1,9 +1,11 @@
 use rustc_ast::ast;
+use rustc_span::Span;
 
-use crate::config::lists::*;
 use crate::config::IndentStyle;
-use crate::rewrite::{Rewrite, RewriteContext};
+use crate::config::lists::*;
+use crate::rewrite::{Rewrite, RewriteContext, RewriteErrorExt, RewriteResult};
 use crate::shape::Shape;
+use crate::spanned::Spanned;
 use crate::utils::{
     first_line_width, is_single_line, last_line_width, trimmed_last_line_width, wrap_str,
 };
@@ -40,16 +42,19 @@ pub(crate) fn rewrite_all_pairs(
     expr: &ast::Expr,
     shape: Shape,
     context: &RewriteContext<'_>,
-) -> Option<String> {
-    expr.flatten(context, shape).and_then(|list| {
-        if list.let_chain_count() > 0 && !list.can_rewrite_let_chain_single_line() {
-            rewrite_pairs_multiline(&list, shape, context)
-        } else {
-            // First we try formatting on one line.
-            rewrite_pairs_one_line(&list, shape, context)
-                .or_else(|| rewrite_pairs_multiline(&list, shape, context))
-        }
-    })
+) -> RewriteResult {
+    expr.flatten(context, shape)
+        .unknown_error()
+        .and_then(|list| {
+            if list.let_chain_count() > 0 && !list.can_rewrite_let_chain_single_line() {
+                rewrite_pairs_multiline(&list, shape, context)
+            } else {
+                // First we try formatting on one line.
+                rewrite_pairs_one_line(&list, shape, context)
+                    .unknown_error()
+                    .or_else(|_| rewrite_pairs_multiline(&list, shape, context))
+            }
+        })
 }
 
 // This may return a multi-line result since we allow the last expression to go
@@ -65,7 +70,7 @@ fn rewrite_pairs_one_line<T: Rewrite>(
     let base_shape = shape.block();
 
     for ((_, rewrite), s) in list.list.iter().zip(list.separators.iter()) {
-        if let Some(rewrite) = rewrite {
+        if let Ok(rewrite) = rewrite {
             if !is_single_line(rewrite) || result.len() > shape.width {
                 return None;
             }
@@ -104,19 +109,20 @@ fn rewrite_pairs_multiline<T: Rewrite>(
     list: &PairList<'_, '_, T>,
     shape: Shape,
     context: &RewriteContext<'_>,
-) -> Option<String> {
+) -> RewriteResult {
     let rhs_offset = shape.rhs_overhead(context.config);
     let nested_shape = (match context.config.indent_style() {
         IndentStyle::Visual => shape.visual_indent(0),
         IndentStyle::Block => shape.block_indent(context.config.tab_spaces()),
     })
     .with_max_width(context.config)
-    .sub_width(rhs_offset)?;
+    .sub_width(rhs_offset)
+    .max_width_error(shape.width, list.span)?;
 
     let indent_str = nested_shape.indent.to_string_with_newline(context.config);
     let mut result = String::new();
 
-    result.push_str(list.list[0].1.as_ref()?);
+    result.push_str(list.list[0].1.as_ref().map_err(|err| err.clone())?);
 
     for ((e, default_rw), s) in list.list[1..].iter().zip(list.separators.iter()) {
         // The following test checks if we should keep two subexprs on the same
@@ -132,7 +138,7 @@ fn rewrite_pairs_multiline<T: Rewrite>(
             if let Some(line_shape) =
                 shape.offset_left(s.len() + 2 + trimmed_last_line_width(&result))
             {
-                if let Some(rewrite) = e.rewrite(context, line_shape) {
+                if let Ok(rewrite) = e.rewrite_result(context, line_shape) {
                     result.push(' ');
                     result.push_str(s);
                     result.push(' ');
@@ -155,9 +161,9 @@ fn rewrite_pairs_multiline<T: Rewrite>(
             }
         }
 
-        result.push_str(default_rw.as_ref()?);
+        result.push_str(default_rw.as_ref().map_err(|err| err.clone())?);
     }
-    Some(result)
+    Ok(result)
 }
 
 // Rewrites a single pair.
@@ -168,10 +174,10 @@ pub(crate) fn rewrite_pair<LHS, RHS>(
     context: &RewriteContext<'_>,
     shape: Shape,
     separator_place: SeparatorPlace,
-) -> Option<String>
+) -> RewriteResult
 where
-    LHS: Rewrite,
-    RHS: Rewrite,
+    LHS: Rewrite + Spanned,
+    RHS: Rewrite + Spanned,
 {
     let tab_spaces = context.config.tab_spaces();
     let lhs_overhead = match separator_place {
@@ -183,15 +189,17 @@ where
         ..shape
     };
     let lhs_result = lhs
-        .rewrite(context, lhs_shape)
+        .rewrite_result(context, lhs_shape)
         .map(|lhs_str| format!("{}{}", pp.prefix, lhs_str))?;
 
     // Try to put both lhs and rhs on the same line.
     let rhs_orig_result = shape
         .offset_left(last_line_width(&lhs_result) + pp.infix.len())
         .and_then(|s| s.sub_width(pp.suffix.len()))
-        .and_then(|rhs_shape| rhs.rewrite(context, rhs_shape));
-    if let Some(ref rhs_result) = rhs_orig_result {
+        .max_width_error(shape.width, rhs.span())
+        .and_then(|rhs_shape| rhs.rewrite_result(context, rhs_shape));
+
+    if let Ok(ref rhs_result) = rhs_orig_result {
         // If the length of the lhs is equal to or shorter than the tab width or
         // the rhs looks like block expression, we put the rhs on the same
         // line with the lhs even if the rhs is multi-lined.
@@ -207,7 +215,7 @@ where
                 + first_line_width(rhs_result)
                 + pp.suffix.len();
             if one_line_width <= shape.width {
-                return Some(format!(
+                return Ok(format!(
                     "{}{}{}{}",
                     lhs_result, pp.infix, rhs_result, pp.suffix
                 ));
@@ -219,13 +227,15 @@ where
     // Re-evaluate the rhs because we have more space now:
     let mut rhs_shape = match context.config.indent_style() {
         IndentStyle::Visual => shape
-            .sub_width(pp.suffix.len() + pp.prefix.len())?
+            .sub_width(pp.suffix.len() + pp.prefix.len())
+            .max_width_error(shape.width, rhs.span())?
             .visual_indent(pp.prefix.len()),
         IndentStyle::Block => {
             // Try to calculate the initial constraint on the right hand side.
             let rhs_overhead = shape.rhs_overhead(context.config);
             Shape::indented(shape.indent.block_indent(context.config), context.config)
-                .sub_width(rhs_overhead)?
+                .sub_width(rhs_overhead)
+                .max_width_error(shape.width, rhs.span())?
         }
     };
     let infix = match separator_place {
@@ -233,15 +243,17 @@ where
         SeparatorPlace::Front => pp.infix.trim_start(),
     };
     if separator_place == SeparatorPlace::Front {
-        rhs_shape = rhs_shape.offset_left(infix.len())?;
+        rhs_shape = rhs_shape
+            .offset_left(infix.len())
+            .max_width_error(rhs_shape.width, rhs.span())?;
     }
-    let rhs_result = rhs.rewrite(context, rhs_shape)?;
+    let rhs_result = rhs.rewrite_result(context, rhs_shape)?;
     let indent_str = rhs_shape.indent.to_string_with_newline(context.config);
     let infix_with_sep = match separator_place {
         SeparatorPlace::Back => format!("{infix}{indent_str}"),
         SeparatorPlace::Front => format!("{indent_str}{infix}"),
     };
-    Some(format!(
+    Ok(format!(
         "{}{}{}{}",
         lhs_result, infix_with_sep, rhs_result, pp.suffix
     ))
@@ -255,8 +267,9 @@ trait FlattenPair: Rewrite + Sized {
 }
 
 struct PairList<'a, 'b, T: Rewrite> {
-    list: Vec<(&'b T, Option<String>)>,
+    list: Vec<(&'b T, RewriteResult)>,
     separators: Vec<&'a str>,
+    span: Span,
 }
 
 fn is_ident(expr: &ast::Expr) -> bool {
@@ -303,7 +316,7 @@ impl FlattenPair for ast::Expr {
 
         let default_rewrite = |node: &ast::Expr, sep: usize, is_first: bool| {
             if is_first {
-                return node.rewrite(context, shape);
+                return node.rewrite_result(context, shape);
             }
             let nested_overhead = sep + 1;
             let rhs_offset = shape.rhs_overhead(context.config);
@@ -312,12 +325,17 @@ impl FlattenPair for ast::Expr {
                 IndentStyle::Block => shape.block_indent(context.config.tab_spaces()),
             })
             .with_max_width(context.config)
-            .sub_width(rhs_offset)?;
+            .sub_width(rhs_offset)
+            .max_width_error(shape.width, node.span)?;
             let default_shape = match context.config.binop_separator() {
-                SeparatorPlace::Back => nested_shape.sub_width(nested_overhead)?,
-                SeparatorPlace::Front => nested_shape.offset_left(nested_overhead)?,
+                SeparatorPlace::Back => nested_shape
+                    .sub_width(nested_overhead)
+                    .max_width_error(nested_shape.width, node.span)?,
+                SeparatorPlace::Front => nested_shape
+                    .offset_left(nested_overhead)
+                    .max_width_error(nested_shape.width, node.span)?,
             };
-            node.rewrite(context, default_shape)
+            node.rewrite_result(context, default_shape)
         };
 
         // Turn a tree of binop expressions into a list using a depth-first,
@@ -326,6 +344,7 @@ impl FlattenPair for ast::Expr {
         let mut list = vec![];
         let mut separators = vec![];
         let mut node = self;
+        let span = self.span();
         loop {
             match node.kind {
                 ast::ExprKind::Binary(op, ref lhs, _) if op.node == top_op => {
@@ -352,7 +371,11 @@ impl FlattenPair for ast::Expr {
         }
 
         assert_eq!(list.len() - 1, separators.len());
-        Some(PairList { list, separators })
+        Some(PairList {
+            list,
+            separators,
+            span,
+        })
     }
 }
 
diff --git a/src/tools/rustfmt/src/parse/macros/asm.rs b/src/tools/rustfmt/src/parse/macros/asm.rs
index 6373d0251f8..5ee083da539 100644
--- a/src/tools/rustfmt/src/parse/macros/asm.rs
+++ b/src/tools/rustfmt/src/parse/macros/asm.rs
@@ -1,5 +1,5 @@
 use rustc_ast::ast;
-use rustc_builtin_macros::asm::{parse_asm_args, AsmArgs};
+use rustc_builtin_macros::asm::{AsmArgs, parse_asm_args};
 
 use crate::rewrite::RewriteContext;
 
diff --git a/src/tools/rustfmt/src/parse/macros/cfg_if.rs b/src/tools/rustfmt/src/parse/macros/cfg_if.rs
index b91d203d531..ec771f96a3f 100644
--- a/src/tools/rustfmt/src/parse/macros/cfg_if.rs
+++ b/src/tools/rustfmt/src/parse/macros/cfg_if.rs
@@ -1,4 +1,4 @@
-use std::panic::{catch_unwind, AssertUnwindSafe};
+use std::panic::{AssertUnwindSafe, catch_unwind};
 
 use rustc_ast::ast;
 use rustc_ast::token::{Delimiter, TokenKind};
diff --git a/src/tools/rustfmt/src/parse/macros/mod.rs b/src/tools/rustfmt/src/parse/macros/mod.rs
index 8d5f7f90958..7271e73db8d 100644
--- a/src/tools/rustfmt/src/parse/macros/mod.rs
+++ b/src/tools/rustfmt/src/parse/macros/mod.rs
@@ -1,11 +1,11 @@
 use rustc_ast::token::{Delimiter, NonterminalKind, NtExprKind::*, NtPatKind::*, TokenKind};
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast::{ast, ptr};
-use rustc_parse::parser::{ForceCollect, Parser, Recovery};
 use rustc_parse::MACRO_ARGUMENTS;
+use rustc_parse::parser::{ForceCollect, Parser, Recovery};
 use rustc_session::parse::ParseSess;
-use rustc_span::symbol::{self, kw};
 use rustc_span::Symbol;
+use rustc_span::symbol::{self, kw};
 
 use crate::macros::MacroArg;
 use crate::rewrite::RewriteContext;
diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs
index 6051241309d..28b4c2b612f 100644
--- a/src/tools/rustfmt/src/parse/parser.rs
+++ b/src/tools/rustfmt/src/parse/parser.rs
@@ -1,4 +1,4 @@
-use std::panic::{catch_unwind, AssertUnwindSafe};
+use std::panic::{AssertUnwindSafe, catch_unwind};
 use std::path::{Path, PathBuf};
 
 use rustc_ast::token::TokenKind;
@@ -6,11 +6,11 @@ use rustc_ast::{ast, attr, ptr};
 use rustc_errors::Diag;
 use rustc_parse::parser::Parser as RawParser;
 use rustc_parse::{new_parser_from_file, new_parser_from_source_str, unwrap_or_emit_fatal};
-use rustc_span::{sym, Span};
+use rustc_span::{Span, sym};
 use thin_vec::ThinVec;
 
-use crate::parse::session::ParseSess;
 use crate::Input;
+use crate::parse::session::ParseSess;
 
 pub(crate) type DirectoryOwnership = rustc_expand::module::DirOwnership;
 pub(crate) type ModulePathSuccess = rustc_expand::module::ModulePathSuccess;
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs
index 05cf467167c..9f27a05939e 100644
--- a/src/tools/rustfmt/src/parse/session.rs
+++ b/src/tools/rustfmt/src/parse/session.rs
@@ -2,13 +2,14 @@ use std::path::Path;
 use std::sync::atomic::{AtomicBool, Ordering};
 
 use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
-use rustc_errors::emitter::{stderr_destination, DynEmitter, Emitter, HumanEmitter, SilentEmitter};
+use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter, SilentEmitter, stderr_destination};
 use rustc_errors::translation::Translate;
 use rustc_errors::{ColorConfig, Diag, DiagCtxt, DiagInner, Level as DiagnosticLevel};
 use rustc_session::parse::ParseSess as RawParseSess;
 use rustc_span::{
+    BytePos, Span,
     source_map::{FilePathMapping, SourceMap},
-    symbol, BytePos, Span,
+    symbol,
 };
 
 use crate::config::file_lines::LineRange;
@@ -394,7 +395,9 @@ mod tests {
         }
 
         fn get_ignore_list(config: &str) -> IgnoreList {
-            Config::from_toml(config, Path::new("")).unwrap().ignore()
+            Config::from_toml(config, Path::new("./rustfmt.toml"))
+                .unwrap()
+                .ignore()
         }
 
         #[test]
diff --git a/src/tools/rustfmt/src/patterns.rs b/src/tools/rustfmt/src/patterns.rs
index d8cb26a20f1..6fe2d4a8520 100644
--- a/src/tools/rustfmt/src/patterns.rs
+++ b/src/tools/rustfmt/src/patterns.rs
@@ -2,22 +2,22 @@ use rustc_ast::ast::{self, BindingMode, ByRef, Pat, PatField, PatKind, RangeEnd,
 use rustc_ast::ptr;
 use rustc_span::{BytePos, Span};
 
-use crate::comment::{combine_strs_with_missing_comments, FindUncommented};
+use crate::comment::{FindUncommented, combine_strs_with_missing_comments};
+use crate::config::StyleEdition;
 use crate::config::lists::*;
-use crate::config::Version;
 use crate::expr::{can_be_overflowed_expr, rewrite_unary_prefix, wrap_struct_field};
 use crate::lists::{
-    definitive_tactic, itemize_list, shape_for_tactic, struct_lit_formatting, struct_lit_shape,
-    struct_lit_tactic, write_list, ListFormatting, ListItem, Separator,
+    ListFormatting, ListItem, Separator, definitive_tactic, itemize_list, shape_for_tactic,
+    struct_lit_formatting, struct_lit_shape, struct_lit_tactic, write_list,
 };
-use crate::macros::{rewrite_macro, MacroPosition};
+use crate::macros::{MacroPosition, rewrite_macro};
 use crate::overflow;
-use crate::pairs::{rewrite_pair, PairParts};
-use crate::rewrite::{Rewrite, RewriteContext};
+use crate::pairs::{PairParts, rewrite_pair};
+use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
 use crate::shape::Shape;
 use crate::source_map::SpanUtils;
 use crate::spanned::Spanned;
-use crate::types::{rewrite_path, PathContext};
+use crate::types::{PathContext, rewrite_path};
 use crate::utils::{format_mutability, mk_sp, mk_sp_lo_plus_one, rewrite_ident};
 
 /// Returns `true` if the given pattern is "short".
@@ -61,25 +61,36 @@ fn is_short_pattern_inner(pat: &ast::Pat) -> bool {
     }
 }
 
-struct RangeOperand<'a>(&'a Option<ptr::P<ast::Expr>>);
+pub(crate) struct RangeOperand<'a> {
+    operand: &'a Option<ptr::P<ast::Expr>>,
+    pub(crate) span: Span,
+}
 
 impl<'a> Rewrite for RangeOperand<'a> {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
-        match &self.0 {
-            None => Some("".to_owned()),
-            Some(ref exp) => exp.rewrite(context, shape),
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
+        match &self.operand {
+            None => Ok("".to_owned()),
+            Some(ref exp) => exp.rewrite_result(context, shape),
         }
     }
 }
 
 impl Rewrite for Pat {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         match self.kind {
             PatKind::Or(ref pats) => {
                 let pat_strs = pats
                     .iter()
-                    .map(|p| p.rewrite(context, shape))
-                    .collect::<Option<Vec<_>>>()?;
+                    .map(|p| p.rewrite_result(context, shape))
+                    .collect::<Result<Vec<_>, RewriteError>>()?;
 
                 let use_mixed_layout = pats
                     .iter()
@@ -115,14 +126,21 @@ impl Rewrite for Pat {
                 let sub_pat = match *sub_pat {
                     Some(ref p) => {
                         // 2 - `@ `.
-                        let width = shape.width.checked_sub(
-                            mut_prefix.len() + ref_kw.len() + mut_infix.len() + id_str.len() + 2,
-                        )?;
+                        let width = shape
+                            .width
+                            .checked_sub(
+                                mut_prefix.len()
+                                    + ref_kw.len()
+                                    + mut_infix.len()
+                                    + id_str.len()
+                                    + 2,
+                            )
+                            .max_width_error(shape.width, p.span())?;
                         let lo = context.snippet_provider.span_after(self.span, "@");
                         combine_strs_with_missing_comments(
                             context,
                             "@",
-                            &p.rewrite(context, Shape::legacy(width, shape.indent))?,
+                            &p.rewrite_result(context, Shape::legacy(width, shape.indent))?,
                             mk_sp(lo, p.span.lo()),
                             shape,
                             true,
@@ -207,19 +225,25 @@ impl Rewrite for Pat {
             }
             PatKind::Wild => {
                 if 1 <= shape.width {
-                    Some("_".to_owned())
+                    Ok("_".to_owned())
                 } else {
-                    None
+                    Err(RewriteError::ExceedsMaxWidth {
+                        configured_width: 1,
+                        span: self.span,
+                    })
                 }
             }
             PatKind::Rest => {
                 if 1 <= shape.width {
-                    Some("..".to_owned())
+                    Ok("..".to_owned())
                 } else {
-                    None
+                    Err(RewriteError::ExceedsMaxWidth {
+                        configured_width: 1,
+                        span: self.span,
+                    })
                 }
             }
-            PatKind::Never => None,
+            PatKind::Never => Err(RewriteError::Unknown),
             PatKind::Range(ref lhs, ref rhs, ref end_kind) => {
                 let infix = match end_kind.node {
                     RangeEnd::Included(RangeSyntax::DotDotDot) => "...",
@@ -239,9 +263,17 @@ impl Rewrite for Pat {
                 } else {
                     infix.to_owned()
                 };
+                let lspan = self.span.with_hi(end_kind.span.lo());
+                let rspan = self.span.with_lo(end_kind.span.hi());
                 rewrite_pair(
-                    &RangeOperand(lhs),
-                    &RangeOperand(rhs),
+                    &RangeOperand {
+                        operand: lhs,
+                        span: lspan,
+                    },
+                    &RangeOperand {
+                        operand: rhs,
+                        span: rspan,
+                    },
                     PairParts::infix(&infix),
                     context,
                     shape,
@@ -260,19 +292,21 @@ impl Rewrite for Pat {
                 let path_str = rewrite_path(context, PathContext::Expr, q_self, path, shape)?;
                 rewrite_tuple_pat(pat_vec, Some(path_str), self.span, context, shape)
             }
-            PatKind::Lit(ref expr) => expr.rewrite(context, shape),
-            PatKind::Slice(ref slice_pat) if context.config.version() == Version::One => {
+            PatKind::Lit(ref expr) => expr.rewrite_result(context, shape),
+            PatKind::Slice(ref slice_pat)
+                if context.config.style_edition() <= StyleEdition::Edition2021 =>
+            {
                 let rw: Vec<String> = slice_pat
                     .iter()
                     .map(|p| {
-                        if let Some(rw) = p.rewrite(context, shape) {
+                        if let Ok(rw) = p.rewrite_result(context, shape) {
                             rw
                         } else {
                             context.snippet(p.span).to_string()
                         }
                     })
                     .collect();
-                Some(format!("[{}]", rw.join(", ")))
+                Ok(format!("[{}]", rw.join(", ")))
             }
             PatKind::Slice(ref slice_pat) => overflow::rewrite_with_square_brackets(
                 context,
@@ -296,10 +330,16 @@ impl Rewrite for Pat {
                 rewrite_macro(mac, None, context, shape, MacroPosition::Pat)
             }
             PatKind::Paren(ref pat) => pat
-                .rewrite(context, shape.offset_left(1)?.sub_width(1)?)
+                .rewrite_result(
+                    context,
+                    shape
+                        .offset_left(1)
+                        .and_then(|s| s.sub_width(1))
+                        .max_width_error(shape.width, self.span)?,
+                )
                 .map(|inner_pat| format!("({})", inner_pat)),
-            PatKind::Err(_) => None,
-            PatKind::Deref(_) => None,
+            PatKind::Err(_) => Err(RewriteError::Unknown),
+            PatKind::Deref(_) => Err(RewriteError::Unknown),
         }
     }
 }
@@ -312,20 +352,21 @@ fn rewrite_struct_pat(
     span: Span,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     // 2 =  ` {`
-    let path_shape = shape.sub_width(2)?;
+    let path_shape = shape.sub_width(2).max_width_error(shape.width, span)?;
     let path_str = rewrite_path(context, PathContext::Expr, qself, path, path_shape)?;
 
     if fields.is_empty() && !ellipsis {
-        return Some(format!("{path_str} {{}}"));
+        return Ok(format!("{path_str} {{}}"));
     }
 
     let (ellipsis_str, terminator) = if ellipsis { (", ..", "..") } else { ("", "}") };
 
     // 3 = ` { `, 2 = ` }`.
     let (h_shape, v_shape) =
-        struct_lit_shape(shape, context, path_str.len() + 3, ellipsis_str.len() + 2)?;
+        struct_lit_shape(shape, context, path_str.len() + 3, ellipsis_str.len() + 2)
+            .max_width_error(shape.width, span)?;
 
     let items = itemize_list(
         context.snippet_provider,
@@ -340,7 +381,7 @@ fn rewrite_struct_pat(
             }
         },
         |f| f.span.hi(),
-        |f| f.rewrite(context, v_shape),
+        |f| f.rewrite_result(context, v_shape),
         context.snippet_provider.span_after(span, "{"),
         span.hi(),
         false,
@@ -379,11 +420,15 @@ fn rewrite_struct_pat(
 
     // ast::Pat doesn't have attrs so use &[]
     let fields_str = wrap_struct_field(context, &[], &fields_str, shape, v_shape, one_line_width)?;
-    Some(format!("{path_str} {{{fields_str}}}"))
+    Ok(format!("{path_str} {{{fields_str}}}"))
 }
 
 impl Rewrite for PatField {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         let hi_pos = if let Some(last) = self.attrs.last() {
             last.span.hi()
         } else {
@@ -393,10 +438,10 @@ impl Rewrite for PatField {
         let attrs_str = if self.attrs.is_empty() {
             String::from("")
         } else {
-            self.attrs.rewrite(context, shape)?
+            self.attrs.rewrite_result(context, shape)?
         };
 
-        let pat_str = self.pat.rewrite(context, shape)?;
+        let pat_str = self.pat.rewrite_result(context, shape)?;
         if self.is_shorthand {
             combine_strs_with_missing_comments(
                 context,
@@ -417,7 +462,7 @@ impl Rewrite for PatField {
                     "{}:\n{}{}",
                     id_str,
                     nested_shape.indent.to_string(context.config),
-                    self.pat.rewrite(context, nested_shape)?
+                    self.pat.rewrite_result(context, nested_shape)?
                 )
             };
             combine_strs_with_missing_comments(
@@ -440,9 +485,13 @@ pub(crate) enum TuplePatField<'a> {
 
 impl<'a> Rewrite for TuplePatField<'a> {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         match *self {
-            TuplePatField::Pat(p) => p.rewrite(context, shape),
-            TuplePatField::Dotdot(_) => Some("..".to_string()),
+            TuplePatField::Pat(p) => p.rewrite_result(context, shape),
+            TuplePatField::Dotdot(_) => Ok("..".to_string()),
         }
     }
 }
@@ -492,9 +541,9 @@ fn rewrite_tuple_pat(
     span: Span,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     if pats.is_empty() {
-        return Some(format!("{}()", path_str.unwrap_or_default()));
+        return Ok(format!("{}()", path_str.unwrap_or_default()));
     }
     let mut pat_vec: Vec<_> = pats.iter().map(TuplePatField::Pat).collect();
 
@@ -548,7 +597,7 @@ fn count_wildcard_suffix_len(
         ",",
         |item| item.span().lo(),
         |item| item.span().hi(),
-        |item| item.rewrite(context, shape),
+        |item| item.rewrite_result(context, shape),
         context.snippet_provider.span_after(span, "("),
         span.hi() - BytePos(1),
         false,
@@ -558,7 +607,7 @@ fn count_wildcard_suffix_len(
     for item in items
         .iter()
         .rev()
-        .take_while(|i| matches!(i.item, Some(ref internal_string) if internal_string == "_"))
+        .take_while(|i| matches!(i.item, Ok(ref internal_string) if internal_string == "_"))
     {
         suffix_len += 1;
 
diff --git a/src/tools/rustfmt/src/reorder.rs b/src/tools/rustfmt/src/reorder.rs
index fdbed939af5..8a31e0ac816 100644
--- a/src/tools/rustfmt/src/reorder.rs
+++ b/src/tools/rustfmt/src/reorder.rs
@@ -9,13 +9,13 @@
 use std::cmp::Ordering;
 
 use rustc_ast::{ast, attr};
-use rustc_span::{symbol::sym, Span};
+use rustc_span::{Span, symbol::sym};
 
 use crate::config::{Config, GroupImportsTactic};
-use crate::imports::{normalize_use_trees_with_granularity, UseSegmentKind, UseTree};
+use crate::imports::{UseSegmentKind, UseTree, normalize_use_trees_with_granularity};
 use crate::items::{is_mod_decl, rewrite_extern_crate, rewrite_mod};
-use crate::lists::{itemize_list, write_list, ListFormatting, ListItem};
-use crate::rewrite::RewriteContext;
+use crate::lists::{ListFormatting, ListItem, itemize_list, write_list};
+use crate::rewrite::{RewriteContext, RewriteErrorExt};
 use crate::shape::Shape;
 use crate::source_map::LineRangeUtils;
 use crate::spanned::Spanned;
@@ -59,7 +59,7 @@ fn wrap_reorderable_items(
     let fmt = ListFormatting::new(shape, context.config)
         .separator("")
         .align_comments(false);
-    write_list(list_items, &fmt)
+    write_list(list_items, &fmt).ok()
 }
 
 fn rewrite_reorderable_item(
@@ -99,7 +99,7 @@ fn rewrite_reorderable_or_regroupable_items(
                 ";",
                 |item| item.span().lo(),
                 |item| item.span().hi(),
-                |_item| Some("".to_owned()),
+                |_item| Ok("".to_owned()),
                 span.lo(),
                 span.hi(),
                 false,
@@ -131,9 +131,16 @@ fn rewrite_reorderable_or_regroupable_items(
                 .map(|use_group| {
                     let item_vec: Vec<_> = use_group
                         .into_iter()
-                        .map(|use_tree| ListItem {
-                            item: use_tree.rewrite_top_level(context, nested_shape),
-                            ..use_tree.list_item.unwrap_or_else(ListItem::empty)
+                        .map(|use_tree| {
+                            let item = use_tree.rewrite_top_level(context, nested_shape);
+                            if let Some(list_item) = use_tree.list_item {
+                                ListItem {
+                                    item: item,
+                                    ..list_item
+                                }
+                            } else {
+                                ListItem::from_item(item)
+                            }
                         })
                         .collect();
                     wrap_reorderable_items(context, &item_vec, nested_shape)
@@ -151,7 +158,7 @@ fn rewrite_reorderable_or_regroupable_items(
                 ";",
                 |item| item.span().lo(),
                 |item| item.span().hi(),
-                |item| rewrite_reorderable_item(context, item, shape),
+                |item| rewrite_reorderable_item(context, item, shape).unknown_error(),
                 span.lo(),
                 span.hi(),
                 false,
diff --git a/src/tools/rustfmt/src/rewrite.rs b/src/tools/rustfmt/src/rewrite.rs
index e2498a3500a..83020709797 100644
--- a/src/tools/rustfmt/src/rewrite.rs
+++ b/src/tools/rustfmt/src/rewrite.rs
@@ -5,17 +5,23 @@ use std::rc::Rc;
 
 use rustc_ast::ptr;
 use rustc_span::Span;
+use thiserror::Error;
 
+use crate::FormatReport;
 use crate::config::{Config, IndentStyle};
 use crate::parse::session::ParseSess;
 use crate::shape::Shape;
 use crate::skip::SkipContext;
 use crate::visitor::SnippetProvider;
-use crate::FormatReport;
 
+pub(crate) type RewriteResult = Result<String, RewriteError>;
 pub(crate) trait Rewrite {
     /// Rewrite self into shape.
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>;
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
+        self.rewrite(context, shape).unknown_error()
+    }
 }
 
 impl<T: Rewrite> Rewrite for ptr::P<T> {
@@ -24,6 +30,66 @@ impl<T: Rewrite> Rewrite for ptr::P<T> {
     }
 }
 
+#[derive(Clone, Debug, PartialEq)]
+pub(crate) enum MacroErrorKind {
+    ParseFailure,
+    ReplaceMacroVariable,
+    Unknown,
+}
+
+impl std::fmt::Display for MacroErrorKind {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            MacroErrorKind::ParseFailure => write!(f, "(parse failure)"),
+            MacroErrorKind::ReplaceMacroVariable => write!(f, "(replacing macro variables with $)"),
+            MacroErrorKind::Unknown => write!(f, ""),
+        }
+    }
+}
+
+#[derive(Clone, Error, Debug)]
+pub(crate) enum RewriteError {
+    #[error("Formatting was skipped due to skip attribute or out of file range.")]
+    SkipFormatting,
+
+    #[error("It exceeds the required width of {configured_width} for the span: {span:?}")]
+    ExceedsMaxWidth { configured_width: usize, span: Span },
+
+    #[error("Failed to format given macro{} at: {span:?}", kind)]
+    MacroFailure { kind: MacroErrorKind, span: Span },
+
+    /// Format failure that does not fit to above categories.
+    #[error("An unknown error occurred during formatting.")]
+    Unknown,
+}
+
+/// Extension trait used to conveniently convert to RewriteError
+pub(crate) trait RewriteErrorExt<T> {
+    fn max_width_error(self, width: usize, span: Span) -> Result<T, RewriteError>;
+    fn macro_error(self, kind: MacroErrorKind, span: Span) -> Result<T, RewriteError>;
+    fn unknown_error(self) -> Result<T, RewriteError>;
+}
+
+impl<T> RewriteErrorExt<T> for Option<T> {
+    fn max_width_error(self, width: usize, span: Span) -> Result<T, RewriteError> {
+        self.ok_or_else(|| RewriteError::ExceedsMaxWidth {
+            configured_width: width,
+            span: span,
+        })
+    }
+
+    fn macro_error(self, kind: MacroErrorKind, span: Span) -> Result<T, RewriteError> {
+        self.ok_or_else(|| RewriteError::MacroFailure {
+            kind: kind,
+            span: span,
+        })
+    }
+
+    fn unknown_error(self) -> Result<T, RewriteError> {
+        self.ok_or_else(|| RewriteError::Unknown)
+    }
+}
+
 #[derive(Clone)]
 pub(crate) struct RewriteContext<'a> {
     pub(crate) psess: &'a ParseSess,
diff --git a/src/tools/rustfmt/src/rustfmt_diff.rs b/src/tools/rustfmt/src/rustfmt_diff.rs
index c9883452185..4624683fa05 100644
--- a/src/tools/rustfmt/src/rustfmt_diff.rs
+++ b/src/tools/rustfmt/src/rustfmt_diff.rs
@@ -282,7 +282,7 @@ where
 #[cfg(test)]
 mod test {
     use super::DiffLine::*;
-    use super::{make_diff, Mismatch};
+    use super::{Mismatch, make_diff};
     use super::{ModifiedChunk, ModifiedLines};
 
     #[test]
diff --git a/src/tools/rustfmt/src/sort.rs b/src/tools/rustfmt/src/sort.rs
new file mode 100644
index 00000000000..670f664a119
--- /dev/null
+++ b/src/tools/rustfmt/src/sort.rs
@@ -0,0 +1,368 @@
+use itertools::EitherOrBoth;
+use itertools::Itertools;
+
+/// Iterator which breaks an identifier into various [VersionChunk]s.
+struct VersionChunkIter<'a> {
+    ident: &'a str,
+    start: usize,
+}
+
+impl<'a> VersionChunkIter<'a> {
+    pub(crate) fn new(ident: &'a str) -> Self {
+        Self { ident, start: 0 }
+    }
+
+    fn parse_numeric_chunk(
+        &mut self,
+        mut chars: std::str::CharIndices<'a>,
+    ) -> Option<VersionChunk<'a>> {
+        let mut end = self.start;
+        let mut is_end_of_chunk = false;
+
+        while let Some((idx, c)) = chars.next() {
+            end = self.start + idx;
+
+            if c.is_ascii_digit() {
+                continue;
+            }
+
+            is_end_of_chunk = true;
+            break;
+        }
+
+        let source = if is_end_of_chunk {
+            let value = &self.ident[self.start..end];
+            self.start = end;
+            value
+        } else {
+            let value = &self.ident[self.start..];
+            self.start = self.ident.len();
+            value
+        };
+
+        let zeros = source.chars().take_while(|c| *c == '0').count();
+        let value = source.parse::<usize>().ok()?;
+
+        Some(VersionChunk::Number {
+            value,
+            zeros,
+            source,
+        })
+    }
+
+    fn parse_str_chunk(
+        &mut self,
+        mut chars: std::str::CharIndices<'a>,
+    ) -> Option<VersionChunk<'a>> {
+        let mut end = self.start;
+        let mut is_end_of_chunk = false;
+
+        while let Some((idx, c)) = chars.next() {
+            end = self.start + idx;
+
+            if c == '_' {
+                is_end_of_chunk = true;
+                break;
+            }
+
+            if !c.is_numeric() {
+                continue;
+            }
+
+            is_end_of_chunk = true;
+            break;
+        }
+
+        let source = if is_end_of_chunk {
+            let value = &self.ident[self.start..end];
+            self.start = end;
+            value
+        } else {
+            let value = &self.ident[self.start..];
+            self.start = self.ident.len();
+            value
+        };
+
+        Some(VersionChunk::Str(source))
+    }
+}
+
+impl<'a> Iterator for VersionChunkIter<'a> {
+    type Item = VersionChunk<'a>;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        let mut chars = self.ident[self.start..].char_indices();
+        let (_, next) = chars.next()?;
+
+        if next == '_' {
+            self.start = self.start + next.len_utf8();
+            return Some(VersionChunk::Underscore);
+        }
+
+        if next.is_ascii_digit() {
+            return self.parse_numeric_chunk(chars);
+        }
+
+        self.parse_str_chunk(chars)
+    }
+}
+
+/// Represents a chunk in the version-sort algorithm
+#[derive(Debug, PartialEq, Eq)]
+enum VersionChunk<'a> {
+    /// A single `_` in an identifier. Underscores are sorted before all other characters.
+    Underscore,
+    /// A &str chunk in the version sort.
+    Str(&'a str),
+    /// A numeric chunk in the version sort. Keeps track of the numeric value and leading zeros.
+    Number {
+        value: usize,
+        zeros: usize,
+        source: &'a str,
+    },
+}
+
+/// Determine which side of the version-sort comparison had more leading zeros.
+#[derive(Debug, PartialEq, Eq)]
+enum MoreLeadingZeros {
+    Left,
+    Right,
+    Equal,
+}
+
+/// Compare two identifiers based on the version sorting algorithm described in [the style guide]
+///
+/// [the style guide]: https://doc.rust-lang.org/nightly/style-guide/#sorting
+pub(crate) fn version_sort(a: &str, b: &str) -> std::cmp::Ordering {
+    let iter_a = VersionChunkIter::new(a);
+    let iter_b = VersionChunkIter::new(b);
+    let mut more_leading_zeros = MoreLeadingZeros::Equal;
+
+    for either_or_both in iter_a.zip_longest(iter_b) {
+        match either_or_both {
+            EitherOrBoth::Left(_) => return std::cmp::Ordering::Greater,
+            EitherOrBoth::Right(_) => return std::cmp::Ordering::Less,
+            EitherOrBoth::Both(a, b) => match (a, b) {
+                (VersionChunk::Underscore, VersionChunk::Underscore) => {
+                    continue;
+                }
+                (VersionChunk::Underscore, _) => return std::cmp::Ordering::Less,
+                (_, VersionChunk::Underscore) => return std::cmp::Ordering::Greater,
+                (VersionChunk::Str(ca), VersionChunk::Str(cb))
+                | (VersionChunk::Str(ca), VersionChunk::Number { source: cb, .. })
+                | (VersionChunk::Number { source: ca, .. }, VersionChunk::Str(cb)) => {
+                    match ca.cmp(&cb) {
+                        std::cmp::Ordering::Equal => {
+                            continue;
+                        }
+                        order @ _ => return order,
+                    }
+                }
+                (
+                    VersionChunk::Number {
+                        value: va,
+                        zeros: lza,
+                        ..
+                    },
+                    VersionChunk::Number {
+                        value: vb,
+                        zeros: lzb,
+                        ..
+                    },
+                ) => match va.cmp(&vb) {
+                    std::cmp::Ordering::Equal => {
+                        if lza == lzb {
+                            continue;
+                        }
+
+                        if more_leading_zeros == MoreLeadingZeros::Equal && lza > lzb {
+                            more_leading_zeros = MoreLeadingZeros::Left;
+                        } else if more_leading_zeros == MoreLeadingZeros::Equal && lza < lzb {
+                            more_leading_zeros = MoreLeadingZeros::Right;
+                        }
+                        continue;
+                    }
+                    order @ _ => return order,
+                },
+            },
+        }
+    }
+
+    match more_leading_zeros {
+        MoreLeadingZeros::Equal => std::cmp::Ordering::Equal,
+        MoreLeadingZeros::Left => std::cmp::Ordering::Less,
+        MoreLeadingZeros::Right => std::cmp::Ordering::Greater,
+    }
+}
+
+#[cfg(test)]
+mod test {
+    use super::*;
+
+    #[test]
+    fn test_chunks() {
+        let mut iter = VersionChunkIter::new("x86_128");
+        assert_eq!(iter.next(), Some(VersionChunk::Str("x")));
+        assert_eq!(
+            iter.next(),
+            Some(VersionChunk::Number {
+                value: 86,
+                zeros: 0,
+                source: "86"
+            })
+        );
+        assert_eq!(iter.next(), Some(VersionChunk::Underscore));
+        assert_eq!(
+            iter.next(),
+            Some(VersionChunk::Number {
+                value: 128,
+                zeros: 0,
+                source: "128"
+            })
+        );
+        assert_eq!(iter.next(), None);
+
+        let mut iter = VersionChunkIter::new("w005s09t");
+        assert_eq!(iter.next(), Some(VersionChunk::Str("w")));
+        assert_eq!(
+            iter.next(),
+            Some(VersionChunk::Number {
+                value: 5,
+                zeros: 2,
+                source: "005"
+            })
+        );
+        assert_eq!(iter.next(), Some(VersionChunk::Str("s")));
+        assert_eq!(
+            iter.next(),
+            Some(VersionChunk::Number {
+                value: 9,
+                zeros: 1,
+                source: "09"
+            })
+        );
+        assert_eq!(iter.next(), Some(VersionChunk::Str("t")));
+        assert_eq!(iter.next(), None);
+
+        let mut iter = VersionChunkIter::new("ZY_WX");
+        assert_eq!(iter.next(), Some(VersionChunk::Str("ZY")));
+        assert_eq!(iter.next(), Some(VersionChunk::Underscore));
+        assert_eq!(iter.next(), Some(VersionChunk::Str("WX")));
+
+        let mut iter = VersionChunkIter::new("_v1");
+        assert_eq!(iter.next(), Some(VersionChunk::Underscore));
+        assert_eq!(iter.next(), Some(VersionChunk::Str("v")));
+        assert_eq!(
+            iter.next(),
+            Some(VersionChunk::Number {
+                value: 1,
+                zeros: 0,
+                source: "1"
+            })
+        );
+
+        let mut iter = VersionChunkIter::new("_1v");
+        assert_eq!(iter.next(), Some(VersionChunk::Underscore));
+        assert_eq!(
+            iter.next(),
+            Some(VersionChunk::Number {
+                value: 1,
+                zeros: 0,
+                source: "1"
+            })
+        );
+        assert_eq!(iter.next(), Some(VersionChunk::Str("v")));
+
+        let mut iter = VersionChunkIter::new("v009");
+        assert_eq!(iter.next(), Some(VersionChunk::Str("v")));
+        assert_eq!(
+            iter.next(),
+            Some(VersionChunk::Number {
+                value: 9,
+                zeros: 2,
+                source: "009"
+            })
+        );
+    }
+
+    #[test]
+    fn test_version_sort() {
+        let mut input = vec!["", "b", "a"];
+        let expected = vec!["", "a", "b"];
+        input.sort_by(|a, b| version_sort(a, b));
+        assert_eq!(input, expected);
+
+        let mut input = vec!["x7x", "xxx"];
+        let expected = vec!["x7x", "xxx"];
+        input.sort_by(|a, b| version_sort(a, b));
+        assert_eq!(input, expected);
+
+        let mut input = vec!["applesauce", "apple"];
+        let expected = vec!["apple", "applesauce"];
+        input.sort_by(|a, b| version_sort(a, b));
+        assert_eq!(input, expected);
+
+        let mut input = vec!["aaaaa", "aaa_a"];
+        let expected = vec!["aaa_a", "aaaaa"];
+        input.sort_by(|a, b| version_sort(a, b));
+        assert_eq!(input, expected);
+
+        let mut input = vec!["AAAAA", "AAA1A", "BBBBB", "BB_BB", "C3CCC"];
+        let expected = vec!["AAA1A", "AAAAA", "BB_BB", "BBBBB", "C3CCC"];
+        input.sort_by(|a, b| version_sort(a, b));
+        assert_eq!(input, expected);
+
+        let mut input = vec!["1_000_000", "1_010_001"];
+        let expected = vec!["1_000_000", "1_010_001"];
+        input.sort_by(|a, b| version_sort(a, b));
+        assert_eq!(input, expected);
+
+        let mut input = vec![
+            "5", "50", "500", "5_000", "5_005", "5_050", "5_500", "50_000", "50_005", "50_050",
+            "50_500",
+        ];
+        let expected = vec![
+            "5", "5_000", "5_005", "5_050", "5_500", "50", "50_000", "50_005", "50_050", "50_500",
+            "500",
+        ];
+        input.sort_by(|a, b| version_sort(a, b));
+        assert_eq!(input, expected);
+
+        let mut input = vec!["X86_64", "x86_64", "X86_128", "x86_128"];
+        let expected = vec!["X86_64", "X86_128", "x86_64", "x86_128"];
+        input.sort_by(|a, b| version_sort(a, b));
+        assert_eq!(input, expected);
+
+        let mut input = vec!["__", "_"];
+        let expected = vec!["_", "__"];
+        input.sort_by(|a, b| version_sort(a, b));
+        assert_eq!(input, expected);
+
+        let mut input = vec!["foo_", "foo"];
+        let expected = vec!["foo", "foo_"];
+        input.sort_by(|a, b| version_sort(a, b));
+        assert_eq!(input, expected);
+
+        let mut input = vec!["A", "AA", "B", "a", "aA", "aa", "b"];
+        let expected = vec!["A", "AA", "B", "a", "aA", "aa", "b"];
+        input.sort_by(|a, b| version_sort(a, b));
+        assert_eq!(input, expected);
+
+        let mut input = vec![
+            "x86_128", "usize", "uz", "v000", "v00", "v0", "v0s", "v00t", "v0u", "v001", "v01",
+            "v1", "v009", "x87", "zyxw", "_ZYXW", "_abcd", "A2", "ABCD", "Z_YXW", "ZY_XW", "ZY_XW",
+            "ZYXW", "v09", "v9", "v010", "v10", "w005s09t", "w5s009t", "x64", "x86", "x86_32",
+            "ua", "x86_64", "ZYXW_", "a1", "abcd", "u_zzz", "u8", "u16", "u32", "u64", "u128",
+            "u256",
+        ];
+        let expected = vec![
+            "_ZYXW", "_abcd", "A2", "ABCD", "Z_YXW", "ZY_XW", "ZY_XW", "ZYXW", "ZYXW_", "a1",
+            "abcd", "u_zzz", "u8", "u16", "u32", "u64", "u128", "u256", "ua", "usize", "uz",
+            "v000", "v00", "v0", "v0s", "v00t", "v0u", "v001", "v01", "v1", "v009", "v09", "v9",
+            "v010", "v10", "w005s09t", "w5s009t", "x64", "x86", "x86_32", "x86_64", "x86_128",
+            "x87", "zyxw",
+        ];
+        input.sort_by(|a, b| version_sort(a, b));
+        assert_eq!(input, expected)
+    }
+}
diff --git a/src/tools/rustfmt/src/source_file.rs b/src/tools/rustfmt/src/source_file.rs
index 5eea8021b32..73f8ecb5529 100644
--- a/src/tools/rustfmt/src/source_file.rs
+++ b/src/tools/rustfmt/src/source_file.rs
@@ -2,10 +2,10 @@ use std::fs;
 use std::io::{self, Write};
 use std::path::Path;
 
+use crate::NewlineStyle;
 use crate::config::FileName;
 use crate::emitter::{self, Emitter};
 use crate::parse::session::ParseSess;
-use crate::NewlineStyle;
 
 #[cfg(test)]
 use crate::config::Config;
diff --git a/src/tools/rustfmt/src/spanned.rs b/src/tools/rustfmt/src/spanned.rs
index 1ee691b4ade..b4424e476ee 100644
--- a/src/tools/rustfmt/src/spanned.rs
+++ b/src/tools/rustfmt/src/spanned.rs
@@ -1,9 +1,10 @@
 use std::cmp::max;
 
 use rustc_ast::{ast, ptr};
-use rustc_span::{source_map, Span};
+use rustc_span::{Span, source_map};
 
 use crate::macros::MacroArg;
+use crate::patterns::RangeOperand;
 use crate::utils::{mk_sp, outer_attributes};
 
 /// Spanned returns a span including attributes, if available.
@@ -212,3 +213,9 @@ impl Spanned for ast::PreciseCapturingArg {
         }
     }
 }
+
+impl<'a> Spanned for RangeOperand<'a> {
+    fn span(&self) -> Span {
+        self.span
+    }
+}
diff --git a/src/tools/rustfmt/src/stmt.rs b/src/tools/rustfmt/src/stmt.rs
index 73a9cce416c..2788159018d 100644
--- a/src/tools/rustfmt/src/stmt.rs
+++ b/src/tools/rustfmt/src/stmt.rs
@@ -2,9 +2,9 @@ use rustc_ast::ast;
 use rustc_span::Span;
 
 use crate::comment::recover_comment_removed;
-use crate::config::Version;
-use crate::expr::{format_expr, is_simple_block, ExprType};
-use crate::rewrite::{Rewrite, RewriteContext};
+use crate::config::StyleEdition;
+use crate::expr::{ExprType, format_expr, is_simple_block};
+use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
 use crate::shape::Shape;
 use crate::source_map::LineRangeUtils;
 use crate::spanned::Spanned;
@@ -90,11 +90,20 @@ impl<'a> Stmt<'a> {
 
 impl<'a> Rewrite for Stmt<'a> {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
-        let expr_type = if context.config.version() == Version::Two && self.is_last_expr() {
-            ExprType::SubExpression
-        } else {
-            ExprType::Statement
-        };
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(
+        &self,
+        context: &RewriteContext<'_>,
+        shape: Shape,
+    ) -> crate::rewrite::RewriteResult {
+        let expr_type =
+            if context.config.style_edition() >= StyleEdition::Edition2024 && self.is_last_expr() {
+                ExprType::SubExpression
+            } else {
+                ExprType::Statement
+            };
         format_stmt(
             context,
             shape,
@@ -111,11 +120,11 @@ fn format_stmt(
     stmt: &ast::Stmt,
     expr_type: ExprType,
     is_last_expr: bool,
-) -> Option<String> {
-    skip_out_of_file_lines_range!(context, stmt.span());
+) -> RewriteResult {
+    skip_out_of_file_lines_range_err!(context, stmt.span());
 
     let result = match stmt.kind {
-        ast::StmtKind::Let(ref local) => local.rewrite(context, shape),
+        ast::StmtKind::Let(ref local) => local.rewrite_result(context, shape),
         ast::StmtKind::Expr(ref ex) | ast::StmtKind::Semi(ref ex) => {
             let suffix = if semicolon_for_stmt(context, stmt, is_last_expr) {
                 ";"
@@ -123,10 +132,14 @@ fn format_stmt(
                 ""
             };
 
-            let shape = shape.sub_width(suffix.len())?;
+            let shape = shape
+                .sub_width(suffix.len())
+                .max_width_error(shape.width, ex.span())?;
             format_expr(ex, expr_type, context, shape).map(|s| s + suffix)
         }
-        ast::StmtKind::MacCall(..) | ast::StmtKind::Item(..) | ast::StmtKind::Empty => None,
+        ast::StmtKind::MacCall(..) | ast::StmtKind::Item(..) | ast::StmtKind::Empty => {
+            Err(RewriteError::Unknown)
+        }
     };
-    result.and_then(|res| recover_comment_removed(res, stmt.span(), context))
+    result.map(|res| recover_comment_removed(res, stmt.span(), context))
 }
diff --git a/src/tools/rustfmt/src/string.rs b/src/tools/rustfmt/src/string.rs
index cb666fff695..3b971188cd5 100644
--- a/src/tools/rustfmt/src/string.rs
+++ b/src/tools/rustfmt/src/string.rs
@@ -84,7 +84,7 @@ pub(crate) fn rewrite_string<'a>(
         stripped_str
             .len()
             .checked_next_power_of_two()
-            .unwrap_or(usize::max_value()),
+            .unwrap_or(usize::MAX),
     );
     result.push_str(fmt.opener);
 
@@ -375,7 +375,7 @@ fn graphemes_width(graphemes: &[&str]) -> usize {
 
 #[cfg(test)]
 mod test {
-    use super::{break_string, detect_url, rewrite_string, SnippetState, StringFormat};
+    use super::{SnippetState, StringFormat, break_string, detect_url, rewrite_string};
     use crate::config::Config;
     use crate::shape::{Indent, Shape};
     use unicode_segmentation::UnicodeSegmentation;
diff --git a/src/tools/rustfmt/src/test/configuration_snippet.rs b/src/tools/rustfmt/src/test/configuration_snippet.rs
index e4a390ada66..5b93703de0b 100644
--- a/src/tools/rustfmt/src/test/configuration_snippet.rs
+++ b/src/tools/rustfmt/src/test/configuration_snippet.rs
@@ -4,9 +4,9 @@ use std::io::{BufRead, BufReader, Write};
 use std::iter::Enumerate;
 use std::path::{Path, PathBuf};
 
-use super::{print_mismatches, write_message, DIFF_CONTEXT_SIZE};
+use super::{DIFF_CONTEXT_SIZE, print_mismatches, write_message};
 use crate::config::{Config, EmitMode, Verbosity};
-use crate::rustfmt_diff::{make_diff, Mismatch};
+use crate::rustfmt_diff::{Mismatch, make_diff};
 use crate::{Input, Session};
 
 const CONFIGURATIONS_FILE_NAME: &str = "Configurations.md";
diff --git a/src/tools/rustfmt/src/test/mod.rs b/src/tools/rustfmt/src/test/mod.rs
index 286e8b8760a..d62da08fff8 100644
--- a/src/tools/rustfmt/src/test/mod.rs
+++ b/src/tools/rustfmt/src/test/mod.rs
@@ -6,14 +6,17 @@ use std::iter::Peekable;
 use std::mem;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
-use std::str::Chars;
+use std::str::{Chars, FromStr};
 use std::thread;
 
 use crate::config::{Color, Config, EmitMode, FileName, NewlineStyle};
 use crate::formatting::{ReportedErrors, SourceFile};
-use crate::rustfmt_diff::{make_diff, print_diff, DiffLine, Mismatch, ModifiedChunk, OutputWriter};
+use crate::rustfmt_diff::{DiffLine, Mismatch, ModifiedChunk, OutputWriter, make_diff, print_diff};
 use crate::source_file;
-use crate::{is_nightly_channel, FormatReport, FormatReportFormatterBuilder, Input, Session};
+use crate::{
+    Edition, FormatReport, FormatReportFormatterBuilder, Input, Session, StyleEdition, Version,
+    is_nightly_channel,
+};
 
 use rustfmt_config_proc_macro::nightly_only_test;
 use tracing::{debug, warn};
@@ -102,10 +105,9 @@ fn is_file_skip(path: &Path) -> bool {
 fn get_test_files(path: &Path, recursive: bool) -> Vec<PathBuf> {
     let mut files = vec![];
     if path.is_dir() {
-        for entry in fs::read_dir(path).expect(&format!(
-            "couldn't read directory {}",
-            path.to_str().unwrap()
-        )) {
+        for entry in
+            fs::read_dir(path).expect(&format!("couldn't read directory {}", path.display()))
+        {
             let entry = entry.expect("couldn't get `DirEntry`");
             let path = entry.path();
             if path.is_dir() && recursive {
@@ -119,10 +121,7 @@ fn get_test_files(path: &Path, recursive: bool) -> Vec<PathBuf> {
 }
 
 fn verify_config_used(path: &Path, config_name: &str) {
-    for entry in fs::read_dir(path).expect(&format!(
-        "couldn't read {} directory",
-        path.to_str().unwrap()
-    )) {
+    for entry in fs::read_dir(path).expect(&format!("couldn't read {} directory", path.display())) {
         let entry = entry.expect("couldn't get directory entry");
         let path = entry.path();
         if path.extension().map_or(false, |f| f == "rs") {
@@ -711,13 +710,24 @@ fn print_mismatches<T: Fn(u32) -> String>(
 
 fn read_config(filename: &Path) -> Config {
     let sig_comments = read_significant_comments(filename);
+    let (edition, style_edition, version) = get_editions_from_comments(&sig_comments);
     // Look for a config file. If there is a 'config' property in the significant comments, use
     // that. Otherwise, if there are no significant comments at all, look for a config file with
     // the same name as the test file.
     let mut config = if !sig_comments.is_empty() {
-        get_config(sig_comments.get("config").map(Path::new))
+        get_config(
+            sig_comments.get("config").map(Path::new),
+            edition,
+            style_edition,
+            version,
+        )
     } else {
-        get_config(filename.with_extension("toml").file_name().map(Path::new))
+        get_config(
+            filename.with_extension("toml").file_name().map(Path::new),
+            edition,
+            style_edition,
+            version,
+        )
     };
 
     for (key, val) in &sig_comments {
@@ -748,13 +758,31 @@ enum IdempotentCheckError {
     Parse,
 }
 
+fn get_editions_from_comments(
+    comments: &HashMap<String, String>,
+) -> (Option<Edition>, Option<StyleEdition>, Option<Version>) {
+    (
+        comments
+            .get("edition")
+            .map(|e| Edition::from_str(e).expect(&format!("invalid edition value: '{}'", e))),
+        comments.get("style_edition").map(|se| {
+            StyleEdition::from_str(se).expect(&format!("invalid style_edition value: '{}'", se))
+        }),
+        comments
+            .get("version")
+            .map(|v| Version::from_str(v).expect(&format!("invalid version value: '{}'", v))),
+    )
+}
+
 fn idempotent_check(
     filename: &PathBuf,
     opt_config: &Option<PathBuf>,
 ) -> Result<FormatReport, IdempotentCheckError> {
     let sig_comments = read_significant_comments(filename);
     let config = if let Some(ref config_file_path) = opt_config {
-        Config::from_toml_path(config_file_path).expect("`rustfmt.toml` not found")
+        let (edition, style_edition, version) = get_editions_from_comments(&sig_comments);
+        Config::from_toml_path(config_file_path, edition, style_edition, version)
+            .expect("`rustfmt.toml` not found")
     } else {
         read_config(filename)
     };
@@ -778,14 +806,19 @@ fn idempotent_check(
 // Reads test config file using the supplied (optional) file name. If there's no file name or the
 // file doesn't exist, just return the default config. Otherwise, the file must be read
 // successfully.
-fn get_config(config_file: Option<&Path>) -> Config {
+fn get_config(
+    config_file: Option<&Path>,
+    edition: Option<Edition>,
+    style_edition: Option<StyleEdition>,
+    version: Option<Version>,
+) -> Config {
     let config_file_name = match config_file {
-        None => return Default::default(),
+        None => return Config::default_for_possible_style_edition(style_edition, edition, version),
         Some(file_name) => {
             let mut full_path = PathBuf::from("tests/config/");
             full_path.push(file_name);
             if !full_path.exists() {
-                return Default::default();
+                return Config::default_for_possible_style_edition(style_edition, edition, version);
             };
             full_path
         }
@@ -797,7 +830,14 @@ fn get_config(config_file: Option<&Path>) -> Config {
         .read_to_string(&mut def_config)
         .expect("Couldn't read config");
 
-    Config::from_toml(&def_config, Path::new("tests/config/")).expect("invalid TOML")
+    Config::from_toml_for_style_edition(
+        &def_config,
+        Path::new("tests/config/"),
+        edition,
+        style_edition,
+        version,
+    )
+    .expect("invalid TOML")
 }
 
 // Reads significant comments of the form: `// rustfmt-key: value` into a hash map.
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 7730aa467ce..07b483b2b37 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -2,23 +2,23 @@ use std::ops::Deref;
 
 use rustc_ast::ast::{self, FnRetTy, Mutability, Term};
 use rustc_ast::ptr;
-use rustc_span::{symbol::kw, BytePos, Pos, Span};
+use rustc_span::{BytePos, Pos, Span, symbol::kw};
 use tracing::debug;
 
 use crate::comment::{combine_strs_with_missing_comments, contains_comment};
 use crate::config::lists::*;
-use crate::config::{IndentStyle, TypeDensity, Version};
+use crate::config::{IndentStyle, StyleEdition, TypeDensity};
 use crate::expr::{
-    format_expr, rewrite_assign_rhs, rewrite_call, rewrite_tuple, rewrite_unary_prefix, ExprType,
-    RhsAssignKind,
+    ExprType, RhsAssignKind, format_expr, rewrite_assign_rhs, rewrite_call, rewrite_tuple,
+    rewrite_unary_prefix,
 };
 use crate::lists::{
-    definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
+    ListFormatting, ListItem, Separator, definitive_tactic, itemize_list, write_list,
 };
-use crate::macros::{rewrite_macro, MacroPosition};
+use crate::macros::{MacroPosition, rewrite_macro};
 use crate::overflow;
-use crate::pairs::{rewrite_pair, PairParts};
-use crate::rewrite::{Rewrite, RewriteContext};
+use crate::pairs::{PairParts, rewrite_pair};
+use crate::rewrite::{Rewrite, RewriteContext, RewriteError, RewriteErrorExt, RewriteResult};
 use crate::shape::Shape;
 use crate::source_map::SpanUtils;
 use crate::spanned::Spanned;
@@ -41,7 +41,7 @@ pub(crate) fn rewrite_path(
     qself: &Option<ptr::P<ast::QSelf>>,
     path: &ast::Path,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     let skip_count = qself.as_ref().map_or(0, |x| x.position);
 
     // 32 covers almost all path lengths measured when compiling core, and there isn't a big
@@ -57,7 +57,7 @@ pub(crate) fn rewrite_path(
     if let Some(qself) = qself {
         result.push('<');
 
-        let fmt_ty = qself.ty.rewrite(context, shape)?;
+        let fmt_ty = qself.ty.rewrite_result(context, shape)?;
         result.push_str(&fmt_ty);
 
         if skip_count > 0 {
@@ -67,7 +67,7 @@ pub(crate) fn rewrite_path(
             }
 
             // 3 = ">::".len()
-            let shape = shape.sub_width(3)?;
+            let shape = shape.sub_width(3).max_width_error(shape.width, path.span)?;
 
             result = rewrite_path_segments(
                 PathContext::Type,
@@ -103,7 +103,7 @@ fn rewrite_path_segments<'a, I>(
     span_hi: BytePos,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String>
+) -> RewriteResult
 where
     I: Iterator<Item = &'a ast::PathSegment>,
 {
@@ -122,7 +122,9 @@ where
         }
 
         let extra_offset = extra_offset(&buffer, shape);
-        let new_shape = shape.shrink_left(extra_offset)?;
+        let new_shape = shape
+            .shrink_left(extra_offset)
+            .max_width_error(shape.width, mk_sp(span_lo, span_hi))?;
         let segment_string = rewrite_segment(
             path_context,
             segment,
@@ -135,7 +137,7 @@ where
         buffer.push_str(&segment_string);
     }
 
-    Some(buffer)
+    Ok(buffer)
 }
 
 #[derive(Debug)]
@@ -169,19 +171,27 @@ impl<'a> Spanned for SegmentParam<'a> {
 
 impl<'a> Rewrite for SegmentParam<'a> {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         match *self {
-            SegmentParam::Const(const_) => const_.rewrite(context, shape),
-            SegmentParam::LifeTime(lt) => lt.rewrite(context, shape),
-            SegmentParam::Type(ty) => ty.rewrite(context, shape),
-            SegmentParam::Binding(atc) => atc.rewrite(context, shape),
+            SegmentParam::Const(const_) => const_.rewrite_result(context, shape),
+            SegmentParam::LifeTime(lt) => lt.rewrite_result(context, shape),
+            SegmentParam::Type(ty) => ty.rewrite_result(context, shape),
+            SegmentParam::Binding(atc) => atc.rewrite_result(context, shape),
         }
     }
 }
 
 impl Rewrite for ast::PreciseCapturingArg {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         match self {
-            ast::PreciseCapturingArg::Lifetime(lt) => lt.rewrite(context, shape),
+            ast::PreciseCapturingArg::Lifetime(lt) => lt.rewrite_result(context, shape),
             ast::PreciseCapturingArg::Arg(p, _) => {
                 rewrite_path(context, PathContext::Type, &None, p, shape)
             }
@@ -191,13 +201,20 @@ impl Rewrite for ast::PreciseCapturingArg {
 
 impl Rewrite for ast::AssocItemConstraint {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         use ast::AssocItemConstraintKind::{Bound, Equality};
 
         let mut result = String::with_capacity(128);
         result.push_str(rewrite_ident(context, self.ident));
 
         if let Some(ref gen_args) = self.gen_args {
-            let budget = shape.width.checked_sub(result.len())?;
+            let budget = shape
+                .width
+                .checked_sub(result.len())
+                .max_width_error(shape.width, self.span)?;
             let shape = Shape::legacy(budget, shape.indent + result.len());
             let gen_str = rewrite_generic_args(gen_args, context, shape, gen_args.span())?;
             result.push_str(&gen_str);
@@ -210,23 +227,30 @@ impl Rewrite for ast::AssocItemConstraint {
         };
         result.push_str(infix);
 
-        let budget = shape.width.checked_sub(result.len())?;
+        let budget = shape
+            .width
+            .checked_sub(result.len())
+            .max_width_error(shape.width, self.span)?;
         let shape = Shape::legacy(budget, shape.indent + result.len());
-        let rewrite = self.kind.rewrite(context, shape)?;
+        let rewrite = self.kind.rewrite_result(context, shape)?;
         result.push_str(&rewrite);
 
-        Some(result)
+        Ok(result)
     }
 }
 
 impl Rewrite for ast::AssocItemConstraintKind {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         match self {
             ast::AssocItemConstraintKind::Equality { term } => match term {
-                Term::Ty(ty) => ty.rewrite(context, shape),
-                Term::Const(c) => c.rewrite(context, shape),
+                Term::Ty(ty) => ty.rewrite_result(context, shape),
+                Term::Const(c) => c.rewrite_result(context, shape),
             },
-            ast::AssocItemConstraintKind::Bound { bounds } => bounds.rewrite(context, shape),
+            ast::AssocItemConstraintKind::Bound { bounds } => bounds.rewrite_result(context, shape),
         }
     }
 }
@@ -248,16 +272,17 @@ fn rewrite_segment(
     span_hi: BytePos,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     let mut result = String::with_capacity(128);
     result.push_str(rewrite_ident(context, segment.ident));
 
     let ident_len = result.len();
     let shape = if context.use_block_indent() {
-        shape.offset_left(ident_len)?
+        shape.offset_left(ident_len)
     } else {
-        shape.shrink_left(ident_len)?
-    };
+        shape.shrink_left(ident_len)
+    }
+    .max_width_error(shape.width, mk_sp(*span_lo, span_hi))?;
 
     if let Some(ref args) = segment.args {
         let generics_str = rewrite_generic_args(args, context, shape, mk_sp(*span_lo, span_hi))?;
@@ -288,7 +313,7 @@ fn rewrite_segment(
         result.push_str(&generics_str)
     }
 
-    Some(result)
+    Ok(result)
 }
 
 fn format_function_type<'a, I>(
@@ -298,7 +323,7 @@ fn format_function_type<'a, I>(
     span: Span,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String>
+) -> RewriteResult
 where
     I: ExactSizeIterator,
     <I as Iterator>::Item: Deref,
@@ -308,12 +333,12 @@ where
 
     let ty_shape = match context.config.indent_style() {
         // 4 = " -> "
-        IndentStyle::Block => shape.offset_left(4)?,
-        IndentStyle::Visual => shape.block_left(4)?,
+        IndentStyle::Block => shape.offset_left(4).max_width_error(shape.width, span)?,
+        IndentStyle::Visual => shape.block_left(4).max_width_error(shape.width, span)?,
     };
     let output = match *output {
         FnRetTy::Ty(ref ty) => {
-            let type_str = ty.rewrite(context, ty_shape)?;
+            let type_str = ty.rewrite_result(context, ty_shape)?;
             format!(" -> {type_str}")
         }
         FnRetTy::Default(..) => String::new(),
@@ -326,7 +351,10 @@ where
         )
     } else {
         // 2 for ()
-        let budget = shape.width.checked_sub(2)?;
+        let budget = shape
+            .width
+            .checked_sub(2)
+            .max_width_error(shape.width, span)?;
         // 1 for (
         let offset = shape.indent + 1;
         Shape::legacy(budget, offset)
@@ -339,7 +367,8 @@ where
         let list_hi = context.snippet_provider.span_before(span, ")");
         let comment = context
             .snippet_provider
-            .span_to_snippet(mk_sp(list_lo, list_hi))?
+            .span_to_snippet(mk_sp(list_lo, list_hi))
+            .unknown_error()?
             .trim();
         let comment = if comment.starts_with("//") {
             format!(
@@ -360,7 +389,7 @@ where
             ",",
             |arg| arg.span().lo(),
             |arg| arg.span().hi(),
-            |arg| arg.rewrite(context, list_shape),
+            |arg| arg.rewrite_result(context, list_shape),
             list_lo,
             span.hi(),
             false,
@@ -396,9 +425,9 @@ where
         )
     };
     if output.is_empty() || last_line_width(&args) + first_line_width(&output) <= shape.width {
-        Some(format!("{args}{output}"))
+        Ok(format!("{args}{output}"))
     } else {
-        Some(format!(
+        Ok(format!(
             "{}\n{}{}",
             args,
             list_shape.indent.to_string(context.config),
@@ -429,6 +458,10 @@ fn get_tactics(item_vec: &[ListItem], output: &str, shape: Shape) -> DefinitiveL
 
 impl Rewrite for ast::WherePredicate {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         // FIXME: dead spans?
         let result = match *self {
             ast::WherePredicate::BoundPredicate(ast::WhereBoundPredicate {
@@ -437,7 +470,7 @@ impl Rewrite for ast::WherePredicate {
                 ref bounds,
                 ..
             }) => {
-                let type_str = bounded_ty.rewrite(context, shape)?;
+                let type_str = bounded_ty.rewrite_result(context, shape)?;
                 let colon = type_bound_colon(context).trim_end();
                 let lhs = if let Some(binder_str) =
                     rewrite_bound_params(context, shape, bound_generic_params)
@@ -452,28 +485,34 @@ impl Rewrite for ast::WherePredicate {
             ast::WherePredicate::RegionPredicate(ast::WhereRegionPredicate {
                 ref lifetime,
                 ref bounds,
-                ..
-            }) => rewrite_bounded_lifetime(lifetime, bounds, context, shape)?,
+                span,
+            }) => rewrite_bounded_lifetime(lifetime, bounds, span, context, shape)?,
             ast::WherePredicate::EqPredicate(ast::WhereEqPredicate {
                 ref lhs_ty,
                 ref rhs_ty,
                 ..
             }) => {
-                let lhs_ty_str = lhs_ty.rewrite(context, shape).map(|lhs| lhs + " =")?;
+                let lhs_ty_str = lhs_ty
+                    .rewrite_result(context, shape)
+                    .map(|lhs| lhs + " =")?;
                 rewrite_assign_rhs(context, lhs_ty_str, &**rhs_ty, &RhsAssignKind::Ty, shape)?
             }
         };
 
-        Some(result)
+        Ok(result)
     }
 }
 
 impl Rewrite for ast::GenericArg {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         match *self {
-            ast::GenericArg::Lifetime(ref lt) => lt.rewrite(context, shape),
-            ast::GenericArg::Type(ref ty) => ty.rewrite(context, shape),
-            ast::GenericArg::Const(ref const_) => const_.rewrite(context, shape),
+            ast::GenericArg::Lifetime(ref lt) => lt.rewrite_result(context, shape),
+            ast::GenericArg::Type(ref ty) => ty.rewrite_result(context, shape),
+            ast::GenericArg::Const(ref const_) => const_.rewrite_result(context, shape),
         }
     }
 }
@@ -483,11 +522,11 @@ fn rewrite_generic_args(
     context: &RewriteContext<'_>,
     shape: Shape,
     span: Span,
-) -> Option<String> {
+) -> RewriteResult {
     match gen_args {
         ast::GenericArgs::AngleBracketed(ref data) => {
             if data.args.is_empty() {
-                Some("".to_owned())
+                Ok("".to_owned())
             } else {
                 let args = data
                     .args
@@ -513,47 +552,63 @@ fn rewrite_generic_args(
             context,
             shape,
         ),
-        ast::GenericArgs::ParenthesizedElided(..) => Some("(..)".to_owned()),
+        ast::GenericArgs::ParenthesizedElided(..) => Ok("(..)".to_owned()),
     }
 }
 
 fn rewrite_bounded_lifetime(
     lt: &ast::Lifetime,
     bounds: &[ast::GenericBound],
+    span: Span,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
-    let result = lt.rewrite(context, shape)?;
+) -> RewriteResult {
+    let result = lt.rewrite_result(context, shape)?;
 
     if bounds.is_empty() {
-        Some(result)
+        Ok(result)
     } else {
         let colon = type_bound_colon(context);
         let overhead = last_line_width(&result) + colon.len();
+        let shape = shape
+            .sub_width(overhead)
+            .max_width_error(shape.width, span)?;
         let result = format!(
             "{}{}{}",
             result,
             colon,
-            join_bounds(context, shape.sub_width(overhead)?, bounds, true)?
+            join_bounds(context, shape, bounds, true)?
         );
-        Some(result)
+        Ok(result)
     }
 }
 
 impl Rewrite for ast::AnonConst {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         format_expr(&self.value, ExprType::SubExpression, context, shape)
     }
 }
 
 impl Rewrite for ast::Lifetime {
-    fn rewrite(&self, context: &RewriteContext<'_>, _: Shape) -> Option<String> {
-        Some(context.snippet(self.ident.span).to_owned())
+    fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, _: Shape) -> RewriteResult {
+        Ok(context.snippet(self.ident.span).to_owned())
     }
 }
 
 impl Rewrite for ast::GenericBound {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         match *self {
             ast::GenericBound::Trait(
                 ref poly_trait_ref,
@@ -574,24 +629,30 @@ impl Rewrite for ast::GenericBound {
                     asyncness.push(' ');
                 }
                 let polarity = polarity.as_str();
-                let shape = shape.offset_left(constness.len() + polarity.len())?;
+                let shape = shape
+                    .offset_left(constness.len() + polarity.len())
+                    .max_width_error(shape.width, self.span())?;
                 poly_trait_ref
-                    .rewrite(context, shape)
+                    .rewrite_result(context, shape)
                     .map(|s| format!("{constness}{asyncness}{polarity}{s}"))
                     .map(|s| if has_paren { format!("({})", s) } else { s })
             }
             ast::GenericBound::Use(ref args, span) => {
                 overflow::rewrite_with_angle_brackets(context, "use", args.iter(), shape, span)
             }
-            ast::GenericBound::Outlives(ref lifetime) => lifetime.rewrite(context, shape),
+            ast::GenericBound::Outlives(ref lifetime) => lifetime.rewrite_result(context, shape),
         }
     }
 }
 
 impl Rewrite for ast::GenericBounds {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         if self.is_empty() {
-            return Some(String::new());
+            return Ok(String::new());
         }
 
         join_bounds(context, shape, self, true)
@@ -600,8 +661,15 @@ impl Rewrite for ast::GenericBounds {
 
 impl Rewrite for ast::GenericParam {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         // FIXME: If there are more than one attributes, this will force multiline.
-        let mut result = self.attrs.rewrite(context, shape).unwrap_or(String::new());
+        let mut result = self
+            .attrs
+            .rewrite_result(context, shape)
+            .unwrap_or(String::new());
         let has_attrs = !result.is_empty();
 
         let mut param = String::with_capacity(128);
@@ -615,15 +683,19 @@ impl Rewrite for ast::GenericParam {
             param.push_str("const ");
             param.push_str(rewrite_ident(context, self.ident));
             param.push_str(": ");
-            param.push_str(&ty.rewrite(context, shape)?);
+            param.push_str(&ty.rewrite_result(context, shape)?);
             if let Some(default) = default {
                 let eq_str = match context.config.type_punctuation_density() {
                     TypeDensity::Compressed => "=",
                     TypeDensity::Wide => " = ",
                 };
                 param.push_str(eq_str);
-                let budget = shape.width.checked_sub(param.len())?;
-                let rewrite = default.rewrite(context, Shape::legacy(budget, shape.indent))?;
+                let budget = shape
+                    .width
+                    .checked_sub(param.len())
+                    .max_width_error(shape.width, self.span())?;
+                let rewrite =
+                    default.rewrite_result(context, Shape::legacy(budget, shape.indent))?;
                 param.push_str(&rewrite);
             }
             kw_span.lo()
@@ -634,7 +706,7 @@ impl Rewrite for ast::GenericParam {
 
         if !self.bounds.is_empty() {
             param.push_str(type_bound_colon(context));
-            param.push_str(&self.bounds.rewrite(context, shape)?)
+            param.push_str(&self.bounds.rewrite_result(context, shape)?)
         }
         if let ast::GenericParamKind::Type {
             default: Some(ref def),
@@ -645,9 +717,12 @@ impl Rewrite for ast::GenericParam {
                 TypeDensity::Wide => " = ",
             };
             param.push_str(eq_str);
-            let budget = shape.width.checked_sub(param.len())?;
+            let budget = shape
+                .width
+                .checked_sub(param.len())
+                .max_width_error(shape.width, self.span())?;
             let rewrite =
-                def.rewrite(context, Shape::legacy(budget, shape.indent + param.len()))?;
+                def.rewrite_result(context, Shape::legacy(budget, shape.indent + param.len()))?;
             param.push_str(&rewrite);
         }
 
@@ -673,44 +748,67 @@ impl Rewrite for ast::GenericParam {
             result.push_str(&param);
         }
 
-        Some(result)
+        Ok(result)
     }
 }
 
 impl Rewrite for ast::PolyTraitRef {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         if let Some(lifetime_str) = rewrite_bound_params(context, shape, &self.bound_generic_params)
         {
             // 6 is "for<> ".len()
             let extra_offset = lifetime_str.len() + 6;
-            let path_str = self
-                .trait_ref
-                .rewrite(context, shape.offset_left(extra_offset)?)?;
+            let shape = shape
+                .offset_left(extra_offset)
+                .max_width_error(shape.width, self.span)?;
+            let path_str = self.trait_ref.rewrite_result(context, shape)?;
 
-            Some(format!("for<{lifetime_str}> {path_str}"))
+            Ok(format!("for<{lifetime_str}> {path_str}"))
         } else {
-            self.trait_ref.rewrite(context, shape)
+            self.trait_ref.rewrite_result(context, shape)
         }
     }
 }
 
 impl Rewrite for ast::TraitRef {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         rewrite_path(context, PathContext::Type, &None, &self.path, shape)
     }
 }
 
 impl Rewrite for ast::Ty {
     fn rewrite(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
+        self.rewrite_result(context, shape).ok()
+    }
+
+    fn rewrite_result(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
         match self.kind {
             ast::TyKind::TraitObject(ref bounds, tobj_syntax) => {
                 // we have to consider 'dyn' keyword is used or not!!!
                 let (shape, prefix) = match tobj_syntax {
-                    ast::TraitObjectSyntax::Dyn => (shape.offset_left(4)?, "dyn "),
-                    ast::TraitObjectSyntax::DynStar => (shape.offset_left(5)?, "dyn* "),
+                    ast::TraitObjectSyntax::Dyn => {
+                        let shape = shape
+                            .offset_left(4)
+                            .max_width_error(shape.width, self.span())?;
+                        (shape, "dyn ")
+                    }
+                    ast::TraitObjectSyntax::DynStar => {
+                        let shape = shape
+                            .offset_left(5)
+                            .max_width_error(shape.width, self.span())?;
+                        (shape, "dyn* ")
+                    }
                     ast::TraitObjectSyntax::None => (shape, ""),
                 };
-                let mut res = bounds.rewrite(context, shape)?;
+                let mut res = bounds.rewrite_result(context, shape)?;
                 // We may have falsely removed a trailing `+` inside macro call.
                 if context.inside_macro()
                     && bounds.len() == 1
@@ -719,7 +817,7 @@ impl Rewrite for ast::Ty {
                 {
                     res.push('+');
                 }
-                Some(format!("{prefix}{res}"))
+                Ok(format!("{prefix}{res}"))
             }
             ast::TyKind::Ptr(ref mt) => {
                 let prefix = match mt.mutbl {
@@ -738,8 +836,11 @@ impl Rewrite for ast::Ty {
                 let mut cmnt_lo = ref_hi;
 
                 if let Some(ref lifetime) = *lifetime {
-                    let lt_budget = shape.width.checked_sub(2 + mut_len)?;
-                    let lt_str = lifetime.rewrite(
+                    let lt_budget = shape
+                        .width
+                        .checked_sub(2 + mut_len)
+                        .max_width_error(shape.width, self.span())?;
+                    let lt_str = lifetime.rewrite_result(
                         context,
                         Shape::legacy(lt_budget, shape.indent + 2 + mut_len),
                     )?;
@@ -783,39 +884,46 @@ impl Rewrite for ast::Ty {
                     result = combine_strs_with_missing_comments(
                         context,
                         result.trim_end(),
-                        &mt.ty.rewrite(context, shape)?,
+                        &mt.ty.rewrite_result(context, shape)?,
                         before_ty_span,
                         shape,
                         true,
                     )?;
                 } else {
                     let used_width = last_line_width(&result);
-                    let budget = shape.width.checked_sub(used_width)?;
-                    let ty_str = mt
-                        .ty
-                        .rewrite(context, Shape::legacy(budget, shape.indent + used_width))?;
+                    let budget = shape
+                        .width
+                        .checked_sub(used_width)
+                        .max_width_error(shape.width, self.span())?;
+                    let ty_str = mt.ty.rewrite_result(
+                        context,
+                        Shape::legacy(budget, shape.indent + used_width),
+                    )?;
                     result.push_str(&ty_str);
                 }
 
-                Some(result)
+                Ok(result)
             }
             // FIXME: we drop any comments here, even though it's a silly place to put
             // comments.
             ast::TyKind::Paren(ref ty) => {
-                if context.config.version() == Version::One
+                if context.config.style_edition() <= StyleEdition::Edition2021
                     || context.config.indent_style() == IndentStyle::Visual
                 {
-                    let budget = shape.width.checked_sub(2)?;
+                    let budget = shape
+                        .width
+                        .checked_sub(2)
+                        .max_width_error(shape.width, self.span())?;
                     return ty
-                        .rewrite(context, Shape::legacy(budget, shape.indent + 1))
+                        .rewrite_result(context, Shape::legacy(budget, shape.indent + 1))
                         .map(|ty_str| format!("({})", ty_str));
                 }
 
                 // 2 = ()
                 if let Some(sh) = shape.sub_width(2) {
-                    if let Some(ref s) = ty.rewrite(context, sh) {
+                    if let Ok(ref s) = ty.rewrite_result(context, sh) {
                         if !s.contains('\n') {
-                            return Some(format!("({s})"));
+                            return Ok(format!("({s})"));
                         }
                     }
                 }
@@ -824,8 +932,8 @@ impl Rewrite for ast::Ty {
                 let shape = shape
                     .block_indent(context.config.tab_spaces())
                     .with_max_width(context.config);
-                let rw = ty.rewrite(context, shape)?;
-                Some(format!(
+                let rw = ty.rewrite_result(context, shape)?;
+                Ok(format!(
                     "({}{}{})",
                     shape.to_string_with_newline(context.config),
                     rw,
@@ -833,15 +941,18 @@ impl Rewrite for ast::Ty {
                 ))
             }
             ast::TyKind::Slice(ref ty) => {
-                let budget = shape.width.checked_sub(4)?;
-                ty.rewrite(context, Shape::legacy(budget, shape.indent + 1))
+                let budget = shape
+                    .width
+                    .checked_sub(4)
+                    .max_width_error(shape.width, self.span())?;
+                ty.rewrite_result(context, Shape::legacy(budget, shape.indent + 1))
                     .map(|ty_str| format!("[{}]", ty_str))
             }
             ast::TyKind::Tup(ref items) => {
                 rewrite_tuple(context, items.iter(), self.span, shape, items.len() == 1)
             }
-            ast::TyKind::AnonStruct(..) => Some(context.snippet(self.span).to_owned()),
-            ast::TyKind::AnonUnion(..) => Some(context.snippet(self.span).to_owned()),
+            ast::TyKind::AnonStruct(..) => Ok(context.snippet(self.span).to_owned()),
+            ast::TyKind::AnonUnion(..) => Ok(context.snippet(self.span).to_owned()),
             ast::TyKind::Path(ref q_self, ref path) => {
                 rewrite_path(context, PathContext::Type, q_self, path, shape)
             }
@@ -855,24 +966,27 @@ impl Rewrite for ast::Ty {
             ),
             ast::TyKind::Infer => {
                 if shape.width >= 1 {
-                    Some("_".to_owned())
+                    Ok("_".to_owned())
                 } else {
-                    None
+                    Err(RewriteError::ExceedsMaxWidth {
+                        configured_width: shape.width,
+                        span: self.span(),
+                    })
                 }
             }
             ast::TyKind::BareFn(ref bare_fn) => rewrite_bare_fn(bare_fn, self.span, context, shape),
-            ast::TyKind::Never => Some(String::from("!")),
+            ast::TyKind::Never => Ok(String::from("!")),
             ast::TyKind::MacCall(ref mac) => {
                 rewrite_macro(mac, None, context, shape, MacroPosition::Expression)
             }
-            ast::TyKind::ImplicitSelf => Some(String::from("")),
+            ast::TyKind::ImplicitSelf => Ok(String::from("")),
             ast::TyKind::ImplTrait(_, ref it) => {
                 // Empty trait is not a parser error.
                 if it.is_empty() {
-                    return Some("impl".to_owned());
+                    return Ok("impl".to_owned());
                 }
-                let rw = if context.config.version() == Version::One {
-                    it.rewrite(context, shape)
+                let rw = if context.config.style_edition() <= StyleEdition::Edition2021 {
+                    it.rewrite_result(context, shape)
                 } else {
                     join_bounds(context, shape, it, false)
                 };
@@ -881,8 +995,8 @@ impl Rewrite for ast::Ty {
                     format!("impl{}{}", space, it_str)
                 })
             }
-            ast::TyKind::CVarArgs => Some("...".to_owned()),
-            ast::TyKind::Dummy | ast::TyKind::Err(_) => Some(context.snippet(self.span).to_owned()),
+            ast::TyKind::CVarArgs => Ok("...".to_owned()),
+            ast::TyKind::Dummy | ast::TyKind::Err(_) => Ok(context.snippet(self.span).to_owned()),
             ast::TyKind::Typeof(ref anon_const) => rewrite_call(
                 context,
                 "typeof",
@@ -891,9 +1005,9 @@ impl Rewrite for ast::Ty {
                 shape,
             ),
             ast::TyKind::Pat(ref ty, ref pat) => {
-                let ty = ty.rewrite(context, shape)?;
-                let pat = pat.rewrite(context, shape)?;
-                Some(format!("{ty} is {pat}"))
+                let ty = ty.rewrite_result(context, shape)?;
+                let pat = pat.rewrite_result(context, shape)?;
+                Ok(format!("{ty} is {pat}"))
             }
         }
     }
@@ -904,7 +1018,7 @@ fn rewrite_bare_fn(
     span: Span,
     context: &RewriteContext<'_>,
     shape: Shape,
-) -> Option<String> {
+) -> RewriteResult {
     debug!("rewrite_bare_fn {:#?}", shape);
 
     let mut result = String::with_capacity(128);
@@ -928,9 +1042,14 @@ fn rewrite_bare_fn(
     result.push_str("fn");
 
     let func_ty_shape = if context.use_block_indent() {
-        shape.offset_left(result.len())?
+        shape
+            .offset_left(result.len())
+            .max_width_error(shape.width, span)?
     } else {
-        shape.visual_indent(result.len()).sub_width(result.len())?
+        shape
+            .visual_indent(result.len())
+            .sub_width(result.len())
+            .max_width_error(shape.width, span)?
     };
 
     let rewrite = format_function_type(
@@ -944,7 +1063,7 @@ fn rewrite_bare_fn(
 
     result.push_str(&rewrite);
 
-    Some(result)
+    Ok(result)
 }
 
 fn is_generic_bounds_in_order(generic_bounds: &[ast::GenericBound]) -> bool {
@@ -968,7 +1087,7 @@ fn join_bounds(
     shape: Shape,
     items: &[ast::GenericBound],
     need_indent: bool,
-) -> Option<String> {
+) -> RewriteResult {
     join_bounds_inner(context, shape, items, need_indent, false)
 }
 
@@ -978,7 +1097,7 @@ fn join_bounds_inner(
     items: &[ast::GenericBound],
     need_indent: bool,
     force_newline: bool,
-) -> Option<String> {
+) -> RewriteResult {
     debug_assert!(!items.is_empty());
 
     let generic_bounds_in_order = is_generic_bounds_in_order(items);
@@ -1073,10 +1192,10 @@ fn join_bounds_inner(
             };
 
             let (extendable, trailing_str) = if i == 0 {
-                let bound_str = item.rewrite(context, shape)?;
+                let bound_str = item.rewrite_result(context, shape)?;
                 (is_bound_extendable(&bound_str, item), bound_str)
             } else {
-                let bound_str = &item.rewrite(context, shape)?;
+                let bound_str = &item.rewrite_result(context, shape)?;
                 match leading_span {
                     Some(ls) if has_leading_comment => (
                         is_bound_extendable(bound_str, item),
@@ -1100,7 +1219,7 @@ fn join_bounds_inner(
                     true,
                 )
                 .map(|v| (v, trailing_span, extendable)),
-                _ => Some((strs + &trailing_str, trailing_span, extendable)),
+                _ => Ok((strs + &trailing_str, trailing_span, extendable)),
             }
         },
     )?;
@@ -1110,22 +1229,22 @@ fn join_bounds_inner(
     //   and either there is more than one item;
     //       or the single item is of type `Trait`,
     //          and any of the internal arrays contains more than one item;
-    let retry_with_force_newline = match context.config.version() {
-        Version::One => {
+    let retry_with_force_newline = match context.config.style_edition() {
+        style_edition @ _ if style_edition <= StyleEdition::Edition2021 => {
             !force_newline
                 && items.len() > 1
                 && (result.0.contains('\n') || result.0.len() > shape.width)
         }
-        Version::Two if force_newline => false,
-        Version::Two if (!result.0.contains('\n') && result.0.len() <= shape.width) => false,
-        Version::Two if items.len() > 1 => true,
-        Version::Two => is_item_with_multi_items_array(&items[0]),
+        _ if force_newline => false,
+        _ if (!result.0.contains('\n') && result.0.len() <= shape.width) => false,
+        _ if items.len() > 1 => true,
+        _ => is_item_with_multi_items_array(&items[0]),
     };
 
     if retry_with_force_newline {
         join_bounds_inner(context, shape, items, need_indent, true)
     } else {
-        Some(result.0)
+        Ok(result.0)
     }
 }
 
diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs
index fd59aedadfe..d1cfc6acc49 100644
--- a/src/tools/rustfmt/src/utils.rs
+++ b/src/tools/rustfmt/src/utils.rs
@@ -6,11 +6,11 @@ use rustc_ast::ast::{
 };
 use rustc_ast::ptr;
 use rustc_ast_pretty::pprust;
-use rustc_span::{sym, symbol, BytePos, LocalExpnId, Span, Symbol, SyntaxContext};
+use rustc_span::{BytePos, LocalExpnId, Span, Symbol, SyntaxContext, sym, symbol};
 use unicode_width::UnicodeWidthStr;
 
-use crate::comment::{filter_normal_code, CharClasses, FullCodeCharKind, LineClasses};
-use crate::config::{Config, Version};
+use crate::comment::{CharClasses, FullCodeCharKind, LineClasses, filter_normal_code};
+use crate::config::{Config, StyleEdition};
 use crate::rewrite::RewriteContext;
 use crate::shape::{Indent, Shape};
 
@@ -367,10 +367,10 @@ macro_rules! out_of_file_lines_range {
     };
 }
 
-macro_rules! skip_out_of_file_lines_range {
+macro_rules! skip_out_of_file_lines_range_err {
     ($self:ident, $span:expr) => {
         if out_of_file_lines_range!($self, $span) {
-            return None;
+            return Err(RewriteError::SkipFormatting);
         }
     };
 }
@@ -596,7 +596,7 @@ pub(crate) fn trim_left_preserve_layout(
 
             // just InString{Commented} in order to allow the start of a string to be indented
             let new_veto_trim_value = (kind == FullCodeCharKind::InString
-                || (config.version() == Version::Two
+                || (config.style_edition() >= StyleEdition::Edition2024
                     && kind == FullCodeCharKind::InStringCommented))
                 && !line.ends_with('\\');
             let line = if veto_trim || new_veto_trim_value {
@@ -612,7 +612,7 @@ pub(crate) fn trim_left_preserve_layout(
             // such lines should not be taken into account when computing the minimum.
             match kind {
                 FullCodeCharKind::InStringCommented | FullCodeCharKind::EndStringCommented
-                    if config.version() == Version::Two =>
+                    if config.style_edition() >= StyleEdition::Edition2024 =>
                 {
                     None
                 }
@@ -656,7 +656,7 @@ pub(crate) fn indent_next_line(kind: FullCodeCharKind, line: &str, config: &Conf
         // formatting the code block, therefore the string's indentation needs
         // to be adjusted for the code surrounding the code block.
         config.format_strings() && line.ends_with('\\')
-    } else if config.version() == Version::Two {
+    } else if config.style_edition() >= StyleEdition::Edition2024 {
         !kind.is_commented_string()
     } else {
         true
diff --git a/src/tools/rustfmt/src/vertical.rs b/src/tools/rustfmt/src/vertical.rs
index a06bc995aa5..1ec239c3821 100644
--- a/src/tools/rustfmt/src/vertical.rs
+++ b/src/tools/rustfmt/src/vertical.rs
@@ -11,9 +11,9 @@ use crate::config::lists::*;
 use crate::expr::rewrite_field;
 use crate::items::{rewrite_struct_field, rewrite_struct_field_prefix};
 use crate::lists::{
-    definitive_tactic, itemize_list, write_list, ListFormatting, ListItem, Separator,
+    ListFormatting, ListItem, Separator, definitive_tactic, itemize_list, write_list,
 };
-use crate::rewrite::{Rewrite, RewriteContext};
+use crate::rewrite::{Rewrite, RewriteContext, RewriteResult};
 use crate::shape::{Indent, Shape};
 use crate::source_map::SpanUtils;
 use crate::spanned::Spanned;
@@ -24,13 +24,13 @@ use crate::utils::{
 pub(crate) trait AlignedItem {
     fn skip(&self) -> bool;
     fn get_span(&self) -> Span;
-    fn rewrite_prefix(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String>;
+    fn rewrite_prefix(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult;
     fn rewrite_aligned_item(
         &self,
         context: &RewriteContext<'_>,
         shape: Shape,
         prefix_max_width: usize,
-    ) -> Option<String>;
+    ) -> RewriteResult;
 }
 
 impl AlignedItem for ast::FieldDef {
@@ -42,24 +42,23 @@ impl AlignedItem for ast::FieldDef {
         self.span()
     }
 
-    fn rewrite_prefix(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
-        let attrs_str = self.attrs.rewrite(context, shape)?;
+    fn rewrite_prefix(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
+        let attrs_str = self.attrs.rewrite_result(context, shape)?;
         let missing_span = if self.attrs.is_empty() {
             mk_sp(self.span.lo(), self.span.lo())
         } else {
             mk_sp(self.attrs.last().unwrap().span.hi(), self.span.lo())
         };
         let attrs_extendable = self.ident.is_none() && is_attributes_extendable(&attrs_str);
-        rewrite_struct_field_prefix(context, self).and_then(|field_str| {
-            combine_strs_with_missing_comments(
-                context,
-                &attrs_str,
-                &field_str,
-                missing_span,
-                shape,
-                attrs_extendable,
-            )
-        })
+        let field_str = rewrite_struct_field_prefix(context, self)?;
+        combine_strs_with_missing_comments(
+            context,
+            &attrs_str,
+            &field_str,
+            missing_span,
+            shape,
+            attrs_extendable,
+        )
     }
 
     fn rewrite_aligned_item(
@@ -67,7 +66,7 @@ impl AlignedItem for ast::FieldDef {
         context: &RewriteContext<'_>,
         shape: Shape,
         prefix_max_width: usize,
-    ) -> Option<String> {
+    ) -> RewriteResult {
         rewrite_struct_field(context, self, shape, prefix_max_width)
     }
 }
@@ -81,8 +80,8 @@ impl AlignedItem for ast::ExprField {
         self.span()
     }
 
-    fn rewrite_prefix(&self, context: &RewriteContext<'_>, shape: Shape) -> Option<String> {
-        let attrs_str = self.attrs.rewrite(context, shape)?;
+    fn rewrite_prefix(&self, context: &RewriteContext<'_>, shape: Shape) -> RewriteResult {
+        let attrs_str = self.attrs.rewrite_result(context, shape)?;
         let name = rewrite_ident(context, self.ident);
         let missing_span = if self.attrs.is_empty() {
             mk_sp(self.span.lo(), self.span.lo())
@@ -104,7 +103,7 @@ impl AlignedItem for ast::ExprField {
         context: &RewriteContext<'_>,
         shape: Shape,
         prefix_max_width: usize,
-    ) -> Option<String> {
+    ) -> RewriteResult {
         rewrite_field(context, self, shape, prefix_max_width)
     }
 }
@@ -199,7 +198,7 @@ fn struct_field_prefix_max_min_width<T: AlignedItem>(
                 .rewrite_prefix(context, shape)
                 .map(|field_str| trimmed_last_line_width(&field_str))
         })
-        .fold_options((0, ::std::usize::MAX), |(max_len, min_len), len| {
+        .fold_ok((0, ::std::usize::MAX), |(max_len, min_len), len| {
             (cmp::max(max_len, len), cmp::min(min_len, len))
         })
         .unwrap_or((0, 0))
@@ -246,12 +245,12 @@ fn rewrite_aligned_items_inner<T: AlignedItem>(
     if tactic == DefinitiveListTactic::Horizontal {
         // since the items fits on a line, there is no need to align them
         let do_rewrite =
-            |field: &T| -> Option<String> { field.rewrite_aligned_item(context, item_shape, 0) };
+            |field: &T| -> RewriteResult { field.rewrite_aligned_item(context, item_shape, 0) };
         fields
             .iter()
             .zip(items.iter_mut())
             .for_each(|(field, list_item): (&T, &mut ListItem)| {
-                if list_item.item.is_some() {
+                if list_item.item.is_ok() {
                     list_item.item = do_rewrite(field);
                 }
             });
@@ -267,7 +266,7 @@ fn rewrite_aligned_items_inner<T: AlignedItem>(
         .tactic(tactic)
         .trailing_separator(separator_tactic)
         .preserve_newline(true);
-    write_list(&items, &fmt)
+    write_list(&items, &fmt).ok()
 }
 
 /// Returns the index in `fields` up to which a field belongs to the current group.
diff --git a/src/tools/rustfmt/src/visitor.rs b/src/tools/rustfmt/src/visitor.rs
index ac68fc5fecf..8102fe7ad8f 100644
--- a/src/tools/rustfmt/src/visitor.rs
+++ b/src/tools/rustfmt/src/visitor.rs
@@ -3,24 +3,23 @@ use std::rc::Rc;
 
 use rustc_ast::{ast, token::Delimiter, visit};
 use rustc_data_structures::sync::Lrc;
-use rustc_span::{symbol, BytePos, Pos, Span};
+use rustc_span::{BytePos, Pos, Span, symbol};
 use tracing::debug;
 
 use crate::attr::*;
-use crate::comment::{contains_comment, rewrite_comment, CodeCharKind, CommentCodeSlices};
-use crate::config::Version;
-use crate::config::{BraceStyle, Config, MacroSelector};
+use crate::comment::{CodeCharKind, CommentCodeSlices, contains_comment, rewrite_comment};
+use crate::config::{BraceStyle, Config, MacroSelector, StyleEdition};
 use crate::coverage::transform_missing_snippet;
 use crate::items::{
-    format_impl, format_trait, format_trait_alias, is_mod_decl, is_use_item, rewrite_extern_crate,
-    rewrite_type_alias, FnBraceStyle, FnSig, ItemVisitorKind, StaticParts, StructParts,
+    FnBraceStyle, FnSig, ItemVisitorKind, StaticParts, StructParts, format_impl, format_trait,
+    format_trait_alias, is_mod_decl, is_use_item, rewrite_extern_crate, rewrite_type_alias,
 };
-use crate::macros::{macro_style, rewrite_macro, rewrite_macro_def, MacroPosition};
+use crate::macros::{MacroPosition, macro_style, rewrite_macro, rewrite_macro_def};
 use crate::modules::Module;
 use crate::parse::session::ParseSess;
 use crate::rewrite::{Rewrite, RewriteContext};
 use crate::shape::{Indent, Shape};
-use crate::skip::{is_skip_attr, SkipContext};
+use crate::skip::{SkipContext, is_skip_attr};
 use crate::source_map::{LineRangeUtils, SpanUtils};
 use crate::spanned::Spanned;
 use crate::stmt::Stmt;
@@ -291,7 +290,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
 
                     let mut comment_shape =
                         Shape::indented(self.block_indent, config).comment(config);
-                    if self.config.version() == Version::Two && comment_on_same_line {
+                    if self.config.style_edition() >= StyleEdition::Edition2024
+                        && comment_on_same_line
+                    {
                         self.push_str(" ");
                         // put the first line of the comment on the same line as the
                         // block's last line
@@ -312,8 +313,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                                 let comment_str =
                                     rewrite_comment(other_lines, false, comment_shape, config);
                                 match comment_str {
-                                    Some(ref s) => self.push_str(s),
-                                    None => self.push_str(other_lines),
+                                    Ok(ref s) => self.push_str(s),
+                                    Err(_) => self.push_str(other_lines),
                                 }
                             }
                         }
@@ -342,8 +343,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
 
                         let comment_str = rewrite_comment(&sub_slice, false, comment_shape, config);
                         match comment_str {
-                            Some(ref s) => self.push_str(s),
-                            None => self.push_str(&sub_slice),
+                            Ok(ref s) => self.push_str(s),
+                            Err(_) => self.push_str(&sub_slice),
                         }
                     }
                 }
@@ -561,9 +562,11 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                         )
                     } else {
                         let indent = self.block_indent;
-                        let rewrite = self.rewrite_required_fn(
-                            indent, item.ident, sig, &item.vis, generics, item.span,
-                        );
+                        let rewrite = self
+                            .rewrite_required_fn(
+                                indent, item.ident, sig, &item.vis, generics, item.span,
+                            )
+                            .ok();
                         self.push_rewrite(item.span, rewrite);
                     }
                 }
@@ -584,7 +587,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                         item.ident,
                         &item.vis,
                         item.span,
-                    );
+                    )
+                    .ok();
                     self.push_rewrite(item.span, rewrite);
                 }
                 ast::ItemKind::Delegation(..) | ast::ItemKind::DelegationMac(..) => {
@@ -609,7 +613,8 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
             self.block_indent,
             visitor_kind,
             span,
-        );
+        )
+        .ok();
         self.push_rewrite(span, rewrite);
     }
 
@@ -655,8 +660,9 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
                     );
                 } else {
                     let indent = self.block_indent;
-                    let rewrite =
-                        self.rewrite_required_fn(indent, ai.ident, sig, &ai.vis, generics, ai.span);
+                    let rewrite = self
+                        .rewrite_required_fn(indent, ai.ident, sig, &ai.vis, generics, ai.span)
+                        .ok();
                     self.push_rewrite(ai.span, rewrite);
                 }
             }
@@ -683,7 +689,7 @@ impl<'b, 'a: 'b> FmtVisitor<'a> {
 
         // 1 = ;
         let shape = self.shape().saturating_sub_width(1);
-        let rewrite = self.with_context(|ctx| rewrite_macro(mac, ident, ctx, shape, pos));
+        let rewrite = self.with_context(|ctx| rewrite_macro(mac, ident, ctx, shape, pos).ok());
         // As of v638 of the rustc-ap-* crates, the associated span no longer includes
         // the trailing semicolon. This determines the correct span to ensure scenarios
         // with whitespace between the delimiters and trailing semi (i.e. `foo!(abc)     ;`)
diff --git a/src/tools/rustfmt/tests/config/issue-5801-v2.toml b/src/tools/rustfmt/tests/config/issue-5801-v2.toml
index 948f4fb66bf..98e89d37916 100644
--- a/src/tools/rustfmt/tests/config/issue-5801-v2.toml
+++ b/src/tools/rustfmt/tests/config/issue-5801-v2.toml
@@ -1,3 +1,3 @@
 max_width = 120
 version = "Two"
-attr_fn_like_width = 120
\ No newline at end of file
+attr_fn_like_width = 120
diff --git a/src/tools/rustfmt/tests/config/issue-6302.toml b/src/tools/rustfmt/tests/config/issue-6302.toml
new file mode 100644
index 00000000000..8148b37b1f6
--- /dev/null
+++ b/src/tools/rustfmt/tests/config/issue-6302.toml
@@ -0,0 +1 @@
+edition = 2019
diff --git a/src/tools/rustfmt/tests/config/style-edition/just-style-edition/rustfmt.toml b/src/tools/rustfmt/tests/config/style-edition/just-style-edition/rustfmt.toml
new file mode 100644
index 00000000000..3501136812c
--- /dev/null
+++ b/src/tools/rustfmt/tests/config/style-edition/just-style-edition/rustfmt.toml
@@ -0,0 +1 @@
+style_edition = "2024"
diff --git a/src/tools/rustfmt/tests/config/style-edition/just-version/rustfmt.toml b/src/tools/rustfmt/tests/config/style-edition/just-version/rustfmt.toml
new file mode 100644
index 00000000000..1082fd88889
--- /dev/null
+++ b/src/tools/rustfmt/tests/config/style-edition/just-version/rustfmt.toml
@@ -0,0 +1 @@
+version = "Two"
diff --git a/src/tools/rustfmt/tests/config/style-edition/overrides/rustfmt.toml b/src/tools/rustfmt/tests/config/style-edition/overrides/rustfmt.toml
new file mode 100644
index 00000000000..24205692b1f
--- /dev/null
+++ b/src/tools/rustfmt/tests/config/style-edition/overrides/rustfmt.toml
@@ -0,0 +1,2 @@
+style_edition = "2024"
+overflow_delimited_expr = false
diff --git a/src/tools/rustfmt/tests/config/style-edition/style-edition-and-edition/rustfmt.toml b/src/tools/rustfmt/tests/config/style-edition/style-edition-and-edition/rustfmt.toml
new file mode 100644
index 00000000000..92844e03ab6
--- /dev/null
+++ b/src/tools/rustfmt/tests/config/style-edition/style-edition-and-edition/rustfmt.toml
@@ -0,0 +1,2 @@
+style_edition = "2021"
+edition = "2024"
diff --git a/src/tools/rustfmt/tests/config/style-edition/version-edition/rustfmt.toml b/src/tools/rustfmt/tests/config/style-edition/version-edition/rustfmt.toml
new file mode 100644
index 00000000000..16ea9a13f36
--- /dev/null
+++ b/src/tools/rustfmt/tests/config/style-edition/version-edition/rustfmt.toml
@@ -0,0 +1,2 @@
+version = "Two"
+edition = "2018"
diff --git a/src/tools/rustfmt/tests/config/style-edition/version-style-edition-and-edition/rustfmt.toml b/src/tools/rustfmt/tests/config/style-edition/version-style-edition-and-edition/rustfmt.toml
new file mode 100644
index 00000000000..187ba13cfb6
--- /dev/null
+++ b/src/tools/rustfmt/tests/config/style-edition/version-style-edition-and-edition/rustfmt.toml
@@ -0,0 +1,3 @@
+version = "Two"
+edition = "2018"
+style_edition = "2021"
diff --git a/src/tools/rustfmt/tests/config/style-edition/version-style-edition/rustfmt.toml b/src/tools/rustfmt/tests/config/style-edition/version-style-edition/rustfmt.toml
new file mode 100644
index 00000000000..c894bd981bc
--- /dev/null
+++ b/src/tools/rustfmt/tests/config/style-edition/version-style-edition/rustfmt.toml
@@ -0,0 +1,2 @@
+version = "Two"
+style_edition = "2021"
diff --git a/src/tools/rustfmt/tests/rustfmt/main.rs b/src/tools/rustfmt/tests/rustfmt/main.rs
index 58cf0e5e4db..a9f58b9328e 100644
--- a/src/tools/rustfmt/tests/rustfmt/main.rs
+++ b/src/tools/rustfmt/tests/rustfmt/main.rs
@@ -5,7 +5,7 @@ use std::fs::remove_file;
 use std::path::Path;
 use std::process::Command;
 
-use rustfmt_config_proc_macro::rustfmt_only_ci_test;
+use rustfmt_config_proc_macro::{nightly_only_test, rustfmt_only_ci_test};
 
 /// Run the rustfmt executable and return its output.
 fn rustfmt(args: &[&str]) -> (String, String) {
@@ -207,3 +207,28 @@ fn rustfmt_emits_error_when_control_brace_style_is_always_next_line() {
     let (_stdout, stderr) = rustfmt(&args);
     assert!(!stderr.contains("error[internal]: left behind trailing whitespace"))
 }
+
+#[nightly_only_test]
+#[test]
+fn rustfmt_generates_no_error_if_failed_format_code_in_doc_comments() {
+    // See also https://github.com/rust-lang/rustfmt/issues/6109
+
+    let file = "tests/target/issue-6109.rs";
+    let args = ["--config", "format_code_in_doc_comments=true", file];
+    let (stdout, stderr) = rustfmt(&args);
+    assert!(stderr.is_empty());
+    assert!(stdout.is_empty());
+}
+
+#[test]
+fn rustfmt_error_improvement_regarding_invalid_toml() {
+    // See also https://github.com/rust-lang/rustfmt/issues/6302
+    let invalid_toml_config = "tests/config/issue-6302.toml";
+    let args = ["--config-path", invalid_toml_config];
+    let (_stdout, stderr) = rustfmt(&args);
+
+    let toml_path = Path::new(invalid_toml_config).canonicalize().unwrap();
+    let expected_error_message = format!("The file `{}` failed to parse", toml_path.display());
+
+    assert!(stderr.contains(&expected_error_message));
+}
diff --git a/src/tools/rustfmt/tests/source/arrow_in_comments/arrow_in_single_comment.rs b/src/tools/rustfmt/tests/source/arrow_in_comments/arrow_in_single_comment.rs
index fb0576a4822..38e8967e7e6 100644
--- a/src/tools/rustfmt/tests/source/arrow_in_comments/arrow_in_single_comment.rs
+++ b/src/tools/rustfmt/tests/source/arrow_in_comments/arrow_in_single_comment.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 fn main() {
     match a {
         _ =>
diff --git a/src/tools/rustfmt/tests/source/arrow_in_comments/multiple_arrows.rs b/src/tools/rustfmt/tests/source/arrow_in_comments/multiple_arrows.rs
index fc696b309f2..98ef919450f 100644
--- a/src/tools/rustfmt/tests/source/arrow_in_comments/multiple_arrows.rs
+++ b/src/tools/rustfmt/tests/source/arrow_in_comments/multiple_arrows.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 fn main() {
     match a {
         _ => // comment with => 
diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/one.rs b/src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/one.rs
index 6d48ea742fc..66e2f538415 100644
--- a/src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/one.rs
+++ b/src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 // rustfmt-error_on_line_overflow: false
 // rustfmt-indent_style: Block
 
diff --git a/src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/two.rs b/src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/two.rs
index 7a62d722c6e..51aa6376e23 100644
--- a/src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/two.rs
+++ b/src/tools/rustfmt/tests/source/configs/indent_style/block_trailing_comma_call/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // rustfmt-error_on_line_overflow: false
 // rustfmt-indent_style: Block
 
diff --git a/src/tools/rustfmt/tests/source/configs/style_edition/overflow_delim_expr_2015.rs b/src/tools/rustfmt/tests/source/configs/style_edition/overflow_delim_expr_2015.rs
new file mode 100644
index 00000000000..5cb4a870fc1
--- /dev/null
+++ b/src/tools/rustfmt/tests/source/configs/style_edition/overflow_delim_expr_2015.rs
@@ -0,0 +1,155 @@
+// rustfmt-style_edition: 2015
+
+fn combine_blocklike() {
+    do_thing(
+        |param| {
+            action();
+            foo(param)
+        },
+    );
+
+    do_thing(
+        x,
+        |param| {
+            action();
+            foo(param)
+        },
+    );
+
+    do_thing(
+        x,
+
+        // I'll be discussing the `action` with your para(m)legal counsel
+        |param| {
+            action();
+            foo(param)
+        },
+    );
+
+    do_thing(
+        Bar {
+            x: value,
+            y: value2,
+        },
+    );
+
+    do_thing(
+        x,
+        Bar {
+            x: value,
+            y: value2,
+        },
+    );
+
+    do_thing(
+        x,
+
+        // Let me tell you about that one time at the `Bar`
+        Bar {
+            x: value,
+            y: value2,
+        },
+    );
+
+    do_thing(
+        &[
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        x,
+        &[
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        x,
+
+        // Just admit it; my list is longer than can be folded on to one line
+        &[
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        vec![
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        x,
+        vec![
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        x,
+
+        // Just admit it; my list is longer than can be folded on to one line
+        vec![
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        x,
+        (
+            1,
+            2,
+            3,
+            |param| {
+                action();
+                foo(param)
+            },
+        ),
+    );
+}
+
+fn combine_struct_sample() {
+    let identity = verify(
+        &ctx,
+        VerifyLogin {
+            type_: LoginType::Username,
+            username: args.username.clone(),
+            password: Some(args.password.clone()),
+            domain: None,
+        },
+    )?;
+}
+
+fn combine_macro_sample() {
+    rocket::ignite()
+        .mount(
+            "/",
+            routes![
+                http::auth::login,
+                http::auth::logout,
+                http::cors::options,
+                http::action::dance,
+                http::action::sleep,
+            ],
+        )
+        .launch();
+}
diff --git a/src/tools/rustfmt/tests/source/configs/style_edition/overflow_delim_expr_2024.rs b/src/tools/rustfmt/tests/source/configs/style_edition/overflow_delim_expr_2024.rs
new file mode 100644
index 00000000000..66c95e71aa9
--- /dev/null
+++ b/src/tools/rustfmt/tests/source/configs/style_edition/overflow_delim_expr_2024.rs
@@ -0,0 +1,155 @@
+// rustfmt-style_edition: 2024
+
+fn combine_blocklike() {
+    do_thing(
+        |param| {
+            action();
+            foo(param)
+        },
+    );
+
+    do_thing(
+        x,
+        |param| {
+            action();
+            foo(param)
+        },
+    );
+
+    do_thing(
+        x,
+
+        // I'll be discussing the `action` with your para(m)legal counsel
+        |param| {
+            action();
+            foo(param)
+        },
+    );
+
+    do_thing(
+        Bar {
+            x: value,
+            y: value2,
+        },
+    );
+
+    do_thing(
+        x,
+        Bar {
+            x: value,
+            y: value2,
+        },
+    );
+
+    do_thing(
+        x,
+
+        // Let me tell you about that one time at the `Bar`
+        Bar {
+            x: value,
+            y: value2,
+        },
+    );
+
+    do_thing(
+        &[
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        x,
+        &[
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        x,
+
+        // Just admit it; my list is longer than can be folded on to one line
+        &[
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        vec![
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        x,
+        vec![
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        x,
+
+        // Just admit it; my list is longer than can be folded on to one line
+        vec![
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        x,
+        (
+            1,
+            2,
+            3,
+            |param| {
+                action();
+                foo(param)
+            },
+        ),
+    );
+}
+
+fn combine_struct_sample() {
+    let identity = verify(
+        &ctx,
+        VerifyLogin {
+            type_: LoginType::Username,
+            username: args.username.clone(),
+            password: Some(args.password.clone()),
+            domain: None,
+        },
+    )?;
+}
+
+fn combine_macro_sample() {
+    rocket::ignite()
+        .mount(
+            "/",
+            routes![
+                http::auth::login,
+                http::auth::logout,
+                http::cors::options,
+                http::action::dance,
+                http::action::sleep,
+            ],
+        )
+        .launch();
+}
diff --git a/src/tools/rustfmt/tests/source/fn-single-line/version_one.rs b/src/tools/rustfmt/tests/source/fn-single-line/version_one.rs
index 469ab621567..85957e3fdcc 100644
--- a/src/tools/rustfmt/tests/source/fn-single-line/version_one.rs
+++ b/src/tools/rustfmt/tests/source/fn-single-line/version_one.rs
@@ -1,5 +1,5 @@
 // rustfmt-fn_single_line: true
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 // Test single-line functions.
 
 fn foo_expr() {
diff --git a/src/tools/rustfmt/tests/source/fn-single-line/version_two.rs b/src/tools/rustfmt/tests/source/fn-single-line/version_two.rs
index bf381ff1065..f119e581217 100644
--- a/src/tools/rustfmt/tests/source/fn-single-line/version_two.rs
+++ b/src/tools/rustfmt/tests/source/fn-single-line/version_two.rs
@@ -1,5 +1,5 @@
 // rustfmt-fn_single_line: true
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // Test single-line functions.
 
 fn foo_expr() {
diff --git a/src/tools/rustfmt/tests/source/issue-2179/one.rs b/src/tools/rustfmt/tests/source/issue-2179/one.rs
index d23947931ff..8bbd56f0521 100644
--- a/src/tools/rustfmt/tests/source/issue-2179/one.rs
+++ b/src/tools/rustfmt/tests/source/issue-2179/one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 // rustfmt-error_on_line_overflow: false
 
 fn issue_2179() {
diff --git a/src/tools/rustfmt/tests/source/issue-2179/two.rs b/src/tools/rustfmt/tests/source/issue-2179/two.rs
index f4cc9cc488b..631b0f3c86e 100644
--- a/src/tools/rustfmt/tests/source/issue-2179/two.rs
+++ b/src/tools/rustfmt/tests/source/issue-2179/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // rustfmt-error_on_line_overflow: false
 
 fn issue_2179() {
diff --git a/src/tools/rustfmt/tests/source/issue-3213/version_one.rs b/src/tools/rustfmt/tests/source/issue-3213/version_one.rs
index f9f4cab55e3..ed7d5145150 100644
--- a/src/tools/rustfmt/tests/source/issue-3213/version_one.rs
+++ b/src/tools/rustfmt/tests/source/issue-3213/version_one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 fn foo() {
     match 0 {
diff --git a/src/tools/rustfmt/tests/source/issue-3213/version_two.rs b/src/tools/rustfmt/tests/source/issue-3213/version_two.rs
index 0f068c19d74..c6d04aced8d 100644
--- a/src/tools/rustfmt/tests/source/issue-3213/version_two.rs
+++ b/src/tools/rustfmt/tests/source/issue-3213/version_two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn foo() {
     match 0 {
diff --git a/src/tools/rustfmt/tests/source/issue-3227/two.rs b/src/tools/rustfmt/tests/source/issue-3227/two.rs
index c1572c00d57..50c0ad47dc1 100644
--- a/src/tools/rustfmt/tests/source/issue-3227/two.rs
+++ b/src/tools/rustfmt/tests/source/issue-3227/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn main() {
     thread::spawn(|| {
diff --git a/src/tools/rustfmt/tests/source/issue-3270/one.rs b/src/tools/rustfmt/tests/source/issue-3270/one.rs
index 3c2e27e2293..64861176b91 100644
--- a/src/tools/rustfmt/tests/source/issue-3270/one.rs
+++ b/src/tools/rustfmt/tests/source/issue-3270/one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 pub fn main() {
     /*   let s = String::from(
diff --git a/src/tools/rustfmt/tests/source/issue-3270/two.rs b/src/tools/rustfmt/tests/source/issue-3270/two.rs
index 0eb756471e7..1342cf03c39 100644
--- a/src/tools/rustfmt/tests/source/issue-3270/two.rs
+++ b/src/tools/rustfmt/tests/source/issue-3270/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 pub fn main() {
  /*   let s = String::from(
diff --git a/src/tools/rustfmt/tests/source/issue-3272/v1.rs b/src/tools/rustfmt/tests/source/issue-3272/v1.rs
index f4c1b7c992b..56dc048bf8a 100644
--- a/src/tools/rustfmt/tests/source/issue-3272/v1.rs
+++ b/src/tools/rustfmt/tests/source/issue-3272/v1.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 fn main() {
     assert!(HAYSTACK
diff --git a/src/tools/rustfmt/tests/source/issue-3272/v2.rs b/src/tools/rustfmt/tests/source/issue-3272/v2.rs
index 0148368edc8..f3adbe37c76 100644
--- a/src/tools/rustfmt/tests/source/issue-3272/v2.rs
+++ b/src/tools/rustfmt/tests/source/issue-3272/v2.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn main() {
     assert!(HAYSTACK
diff --git a/src/tools/rustfmt/tests/source/issue-3278/version_one.rs b/src/tools/rustfmt/tests/source/issue-3278/version_one.rs
index 580679fbae3..718a32b4c7e 100644
--- a/src/tools/rustfmt/tests/source/issue-3278/version_one.rs
+++ b/src/tools/rustfmt/tests/source/issue-3278/version_one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 pub fn parse_conditional<'a, I: 'a>(
 ) -> impl Parser<Input = I, Output = Expr, PartialState = ()> + 'a
diff --git a/src/tools/rustfmt/tests/source/issue-3278/version_two.rs b/src/tools/rustfmt/tests/source/issue-3278/version_two.rs
index c17b1742d39..eb605e509f9 100644
--- a/src/tools/rustfmt/tests/source/issue-3278/version_two.rs
+++ b/src/tools/rustfmt/tests/source/issue-3278/version_two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 pub fn parse_conditional<'a, I: 'a>()
 -> impl Parser<Input = I, Output = Expr, PartialState = ()> + 'a
diff --git a/src/tools/rustfmt/tests/source/issue-3295/two.rs b/src/tools/rustfmt/tests/source/issue-3295/two.rs
index 0eaf022249b..ae3d2ec28c0 100644
--- a/src/tools/rustfmt/tests/source/issue-3295/two.rs
+++ b/src/tools/rustfmt/tests/source/issue-3295/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 pub enum TestEnum {
     a,
     b,
diff --git a/src/tools/rustfmt/tests/source/issue-3302.rs b/src/tools/rustfmt/tests/source/issue-3302.rs
index c037584fd71..5e0862cb399 100644
--- a/src/tools/rustfmt/tests/source/issue-3302.rs
+++ b/src/tools/rustfmt/tests/source/issue-3302.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 macro_rules! moo1 {
     () => {
diff --git a/src/tools/rustfmt/tests/source/issue-3701/one.rs b/src/tools/rustfmt/tests/source/issue-3701/one.rs
index a7f0bd3aa17..4e8518b6f18 100644
--- a/src/tools/rustfmt/tests/source/issue-3701/one.rs
+++ b/src/tools/rustfmt/tests/source/issue-3701/one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 fn build_sorted_static_get_entry_names(
     mut entries: Vec<(u8, &'static str)>,
diff --git a/src/tools/rustfmt/tests/source/issue-3701/two.rs b/src/tools/rustfmt/tests/source/issue-3701/two.rs
index 8e15c58b8b2..d7cb790a754 100644
--- a/src/tools/rustfmt/tests/source/issue-3701/two.rs
+++ b/src/tools/rustfmt/tests/source/issue-3701/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn build_sorted_static_get_entry_names(
     mut entries: Vec<(u8, &'static str)>,
diff --git a/src/tools/rustfmt/tests/source/issue-3805.rs b/src/tools/rustfmt/tests/source/issue-3805.rs
index a0289b57974..aadc4a9dddc 100644
--- a/src/tools/rustfmt/tests/source/issue-3805.rs
+++ b/src/tools/rustfmt/tests/source/issue-3805.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // rustfmt-format_macro_matchers: true
 
 // From original issue example - Line length 101
diff --git a/src/tools/rustfmt/tests/source/issue-3840/version-two_hard-tabs.rs b/src/tools/rustfmt/tests/source/issue-3840/version-two_hard-tabs.rs
index 7b505fda87c..8d009eabdec 100644
--- a/src/tools/rustfmt/tests/source/issue-3840/version-two_hard-tabs.rs
+++ b/src/tools/rustfmt/tests/source/issue-3840/version-two_hard-tabs.rs
@@ -1,5 +1,5 @@
 // rustfmt-hard_tabs: true
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 impl<Target: FromEvent<A> + FromEvent<B>, A: Widget2<Ctx = C>, B: Widget2<Ctx = C>, C: for<'a> CtxFamily<'a>> Widget2 for WidgetEventLifter<Target, A, B>
 {
diff --git a/src/tools/rustfmt/tests/source/issue-3840/version-two_soft-tabs.rs b/src/tools/rustfmt/tests/source/issue-3840/version-two_soft-tabs.rs
index 39c8ef31292..9e283d3be0a 100644
--- a/src/tools/rustfmt/tests/source/issue-3840/version-two_soft-tabs.rs
+++ b/src/tools/rustfmt/tests/source/issue-3840/version-two_soft-tabs.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 impl<Target: FromEvent<A> + FromEvent<B>, A: Widget2<Ctx = C>, B: Widget2<Ctx = C>, C: for<'a> CtxFamily<'a>> Widget2 for WidgetEventLifter<Target, A, B>
 {
diff --git a/src/tools/rustfmt/tests/source/issue-4381/style_edition_2015.rs b/src/tools/rustfmt/tests/source/issue-4381/style_edition_2015.rs
new file mode 100644
index 00000000000..bb4c9feae1d
--- /dev/null
+++ b/src/tools/rustfmt/tests/source/issue-4381/style_edition_2015.rs
@@ -0,0 +1,3 @@
+// rustfmt-style_edition: 2015
+
+use std::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64};
diff --git a/src/tools/rustfmt/tests/source/issue-4530.rs b/src/tools/rustfmt/tests/source/issue-4530.rs
index 9d2882abb3c..6b92122f0c0 100644
--- a/src/tools/rustfmt/tests/source/issue-4530.rs
+++ b/src/tools/rustfmt/tests/source/issue-4530.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 fn main() {
     let [aaaaaaaaaaaaaaaaaaaaaaaaaa, bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb, cccccccccccccccccccccccccc, ddddddddddddddddddddddddd] = panic!();
 }
diff --git a/src/tools/rustfmt/tests/source/issue-4689/one.rs b/src/tools/rustfmt/tests/source/issue-4689/one.rs
index d048eb10fb1..bff090a3525 100644
--- a/src/tools/rustfmt/tests/source/issue-4689/one.rs
+++ b/src/tools/rustfmt/tests/source/issue-4689/one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 // Based on the issue description
 pub trait PrettyPrinter<'tcx>:
diff --git a/src/tools/rustfmt/tests/source/issue-4689/two.rs b/src/tools/rustfmt/tests/source/issue-4689/two.rs
index ea7feda825d..217535c046e 100644
--- a/src/tools/rustfmt/tests/source/issue-4689/two.rs
+++ b/src/tools/rustfmt/tests/source/issue-4689/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 // Based on the issue description
 pub trait PrettyPrinter<'tcx>:
diff --git a/src/tools/rustfmt/tests/source/issue-5586.rs b/src/tools/rustfmt/tests/source/issue-5586.rs
index 9cf6c1d58dd..061ad4bdaa4 100644
--- a/src/tools/rustfmt/tests/source/issue-5586.rs
+++ b/src/tools/rustfmt/tests/source/issue-5586.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 fn main() {
     // sample 1
     {
diff --git a/src/tools/rustfmt/tests/source/issue-5655/one.rs b/src/tools/rustfmt/tests/source/issue-5655/one.rs
index 1758ec56f8b..62df2655c29 100644
--- a/src/tools/rustfmt/tests/source/issue-5655/one.rs
+++ b/src/tools/rustfmt/tests/source/issue-5655/one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 fn foo<T>(_: T)
 where
diff --git a/src/tools/rustfmt/tests/source/issue-5655/two.rs b/src/tools/rustfmt/tests/source/issue-5655/two.rs
index e37ebbea8af..bfe1d3813bb 100644
--- a/src/tools/rustfmt/tests/source/issue-5655/two.rs
+++ b/src/tools/rustfmt/tests/source/issue-5655/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn foo<T>(_: T)
 where
diff --git a/src/tools/rustfmt/tests/source/issue-5801/comment_unexpectedly_wraps_before_max_width.rs b/src/tools/rustfmt/tests/source/issue-5801/comment_unexpectedly_wraps_before_max_width.rs
index 5847afd9560..e61d34604a1 100644
--- a/src/tools/rustfmt/tests/source/issue-5801/comment_unexpectedly_wraps_before_max_width.rs
+++ b/src/tools/rustfmt/tests/source/issue-5801/comment_unexpectedly_wraps_before_max_width.rs
@@ -1,7 +1,7 @@
 // rustfmt-comment_width: 120
 // rustfmt-wrap_comments: true
 // rustfmt-max_width: 120
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 /// This function is 120 columns wide and is left alone. This comment is 120 columns wide and the formatter is also fine
 fn my_super_cool_function_name(my_very_cool_argument_name: String, my_other_very_cool_argument_name: String) -> String {
diff --git a/src/tools/rustfmt/tests/source/issue-5987/two.rs b/src/tools/rustfmt/tests/source/issue-5987/two.rs
index e20026b5565..98ed35c4f9a 100644
--- a/src/tools/rustfmt/tests/source/issue-5987/two.rs
+++ b/src/tools/rustfmt/tests/source/issue-5987/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn main() {
     trace!(
diff --git a/src/tools/rustfmt/tests/source/issue-6147/case_rustfmt_v1.rs b/src/tools/rustfmt/tests/source/issue-6147/case_rustfmt_v1.rs
index 2ac2e0361c3..bcae86aaff2 100644
--- a/src/tools/rustfmt/tests/source/issue-6147/case_rustfmt_v1.rs
+++ b/src/tools/rustfmt/tests/source/issue-6147/case_rustfmt_v1.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 pub fn main() {
 let a = Some(12);
diff --git a/src/tools/rustfmt/tests/source/issue-6147/case_rustfmt_v2.rs b/src/tools/rustfmt/tests/source/issue-6147/case_rustfmt_v2.rs
index c1bf1ad4bf8..da612b213fc 100644
--- a/src/tools/rustfmt/tests/source/issue-6147/case_rustfmt_v2.rs
+++ b/src/tools/rustfmt/tests/source/issue-6147/case_rustfmt_v2.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 pub fn main() {
 let a = Some(12);
diff --git a/src/tools/rustfmt/tests/source/issue_5027.rs b/src/tools/rustfmt/tests/source/issue_5027.rs
index 67beeb23b71..a47d6df6f0f 100644
--- a/src/tools/rustfmt/tests/source/issue_5027.rs
+++ b/src/tools/rustfmt/tests/source/issue_5027.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 pub type Iter<'a, D> =                 impl       DoubleEndedIterator<Item = (SomethingSomethingSomethingLongType<D>)>+ ExactSizeIterator+ 'a;
 
diff --git a/src/tools/rustfmt/tests/source/let_else_v2.rs b/src/tools/rustfmt/tests/source/let_else_v2.rs
index a420fbcf95b..23be32d629a 100644
--- a/src/tools/rustfmt/tests/source/let_else_v2.rs
+++ b/src/tools/rustfmt/tests/source/let_else_v2.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // rustfmt-single_line_let_else_max_width: 100
 
 fn issue5901() {
diff --git a/src/tools/rustfmt/tests/source/long-fn-1/version_one.rs b/src/tools/rustfmt/tests/source/long-fn-1/version_one.rs
index d6832c2af09..60083024810 100644
--- a/src/tools/rustfmt/tests/source/long-fn-1/version_one.rs
+++ b/src/tools/rustfmt/tests/source/long-fn-1/version_one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 // Tests that a function which is almost short enough, but not quite, gets
 // formatted correctly.
 
diff --git a/src/tools/rustfmt/tests/source/long-fn-1/version_two.rs b/src/tools/rustfmt/tests/source/long-fn-1/version_two.rs
index f402a26e8b6..bce2c551c6a 100644
--- a/src/tools/rustfmt/tests/source/long-fn-1/version_two.rs
+++ b/src/tools/rustfmt/tests/source/long-fn-1/version_two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // Tests that a function which is almost short enough, but not quite, gets
 // formatted correctly.
 
diff --git a/src/tools/rustfmt/tests/source/one_line_if_v1.rs b/src/tools/rustfmt/tests/source/one_line_if_v1.rs
index d3dcbe6787a..bf7bc75fb88 100644
--- a/src/tools/rustfmt/tests/source/one_line_if_v1.rs
+++ b/src/tools/rustfmt/tests/source/one_line_if_v1.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 fn plain_if(x: bool) -> u8 {
     if x {
diff --git a/src/tools/rustfmt/tests/source/one_line_if_v2.rs b/src/tools/rustfmt/tests/source/one_line_if_v2.rs
index 40c834959f9..f3c974b12db 100644
--- a/src/tools/rustfmt/tests/source/one_line_if_v2.rs
+++ b/src/tools/rustfmt/tests/source/one_line_if_v2.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn plain_if(x: bool) -> u8 {
     if x {
diff --git a/src/tools/rustfmt/tests/source/single-line-macro/v1.rs b/src/tools/rustfmt/tests/source/single-line-macro/v1.rs
index a3aa631ed4a..fea146d8d33 100644
--- a/src/tools/rustfmt/tests/source/single-line-macro/v1.rs
+++ b/src/tools/rustfmt/tests/source/single-line-macro/v1.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 // #2652
 // Preserve trailing comma inside macro, even if it looks an array.
diff --git a/src/tools/rustfmt/tests/source/single-line-macro/v2.rs b/src/tools/rustfmt/tests/source/single-line-macro/v2.rs
index 51a665f7560..d9fba64ac70 100644
--- a/src/tools/rustfmt/tests/source/single-line-macro/v2.rs
+++ b/src/tools/rustfmt/tests/source/single-line-macro/v2.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 // #2652
 // Preserve trailing comma inside macro, even if it looks an array.
diff --git a/src/tools/rustfmt/tests/source/trailing_comments/hard_tabs.rs b/src/tools/rustfmt/tests/source/trailing_comments/hard_tabs.rs
index 88249aa5fb9..c6d1b3f0ab7 100644
--- a/src/tools/rustfmt/tests/source/trailing_comments/hard_tabs.rs
+++ b/src/tools/rustfmt/tests/source/trailing_comments/hard_tabs.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // rustfmt-wrap_comments: true
 // rustfmt-hard_tabs: true
 
diff --git a/src/tools/rustfmt/tests/source/trailing_comments/soft_tabs.rs b/src/tools/rustfmt/tests/source/trailing_comments/soft_tabs.rs
index 7845f713b8a..431875989f3 100644
--- a/src/tools/rustfmt/tests/source/trailing_comments/soft_tabs.rs
+++ b/src/tools/rustfmt/tests/source/trailing_comments/soft_tabs.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // rustfmt-wrap_comments: true
 
 pub const IFF_MULTICAST: ::c_int = 0x0000000800; // Supports multicast
diff --git a/src/tools/rustfmt/tests/source/tuple_v2.rs b/src/tools/rustfmt/tests/source/tuple_v2.rs
index 9223033832b..6dc18e00d7e 100644
--- a/src/tools/rustfmt/tests/source/tuple_v2.rs
+++ b/src/tools/rustfmt/tests/source/tuple_v2.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn issue_4355() {
     let _ = ((1,),).0 .0;
diff --git a/src/tools/rustfmt/tests/source/type-alias-where-clauses-with-comments.rs b/src/tools/rustfmt/tests/source/type-alias-where-clauses-with-comments.rs
new file mode 100644
index 00000000000..722ebac47ac
--- /dev/null
+++ b/src/tools/rustfmt/tests/source/type-alias-where-clauses-with-comments.rs
@@ -0,0 +1,31 @@
+type Foo // comment1
+    // interlinear1
+where // comment2
+    // interlinear2
+A: B, // comment3
+C: D, // comment4
+    // interlinear3
+= E; // comment5
+
+type Foo // comment6
+    // interlinear4
+where// comment7
+    // interlinear5
+A: B, // comment8
+C: D, // comment9
+    // interlinear6
+= E // comment10
+    // interlinear7
+where // comment11
+    // interlinear8
+F: G, // comment12
+H: I; // comment13
+
+type Foo // comment14
+    // interlinear9
+= E // comment15
+    // interlinear10
+where // comment16
+    // interlinear11
+F: G,// comment17
+H: I;// comment18
diff --git a/src/tools/rustfmt/tests/source/type-alias-where-clauses.rs b/src/tools/rustfmt/tests/source/type-alias-where-clauses.rs
new file mode 100644
index 00000000000..ad998caf308
--- /dev/null
+++ b/src/tools/rustfmt/tests/source/type-alias-where-clauses.rs
@@ -0,0 +1,20 @@
+    type Foo
+    where
+    A: B,
+    C: D,
+    = E;
+
+    type Foo
+    where
+    A: B,
+    C: D,
+    = E
+    where
+    F: G,
+    H: I;
+
+    type Foo
+    = E
+    where
+    F: G,
+    H: I;
\ No newline at end of file
diff --git a/src/tools/rustfmt/tests/target/arrow_in_comments/arrow_in_single_comment.rs b/src/tools/rustfmt/tests/target/arrow_in_comments/arrow_in_single_comment.rs
index deffdbeeaaf..d638a6b4ef0 100644
--- a/src/tools/rustfmt/tests/target/arrow_in_comments/arrow_in_single_comment.rs
+++ b/src/tools/rustfmt/tests/target/arrow_in_comments/arrow_in_single_comment.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 fn main() {
     match a {
         _ =>
diff --git a/src/tools/rustfmt/tests/target/arrow_in_comments/multiple_arrows.rs b/src/tools/rustfmt/tests/target/arrow_in_comments/multiple_arrows.rs
index b0443411816..f6f4a60eec3 100644
--- a/src/tools/rustfmt/tests/target/arrow_in_comments/multiple_arrows.rs
+++ b/src/tools/rustfmt/tests/target/arrow_in_comments/multiple_arrows.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 fn main() {
     match a {
         _ =>
diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/one.rs b/src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/one.rs
index 6b9489bef55..204dce6d655 100644
--- a/src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/one.rs
+++ b/src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 // rustfmt-error_on_line_overflow: false
 // rustfmt-indent_style: Block
 
diff --git a/src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/two.rs b/src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/two.rs
index 4f4292e5f48..887e8328ccc 100644
--- a/src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/two.rs
+++ b/src/tools/rustfmt/tests/target/configs/indent_style/block_trailing_comma_call/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // rustfmt-error_on_line_overflow: false
 // rustfmt-indent_style: Block
 
diff --git a/src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2015.rs b/src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2015.rs
new file mode 100644
index 00000000000..05d4b8b6d33
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2015.rs
@@ -0,0 +1,135 @@
+// rustfmt-style_edition: 2015
+
+fn combine_blocklike() {
+    do_thing(|param| {
+        action();
+        foo(param)
+    });
+
+    do_thing(x, |param| {
+        action();
+        foo(param)
+    });
+
+    do_thing(
+        x,
+        // I'll be discussing the `action` with your para(m)legal counsel
+        |param| {
+            action();
+            foo(param)
+        },
+    );
+
+    do_thing(Bar {
+        x: value,
+        y: value2,
+    });
+
+    do_thing(
+        x,
+        Bar {
+            x: value,
+            y: value2,
+        },
+    );
+
+    do_thing(
+        x,
+        // Let me tell you about that one time at the `Bar`
+        Bar {
+            x: value,
+            y: value2,
+        },
+    );
+
+    do_thing(&[
+        value_with_longer_name,
+        value2_with_longer_name,
+        value3_with_longer_name,
+        value4_with_longer_name,
+    ]);
+
+    do_thing(
+        x,
+        &[
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        x,
+        // Just admit it; my list is longer than can be folded on to one line
+        &[
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(vec![
+        value_with_longer_name,
+        value2_with_longer_name,
+        value3_with_longer_name,
+        value4_with_longer_name,
+    ]);
+
+    do_thing(
+        x,
+        vec![
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        x,
+        // Just admit it; my list is longer than can be folded on to one line
+        vec![
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        x,
+        (1, 2, 3, |param| {
+            action();
+            foo(param)
+        }),
+    );
+}
+
+fn combine_struct_sample() {
+    let identity = verify(
+        &ctx,
+        VerifyLogin {
+            type_: LoginType::Username,
+            username: args.username.clone(),
+            password: Some(args.password.clone()),
+            domain: None,
+        },
+    )?;
+}
+
+fn combine_macro_sample() {
+    rocket::ignite()
+        .mount(
+            "/",
+            routes![
+                http::auth::login,
+                http::auth::logout,
+                http::cors::options,
+                http::action::dance,
+                http::action::sleep,
+            ],
+        )
+        .launch();
+}
diff --git a/src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2024.rs b/src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2024.rs
new file mode 100644
index 00000000000..ecd2e8ca797
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/configs/style_edition/overflow_delim_expr_2024.rs
@@ -0,0 +1,120 @@
+// rustfmt-style_edition: 2024
+
+fn combine_blocklike() {
+    do_thing(|param| {
+        action();
+        foo(param)
+    });
+
+    do_thing(x, |param| {
+        action();
+        foo(param)
+    });
+
+    do_thing(
+        x,
+        // I'll be discussing the `action` with your para(m)legal counsel
+        |param| {
+            action();
+            foo(param)
+        },
+    );
+
+    do_thing(Bar {
+        x: value,
+        y: value2,
+    });
+
+    do_thing(x, Bar {
+        x: value,
+        y: value2,
+    });
+
+    do_thing(
+        x,
+        // Let me tell you about that one time at the `Bar`
+        Bar {
+            x: value,
+            y: value2,
+        },
+    );
+
+    do_thing(&[
+        value_with_longer_name,
+        value2_with_longer_name,
+        value3_with_longer_name,
+        value4_with_longer_name,
+    ]);
+
+    do_thing(x, &[
+        value_with_longer_name,
+        value2_with_longer_name,
+        value3_with_longer_name,
+        value4_with_longer_name,
+    ]);
+
+    do_thing(
+        x,
+        // Just admit it; my list is longer than can be folded on to one line
+        &[
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(vec![
+        value_with_longer_name,
+        value2_with_longer_name,
+        value3_with_longer_name,
+        value4_with_longer_name,
+    ]);
+
+    do_thing(x, vec![
+        value_with_longer_name,
+        value2_with_longer_name,
+        value3_with_longer_name,
+        value4_with_longer_name,
+    ]);
+
+    do_thing(
+        x,
+        // Just admit it; my list is longer than can be folded on to one line
+        vec![
+            value_with_longer_name,
+            value2_with_longer_name,
+            value3_with_longer_name,
+            value4_with_longer_name,
+        ],
+    );
+
+    do_thing(
+        x,
+        (1, 2, 3, |param| {
+            action();
+            foo(param)
+        }),
+    );
+}
+
+fn combine_struct_sample() {
+    let identity = verify(&ctx, VerifyLogin {
+        type_: LoginType::Username,
+        username: args.username.clone(),
+        password: Some(args.password.clone()),
+        domain: None,
+    })?;
+}
+
+fn combine_macro_sample() {
+    rocket::ignite()
+        .mount("/", routes![
+            http::auth::login,
+            http::auth::logout,
+            http::cors::options,
+            http::action::dance,
+            http::action::sleep,
+        ])
+        .launch();
+}
diff --git a/src/tools/rustfmt/tests/target/configs/version/mapped.rs b/src/tools/rustfmt/tests/target/configs/version/mapped.rs
new file mode 100644
index 00000000000..296dc559a93
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/configs/version/mapped.rs
@@ -0,0 +1,9 @@
+// rustfmt-version: Two
+fn main() {
+    let [
+        aaaaaaaaaaaaaaaaaaaaaaaaaa,
+        bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb,
+        cccccccccccccccccccccccccc,
+        ddddddddddddddddddddddddd,
+    ] = panic!();
+}
diff --git a/src/tools/rustfmt/tests/target/fn-single-line/version_one.rs b/src/tools/rustfmt/tests/target/fn-single-line/version_one.rs
index 013b2cd7216..5b704474d6d 100644
--- a/src/tools/rustfmt/tests/target/fn-single-line/version_one.rs
+++ b/src/tools/rustfmt/tests/target/fn-single-line/version_one.rs
@@ -1,5 +1,5 @@
 // rustfmt-fn_single_line: true
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 // Test single-line functions.
 
 fn foo_expr() { 1 }
diff --git a/src/tools/rustfmt/tests/target/fn-single-line/version_two.rs b/src/tools/rustfmt/tests/target/fn-single-line/version_two.rs
index b8053d4c2f5..aedd1d481b6 100644
--- a/src/tools/rustfmt/tests/target/fn-single-line/version_two.rs
+++ b/src/tools/rustfmt/tests/target/fn-single-line/version_two.rs
@@ -1,5 +1,5 @@
 // rustfmt-fn_single_line: true
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // Test single-line functions.
 
 fn foo_expr() { 1 }
diff --git a/src/tools/rustfmt/tests/target/issue-2179/one.rs b/src/tools/rustfmt/tests/target/issue-2179/one.rs
index 3f98acc8dcd..6593624e589 100644
--- a/src/tools/rustfmt/tests/target/issue-2179/one.rs
+++ b/src/tools/rustfmt/tests/target/issue-2179/one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 // rustfmt-error_on_line_overflow: false
 
 fn issue_2179() {
diff --git a/src/tools/rustfmt/tests/target/issue-2179/two.rs b/src/tools/rustfmt/tests/target/issue-2179/two.rs
index 96531509ea2..088518705fe 100644
--- a/src/tools/rustfmt/tests/target/issue-2179/two.rs
+++ b/src/tools/rustfmt/tests/target/issue-2179/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // rustfmt-error_on_line_overflow: false
 
 fn issue_2179() {
diff --git a/src/tools/rustfmt/tests/target/issue-3132.rs b/src/tools/rustfmt/tests/target/issue-3132.rs
index 4dffe0ab836..4d61baa7507 100644
--- a/src/tools/rustfmt/tests/target/issue-3132.rs
+++ b/src/tools/rustfmt/tests/target/issue-3132.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn test() {
     /*
diff --git a/src/tools/rustfmt/tests/target/issue-3213/version_one.rs b/src/tools/rustfmt/tests/target/issue-3213/version_one.rs
index 307903b128b..a20915df761 100644
--- a/src/tools/rustfmt/tests/target/issue-3213/version_one.rs
+++ b/src/tools/rustfmt/tests/target/issue-3213/version_one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 fn foo() {
     match 0 {
diff --git a/src/tools/rustfmt/tests/target/issue-3213/version_two.rs b/src/tools/rustfmt/tests/target/issue-3213/version_two.rs
index de93d04ba95..fb609f6a67a 100644
--- a/src/tools/rustfmt/tests/target/issue-3213/version_two.rs
+++ b/src/tools/rustfmt/tests/target/issue-3213/version_two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn foo() {
     match 0 {
diff --git a/src/tools/rustfmt/tests/target/issue-3227/one.rs b/src/tools/rustfmt/tests/target/issue-3227/one.rs
index fcc8331000d..2922bfdfef7 100644
--- a/src/tools/rustfmt/tests/target/issue-3227/one.rs
+++ b/src/tools/rustfmt/tests/target/issue-3227/one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 fn main() {
     thread::spawn(|| {
diff --git a/src/tools/rustfmt/tests/target/issue-3227/two.rs b/src/tools/rustfmt/tests/target/issue-3227/two.rs
index 374ab54305d..ae7eee47194 100644
--- a/src/tools/rustfmt/tests/target/issue-3227/two.rs
+++ b/src/tools/rustfmt/tests/target/issue-3227/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn main() {
     thread::spawn(|| {
diff --git a/src/tools/rustfmt/tests/target/issue-3270/one.rs b/src/tools/rustfmt/tests/target/issue-3270/one.rs
index 78de9473243..a31a0ff5742 100644
--- a/src/tools/rustfmt/tests/target/issue-3270/one.rs
+++ b/src/tools/rustfmt/tests/target/issue-3270/one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 pub fn main() {
     /*   let s = String::from(
diff --git a/src/tools/rustfmt/tests/target/issue-3270/two.rs b/src/tools/rustfmt/tests/target/issue-3270/two.rs
index e48b5921329..8e26f8ac23d 100644
--- a/src/tools/rustfmt/tests/target/issue-3270/two.rs
+++ b/src/tools/rustfmt/tests/target/issue-3270/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 pub fn main() {
     /*   let s = String::from(
diff --git a/src/tools/rustfmt/tests/target/issue-3270/wrap.rs b/src/tools/rustfmt/tests/target/issue-3270/wrap.rs
index 7435c5f0866..967bfb5534c 100644
--- a/src/tools/rustfmt/tests/target/issue-3270/wrap.rs
+++ b/src/tools/rustfmt/tests/target/issue-3270/wrap.rs
@@ -1,5 +1,5 @@
 // rustfmt-wrap_comments: true
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 // check that a line below max_width does not get over the limit when wrapping
 // it in a block comment
diff --git a/src/tools/rustfmt/tests/target/issue-3272/v1.rs b/src/tools/rustfmt/tests/target/issue-3272/v1.rs
index aab201027d5..7cca7ea7896 100644
--- a/src/tools/rustfmt/tests/target/issue-3272/v1.rs
+++ b/src/tools/rustfmt/tests/target/issue-3272/v1.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 fn main() {
     assert!(HAYSTACK
diff --git a/src/tools/rustfmt/tests/target/issue-3272/v2.rs b/src/tools/rustfmt/tests/target/issue-3272/v2.rs
index a42a2fccd5b..ca7718c5a61 100644
--- a/src/tools/rustfmt/tests/target/issue-3272/v2.rs
+++ b/src/tools/rustfmt/tests/target/issue-3272/v2.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn main() {
     assert!(
diff --git a/src/tools/rustfmt/tests/target/issue-3278/version_one.rs b/src/tools/rustfmt/tests/target/issue-3278/version_one.rs
index 580679fbae3..718a32b4c7e 100644
--- a/src/tools/rustfmt/tests/target/issue-3278/version_one.rs
+++ b/src/tools/rustfmt/tests/target/issue-3278/version_one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 pub fn parse_conditional<'a, I: 'a>(
 ) -> impl Parser<Input = I, Output = Expr, PartialState = ()> + 'a
diff --git a/src/tools/rustfmt/tests/target/issue-3278/version_two.rs b/src/tools/rustfmt/tests/target/issue-3278/version_two.rs
index c17b1742d39..eb605e509f9 100644
--- a/src/tools/rustfmt/tests/target/issue-3278/version_two.rs
+++ b/src/tools/rustfmt/tests/target/issue-3278/version_two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 pub fn parse_conditional<'a, I: 'a>()
 -> impl Parser<Input = I, Output = Expr, PartialState = ()> + 'a
diff --git a/src/tools/rustfmt/tests/target/issue-3295/two.rs b/src/tools/rustfmt/tests/target/issue-3295/two.rs
index 3e669a0bb75..4f685172cfa 100644
--- a/src/tools/rustfmt/tests/target/issue-3295/two.rs
+++ b/src/tools/rustfmt/tests/target/issue-3295/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 pub enum TestEnum {
     a,
     b,
diff --git a/src/tools/rustfmt/tests/target/issue-3302.rs b/src/tools/rustfmt/tests/target/issue-3302.rs
index 146cb983819..504bfd987f5 100644
--- a/src/tools/rustfmt/tests/target/issue-3302.rs
+++ b/src/tools/rustfmt/tests/target/issue-3302.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 macro_rules! moo1 {
     () => {
diff --git a/src/tools/rustfmt/tests/target/issue-3614/version_one.rs b/src/tools/rustfmt/tests/target/issue-3614/version_one.rs
index 8ab28304732..4bd972aa87a 100644
--- a/src/tools/rustfmt/tests/target/issue-3614/version_one.rs
+++ b/src/tools/rustfmt/tests/target/issue-3614/version_one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 fn main() {
     let toto = || {
diff --git a/src/tools/rustfmt/tests/target/issue-3614/version_two.rs b/src/tools/rustfmt/tests/target/issue-3614/version_two.rs
index 5d6f8e7a313..7b9534caa02 100644
--- a/src/tools/rustfmt/tests/target/issue-3614/version_two.rs
+++ b/src/tools/rustfmt/tests/target/issue-3614/version_two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn main() {
     let toto = || {
diff --git a/src/tools/rustfmt/tests/target/issue-3701/one.rs b/src/tools/rustfmt/tests/target/issue-3701/one.rs
index 9d1ef9eed9a..b154724d341 100644
--- a/src/tools/rustfmt/tests/target/issue-3701/one.rs
+++ b/src/tools/rustfmt/tests/target/issue-3701/one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 fn build_sorted_static_get_entry_names(
     mut entries: Vec<(u8, &'static str)>,
diff --git a/src/tools/rustfmt/tests/target/issue-3701/two.rs b/src/tools/rustfmt/tests/target/issue-3701/two.rs
index 62ffc9d823d..995763ef291 100644
--- a/src/tools/rustfmt/tests/target/issue-3701/two.rs
+++ b/src/tools/rustfmt/tests/target/issue-3701/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn build_sorted_static_get_entry_names(
     mut entries: Vec<(u8, &'static str)>,
diff --git a/src/tools/rustfmt/tests/target/issue-3805.rs b/src/tools/rustfmt/tests/target/issue-3805.rs
index a247a43fe6d..a1eda832d76 100644
--- a/src/tools/rustfmt/tests/target/issue-3805.rs
+++ b/src/tools/rustfmt/tests/target/issue-3805.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // rustfmt-format_macro_matchers: true
 
 // From original issue example - Line length 101
diff --git a/src/tools/rustfmt/tests/target/issue-3840/version-two_hard-tabs.rs b/src/tools/rustfmt/tests/target/issue-3840/version-two_hard-tabs.rs
index 084db3d1465..78a2f921735 100644
--- a/src/tools/rustfmt/tests/target/issue-3840/version-two_hard-tabs.rs
+++ b/src/tools/rustfmt/tests/target/issue-3840/version-two_hard-tabs.rs
@@ -1,5 +1,5 @@
 // rustfmt-hard_tabs: true
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 impl<
 	Target: FromEvent<A> + FromEvent<B>,
diff --git a/src/tools/rustfmt/tests/target/issue-3840/version-two_soft-tabs.rs b/src/tools/rustfmt/tests/target/issue-3840/version-two_soft-tabs.rs
index bc59b0baa56..c76dd4dafbb 100644
--- a/src/tools/rustfmt/tests/target/issue-3840/version-two_soft-tabs.rs
+++ b/src/tools/rustfmt/tests/target/issue-3840/version-two_soft-tabs.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 impl<
     Target: FromEvent<A> + FromEvent<B>,
diff --git a/src/tools/rustfmt/tests/target/issue-3882.rs b/src/tools/rustfmt/tests/target/issue-3882.rs
index 5eb442af974..8e617635b7c 100644
--- a/src/tools/rustfmt/tests/target/issue-3882.rs
+++ b/src/tools/rustfmt/tests/target/issue-3882.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 fn bar(_t: T, // bar
 ) {
 }
diff --git a/src/tools/rustfmt/tests/target/issue-4381/style_edition_2015.rs b/src/tools/rustfmt/tests/target/issue-4381/style_edition_2015.rs
new file mode 100644
index 00000000000..1fc1613083e
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/issue-4381/style_edition_2015.rs
@@ -0,0 +1,3 @@
+// rustfmt-style_edition: 2015
+
+use std::num::{NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8};
diff --git a/src/tools/rustfmt/tests/target/issue-4381/style_edition_2024.rs b/src/tools/rustfmt/tests/target/issue-4381/style_edition_2024.rs
new file mode 100644
index 00000000000..df85636ad57
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/issue-4381/style_edition_2024.rs
@@ -0,0 +1,3 @@
+// rustfmt-style_edition: 2024
+
+use std::num::{NonZeroU8, NonZeroU16, NonZeroU32, NonZeroU64};
diff --git a/src/tools/rustfmt/tests/target/issue-4530.rs b/src/tools/rustfmt/tests/target/issue-4530.rs
index 296dc559a93..9e9fbf95c2d 100644
--- a/src/tools/rustfmt/tests/target/issue-4530.rs
+++ b/src/tools/rustfmt/tests/target/issue-4530.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 fn main() {
     let [
         aaaaaaaaaaaaaaaaaaaaaaaaaa,
diff --git a/src/tools/rustfmt/tests/target/issue-4689/one.rs b/src/tools/rustfmt/tests/target/issue-4689/one.rs
index 7735e34f3b5..fb523f38501 100644
--- a/src/tools/rustfmt/tests/target/issue-4689/one.rs
+++ b/src/tools/rustfmt/tests/target/issue-4689/one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 // Based on the issue description
 pub trait PrettyPrinter<'tcx>:
diff --git a/src/tools/rustfmt/tests/target/issue-4689/two.rs b/src/tools/rustfmt/tests/target/issue-4689/two.rs
index e3b5cd22810..30303490129 100644
--- a/src/tools/rustfmt/tests/target/issue-4689/two.rs
+++ b/src/tools/rustfmt/tests/target/issue-4689/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 // Based on the issue description
 pub trait PrettyPrinter<'tcx>:
diff --git a/src/tools/rustfmt/tests/target/issue-5586.rs b/src/tools/rustfmt/tests/target/issue-5586.rs
index 7033ae975b3..afe13d1fb1c 100644
--- a/src/tools/rustfmt/tests/target/issue-5586.rs
+++ b/src/tools/rustfmt/tests/target/issue-5586.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 fn main() {
     // sample 1
     {
diff --git a/src/tools/rustfmt/tests/target/issue-5655/one.rs b/src/tools/rustfmt/tests/target/issue-5655/one.rs
index 1758ec56f8b..62df2655c29 100644
--- a/src/tools/rustfmt/tests/target/issue-5655/one.rs
+++ b/src/tools/rustfmt/tests/target/issue-5655/one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 fn foo<T>(_: T)
 where
diff --git a/src/tools/rustfmt/tests/target/issue-5655/two.rs b/src/tools/rustfmt/tests/target/issue-5655/two.rs
index 14fbc3d1321..4a7eb4f4bc2 100644
--- a/src/tools/rustfmt/tests/target/issue-5655/two.rs
+++ b/src/tools/rustfmt/tests/target/issue-5655/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn foo<T>(_: T)
 where
diff --git a/src/tools/rustfmt/tests/target/issue-5801/comment_does_not_wrap_within_max_width.rs b/src/tools/rustfmt/tests/target/issue-5801/comment_does_not_wrap_within_max_width.rs
index 9f294751108..461b5873a68 100644
--- a/src/tools/rustfmt/tests/target/issue-5801/comment_does_not_wrap_within_max_width.rs
+++ b/src/tools/rustfmt/tests/target/issue-5801/comment_does_not_wrap_within_max_width.rs
@@ -1,7 +1,7 @@
 // rustfmt-comment_width: 120
 // rustfmt-wrap_comments: true
 // rustfmt-max_width: 120
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 /// This function is 120 columns wide and is left alone. This comment is 120 columns wide and the formatter is also fine
 fn my_super_cool_function_name(my_very_cool_argument_name: String, my_other_very_cool_argument_name: String) -> String {
diff --git a/src/tools/rustfmt/tests/target/issue-5801/comment_unexpectedly_wraps_before_max_width.rs b/src/tools/rustfmt/tests/target/issue-5801/comment_unexpectedly_wraps_before_max_width.rs
index dd839dd4548..58bb8a1c2e3 100644
--- a/src/tools/rustfmt/tests/target/issue-5801/comment_unexpectedly_wraps_before_max_width.rs
+++ b/src/tools/rustfmt/tests/target/issue-5801/comment_unexpectedly_wraps_before_max_width.rs
@@ -1,7 +1,7 @@
 // rustfmt-comment_width: 120
 // rustfmt-wrap_comments: true
 // rustfmt-max_width: 120
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 /// This function is 120 columns wide and is left alone. This comment is 120 columns wide and the formatter is also fine
 fn my_super_cool_function_name(my_very_cool_argument_name: String, my_other_very_cool_argument_name: String) -> String {
diff --git a/src/tools/rustfmt/tests/target/issue-5987/one.rs b/src/tools/rustfmt/tests/target/issue-5987/one.rs
index 3c995ed28ba..17327feead5 100644
--- a/src/tools/rustfmt/tests/target/issue-5987/one.rs
+++ b/src/tools/rustfmt/tests/target/issue-5987/one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 fn main() {
     trace!(
diff --git a/src/tools/rustfmt/tests/target/issue-5987/two.rs b/src/tools/rustfmt/tests/target/issue-5987/two.rs
index 8fd92fc179e..41ecb13e3db 100644
--- a/src/tools/rustfmt/tests/target/issue-5987/two.rs
+++ b/src/tools/rustfmt/tests/target/issue-5987/two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn main() {
     trace!(
diff --git a/src/tools/rustfmt/tests/target/issue-6109.rs b/src/tools/rustfmt/tests/target/issue-6109.rs
new file mode 100644
index 00000000000..7d2bbf75691
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/issue-6109.rs
@@ -0,0 +1,7 @@
+/// Some doc comment with code snippet:
+///```
+/// '\u{1F}
+/// ```
+pub struct Code {}
+
+fn main() {}
diff --git a/src/tools/rustfmt/tests/target/issue-6147/case_rustfmt_v1.rs b/src/tools/rustfmt/tests/target/issue-6147/case_rustfmt_v1.rs
index 75800012c63..d8e67655e4c 100644
--- a/src/tools/rustfmt/tests/target/issue-6147/case_rustfmt_v1.rs
+++ b/src/tools/rustfmt/tests/target/issue-6147/case_rustfmt_v1.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 pub fn main() {
     let a = Some(12);
diff --git a/src/tools/rustfmt/tests/target/issue-6147/case_rustfmt_v2.rs b/src/tools/rustfmt/tests/target/issue-6147/case_rustfmt_v2.rs
index 5e4220e7306..9d0b12d686b 100644
--- a/src/tools/rustfmt/tests/target/issue-6147/case_rustfmt_v2.rs
+++ b/src/tools/rustfmt/tests/target/issue-6147/case_rustfmt_v2.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 pub fn main() {
     let a = Some(12);
diff --git a/src/tools/rustfmt/tests/target/issue_5027.rs b/src/tools/rustfmt/tests/target/issue_5027.rs
index 26d771720b6..1de3e0d4f15 100644
--- a/src/tools/rustfmt/tests/target/issue_5027.rs
+++ b/src/tools/rustfmt/tests/target/issue_5027.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 pub type Iter<'a, D> = impl DoubleEndedIterator<Item = (SomethingSomethingSomethingLongType<D>)>
     + ExactSizeIterator
diff --git a/src/tools/rustfmt/tests/target/let_else_v2.rs b/src/tools/rustfmt/tests/target/let_else_v2.rs
index b25ac1609d8..6e886299cb0 100644
--- a/src/tools/rustfmt/tests/target/let_else_v2.rs
+++ b/src/tools/rustfmt/tests/target/let_else_v2.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // rustfmt-single_line_let_else_max_width: 100
 
 fn issue5901() {
diff --git a/src/tools/rustfmt/tests/target/long-fn-1/version_one.rs b/src/tools/rustfmt/tests/target/long-fn-1/version_one.rs
index 05f69953c26..60f672c1837 100644
--- a/src/tools/rustfmt/tests/target/long-fn-1/version_one.rs
+++ b/src/tools/rustfmt/tests/target/long-fn-1/version_one.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 // Tests that a function which is almost short enough, but not quite, gets
 // formatted correctly.
 
diff --git a/src/tools/rustfmt/tests/target/long-fn-1/version_two.rs b/src/tools/rustfmt/tests/target/long-fn-1/version_two.rs
index 32794bccde2..f6007398bcc 100644
--- a/src/tools/rustfmt/tests/target/long-fn-1/version_two.rs
+++ b/src/tools/rustfmt/tests/target/long-fn-1/version_two.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // Tests that a function which is almost short enough, but not quite, gets
 // formatted correctly.
 
diff --git a/src/tools/rustfmt/tests/target/one_line_if_v1.rs b/src/tools/rustfmt/tests/target/one_line_if_v1.rs
index b3c6c4cbeb2..5160ea0264c 100644
--- a/src/tools/rustfmt/tests/target/one_line_if_v1.rs
+++ b/src/tools/rustfmt/tests/target/one_line_if_v1.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 fn plain_if(x: bool) -> u8 {
     if x {
diff --git a/src/tools/rustfmt/tests/target/one_line_if_v2.rs b/src/tools/rustfmt/tests/target/one_line_if_v2.rs
index 81ca4c8b8b4..a9610ec9749 100644
--- a/src/tools/rustfmt/tests/target/one_line_if_v2.rs
+++ b/src/tools/rustfmt/tests/target/one_line_if_v2.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn plain_if(x: bool) -> u8 {
     if x { 0 } else { 1 }
diff --git a/src/tools/rustfmt/tests/target/single-line-macro/v1.rs b/src/tools/rustfmt/tests/target/single-line-macro/v1.rs
index a3aa631ed4a..fea146d8d33 100644
--- a/src/tools/rustfmt/tests/target/single-line-macro/v1.rs
+++ b/src/tools/rustfmt/tests/target/single-line-macro/v1.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: One
+// rustfmt-style_edition: 2015
 
 // #2652
 // Preserve trailing comma inside macro, even if it looks an array.
diff --git a/src/tools/rustfmt/tests/target/single-line-macro/v2.rs b/src/tools/rustfmt/tests/target/single-line-macro/v2.rs
index 9c6bcf33ad5..6fcacb70ba3 100644
--- a/src/tools/rustfmt/tests/target/single-line-macro/v2.rs
+++ b/src/tools/rustfmt/tests/target/single-line-macro/v2.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 // #2652
 // Preserve trailing comma inside macro, even if it looks an array.
diff --git a/src/tools/rustfmt/tests/target/style_edition/default.rs b/src/tools/rustfmt/tests/target/style_edition/default.rs
new file mode 100644
index 00000000000..17442df6c49
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/style_edition/default.rs
@@ -0,0 +1,10 @@
+fn build_sorted_static_get_entry_names(
+    mut entries: Vec<(u8, &'static str)>,
+) -> (impl Fn(
+    AlphabeticalTraversal,
+    Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>,
+) -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>>
+        + Send
+        + Sync
+        + 'static) {
+}
diff --git a/src/tools/rustfmt/tests/target/style_edition/follows_edition.rs b/src/tools/rustfmt/tests/target/style_edition/follows_edition.rs
new file mode 100644
index 00000000000..c36a993d842
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/style_edition/follows_edition.rs
@@ -0,0 +1,14 @@
+// rustfmt-edition: 2024
+
+fn build_sorted_static_get_entry_names(
+    mut entries: Vec<(u8, &'static str)>,
+) -> (
+    impl Fn(
+        AlphabeticalTraversal,
+        Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>,
+    ) -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>>
+    + Send
+    + Sync
+    + 'static
+) {
+}
diff --git a/src/tools/rustfmt/tests/target/style_edition/overrides_edition_when_set.rs b/src/tools/rustfmt/tests/target/style_edition/overrides_edition_when_set.rs
new file mode 100644
index 00000000000..6d0eaac8970
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/style_edition/overrides_edition_when_set.rs
@@ -0,0 +1,14 @@
+// rustfmt-edition: 2018
+// rustfmt-style_edition: 2024
+fn build_sorted_static_get_entry_names(
+    mut entries: Vec<(u8, &'static str)>,
+) -> (
+    impl Fn(
+        AlphabeticalTraversal,
+        Box<dyn dirents_sink::Sink<AlphabeticalTraversal>>,
+    ) -> BoxFuture<'static, Result<Box<dyn dirents_sink::Sealed>, Status>>
+    + Send
+    + Sync
+    + 'static
+) {
+}
diff --git a/src/tools/rustfmt/tests/target/trailing_comments/hard_tabs.rs b/src/tools/rustfmt/tests/target/trailing_comments/hard_tabs.rs
index 35e72f1affd..e7009ac00c0 100644
--- a/src/tools/rustfmt/tests/target/trailing_comments/hard_tabs.rs
+++ b/src/tools/rustfmt/tests/target/trailing_comments/hard_tabs.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // rustfmt-wrap_comments: true
 // rustfmt-hard_tabs: true
 
diff --git a/src/tools/rustfmt/tests/target/trailing_comments/soft_tabs.rs b/src/tools/rustfmt/tests/target/trailing_comments/soft_tabs.rs
index eba943042ad..34cfed1a229 100644
--- a/src/tools/rustfmt/tests/target/trailing_comments/soft_tabs.rs
+++ b/src/tools/rustfmt/tests/target/trailing_comments/soft_tabs.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 // rustfmt-wrap_comments: true
 
 pub const IFF_MULTICAST: ::c_int = 0x0000000800; // Supports multicast
diff --git a/src/tools/rustfmt/tests/target/tuple_v2.rs b/src/tools/rustfmt/tests/target/tuple_v2.rs
index ba653291c2f..fa508332be5 100644
--- a/src/tools/rustfmt/tests/target/tuple_v2.rs
+++ b/src/tools/rustfmt/tests/target/tuple_v2.rs
@@ -1,4 +1,4 @@
-// rustfmt-version: Two
+// rustfmt-style_edition: 2024
 
 fn issue_4355() {
     let _ = ((1,),).0.0;
diff --git a/src/tools/rustfmt/tests/target/type-alias-where-clauses-with-comments.rs b/src/tools/rustfmt/tests/target/type-alias-where-clauses-with-comments.rs
new file mode 100644
index 00000000000..25c38916376
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/type-alias-where-clauses-with-comments.rs
@@ -0,0 +1,39 @@
+type Foo
+// comment1
+// interlinear1
+where
+    // comment2
+    // interlinear2
+    A: B, // comment3
+    C: D, // comment4
+// interlinear3
+= E; // comment5
+
+type Foo
+// comment6
+// interlinear4
+where
+    // comment7
+    // interlinear5
+    A: B, // comment8
+    C: D, // comment9
+// interlinear6
+= E
+// comment10
+// interlinear7
+where
+    // comment11
+    // interlinear8
+    F: G, // comment12
+    H: I; // comment13
+
+type Foo // comment14
+    // interlinear9
+    = E
+// comment15
+// interlinear10
+where
+    // comment16
+    // interlinear11
+    F: G, // comment17
+    H: I; // comment18
diff --git a/src/tools/rustfmt/tests/target/type-alias-where-clauses.rs b/src/tools/rustfmt/tests/target/type-alias-where-clauses.rs
new file mode 100644
index 00000000000..96d2d63bbb8
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/type-alias-where-clauses.rs
@@ -0,0 +1,20 @@
+type Foo
+where
+    A: B,
+    C: D,
+= E;
+
+type Foo
+where
+    A: B,
+    C: D,
+= E
+where
+    F: G,
+    H: I;
+
+type Foo
+    = E
+where
+    F: G,
+    H: I;
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 8197a1bd859..b2de3457dec 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -1649,7 +1649,6 @@ ui/issues/issue-17068.rs
 ui/issues/issue-17121.rs
 ui/issues/issue-17216.rs
 ui/issues/issue-17252.rs
-ui/issues/issue-17302.rs
 ui/issues/issue-17322.rs
 ui/issues/issue-17336.rs
 ui/issues/issue-17337.rs
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 3215896091d..1e7eb82b83e 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -82,6 +82,7 @@ pub mod pal;
 pub mod run_make_tests;
 pub mod rustdoc_css_themes;
 pub mod rustdoc_gui_tests;
+pub mod rustdoc_templates;
 pub mod style;
 pub mod target_policy;
 pub mod target_specific_tests;
diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs
index e6d21bfb245..38b3f3f6417 100644
--- a/src/tools/tidy/src/main.rs
+++ b/src/tools/tidy/src/main.rs
@@ -108,6 +108,7 @@ fn main() {
         check!(mir_opt_tests, &tests_path, bless);
         check!(rustdoc_gui_tests, &tests_path);
         check!(rustdoc_css_themes, &librustdoc_path);
+        check!(rustdoc_templates, &librustdoc_path);
         check!(known_bug, &crashes_path);
         check!(unknown_revision, &tests_path);
 
diff --git a/src/tools/tidy/src/rustdoc_templates.rs b/src/tools/tidy/src/rustdoc_templates.rs
new file mode 100644
index 00000000000..6c8530e6366
--- /dev/null
+++ b/src/tools/tidy/src/rustdoc_templates.rs
@@ -0,0 +1,58 @@
+//! Tidy check to ensure that rustdoc templates didn't forget a `{# #}` to strip extra whitespace
+//! characters.
+
+use std::ffi::OsStr;
+use std::path::Path;
+
+use ignore::DirEntry;
+
+use crate::walk::walk;
+
+// Array containing `("beginning of tag", "end of tag")`.
+const TAGS: &[(&str, &str)] = &[("{#", "#}"), ("{%", "%}"), ("{{", "}}")];
+
+pub fn check(librustdoc_path: &Path, bad: &mut bool) {
+    walk(
+        &librustdoc_path.join("html/templates"),
+        |path, is_dir| is_dir || !path.extension().is_some_and(|ext| ext == OsStr::new("html")),
+        &mut |path: &DirEntry, file_content: &str| {
+            let mut lines = file_content.lines().enumerate().peekable();
+
+            while let Some((pos, line)) = lines.next() {
+                let line = line.trim();
+                if TAGS.iter().any(|(_, tag)| line.ends_with(tag)) {
+                    continue;
+                }
+                let Some(next_line) = lines.peek().map(|(_, next_line)| next_line.trim()) else {
+                    continue;
+                };
+                if TAGS.iter().any(|(tag, _)| next_line.starts_with(tag)) {
+                    continue;
+                }
+                // Maybe this is a multi-line tag, let's filter it out then.
+                match TAGS.iter().find_map(|(tag, end_tag)| {
+                    if line.rfind(tag).is_some() { Some(end_tag) } else { None }
+                }) {
+                    None => {
+                        // No it's not, let's error.
+                        tidy_error!(
+                            bad,
+                            "`{}` at line {}: missing `{{# #}}` at the end of the line",
+                            path.path().display(),
+                            pos + 1,
+                        );
+                    }
+                    Some(end_tag) => {
+                        // We skip the tag.
+                        while let Some((_, next_line)) = lines.peek() {
+                            if next_line.contains(end_tag) {
+                                break;
+                            }
+                            lines.next();
+                        }
+                    }
+                }
+            }
+        },
+    );
+}
diff --git a/tests/assembly/simd-bitmask.rs b/tests/assembly/simd-bitmask.rs
index cd22ca06706..9a355cc162f 100644
--- a/tests/assembly/simd-bitmask.rs
+++ b/tests/assembly/simd-bitmask.rs
@@ -9,7 +9,6 @@
 //@ [x86-avx512] needs-llvm-components: x86
 //@ [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu
 //@ [aarch64] needs-llvm-components: aarch64
-//@ [aarch64] min-llvm-version: 18.0
 //@ assembly-output: emit-asm
 //@ compile-flags: --crate-type=lib -O -C panic=abort
 
diff --git a/tests/assembly/simd-intrinsic-gather.rs b/tests/assembly/simd-intrinsic-gather.rs
index 83015f05ab3..2cbb6cfbb50 100644
--- a/tests/assembly/simd-intrinsic-gather.rs
+++ b/tests/assembly/simd-intrinsic-gather.rs
@@ -2,7 +2,6 @@
 //@ [x86-avx512] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel
 //@ [x86-avx512] compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512dq
 //@ [x86-avx512] needs-llvm-components: x86
-//@ [x86-avx512] min-llvm-version: 18.0
 //@ assembly-output: emit-asm
 //@ compile-flags: --crate-type=lib -O -C panic=abort
 
diff --git a/tests/assembly/simd-intrinsic-mask-reduce.rs b/tests/assembly/simd-intrinsic-mask-reduce.rs
index dd4dbaeda76..61d7aa59093 100644
--- a/tests/assembly/simd-intrinsic-mask-reduce.rs
+++ b/tests/assembly/simd-intrinsic-mask-reduce.rs
@@ -6,7 +6,6 @@
 //@ [x86] needs-llvm-components: x86
 //@ [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu
 //@ [aarch64] needs-llvm-components: aarch64
-//@ [aarch64] min-llvm-version: 18.0
 //@ assembly-output: emit-asm
 //@ compile-flags: --crate-type=lib -O -C panic=abort
 
diff --git a/tests/assembly/simd-intrinsic-scatter.rs b/tests/assembly/simd-intrinsic-scatter.rs
index 55095e4cb68..679972d9b86 100644
--- a/tests/assembly/simd-intrinsic-scatter.rs
+++ b/tests/assembly/simd-intrinsic-scatter.rs
@@ -2,7 +2,6 @@
 //@ [x86-avx512] compile-flags: --target=x86_64-unknown-linux-gnu -C llvm-args=-x86-asm-syntax=intel
 //@ [x86-avx512] compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bw,+avx512dq
 //@ [x86-avx512] needs-llvm-components: x86
-//@ [x86-avx512] min-llvm-version: 18.0
 //@ assembly-output: emit-asm
 //@ compile-flags: --crate-type=lib -O -C panic=abort
 
diff --git a/tests/assembly/simd-intrinsic-select.rs b/tests/assembly/simd-intrinsic-select.rs
index 4dfc2f9ed1f..57fd36fd9e3 100644
--- a/tests/assembly/simd-intrinsic-select.rs
+++ b/tests/assembly/simd-intrinsic-select.rs
@@ -7,7 +7,6 @@
 //@ [x86-avx512] needs-llvm-components: x86
 //@ [aarch64] compile-flags: --target=aarch64-unknown-linux-gnu
 //@ [aarch64] needs-llvm-components: aarch64
-//@ [aarch64] min-llvm-version: 18.0
 //@ assembly-output: emit-asm
 //@ compile-flags: --crate-type=lib -O -C panic=abort
 
diff --git a/tests/assembly/stack-probes.rs b/tests/assembly/stack-probes.rs
index ddabd4b1632..e0931157ce1 100644
--- a/tests/assembly/stack-probes.rs
+++ b/tests/assembly/stack-probes.rs
@@ -6,7 +6,6 @@
 //@[i686] needs-llvm-components: x86
 //@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
 //@[aarch64] needs-llvm-components: aarch64
-//@[aarch64] min-llvm-version: 18
 
 #![feature(no_core, lang_items)]
 #![crate_type = "lib"]
diff --git a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
index 5ed0b6c50a7..57fc601a2e0 100644
--- a/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
+++ b/tests/assembly/stack-protector/stack-protector-heuristics-effect.rs
@@ -9,7 +9,6 @@
 //@ [basic] compile-flags: -Z stack-protector=basic
 //@ [none] compile-flags: -Z stack-protector=none
 //@ compile-flags: -C opt-level=2 -Z merge-functions=disabled
-//@ min-llvm-version: 17.0.2
 
 // NOTE: the heuristics for stack smash protection inappropriately rely on types in LLVM IR,
 // despite those types having no semantic meaning. This means that the `basic` and `strong`
diff --git a/tests/assembly/targets/targets-macho.rs b/tests/assembly/targets/targets-macho.rs
index 713129b692c..8095ae9029b 100644
--- a/tests/assembly/targets/targets-macho.rs
+++ b/tests/assembly/targets/targets-macho.rs
@@ -18,6 +18,9 @@
 //@ revisions: aarch64_apple_tvos_sim
 //@ [aarch64_apple_tvos_sim] compile-flags: --target aarch64-apple-tvos-sim
 //@ [aarch64_apple_tvos_sim] needs-llvm-components: aarch64
+//@ revisions: arm64e_apple_tvos
+//@ [arm64e_apple_tvos] compile-flags: --target arm64e-apple-tvos
+//@ [arm64e_apple_tvos] needs-llvm-components: aarch64
 //@ revisions: aarch64_apple_watchos
 //@ [aarch64_apple_watchos] compile-flags: --target aarch64-apple-watchos
 //@ [aarch64_apple_watchos] needs-llvm-components: aarch64
@@ -28,11 +31,9 @@
 //@ [arm64_32_apple_watchos] compile-flags: --target arm64_32-apple-watchos
 //@ [arm64_32_apple_watchos] needs-llvm-components: aarch64
 //@ revisions: aarch64_apple_visionos
-//@ [aarch64_apple_visionos] min-llvm-version: 18
 //@ [aarch64_apple_visionos] compile-flags: --target aarch64-apple-visionos
 //@ [aarch64_apple_visionos] needs-llvm-components: aarch64
 //@ revisions: aarch64_apple_visionos_sim
-//@ [aarch64_apple_visionos_sim] min-llvm-version: 18
 //@ [aarch64_apple_visionos_sim] compile-flags: --target aarch64-apple-visionos-sim
 //@ [aarch64_apple_visionos_sim] needs-llvm-components: aarch64
 //@ revisions: arm64e_apple_darwin
diff --git a/tests/codegen/align-byval.rs b/tests/codegen/align-byval.rs
index 223696229cb..b057147ab13 100644
--- a/tests/codegen/align-byval.rs
+++ b/tests/codegen/align-byval.rs
@@ -1,10 +1,8 @@
 // ignore-tidy-linelength
-//@ revisions:m68k wasm x86_64-linux x86_64-windows i686-linux i686-windows
+//@ revisions:m68k x86_64-linux x86_64-windows i686-linux i686-windows
 
 //@[m68k] compile-flags: --target m68k-unknown-linux-gnu
 //@[m68k] needs-llvm-components: m68k
-//@[wasm] compile-flags: --target wasm32-unknown-emscripten
-//@[wasm] needs-llvm-components: webassembly
 //@[x86_64-linux] compile-flags: --target x86_64-unknown-linux-gnu
 //@[x86_64-linux] needs-llvm-components: x86
 //@[x86_64-windows] compile-flags: --target x86_64-pc-windows-msvc
@@ -15,7 +13,7 @@
 //@[i686-windows] needs-llvm-components: x86
 
 // Tests that `byval` alignment is properly specified (#80127).
-// The only targets that use `byval` are m68k, wasm, x86-64, and x86.
+// The only targets that use `byval` are m68k, x86-64, and x86.
 // Note also that Windows mandates a by-ref ABI here, so it does not use byval.
 
 #![feature(no_core, lang_items)]
@@ -112,9 +110,6 @@ pub unsafe fn call_na1(x: NaturalAlign1) {
     // m68k: [[ALLOCA:%[a-z0-9+]]] = alloca [2 x i8], align 1
     // m68k: call void @natural_align_1({{.*}}byval([2 x i8]) align 1{{.*}} [[ALLOCA]])
 
-    // wasm: [[ALLOCA:%[a-z0-9+]]] = alloca [2 x i8], align 1
-    // wasm: call void @natural_align_1({{.*}}byval([2 x i8]) align 1{{.*}} [[ALLOCA]])
-
     // x86_64-linux: call void @natural_align_1(i16
 
     // x86_64-windows: call void @natural_align_1(i16
@@ -133,7 +128,6 @@ pub unsafe fn call_na2(x: NaturalAlign2) {
     // CHECK: start:
 
     // m68k-NEXT: call void @natural_align_2
-    // wasm-NEXT: call void @natural_align_2
     // x86_64-linux-NEXT: call void @natural_align_2
     // x86_64-windows-NEXT: call void @natural_align_2
 
@@ -204,8 +198,6 @@ pub unsafe fn call_fa16(x: ForceAlign16) {
 extern "C" {
     // m68k: declare void @natural_align_1({{.*}}byval([2 x i8]) align 1{{.*}})
 
-    // wasm: declare void @natural_align_1({{.*}}byval([2 x i8]) align 1{{.*}})
-
     // x86_64-linux: declare void @natural_align_1(i16)
 
     // x86_64-windows: declare void @natural_align_1(i16)
@@ -217,8 +209,6 @@ extern "C" {
 
     // m68k: declare void @natural_align_2({{.*}}byval([34 x i8]) align 2{{.*}})
 
-    // wasm: declare void @natural_align_2({{.*}}byval([34 x i8]) align 2{{.*}})
-
     // x86_64-linux: declare void @natural_align_2({{.*}}byval([34 x i8]) align 2{{.*}})
 
     // x86_64-windows: declare void @natural_align_2(
@@ -232,8 +222,6 @@ extern "C" {
 
     // m68k: declare void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
 
-    // wasm: declare void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
-
     // x86_64-linux: declare void @force_align_4({{.*}}byval([20 x i8]) align 4{{.*}})
 
     // x86_64-windows: declare void @force_align_4(
@@ -247,8 +235,6 @@ extern "C" {
 
     // m68k: declare void @natural_align_8({{.*}}byval([24 x i8]) align 4{{.*}})
 
-    // wasm: declare void @natural_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
-
     // x86_64-linux: declare void @natural_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
 
     // x86_64-windows: declare void @natural_align_8(
@@ -262,8 +248,6 @@ extern "C" {
 
     // m68k: declare void @force_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // wasm: declare void @force_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
-
     // x86_64-linux: declare void @force_align_8({{.*}}byval([24 x i8]) align 8{{.*}})
 
     // x86_64-windows: declare void @force_align_8(
@@ -279,8 +263,6 @@ extern "C" {
 
     // m68k: declare void @lower_fa8({{.*}}byval([24 x i8]) align 4{{.*}})
 
-    // wasm: declare void @lower_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
-
     // x86_64-linux: declare void @lower_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
 
     // x86_64-windows: declare void @lower_fa8(
@@ -294,8 +276,6 @@ extern "C" {
 
     // m68k: declare void @wrapped_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // wasm: declare void @wrapped_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
-
     // x86_64-linux: declare void @wrapped_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
 
     // x86_64-windows: declare void @wrapped_fa8(
@@ -311,8 +291,6 @@ extern "C" {
 
     // m68k: declare void @transparent_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
 
-    // wasm: declare void @transparent_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
-
     // x86_64-linux: declare void @transparent_fa8({{.*}}byval([24 x i8]) align 8{{.*}})
 
     // x86_64-windows: declare void @transparent_fa8(
@@ -328,8 +306,6 @@ extern "C" {
 
     // m68k: declare void @force_align_16({{.*}}byval([80 x i8]) align 16{{.*}})
 
-    // wasm: declare void @force_align_16({{.*}}byval([80 x i8]) align 16{{.*}})
-
     // x86_64-linux: declare void @force_align_16({{.*}}byval([80 x i8]) align 16{{.*}})
 
     // x86_64-windows: declare void @force_align_16(
diff --git a/tests/codegen/enum/enum-early-otherwise-branch.rs b/tests/codegen/enum/enum-early-otherwise-branch.rs
index 6c7548912da..07c8aed2624 100644
--- a/tests/codegen/enum/enum-early-otherwise-branch.rs
+++ b/tests/codegen/enum/enum-early-otherwise-branch.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -O
-//@ min-llvm-version: 18
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/issue-97217.rs b/tests/codegen/issue-97217.rs
index ecf1fa1ddb3..ef9acc5fc93 100644
--- a/tests/codegen/issue-97217.rs
+++ b/tests/codegen/issue-97217.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -C opt-level=3
-//@ min-llvm-version: 17.0.2
 #![crate_type = "lib"]
 
 // Regression test for issue 97217 (the following should result in no allocations)
diff --git a/tests/codegen/issues/issue-110797-enum-jump-same.rs b/tests/codegen/issues/issue-110797-enum-jump-same.rs
index f34b191ac70..f114e0e260e 100644
--- a/tests/codegen/issues/issue-110797-enum-jump-same.rs
+++ b/tests/codegen/issues/issue-110797-enum-jump-same.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -O
-//@ min-llvm-version: 18
 
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/issues/issue-118392.rs b/tests/codegen/issues/issue-118392.rs
index 2cbb1f8b204..ce2332b4c3c 100644
--- a/tests/codegen/issues/issue-118392.rs
+++ b/tests/codegen/issues/issue-118392.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -O
-//@ min-llvm-version: 18
 #![crate_type = "lib"]
 
 // CHECK-LABEL: @div2
diff --git a/tests/codegen/issues/issue-44056-macos-tls-align.rs b/tests/codegen/issues/issue-44056-macos-tls-align.rs
deleted file mode 100644
index 972b8490d18..00000000000
--- a/tests/codegen/issues/issue-44056-macos-tls-align.rs
+++ /dev/null
@@ -1,27 +0,0 @@
-//
-//@ only-apple
-//@ compile-flags: -O
-
-#![crate_type = "rlib"]
-#![feature(thread_local)]
-
-// local_unnamed_addr does not appear when std is built with debug assertions.
-// CHECK: @STATIC_VAR_1 = thread_local {{(local_unnamed_addr )?}}global <{ [32 x i8] }> zeroinitializer, section "__DATA,__thread_bss", align 4
-#[no_mangle]
-#[thread_local]
-static mut STATIC_VAR_1: [u32; 8] = [0; 8];
-
-// CHECK: @STATIC_VAR_2 = thread_local {{(local_unnamed_addr )?}}global <{ [32 x i8] }> <{{[^>]*}}>, section "__DATA,__thread_data", align 4
-#[no_mangle]
-#[thread_local]
-static mut STATIC_VAR_2: [u32; 8] = [4; 8];
-
-#[no_mangle]
-pub unsafe fn f(x: &mut [u32; 8]) {
-    std::mem::swap(x, &mut STATIC_VAR_1)
-}
-
-#[no_mangle]
-pub unsafe fn g(x: &mut [u32; 8]) {
-    std::mem::swap(x, &mut STATIC_VAR_2)
-}
diff --git a/tests/codegen/maybeuninit-rvo.rs b/tests/codegen/maybeuninit-rvo.rs
index cc5da39a9ca..db2e33c34bd 100644
--- a/tests/codegen/maybeuninit-rvo.rs
+++ b/tests/codegen/maybeuninit-rvo.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: -O
 //@ needs-unwind
-//@ min-llvm-version: 18
 #![feature(c_unwind)]
 #![crate_type = "lib"]
 
diff --git a/tests/codegen/option-niche-eq.rs b/tests/codegen/option-niche-eq.rs
index 4d3a7ce3764..caef0598b4b 100644
--- a/tests/codegen/option-niche-eq.rs
+++ b/tests/codegen/option-niche-eq.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -O -Zmerge-functions=disabled
-//@ min-llvm-version: 18
 #![crate_type = "lib"]
 
 extern crate core;
diff --git a/tests/codegen/repr/transparent-struct-ptr.rs b/tests/codegen/repr/transparent-byval-struct-ptr.rs
index 9cffd6c7f73..92ef937d734 100644
--- a/tests/codegen/repr/transparent-struct-ptr.rs
+++ b/tests/codegen/repr/transparent-byval-struct-ptr.rs
@@ -1,4 +1,4 @@
-//@ revisions: i686-linux i686-freebsd x64-linux x64-apple wasm32
+//@ revisions: i686-linux i686-freebsd x64-linux x64-apple
 //@ compile-flags: -O -C no-prepopulate-passes
 
 //@[i686-linux] compile-flags: --target i686-unknown-linux-gnu
@@ -9,13 +9,12 @@
 //@[x64-linux] needs-llvm-components: x86
 //@[x64-apple] compile-flags: --target x86_64-apple-darwin
 //@[x64-apple] needs-llvm-components: x86
-//@[wasm32] compile-flags: --target wasm32-wasi
-//@[wasm32] needs-llvm-components: webassembly
 
 // See ./transparent.rs
 // Some platforms pass large aggregates using immediate arrays in LLVMIR
-// Other platforms pass large aggregates using struct pointer in LLVMIR
-// This covers the "struct pointer" case.
+// Other platforms pass large aggregates using by-value struct pointer in LLVMIR
+// Yet more platforms pass large aggregates using opaque pointer in LLVMIR
+// This covers the "by-value struct pointer" case.
 
 #![feature(no_core, lang_items, transparent_unions)]
 #![crate_type = "lib"]
diff --git a/tests/codegen/repr/transparent-imm-array.rs b/tests/codegen/repr/transparent-imm-array.rs
index 1acd4742d35..99828e4e80a 100644
--- a/tests/codegen/repr/transparent-imm-array.rs
+++ b/tests/codegen/repr/transparent-imm-array.rs
@@ -18,7 +18,8 @@
 
 // See ./transparent.rs
 // Some platforms pass large aggregates using immediate arrays in LLVMIR
-// Other platforms pass large aggregates using struct pointer in LLVMIR
+// Other platforms pass large aggregates using by-value struct pointer in LLVMIR
+// Yet more platforms pass large aggregates using opaque pointer in LLVMIR
 // This covers the "immediate array" case.
 
 #![feature(no_core, lang_items, transparent_unions)]
diff --git a/tests/codegen/repr/transparent-opaque-ptr.rs b/tests/codegen/repr/transparent-opaque-ptr.rs
new file mode 100644
index 00000000000..4e7b38bca39
--- /dev/null
+++ b/tests/codegen/repr/transparent-opaque-ptr.rs
@@ -0,0 +1,113 @@
+//@ revisions: aarch64-linux aarch64-darwin wasm32-wasi
+//@ compile-flags: -O -C no-prepopulate-passes
+
+//@[aarch64-linux] compile-flags: --target aarch64-unknown-linux-gnu
+//@[aarch64-linux] needs-llvm-components: aarch64
+//@[aarch64-darwin] compile-flags: --target aarch64-apple-darwin
+//@[aarch64-darwin] needs-llvm-components: aarch64
+//@[wasm32-wasi] compile-flags: --target wasm32-wasi
+//@[wasm32-wasi] needs-llvm-components: webassembly
+
+// See ./transparent.rs
+// Some platforms pass large aggregates using immediate arrays in LLVMIR
+// Other platforms pass large aggregates using by-value struct pointer in LLVMIR
+// Yet more platforms pass large aggregates using opaque pointer in LLVMIR
+// This covers the "opaque pointer" case.
+
+#![feature(no_core, lang_items, transparent_unions)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+#[lang = "freeze"]
+trait Freeze {}
+#[lang = "copy"]
+trait Copy {}
+
+impl Copy for [u32; 16] {}
+impl Copy for BigS {}
+impl Copy for BigU {}
+
+#[repr(C)]
+pub struct BigS([u32; 16]);
+
+#[repr(transparent)]
+pub struct TsBigS(BigS);
+
+#[repr(transparent)]
+pub union TuBigS {
+    field: BigS,
+}
+
+#[repr(transparent)]
+pub enum TeBigS {
+    Variant(BigS),
+}
+
+// CHECK: define{{.*}}void @test_BigS(ptr [[BIGS_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGS_RET_ATTRS2:.*]], ptr [[BIGS_ARG_ATTRS1:.*]])
+#[no_mangle]
+pub extern "C" fn test_BigS(_: BigS) -> BigS {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TsBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]])
+#[no_mangle]
+pub extern "C" fn test_TsBigS(_: TsBigS) -> TsBigS {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TuBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]])
+#[no_mangle]
+pub extern "C" fn test_TuBigS(_: TuBigS) -> TuBigS {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TeBigS(ptr [[BIGS_RET_ATTRS1]] sret([64 x i8]) [[BIGS_RET_ATTRS2]], ptr [[BIGS_ARG_ATTRS1]])
+#[no_mangle]
+pub extern "C" fn test_TeBigS(_: TeBigS) -> TeBigS {
+    loop {}
+}
+
+#[repr(C)]
+pub union BigU {
+    foo: [u32; 16],
+}
+
+#[repr(transparent)]
+pub struct TsBigU(BigU);
+
+#[repr(transparent)]
+pub union TuBigU {
+    field: BigU,
+}
+
+#[repr(transparent)]
+pub enum TeBigU {
+    Variant(BigU),
+}
+
+// CHECK: define{{.*}}void @test_BigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1:.*]])
+#[no_mangle]
+pub extern "C" fn test_BigU(_: BigU) -> BigU {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TsBigU(ptr [[BIGU_RET_ATTRS1:.*]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]])
+#[no_mangle]
+pub extern "C" fn test_TsBigU(_: TsBigU) -> TsBigU {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TuBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]])
+#[no_mangle]
+pub extern "C" fn test_TuBigU(_: TuBigU) -> TuBigU {
+    loop {}
+}
+
+// CHECK: define{{.*}}void @test_TeBigU(ptr [[BIGU_RET_ATTRS1]] sret([64 x i8]) [[BIGU_RET_ATTRS2:.*]], ptr [[BIGU_ARG_ATTRS1]])
+#[no_mangle]
+pub extern "C" fn test_TeBigU(_: TeBigU) -> TeBigU {
+    loop {}
+}
diff --git a/tests/codegen/slice-pointer-nonnull-unwrap.rs b/tests/codegen/slice-pointer-nonnull-unwrap.rs
index 2c4a959685f..202edb98c73 100644
--- a/tests/codegen/slice-pointer-nonnull-unwrap.rs
+++ b/tests/codegen/slice-pointer-nonnull-unwrap.rs
@@ -1,5 +1,4 @@
 //@ compile-flags: -O
-//@ min-llvm-version: 18
 #![crate_type = "lib"]
 
 use std::ptr::NonNull;
diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs
index 321067d1b90..65167f5c5af 100644
--- a/tests/codegen/try_question_mark_nop.rs
+++ b/tests/codegen/try_question_mark_nop.rs
@@ -1,7 +1,10 @@
 //@ compile-flags: -O -Z merge-functions=disabled --edition=2021
 //@ only-x86_64
 // FIXME: Remove the `min-llvm-version`.
-//@ min-llvm-version: 19
+//@ revisions: NINETEEN TWENTY
+//@[NINETEEN] min-llvm-version: 19
+//@[NINETEEN] ignore-llvm-version: 20-99
+//@[TWENTY] min-llvm-version: 20
 
 #![crate_type = "lib"]
 #![feature(try_blocks)]
@@ -9,14 +12,14 @@
 use std::ops::ControlFlow::{self, Break, Continue};
 use std::ptr::NonNull;
 
-// FIXME: The `trunc` and `select` instructions can be eliminated.
 // CHECK-LABEL: @option_nop_match_32
 #[no_mangle]
 pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> {
     // CHECK: start:
-    // CHECK-NEXT: [[TRUNC:%.*]] = trunc nuw i32 %0 to i1
-    // CHECK-NEXT: [[FIRST:%.*]] = select i1 [[TRUNC]], i32 %0
-    // CHECK-NEXT: insertvalue { i32, i32 } poison, i32 [[FIRST]]
+    // NINETEEN-NEXT: [[TRUNC:%.*]] = trunc nuw i32 %0 to i1
+    // NINETEEN-NEXT: [[FIRST:%.*]] = select i1 [[TRUNC]], i32 %0
+    // NINETEEN-NEXT: insertvalue { i32, i32 } poison, i32 [[FIRST]], 0
+    // TWENTY-NEXT: insertvalue { i32, i32 } poison, i32 %0, 0
     // CHECK-NEXT: insertvalue { i32, i32 }
     // CHECK-NEXT: ret { i32, i32 }
     match x {
diff --git a/tests/codegen/unwind-landingpad-cold.rs b/tests/codegen/unwind-landingpad-cold.rs
index fa200bc300c..fb095e04650 100644
--- a/tests/codegen/unwind-landingpad-cold.rs
+++ b/tests/codegen/unwind-landingpad-cold.rs
@@ -1,6 +1,5 @@
 //@ compile-flags: -Cno-prepopulate-passes
 //@ needs-unwind
-//@ min-llvm-version: 17.0.2
 #![crate_type = "lib"]
 
 // This test checks that drop calls in unwind landing pads
diff --git a/tests/codegen/unwind-landingpad-inline.rs b/tests/codegen/unwind-landingpad-inline.rs
index 77ef8d2a5fe..920774b3402 100644
--- a/tests/codegen/unwind-landingpad-inline.rs
+++ b/tests/codegen/unwind-landingpad-inline.rs
@@ -1,4 +1,3 @@
-//@ min-llvm-version: 17.0.2
 //@ compile-flags: -Copt-level=3
 #![crate_type = "lib"]
 
diff --git a/tests/coverage/mcdc/condition-limit.cov-map b/tests/coverage/mcdc/condition-limit.cov-map
index b565353572a..b4447a33691 100644
--- a/tests/coverage/mcdc/condition-limit.cov-map
+++ b/tests/coverage/mcdc/condition-limit.cov-map
@@ -1,5 +1,5 @@
 Function name: condition_limit::bad
-Raw bytes (204): 0x[01, 01, 2c, 01, 05, 05, 1d, 05, 1d, 7a, 19, 05, 1d, 7a, 19, 05, 1d, 76, 15, 7a, 19, 05, 1d, 76, 15, 7a, 19, 05, 1d, 72, 11, 76, 15, 7a, 19, 05, 1d, 72, 11, 76, 15, 7a, 19, 05, 1d, 6e, 0d, 72, 11, 76, 15, 7a, 19, 05, 1d, 6e, 0d, 72, 11, 76, 15, 7a, 19, 05, 1d, 9f, 01, 02, a3, 01, 1d, a7, 01, 19, ab, 01, 15, af, 01, 11, 09, 0d, 21, 9b, 01, 9f, 01, 02, a3, 01, 1d, a7, 01, 19, ab, 01, 15, af, 01, 11, 09, 0d, 11, 01, 15, 01, 03, 09, 20, 05, 02, 03, 08, 00, 09, 05, 00, 0d, 00, 0e, 20, 7a, 1d, 00, 0d, 00, 0e, 7a, 00, 12, 00, 13, 20, 76, 19, 00, 12, 00, 13, 76, 00, 17, 00, 18, 20, 72, 15, 00, 17, 00, 18, 72, 00, 1c, 00, 1d, 20, 6e, 11, 00, 1c, 00, 1d, 6e, 00, 21, 00, 22, 20, 6a, 0d, 00, 21, 00, 22, 6a, 00, 26, 00, 27, 20, 21, 09, 00, 26, 00, 27, 21, 00, 28, 02, 06, 9b, 01, 02, 06, 00, 07, 97, 01, 01, 01, 00, 02]
+Raw bytes (204): 0x[01, 01, 2c, 01, 05, 05, 1d, 05, 1d, 7a, 19, 05, 1d, 7a, 19, 05, 1d, 76, 15, 7a, 19, 05, 1d, 76, 15, 7a, 19, 05, 1d, 72, 11, 76, 15, 7a, 19, 05, 1d, 72, 11, 76, 15, 7a, 19, 05, 1d, 6e, 0d, 72, 11, 76, 15, 7a, 19, 05, 1d, 6e, 0d, 72, 11, 76, 15, 7a, 19, 05, 1d, 9f, 01, 02, a3, 01, 1d, a7, 01, 19, ab, 01, 15, af, 01, 11, 09, 0d, 21, 9b, 01, 9f, 01, 02, a3, 01, 1d, a7, 01, 19, ab, 01, 15, af, 01, 11, 09, 0d, 11, 01, 14, 01, 03, 09, 20, 05, 02, 03, 08, 00, 09, 05, 00, 0d, 00, 0e, 20, 7a, 1d, 00, 0d, 00, 0e, 7a, 00, 12, 00, 13, 20, 76, 19, 00, 12, 00, 13, 76, 00, 17, 00, 18, 20, 72, 15, 00, 17, 00, 18, 72, 00, 1c, 00, 1d, 20, 6e, 11, 00, 1c, 00, 1d, 6e, 00, 21, 00, 22, 20, 6a, 0d, 00, 21, 00, 22, 6a, 00, 26, 00, 27, 20, 21, 09, 00, 26, 00, 27, 21, 00, 28, 02, 06, 9b, 01, 02, 06, 00, 07, 97, 01, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 44
@@ -48,7 +48,7 @@ Number of expressions: 44
 - expression 42 operands: lhs = Expression(43, Add), rhs = Counter(4)
 - expression 43 operands: lhs = Counter(2), rhs = Counter(3)
 Number of file 0 mappings: 17
-- Code(Counter(0)) at (prev + 21, 1) to (start + 3, 9)
+- Code(Counter(0)) at (prev + 20, 1) to (start + 3, 9)
 - Branch { true: Counter(1), false: Expression(0, Sub) } at (prev + 3, 8) to (start + 0, 9)
     true  = c1
     false = (c0 - c1)
@@ -88,7 +88,7 @@ Number of file 0 mappings: 17
     = (c8 + ((((((c2 + c3) + c4) + c5) + c6) + c7) + (c0 - c1)))
 
 Function name: condition_limit::good
-Raw bytes (180): 0x[01, 01, 20, 01, 05, 05, 19, 05, 19, 52, 15, 05, 19, 52, 15, 05, 19, 4e, 11, 52, 15, 05, 19, 4e, 11, 52, 15, 05, 19, 4a, 0d, 4e, 11, 52, 15, 05, 19, 4a, 0d, 4e, 11, 52, 15, 05, 19, 73, 02, 77, 19, 7b, 15, 7f, 11, 09, 0d, 1d, 6f, 73, 02, 77, 19, 7b, 15, 7f, 11, 09, 0d, 10, 01, 0d, 01, 03, 09, 28, 00, 06, 03, 08, 00, 22, 30, 05, 02, 01, 06, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 52, 19, 06, 05, 00, 00, 0d, 00, 0e, 52, 00, 12, 00, 13, 30, 4e, 15, 05, 04, 00, 00, 12, 00, 13, 4e, 00, 17, 00, 18, 30, 4a, 11, 04, 03, 00, 00, 17, 00, 18, 4a, 00, 1c, 00, 1d, 30, 46, 0d, 03, 02, 00, 00, 1c, 00, 1d, 46, 00, 21, 00, 22, 30, 1d, 09, 02, 00, 00, 00, 21, 00, 22, 1d, 00, 23, 02, 06, 6f, 02, 06, 00, 07, 6b, 01, 01, 00, 02]
+Raw bytes (180): 0x[01, 01, 20, 01, 05, 05, 19, 05, 19, 52, 15, 05, 19, 52, 15, 05, 19, 4e, 11, 52, 15, 05, 19, 4e, 11, 52, 15, 05, 19, 4a, 0d, 4e, 11, 52, 15, 05, 19, 4a, 0d, 4e, 11, 52, 15, 05, 19, 73, 02, 77, 19, 7b, 15, 7f, 11, 09, 0d, 1d, 6f, 73, 02, 77, 19, 7b, 15, 7f, 11, 09, 0d, 10, 01, 0c, 01, 03, 09, 28, 00, 06, 03, 08, 00, 22, 30, 05, 02, 01, 06, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 52, 19, 06, 05, 00, 00, 0d, 00, 0e, 52, 00, 12, 00, 13, 30, 4e, 15, 05, 04, 00, 00, 12, 00, 13, 4e, 00, 17, 00, 18, 30, 4a, 11, 04, 03, 00, 00, 17, 00, 18, 4a, 00, 1c, 00, 1d, 30, 46, 0d, 03, 02, 00, 00, 1c, 00, 1d, 46, 00, 21, 00, 22, 30, 1d, 09, 02, 00, 00, 00, 21, 00, 22, 1d, 00, 23, 02, 06, 6f, 02, 06, 00, 07, 6b, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 32
@@ -125,7 +125,7 @@ Number of expressions: 32
 - expression 30 operands: lhs = Expression(31, Add), rhs = Counter(4)
 - expression 31 operands: lhs = Counter(2), rhs = Counter(3)
 Number of file 0 mappings: 16
-- Code(Counter(0)) at (prev + 13, 1) to (start + 3, 9)
+- Code(Counter(0)) at (prev + 12, 1) to (start + 3, 9)
 - MCDCDecision { bitmap_idx: 0, conditions_num: 6 } at (prev + 3, 8) to (start + 0, 34)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 6, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
diff --git a/tests/coverage/mcdc/condition-limit.coverage b/tests/coverage/mcdc/condition-limit.coverage
index 81e832d6a49..ae8596bb961 100644
--- a/tests/coverage/mcdc/condition-limit.coverage
+++ b/tests/coverage/mcdc/condition-limit.coverage
@@ -1,6 +1,5 @@
    LL|       |#![feature(coverage_attribute)]
    LL|       |//@ edition: 2021
-   LL|       |//@ min-llvm-version: 18
    LL|       |//@ ignore-llvm-version: 19 - 99
    LL|       |//@ compile-flags: -Zcoverage-options=mcdc
    LL|       |//@ llvm-cov-flags: --show-branches=count --show-mcdc
diff --git a/tests/coverage/mcdc/condition-limit.rs b/tests/coverage/mcdc/condition-limit.rs
index 2ff46b11a16..0d8546b01cd 100644
--- a/tests/coverage/mcdc/condition-limit.rs
+++ b/tests/coverage/mcdc/condition-limit.rs
@@ -1,6 +1,5 @@
 #![feature(coverage_attribute)]
 //@ edition: 2021
-//@ min-llvm-version: 18
 //@ ignore-llvm-version: 19 - 99
 //@ compile-flags: -Zcoverage-options=mcdc
 //@ llvm-cov-flags: --show-branches=count --show-mcdc
diff --git a/tests/coverage/mcdc/if.cov-map b/tests/coverage/mcdc/if.cov-map
index ea8dedb0ac3..9a7d15f700d 100644
--- a/tests/coverage/mcdc/if.cov-map
+++ b/tests/coverage/mcdc/if.cov-map
@@ -1,5 +1,5 @@
 Function name: if::mcdc_check_a
-Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 10, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02]
+Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 0f, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
@@ -8,7 +8,7 @@ Number of expressions: 4
 - expression 2 operands: lhs = Counter(3), rhs = Expression(3, Add)
 - expression 3 operands: lhs = Counter(2), rhs = Expression(0, Sub)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 16, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 15, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -24,7 +24,7 @@ Number of file 0 mappings: 8
     = (c3 + (c2 + (c0 - c1)))
 
 Function name: if::mcdc_check_b
-Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 18, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02]
+Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 17, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
@@ -33,7 +33,7 @@ Number of expressions: 4
 - expression 2 operands: lhs = Counter(3), rhs = Expression(3, Add)
 - expression 3 operands: lhs = Counter(2), rhs = Expression(0, Sub)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 24, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 23, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -49,7 +49,7 @@ Number of file 0 mappings: 8
     = (c3 + (c2 + (c0 - c1)))
 
 Function name: if::mcdc_check_both
-Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 20, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02]
+Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 1f, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
@@ -58,7 +58,7 @@ Number of expressions: 4
 - expression 2 operands: lhs = Counter(3), rhs = Expression(3, Add)
 - expression 3 operands: lhs = Counter(2), rhs = Expression(0, Sub)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 32, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 31, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -74,7 +74,7 @@ Number of file 0 mappings: 8
     = (c3 + (c2 + (c0 - c1)))
 
 Function name: if::mcdc_check_neither
-Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 08, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02]
+Raw bytes (64): 0x[01, 01, 04, 01, 05, 09, 02, 0d, 0f, 09, 02, 08, 01, 07, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0d, 00, 0e, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 0e, 0d, 00, 0f, 02, 06, 0f, 02, 0c, 02, 06, 0b, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
@@ -83,7 +83,7 @@ Number of expressions: 4
 - expression 2 operands: lhs = Counter(3), rhs = Expression(3, Add)
 - expression 3 operands: lhs = Counter(2), rhs = Expression(0, Sub)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -99,7 +99,7 @@ Number of file 0 mappings: 8
     = (c3 + (c2 + (c0 - c1)))
 
 Function name: if::mcdc_check_not_tree_decision
-Raw bytes (87): 0x[01, 01, 08, 01, 05, 02, 09, 05, 09, 0d, 1e, 02, 09, 11, 1b, 0d, 1e, 02, 09, 0a, 01, 32, 01, 03, 0a, 28, 00, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 1e, 03, 02, 00, 00, 0e, 00, 0f, 0b, 00, 14, 00, 15, 30, 11, 0d, 02, 00, 00, 00, 14, 00, 15, 11, 00, 16, 02, 06, 1b, 02, 0c, 02, 06, 17, 03, 01, 00, 02]
+Raw bytes (87): 0x[01, 01, 08, 01, 05, 02, 09, 05, 09, 0d, 1e, 02, 09, 11, 1b, 0d, 1e, 02, 09, 0a, 01, 31, 01, 03, 0a, 28, 00, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 03, 00, 09, 00, 0a, 02, 00, 0e, 00, 0f, 30, 09, 1e, 03, 02, 00, 00, 0e, 00, 0f, 0b, 00, 14, 00, 15, 30, 11, 0d, 02, 00, 00, 00, 14, 00, 15, 11, 00, 16, 02, 06, 1b, 02, 0c, 02, 06, 17, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 8
@@ -112,7 +112,7 @@ Number of expressions: 8
 - expression 6 operands: lhs = Counter(3), rhs = Expression(7, Sub)
 - expression 7 operands: lhs = Expression(0, Sub), rhs = Counter(2)
 Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 50, 1) to (start + 3, 10)
+- Code(Counter(0)) at (prev + 49, 1) to (start + 3, 10)
 - MCDCDecision { bitmap_idx: 0, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 3 } at (prev + 0, 9) to (start + 0, 10)
     true  = c1
@@ -134,7 +134,7 @@ Number of file 0 mappings: 10
     = (c4 + (c3 + ((c0 - c1) - c2)))
 
 Function name: if::mcdc_check_tree_decision
-Raw bytes (87): 0x[01, 01, 08, 01, 05, 05, 0d, 05, 0d, 0d, 11, 09, 02, 1b, 1f, 0d, 11, 09, 02, 0a, 01, 28, 01, 03, 09, 28, 00, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 0d, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 11, 09, 03, 00, 00, 00, 13, 00, 14, 1b, 00, 16, 02, 06, 1f, 02, 0c, 02, 06, 17, 03, 01, 00, 02]
+Raw bytes (87): 0x[01, 01, 08, 01, 05, 05, 0d, 05, 0d, 0d, 11, 09, 02, 1b, 1f, 0d, 11, 09, 02, 0a, 01, 27, 01, 03, 09, 28, 00, 03, 03, 08, 00, 15, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 05, 00, 0e, 00, 0f, 30, 0d, 0a, 02, 00, 03, 00, 0e, 00, 0f, 0a, 00, 13, 00, 14, 30, 11, 09, 03, 00, 00, 00, 13, 00, 14, 1b, 00, 16, 02, 06, 1f, 02, 0c, 02, 06, 17, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 8
@@ -147,7 +147,7 @@ Number of expressions: 8
 - expression 6 operands: lhs = Counter(3), rhs = Counter(4)
 - expression 7 operands: lhs = Counter(2), rhs = Expression(0, Sub)
 Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 40, 1) to (start + 3, 9)
+- Code(Counter(0)) at (prev + 39, 1) to (start + 3, 9)
 - MCDCDecision { bitmap_idx: 0, conditions_num: 3 } at (prev + 3, 8) to (start + 0, 21)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -169,7 +169,7 @@ Number of file 0 mappings: 10
     = ((c3 + c4) + (c2 + (c0 - c1)))
 
 Function name: if::mcdc_nested_if
-Raw bytes (124): 0x[01, 01, 0d, 01, 05, 02, 09, 05, 09, 1b, 15, 05, 09, 1b, 15, 05, 09, 11, 15, 02, 09, 2b, 32, 0d, 2f, 11, 15, 02, 09, 0e, 01, 3c, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 32, 02, 00, 00, 00, 0d, 00, 0e, 1b, 01, 09, 01, 0d, 28, 01, 02, 01, 0c, 00, 12, 30, 16, 15, 01, 02, 00, 00, 0c, 00, 0d, 16, 00, 11, 00, 12, 30, 0d, 11, 02, 00, 00, 00, 11, 00, 12, 0d, 00, 13, 02, 0a, 2f, 02, 0a, 00, 0b, 32, 01, 0c, 02, 06, 27, 03, 01, 00, 02]
+Raw bytes (124): 0x[01, 01, 0d, 01, 05, 02, 09, 05, 09, 1b, 15, 05, 09, 1b, 15, 05, 09, 11, 15, 02, 09, 2b, 32, 0d, 2f, 11, 15, 02, 09, 0e, 01, 3b, 01, 01, 09, 28, 00, 02, 01, 08, 00, 0e, 30, 05, 02, 01, 00, 02, 00, 08, 00, 09, 02, 00, 0d, 00, 0e, 30, 09, 32, 02, 00, 00, 00, 0d, 00, 0e, 1b, 01, 09, 01, 0d, 28, 01, 02, 01, 0c, 00, 12, 30, 16, 15, 01, 02, 00, 00, 0c, 00, 0d, 16, 00, 11, 00, 12, 30, 0d, 11, 02, 00, 00, 00, 11, 00, 12, 0d, 00, 13, 02, 0a, 2f, 02, 0a, 00, 0b, 32, 01, 0c, 02, 06, 27, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 13
@@ -187,7 +187,7 @@ Number of expressions: 13
 - expression 11 operands: lhs = Counter(4), rhs = Counter(5)
 - expression 12 operands: lhs = Expression(0, Sub), rhs = Counter(2)
 Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 60, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 59, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 14)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 0, false_next_id: 2 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
diff --git a/tests/coverage/mcdc/if.coverage b/tests/coverage/mcdc/if.coverage
index dc93319950b..d71de28c6f6 100644
--- a/tests/coverage/mcdc/if.coverage
+++ b/tests/coverage/mcdc/if.coverage
@@ -1,6 +1,5 @@
    LL|       |#![feature(coverage_attribute)]
    LL|       |//@ edition: 2021
-   LL|       |//@ min-llvm-version: 18
    LL|       |//@ ignore-llvm-version: 19 - 99
    LL|       |//@ compile-flags: -Zcoverage-options=mcdc
    LL|       |//@ llvm-cov-flags: --show-branches=count --show-mcdc
diff --git a/tests/coverage/mcdc/if.rs b/tests/coverage/mcdc/if.rs
index 6f589659a3d..17247f5e0c1 100644
--- a/tests/coverage/mcdc/if.rs
+++ b/tests/coverage/mcdc/if.rs
@@ -1,6 +1,5 @@
 #![feature(coverage_attribute)]
 //@ edition: 2021
-//@ min-llvm-version: 18
 //@ ignore-llvm-version: 19 - 99
 //@ compile-flags: -Zcoverage-options=mcdc
 //@ llvm-cov-flags: --show-branches=count --show-mcdc
diff --git a/tests/coverage/mcdc/inlined_expressions.cov-map b/tests/coverage/mcdc/inlined_expressions.cov-map
index 8bb488c0dc0..09b7291c964 100644
--- a/tests/coverage/mcdc/inlined_expressions.cov-map
+++ b/tests/coverage/mcdc/inlined_expressions.cov-map
@@ -1,5 +1,5 @@
 Function name: inlined_expressions::inlined_instance
-Raw bytes (52): 0x[01, 01, 03, 01, 05, 0b, 02, 09, 0d, 06, 01, 09, 01, 01, 06, 28, 00, 02, 01, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 0d, 02, 00, 00, 00, 0a, 00, 0b, 07, 01, 01, 00, 02]
+Raw bytes (52): 0x[01, 01, 03, 01, 05, 0b, 02, 09, 0d, 06, 01, 08, 01, 01, 06, 28, 00, 02, 01, 05, 00, 0b, 30, 05, 02, 01, 02, 00, 00, 05, 00, 06, 05, 00, 0a, 00, 0b, 30, 09, 0d, 02, 00, 00, 00, 0a, 00, 0b, 07, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 3
@@ -7,7 +7,7 @@ Number of expressions: 3
 - expression 1 operands: lhs = Expression(2, Add), rhs = Expression(0, Sub)
 - expression 2 operands: lhs = Counter(2), rhs = Counter(3)
 Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 9, 1) to (start + 1, 6)
+- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 6)
 - MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 1, 5) to (start + 0, 11)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 5) to (start + 0, 6)
     true  = c1
diff --git a/tests/coverage/mcdc/inlined_expressions.coverage b/tests/coverage/mcdc/inlined_expressions.coverage
index 4e4800310c9..af0b78477d4 100644
--- a/tests/coverage/mcdc/inlined_expressions.coverage
+++ b/tests/coverage/mcdc/inlined_expressions.coverage
@@ -1,6 +1,5 @@
    LL|       |#![feature(coverage_attribute)]
    LL|       |//@ edition: 2021
-   LL|       |//@ min-llvm-version: 18
    LL|       |//@ ignore-llvm-version: 19 - 99
    LL|       |//@ compile-flags: -Zcoverage-options=mcdc -Copt-level=z -Cllvm-args=--inline-threshold=0
    LL|       |//@ llvm-cov-flags: --show-branches=count --show-mcdc
diff --git a/tests/coverage/mcdc/inlined_expressions.rs b/tests/coverage/mcdc/inlined_expressions.rs
index fc1e4dae37c..5c1fde6681a 100644
--- a/tests/coverage/mcdc/inlined_expressions.rs
+++ b/tests/coverage/mcdc/inlined_expressions.rs
@@ -1,6 +1,5 @@
 #![feature(coverage_attribute)]
 //@ edition: 2021
-//@ min-llvm-version: 18
 //@ ignore-llvm-version: 19 - 99
 //@ compile-flags: -Zcoverage-options=mcdc -Copt-level=z -Cllvm-args=--inline-threshold=0
 //@ llvm-cov-flags: --show-branches=count --show-mcdc
diff --git a/tests/coverage/mcdc/nested_if.cov-map b/tests/coverage/mcdc/nested_if.cov-map
index 0bd2aef814c..adeb6cbc1fb 100644
--- a/tests/coverage/mcdc/nested_if.cov-map
+++ b/tests/coverage/mcdc/nested_if.cov-map
@@ -1,5 +1,5 @@
 Function name: nested_if::doubly_nested_if_in_condition
-Raw bytes (168): 0x[01, 01, 0e, 01, 05, 05, 11, 05, 11, 26, 19, 05, 11, 19, 1d, 19, 1d, 1d, 22, 26, 19, 05, 11, 11, 15, 09, 02, 0d, 37, 09, 02, 14, 01, 10, 01, 01, 09, 28, 02, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 01, 02, 00, 10, 00, 36, 30, 11, 26, 01, 00, 02, 00, 10, 00, 11, 30, 15, 21, 02, 00, 00, 00, 15, 00, 36, 26, 00, 18, 00, 19, 28, 00, 02, 00, 18, 00, 1e, 30, 19, 22, 01, 02, 00, 00, 18, 00, 19, 19, 00, 1d, 00, 1e, 30, 1a, 1d, 02, 00, 00, 00, 1d, 00, 1e, 1a, 00, 21, 00, 25, 1f, 00, 2f, 00, 34, 2b, 00, 39, 00, 3e, 21, 00, 48, 00, 4c, 0d, 00, 4f, 02, 06, 37, 02, 0c, 02, 06, 33, 03, 01, 00, 02]
+Raw bytes (168): 0x[01, 01, 0e, 01, 05, 05, 11, 05, 11, 26, 19, 05, 11, 19, 1d, 19, 1d, 1d, 22, 26, 19, 05, 11, 11, 15, 09, 02, 0d, 37, 09, 02, 14, 01, 0f, 01, 01, 09, 28, 02, 02, 01, 08, 00, 4e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 4e, 05, 00, 10, 00, 11, 28, 01, 02, 00, 10, 00, 36, 30, 11, 26, 01, 00, 02, 00, 10, 00, 11, 30, 15, 21, 02, 00, 00, 00, 15, 00, 36, 26, 00, 18, 00, 19, 28, 00, 02, 00, 18, 00, 1e, 30, 19, 22, 01, 02, 00, 00, 18, 00, 19, 19, 00, 1d, 00, 1e, 30, 1a, 1d, 02, 00, 00, 00, 1d, 00, 1e, 1a, 00, 21, 00, 25, 1f, 00, 2f, 00, 34, 2b, 00, 39, 00, 3e, 21, 00, 48, 00, 4c, 0d, 00, 4f, 02, 06, 37, 02, 0c, 02, 06, 33, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 14
@@ -18,7 +18,7 @@ Number of expressions: 14
 - expression 12 operands: lhs = Counter(3), rhs = Expression(13, Add)
 - expression 13 operands: lhs = Counter(2), rhs = Expression(0, Sub)
 Number of file 0 mappings: 20
-- Code(Counter(0)) at (prev + 16, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 15, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 2, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 78)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -58,7 +58,7 @@ Number of file 0 mappings: 20
     = (c3 + (c2 + (c0 - c1)))
 
 Function name: nested_if::nested_if_in_condition
-Raw bytes (120): 0x[01, 01, 0b, 01, 05, 05, 11, 05, 11, 1e, 15, 05, 11, 11, 15, 1e, 15, 05, 11, 09, 02, 0d, 2b, 09, 02, 0e, 01, 08, 01, 01, 09, 28, 01, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 00, 02, 00, 10, 00, 16, 30, 11, 1e, 01, 00, 02, 00, 10, 00, 11, 1e, 00, 15, 00, 16, 30, 15, 1a, 02, 00, 00, 00, 15, 00, 16, 17, 00, 19, 00, 1d, 1a, 00, 27, 00, 2c, 0d, 00, 2f, 02, 06, 2b, 02, 0c, 02, 06, 27, 03, 01, 00, 02]
+Raw bytes (120): 0x[01, 01, 0b, 01, 05, 05, 11, 05, 11, 1e, 15, 05, 11, 11, 15, 1e, 15, 05, 11, 09, 02, 0d, 2b, 09, 02, 0e, 01, 07, 01, 01, 09, 28, 01, 02, 01, 08, 00, 2e, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 2e, 05, 00, 10, 00, 11, 28, 00, 02, 00, 10, 00, 16, 30, 11, 1e, 01, 00, 02, 00, 10, 00, 11, 1e, 00, 15, 00, 16, 30, 15, 1a, 02, 00, 00, 00, 15, 00, 16, 17, 00, 19, 00, 1d, 1a, 00, 27, 00, 2c, 0d, 00, 2f, 02, 06, 2b, 02, 0c, 02, 06, 27, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 11
@@ -74,7 +74,7 @@ Number of expressions: 11
 - expression 9 operands: lhs = Counter(3), rhs = Expression(10, Add)
 - expression 10 operands: lhs = Counter(2), rhs = Expression(0, Sub)
 Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 8, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 7, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 1, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 46)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -103,7 +103,7 @@ Number of file 0 mappings: 14
     = (c3 + (c2 + (c0 - c1)))
 
 Function name: nested_if::nested_in_then_block_in_condition
-Raw bytes (176): 0x[01, 01, 12, 01, 05, 05, 11, 05, 11, 3a, 15, 05, 11, 11, 15, 33, 19, 11, 15, 19, 1d, 19, 1d, 1d, 2e, 33, 19, 11, 15, 3a, 15, 05, 11, 09, 02, 0d, 47, 09, 02, 14, 01, 23, 01, 01, 09, 28, 02, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 00, 02, 00, 10, 00, 16, 30, 11, 3a, 01, 00, 02, 00, 10, 00, 11, 3a, 00, 15, 00, 16, 30, 15, 36, 02, 00, 00, 00, 15, 00, 16, 33, 00, 1c, 00, 1d, 28, 01, 02, 00, 1c, 00, 22, 30, 19, 2e, 01, 02, 00, 00, 1c, 00, 1d, 19, 00, 21, 00, 22, 30, 26, 1d, 02, 00, 00, 00, 21, 00, 22, 26, 00, 25, 00, 29, 2b, 00, 33, 00, 38, 36, 00, 44, 00, 49, 0d, 00, 4c, 02, 06, 47, 02, 0c, 02, 06, 43, 03, 01, 00, 02]
+Raw bytes (176): 0x[01, 01, 12, 01, 05, 05, 11, 05, 11, 3a, 15, 05, 11, 11, 15, 33, 19, 11, 15, 19, 1d, 19, 1d, 1d, 2e, 33, 19, 11, 15, 3a, 15, 05, 11, 09, 02, 0d, 47, 09, 02, 14, 01, 22, 01, 01, 09, 28, 02, 02, 01, 08, 00, 4b, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 4b, 05, 00, 10, 00, 11, 28, 00, 02, 00, 10, 00, 16, 30, 11, 3a, 01, 00, 02, 00, 10, 00, 11, 3a, 00, 15, 00, 16, 30, 15, 36, 02, 00, 00, 00, 15, 00, 16, 33, 00, 1c, 00, 1d, 28, 01, 02, 00, 1c, 00, 22, 30, 19, 2e, 01, 02, 00, 00, 1c, 00, 1d, 19, 00, 21, 00, 22, 30, 26, 1d, 02, 00, 00, 00, 21, 00, 22, 26, 00, 25, 00, 29, 2b, 00, 33, 00, 38, 36, 00, 44, 00, 49, 0d, 00, 4c, 02, 06, 47, 02, 0c, 02, 06, 43, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 18
@@ -126,7 +126,7 @@ Number of expressions: 18
 - expression 16 operands: lhs = Counter(3), rhs = Expression(17, Add)
 - expression 17 operands: lhs = Counter(2), rhs = Expression(0, Sub)
 Number of file 0 mappings: 20
-- Code(Counter(0)) at (prev + 35, 1) to (start + 1, 9)
+- Code(Counter(0)) at (prev + 34, 1) to (start + 1, 9)
 - MCDCDecision { bitmap_idx: 2, conditions_num: 2 } at (prev + 1, 8) to (start + 0, 75)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
@@ -167,7 +167,7 @@ Number of file 0 mappings: 20
     = (c3 + (c2 + (c0 - c1)))
 
 Function name: nested_if::nested_single_condition_decision
-Raw bytes (85): 0x[01, 01, 06, 01, 05, 05, 11, 05, 11, 09, 02, 0d, 17, 09, 02, 0b, 01, 18, 01, 04, 09, 28, 00, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 11, 0a, 00, 10, 00, 11, 11, 00, 14, 00, 19, 0a, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 17, 02, 0c, 02, 06, 13, 03, 01, 00, 02]
+Raw bytes (85): 0x[01, 01, 06, 01, 05, 05, 11, 05, 11, 09, 02, 0d, 17, 09, 02, 0b, 01, 17, 01, 04, 09, 28, 00, 02, 04, 08, 00, 29, 30, 05, 02, 01, 02, 00, 00, 08, 00, 09, 30, 0d, 09, 02, 00, 00, 00, 0d, 00, 29, 05, 00, 10, 00, 11, 20, 11, 0a, 00, 10, 00, 11, 11, 00, 14, 00, 19, 0a, 00, 23, 00, 27, 0d, 00, 2a, 02, 06, 17, 02, 0c, 02, 06, 13, 03, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 6
@@ -178,7 +178,7 @@ Number of expressions: 6
 - expression 4 operands: lhs = Counter(3), rhs = Expression(5, Add)
 - expression 5 operands: lhs = Counter(2), rhs = Expression(0, Sub)
 Number of file 0 mappings: 11
-- Code(Counter(0)) at (prev + 24, 1) to (start + 4, 9)
+- Code(Counter(0)) at (prev + 23, 1) to (start + 4, 9)
 - MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 4, 8) to (start + 0, 41)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 8) to (start + 0, 9)
     true  = c1
diff --git a/tests/coverage/mcdc/nested_if.coverage b/tests/coverage/mcdc/nested_if.coverage
index 916bb94745d..37aa33d5c57 100644
--- a/tests/coverage/mcdc/nested_if.coverage
+++ b/tests/coverage/mcdc/nested_if.coverage
@@ -1,6 +1,5 @@
    LL|       |#![feature(coverage_attribute)]
    LL|       |//@ edition: 2021
-   LL|       |//@ min-llvm-version: 18
    LL|       |//@ ignore-llvm-version: 19 - 99
    LL|       |//@ compile-flags: -Zcoverage-options=mcdc
    LL|       |//@ llvm-cov-flags: --show-branches=count --show-mcdc
diff --git a/tests/coverage/mcdc/nested_if.rs b/tests/coverage/mcdc/nested_if.rs
index f9ce7a0bc25..1443ccc23ab 100644
--- a/tests/coverage/mcdc/nested_if.rs
+++ b/tests/coverage/mcdc/nested_if.rs
@@ -1,6 +1,5 @@
 #![feature(coverage_attribute)]
 //@ edition: 2021
-//@ min-llvm-version: 18
 //@ ignore-llvm-version: 19 - 99
 //@ compile-flags: -Zcoverage-options=mcdc
 //@ llvm-cov-flags: --show-branches=count --show-mcdc
diff --git a/tests/coverage/mcdc/non_control_flow.cov-map b/tests/coverage/mcdc/non_control_flow.cov-map
index 0c6928b684d..f8576831e75 100644
--- a/tests/coverage/mcdc/non_control_flow.cov-map
+++ b/tests/coverage/mcdc/non_control_flow.cov-map
@@ -1,5 +1,5 @@
 Function name: non_control_flow::assign_3
-Raw bytes (89): 0x[01, 01, 09, 05, 07, 0b, 11, 09, 0d, 01, 05, 01, 05, 22, 11, 01, 05, 22, 11, 01, 05, 0a, 01, 17, 01, 00, 28, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 03, 00, 0d, 00, 18, 30, 05, 22, 01, 00, 02, 00, 0d, 00, 0e, 22, 00, 12, 00, 13, 30, 1e, 11, 02, 03, 00, 00, 12, 00, 13, 1e, 00, 17, 00, 18, 30, 09, 0d, 03, 00, 00, 00, 17, 00, 18, 03, 01, 05, 01, 02]
+Raw bytes (89): 0x[01, 01, 09, 05, 07, 0b, 11, 09, 0d, 01, 05, 01, 05, 22, 11, 01, 05, 22, 11, 01, 05, 0a, 01, 16, 01, 00, 28, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 03, 00, 0d, 00, 18, 30, 05, 22, 01, 00, 02, 00, 0d, 00, 0e, 22, 00, 12, 00, 13, 30, 1e, 11, 02, 03, 00, 00, 12, 00, 13, 1e, 00, 17, 00, 18, 30, 09, 0d, 03, 00, 00, 00, 17, 00, 18, 03, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 9
@@ -13,7 +13,7 @@ Number of expressions: 9
 - expression 7 operands: lhs = Expression(8, Sub), rhs = Counter(4)
 - expression 8 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 23, 1) to (start + 0, 40)
+- Code(Counter(0)) at (prev + 22, 1) to (start + 0, 40)
 - Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10)
     = (c1 + ((c2 + c3) + c4))
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
@@ -35,7 +35,7 @@ Number of file 0 mappings: 10
     = (c1 + ((c2 + c3) + c4))
 
 Function name: non_control_flow::assign_3_bis
-Raw bytes (85): 0x[01, 01, 07, 07, 11, 09, 0d, 01, 05, 05, 09, 16, 1a, 05, 09, 01, 05, 0a, 01, 1c, 01, 00, 2c, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 03, 00, 0d, 00, 18, 30, 05, 1a, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 16, 03, 00, 02, 00, 12, 00, 13, 13, 00, 17, 00, 18, 30, 0d, 11, 02, 00, 00, 00, 17, 00, 18, 03, 01, 05, 01, 02]
+Raw bytes (85): 0x[01, 01, 07, 07, 11, 09, 0d, 01, 05, 05, 09, 16, 1a, 05, 09, 01, 05, 0a, 01, 1b, 01, 00, 2c, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 03, 00, 0d, 00, 18, 30, 05, 1a, 01, 03, 02, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 16, 03, 00, 02, 00, 12, 00, 13, 13, 00, 17, 00, 18, 30, 0d, 11, 02, 00, 00, 00, 17, 00, 18, 03, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 7
@@ -47,7 +47,7 @@ Number of expressions: 7
 - expression 5 operands: lhs = Counter(1), rhs = Counter(2)
 - expression 6 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 10
-- Code(Counter(0)) at (prev + 28, 1) to (start + 0, 44)
+- Code(Counter(0)) at (prev + 27, 1) to (start + 0, 44)
 - Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10)
     = ((c2 + c3) + c4)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
@@ -68,7 +68,7 @@ Number of file 0 mappings: 10
     = ((c2 + c3) + c4)
 
 Function name: non_control_flow::assign_and
-Raw bytes (64): 0x[01, 01, 04, 07, 0e, 09, 0d, 01, 05, 01, 05, 08, 01, 0d, 01, 00, 21, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 02, 00, 0d, 00, 13, 30, 05, 0e, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 0d, 02, 00, 00, 00, 12, 00, 13, 03, 01, 05, 01, 02]
+Raw bytes (64): 0x[01, 01, 04, 07, 0e, 09, 0d, 01, 05, 01, 05, 08, 01, 0c, 01, 00, 21, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 02, 00, 0d, 00, 13, 30, 05, 0e, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 12, 00, 13, 30, 09, 0d, 02, 00, 00, 00, 12, 00, 13, 03, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
@@ -77,7 +77,7 @@ Number of expressions: 4
 - expression 2 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 3 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 13, 1) to (start + 0, 33)
+- Code(Counter(0)) at (prev + 12, 1) to (start + 0, 33)
 - Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10)
     = ((c2 + c3) + (c0 - c1))
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
@@ -93,7 +93,7 @@ Number of file 0 mappings: 8
     = ((c2 + c3) + (c0 - c1))
 
 Function name: non_control_flow::assign_or
-Raw bytes (64): 0x[01, 01, 04, 07, 0d, 05, 09, 01, 05, 01, 05, 08, 01, 12, 01, 00, 20, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 02, 00, 0d, 00, 13, 30, 05, 0e, 01, 00, 02, 00, 0d, 00, 0e, 0e, 00, 12, 00, 13, 30, 09, 0d, 02, 00, 00, 00, 12, 00, 13, 03, 01, 05, 01, 02]
+Raw bytes (64): 0x[01, 01, 04, 07, 0d, 05, 09, 01, 05, 01, 05, 08, 01, 11, 01, 00, 20, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 02, 00, 0d, 00, 13, 30, 05, 0e, 01, 00, 02, 00, 0d, 00, 0e, 0e, 00, 12, 00, 13, 30, 09, 0d, 02, 00, 00, 00, 12, 00, 13, 03, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 4
@@ -102,7 +102,7 @@ Number of expressions: 4
 - expression 2 operands: lhs = Counter(0), rhs = Counter(1)
 - expression 3 operands: lhs = Counter(0), rhs = Counter(1)
 Number of file 0 mappings: 8
-- Code(Counter(0)) at (prev + 18, 1) to (start + 0, 32)
+- Code(Counter(0)) at (prev + 17, 1) to (start + 0, 32)
 - Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10)
     = ((c1 + c2) + c3)
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
@@ -119,15 +119,15 @@ Number of file 0 mappings: 8
     = ((c1 + c2) + c3)
 
 Function name: non_control_flow::foo
-Raw bytes (9): 0x[01, 01, 00, 01, 01, 26, 01, 02, 02]
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 25, 01, 02, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
 Number of file 0 mappings: 1
-- Code(Counter(0)) at (prev + 38, 1) to (start + 2, 2)
+- Code(Counter(0)) at (prev + 37, 1) to (start + 2, 2)
 
 Function name: non_control_flow::func_call
-Raw bytes (52): 0x[01, 01, 03, 01, 05, 0b, 02, 09, 0d, 06, 01, 2a, 01, 01, 0a, 28, 00, 02, 01, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 0d, 02, 00, 00, 00, 0e, 00, 0f, 07, 01, 01, 00, 02]
+Raw bytes (52): 0x[01, 01, 03, 01, 05, 0b, 02, 09, 0d, 06, 01, 29, 01, 01, 0a, 28, 00, 02, 01, 09, 00, 0f, 30, 05, 02, 01, 02, 00, 00, 09, 00, 0a, 05, 00, 0e, 00, 0f, 30, 09, 0d, 02, 00, 00, 00, 0e, 00, 0f, 07, 01, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 3
@@ -135,7 +135,7 @@ Number of expressions: 3
 - expression 1 operands: lhs = Expression(2, Add), rhs = Expression(0, Sub)
 - expression 2 operands: lhs = Counter(2), rhs = Counter(3)
 Number of file 0 mappings: 6
-- Code(Counter(0)) at (prev + 42, 1) to (start + 1, 10)
+- Code(Counter(0)) at (prev + 41, 1) to (start + 1, 10)
 - MCDCDecision { bitmap_idx: 0, conditions_num: 2 } at (prev + 1, 9) to (start + 0, 15)
 - MCDCBranch { true: Counter(1), false: Expression(0, Sub), condition_id: 1, true_next_id: 2, false_next_id: 0 } at (prev + 0, 9) to (start + 0, 10)
     true  = c1
@@ -148,7 +148,7 @@ Number of file 0 mappings: 6
     = ((c2 + c3) + (c0 - c1))
 
 Function name: non_control_flow::right_comb_tree
-Raw bytes (139): 0x[01, 01, 13, 07, 1a, 0b, 19, 0f, 15, 13, 11, 09, 0d, 01, 05, 01, 05, 05, 19, 05, 19, 4a, 15, 05, 19, 4a, 15, 05, 19, 46, 11, 4a, 15, 05, 19, 46, 11, 4a, 15, 05, 19, 0e, 01, 21, 01, 00, 41, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 05, 00, 0d, 00, 2a, 30, 05, 1a, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 4a, 19, 02, 03, 00, 00, 13, 00, 14, 4a, 00, 19, 00, 1a, 30, 46, 15, 03, 04, 00, 00, 19, 00, 1a, 46, 00, 1f, 00, 20, 30, 42, 11, 04, 05, 00, 00, 1f, 00, 20, 42, 00, 24, 00, 27, 30, 09, 0d, 05, 00, 00, 00, 24, 00, 27, 03, 01, 05, 01, 02]
+Raw bytes (139): 0x[01, 01, 13, 07, 1a, 0b, 19, 0f, 15, 13, 11, 09, 0d, 01, 05, 01, 05, 05, 19, 05, 19, 4a, 15, 05, 19, 4a, 15, 05, 19, 46, 11, 4a, 15, 05, 19, 46, 11, 4a, 15, 05, 19, 0e, 01, 20, 01, 00, 41, 03, 01, 09, 00, 0a, 01, 00, 0d, 00, 0e, 28, 00, 05, 00, 0d, 00, 2a, 30, 05, 1a, 01, 02, 00, 00, 0d, 00, 0e, 05, 00, 13, 00, 14, 30, 4a, 19, 02, 03, 00, 00, 13, 00, 14, 4a, 00, 19, 00, 1a, 30, 46, 15, 03, 04, 00, 00, 19, 00, 1a, 46, 00, 1f, 00, 20, 30, 42, 11, 04, 05, 00, 00, 1f, 00, 20, 42, 00, 24, 00, 27, 30, 09, 0d, 05, 00, 00, 00, 24, 00, 27, 03, 01, 05, 01, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 19
@@ -172,7 +172,7 @@ Number of expressions: 19
 - expression 17 operands: lhs = Expression(18, Sub), rhs = Counter(5)
 - expression 18 operands: lhs = Counter(1), rhs = Counter(6)
 Number of file 0 mappings: 14
-- Code(Counter(0)) at (prev + 33, 1) to (start + 0, 65)
+- Code(Counter(0)) at (prev + 32, 1) to (start + 0, 65)
 - Code(Expression(0, Add)) at (prev + 1, 9) to (start + 0, 10)
     = (((((c2 + c3) + c4) + c5) + c6) + (c0 - c1))
 - Code(Counter(0)) at (prev + 0, 13) to (start + 0, 14)
diff --git a/tests/coverage/mcdc/non_control_flow.coverage b/tests/coverage/mcdc/non_control_flow.coverage
index c64f61a153c..74c19cf12df 100644
--- a/tests/coverage/mcdc/non_control_flow.coverage
+++ b/tests/coverage/mcdc/non_control_flow.coverage
@@ -1,6 +1,5 @@
    LL|       |#![feature(coverage_attribute)]
    LL|       |//@ edition: 2021
-   LL|       |//@ min-llvm-version: 18
    LL|       |//@ ignore-llvm-version: 19 - 99
    LL|       |//@ compile-flags: -Zcoverage-options=mcdc
    LL|       |//@ llvm-cov-flags: --show-branches=count --show-mcdc
diff --git a/tests/coverage/mcdc/non_control_flow.rs b/tests/coverage/mcdc/non_control_flow.rs
index 633d381a1aa..e0145ed8268 100644
--- a/tests/coverage/mcdc/non_control_flow.rs
+++ b/tests/coverage/mcdc/non_control_flow.rs
@@ -1,6 +1,5 @@
 #![feature(coverage_attribute)]
 //@ edition: 2021
-//@ min-llvm-version: 18
 //@ ignore-llvm-version: 19 - 99
 //@ compile-flags: -Zcoverage-options=mcdc
 //@ llvm-cov-flags: --show-branches=count --show-mcdc
diff --git a/tests/crashes/120016.rs b/tests/crashes/120016.rs
new file mode 100644
index 00000000000..09175689256
--- /dev/null
+++ b/tests/crashes/120016.rs
@@ -0,0 +1,19 @@
+//@ known-bug: #120016
+//@ compile-flags: -Zcrate-attr=feature(const_async_blocks) --edition=2021
+
+#![feature(type_alias_impl_trait, const_async_blocks)]
+
+struct Bug {
+    V1: [(); {
+        type F = impl std::future::Future<Output = impl Sized>;
+        fn concrete_use() -> F {
+            //~^ ERROR to be a future that resolves to `u8`, but it resolves to `()`
+            async {}
+        }
+        let f: F = async { 1 };
+        //~^ ERROR `async` blocks are not allowed in constants
+        1
+    }],
+}
+
+fn main() {}
diff --git a/tests/crashes/127804.rs b/tests/crashes/127804.rs
new file mode 100644
index 00000000000..e583a7c1fc6
--- /dev/null
+++ b/tests/crashes/127804.rs
@@ -0,0 +1,12 @@
+//@ known-bug: #127804
+
+struct Thing;
+
+pub trait Every {
+    type Assoc;
+}
+impl<T: ?Sized> Every for Thing {
+    type Assoc = T;
+}
+
+fn foo(_: <Thing as Every>::Assoc) {}
diff --git a/tests/crashes/128119.rs b/tests/crashes/128119.rs
new file mode 100644
index 00000000000..7677b15a2f3
--- /dev/null
+++ b/tests/crashes/128119.rs
@@ -0,0 +1,15 @@
+//@ known-bug: #128119
+
+trait Trait {
+    reuse to_reuse::foo { self }
+}
+
+struct S;
+
+mod to_reuse {
+    pub fn foo(&self) -> u32 {}
+}
+
+impl Trait  S {
+    reuse to_reuse::foo { self }
+}
diff --git a/tests/crashes/128232.rs b/tests/crashes/128232.rs
new file mode 100644
index 00000000000..67f61e1b240
--- /dev/null
+++ b/tests/crashes/128232.rs
@@ -0,0 +1,15 @@
+//@ known-bug: #128232
+
+#![feature(generic_const_exprs, unsized_const_params)]
+
+fn function() {}
+
+struct Wrapper<const F: fn()>;
+
+impl Wrapper<{ bar() }> {
+    fn call() {}
+}
+
+fn main() {
+    Wrapper::<function>::call;
+}
diff --git a/tests/crashes/130310.rs b/tests/crashes/130310.rs
deleted file mode 100644
index d59dd39983c..00000000000
--- a/tests/crashes/130310.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-//@ known-bug: rust-lang/rust#130310
-
-use std::marker::PhantomData;
-
-#[repr(C)]
-struct A<T> {
-    a: *const A<A<T>>,
-    p: PhantomData<T>,
-}
-
-extern "C" {
-    fn f(a: *const A<()>);
-}
-
-fn main() {}
diff --git a/tests/crashes/130411.rs b/tests/crashes/130411.rs
new file mode 100644
index 00000000000..b733dcb30d5
--- /dev/null
+++ b/tests/crashes/130411.rs
@@ -0,0 +1,6 @@
+//@ known-bug: #130411
+trait Project {
+    const SELF: Self;
+}
+
+fn take1(_: Project<SELF = {}>) {}
diff --git a/tests/crashes/130413.rs b/tests/crashes/130413.rs
new file mode 100644
index 00000000000..08435ac6450
--- /dev/null
+++ b/tests/crashes/130413.rs
@@ -0,0 +1,17 @@
+//@ known-bug: #130413
+
+#![feature(transmutability)]
+trait Aaa {
+    type Y;
+}
+
+trait Bbb {
+    type B: std::mem::TransmuteFrom<()>;
+}
+
+impl<T> Bbb for T
+where
+    T: Aaa,
+{
+    type B = T::Y;
+}
diff --git a/tests/crashes/130425.rs b/tests/crashes/130425.rs
new file mode 100644
index 00000000000..559b86f7bc2
--- /dev/null
+++ b/tests/crashes/130425.rs
@@ -0,0 +1,13 @@
+//@ known-bug: #130425
+//@ compile-flags: -Zmir-opt-level=5 -Zpolymorphize=on
+
+struct S<T>(T)
+where
+    [T; (
+        |_: u8| {
+            static FOO: Sync = AtomicUsize::new(0);
+            unsafe { &*(&FOO as *const _ as *const usize) }
+        },
+        1,
+    )
+        .1]: Copy;
diff --git a/tests/mir-opt/inline/cycle.main.Inline.panic-abort.diff b/tests/mir-opt/inline/cycle.main.Inline.panic-abort.diff
index fd1f698c60d..6522ed6bffd 100644
--- a/tests/mir-opt/inline/cycle.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/cycle.main.Inline.panic-abort.diff
@@ -4,35 +4,16 @@
   fn main() -> () {
       let mut _0: ();
       let _1: ();
-+     let mut _2: fn() {g};
-+     scope 1 (inlined f::<fn() {g}>) {
-+         debug g => _2;
-+         let mut _3: &fn() {g};
-+         let _4: ();
-+     }
   
       bb0: {
           StorageLive(_1);
--         _1 = f::<fn() {g}>(g) -> [return: bb1, unwind unreachable];
-+         StorageLive(_2);
-+         _2 = g;
-+         StorageLive(_4);
-+         StorageLive(_3);
-+         _3 = &_2;
-+         _4 = <fn() {g} as Fn<()>>::call(move _3, const ()) -> [return: bb2, unwind unreachable];
+          _1 = f::<fn() {g}>(g) -> [return: bb1, unwind unreachable];
       }
   
       bb1: {
-+         StorageDead(_4);
-+         StorageDead(_2);
           StorageDead(_1);
           _0 = const ();
           return;
-+     }
-+ 
-+     bb2: {
-+         StorageDead(_3);
-+         drop(_2) -> [return: bb1, unwind unreachable];
       }
   }
   
diff --git a/tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff
index e8299db47db..7a25830a4d0 100644
--- a/tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/cycle.main.Inline.panic-unwind.diff
@@ -4,43 +4,16 @@
   fn main() -> () {
       let mut _0: ();
       let _1: ();
-+     let mut _2: fn() {g};
-+     scope 1 (inlined f::<fn() {g}>) {
-+         debug g => _2;
-+         let mut _3: &fn() {g};
-+         let _4: ();
-+     }
   
       bb0: {
           StorageLive(_1);
--         _1 = f::<fn() {g}>(g) -> [return: bb1, unwind continue];
-+         StorageLive(_2);
-+         _2 = g;
-+         StorageLive(_4);
-+         StorageLive(_3);
-+         _3 = &_2;
-+         _4 = <fn() {g} as Fn<()>>::call(move _3, const ()) -> [return: bb2, unwind: bb3];
+          _1 = f::<fn() {g}>(g) -> [return: bb1, unwind continue];
       }
   
       bb1: {
-+         StorageDead(_4);
-+         StorageDead(_2);
           StorageDead(_1);
           _0 = const ();
           return;
-+     }
-+ 
-+     bb2: {
-+         StorageDead(_3);
-+         drop(_2) -> [return: bb1, unwind continue];
-+     }
-+ 
-+     bb3 (cleanup): {
-+         drop(_2) -> [return: bb4, unwind terminate(cleanup)];
-+     }
-+ 
-+     bb4 (cleanup): {
-+         resume;
       }
   }
   
diff --git a/tests/mir-opt/inline/cycle.rs b/tests/mir-opt/inline/cycle.rs
index cb50638473f..383d0796a88 100644
--- a/tests/mir-opt/inline/cycle.rs
+++ b/tests/mir-opt/inline/cycle.rs
@@ -19,9 +19,5 @@ fn g() {
 
 // EMIT_MIR cycle.main.Inline.diff
 fn main() {
-    // CHECK-LABEL: fn main(
-    // CHECK-NOT: inlined
-    // CHECK: (inlined f::<fn() {g}>)
-    // CHECK-NOT: inlined
     f(g);
 }
diff --git a/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-abort.diff
index 142b9c56598..d437dbf5763 100644
--- a/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-abort.diff
@@ -7,10 +7,6 @@
 +     scope 1 (inlined <C as Call>::call) {
 +         scope 2 (inlined <B<A> as Call>::call) {
 +             scope 3 (inlined <A as Call>::call) {
-+                 scope 4 (inlined <B<C> as Call>::call) {
-+                     scope 5 (inlined <C as Call>::call) {
-+                     }
-+                 }
 +             }
 +         }
 +     }
@@ -18,7 +14,7 @@
       bb0: {
           StorageLive(_1);
 -         _1 = <C as Call>::call() -> [return: bb1, unwind unreachable];
-+         _1 = <B<A> as Call>::call() -> [return: bb1, unwind unreachable];
++         _1 = <B<C> as Call>::call() -> [return: bb1, unwind unreachable];
       }
   
       bb1: {
diff --git a/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff
index 193ada05f02..8314526ee04 100644
--- a/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_cycle_generic.main.Inline.panic-unwind.diff
@@ -7,10 +7,6 @@
 +     scope 1 (inlined <C as Call>::call) {
 +         scope 2 (inlined <B<A> as Call>::call) {
 +             scope 3 (inlined <A as Call>::call) {
-+                 scope 4 (inlined <B<C> as Call>::call) {
-+                     scope 5 (inlined <C as Call>::call) {
-+                     }
-+                 }
 +             }
 +         }
 +     }
@@ -18,7 +14,7 @@
       bb0: {
           StorageLive(_1);
 -         _1 = <C as Call>::call() -> [return: bb1, unwind continue];
-+         _1 = <B<A> as Call>::call() -> [return: bb1, unwind continue];
++         _1 = <B<C> as Call>::call() -> [return: bb1, unwind continue];
       }
   
       bb1: {
diff --git a/tests/run-make/compiler-builtins/rmake.rs b/tests/run-make/compiler-builtins/rmake.rs
index 42ed07d9daf..3b05fe2055c 100644
--- a/tests/run-make/compiler-builtins/rmake.rs
+++ b/tests/run-make/compiler-builtins/rmake.rs
@@ -33,8 +33,8 @@ fn main() {
 
     let path = env_var("PATH");
     let rustc = env_var("RUSTC");
-    let bootstrap_cargo = env_var("BOOTSTRAP_CARGO");
-    let mut cmd = cmd(bootstrap_cargo);
+    let cargo = env_var("CARGO");
+    let mut cmd = cmd(cargo);
     cmd.args(&[
         "build",
         "--manifest-path",
diff --git a/tests/run-make/embed-source-dwarf/rmake.rs b/tests/run-make/embed-source-dwarf/rmake.rs
index 06d550121b0..c7106967a85 100644
--- a/tests/run-make/embed-source-dwarf/rmake.rs
+++ b/tests/run-make/embed-source-dwarf/rmake.rs
@@ -1,11 +1,6 @@
 //@ ignore-windows
 //@ ignore-apple
 
-// LLVM 17's embed-source implementation requires that source code is attached
-// for all files in the output DWARF debug info. This restriction was lifted in
-// LLVM 18 (87e22bdd2bd6d77d782f9d64b3e3ae5bdcd5080d).
-//@ min-llvm-version: 18
-
 // This test should be replaced with one in tests/debuginfo once we can easily
 // tell via GDB or LLDB if debuginfo contains source code. Cheap tricks in LLDB
 // like setting an invalid source map path don't appear to work, maybe this'll
diff --git a/tests/run-make/invalid-symlink-search-path/rmake.rs b/tests/run-make/invalid-symlink-search-path/rmake.rs
index ed2cd9c4bd2..7b7e7c79442 100644
--- a/tests/run-make/invalid-symlink-search-path/rmake.rs
+++ b/tests/run-make/invalid-symlink-search-path/rmake.rs
@@ -1,13 +1,14 @@
-// In this test, the symlink created is invalid (valid relative to the root, but not
-// relatively to where it is located), and used to cause an internal
-// compiler error (ICE) when passed as a library search path. This was fixed in #26044,
-// and this test checks that the invalid symlink is instead simply ignored.
+// In this test, the symlink created is invalid (valid relative to the root, but not relatively to
+// where it is located), and used to cause an internal compiler error (ICE) when passed as a library
+// search path. This was fixed in #26044, and this test checks that the invalid symlink is instead
+// simply ignored.
+//
 // See https://github.com/rust-lang/rust/issues/26006
 
 //@ needs-symlink
 //Reason: symlink requires elevated permission in Windows
 
-use run_make_support::{rfs, rustc};
+use run_make_support::{path, rfs, rustc};
 
 fn main() {
     // We create two libs: `bar` which depends on `foo`. We need to compile `foo` first.
@@ -20,9 +21,9 @@ fn main() {
         .metadata("foo")
         .output("out/foo/libfoo.rlib")
         .run();
-    rfs::create_dir("out/bar");
-    rfs::create_dir("out/bar/deps");
-    rfs::create_symlink("out/foo/libfoo.rlib", "out/bar/deps/libfoo.rlib");
+    rfs::create_dir_all("out/bar/deps");
+    rfs::symlink_file(path("out/foo/libfoo.rlib"), path("out/bar/deps/libfoo.rlib"));
+
     // Check that the invalid symlink does not cause an ICE
     rustc()
         .input("in/bar/lib.rs")
diff --git a/tests/run-make/symlinked-extern/rmake.rs b/tests/run-make/symlinked-extern/rmake.rs
index 7a4a8ce18cb..f35d5a13f5a 100644
--- a/tests/run-make/symlinked-extern/rmake.rs
+++ b/tests/run-make/symlinked-extern/rmake.rs
@@ -1,22 +1,22 @@
-// Crates that are resolved normally have their path canonicalized and all
-// symlinks resolved. This did not happen for paths specified
-// using the --extern option to rustc, which could lead to rustc thinking
-// that it encountered two different versions of a crate, when it's
-// actually the same version found through different paths.
-// See https://github.com/rust-lang/rust/pull/16505
-
-// This test checks that --extern and symlinks together
-// can result in successful compilation.
+// Crates that are resolved normally have their path canonicalized and all symlinks resolved. This
+// did not happen for paths specified using the `--extern` option to rustc, which could lead to
+// rustc thinking that it encountered two different versions of a crate, when it's actually the same
+// version found through different paths.
+//
+// This test checks that `--extern` and symlinks together can result in successful compilation.
+//
+// See <https://github.com/rust-lang/rust/pull/16505>.
 
 //@ ignore-cross-compile
 //@ needs-symlink
 
-use run_make_support::{cwd, rfs, rustc};
+use run_make_support::{cwd, path, rfs, rustc};
 
 fn main() {
     rustc().input("foo.rs").run();
     rfs::create_dir_all("other");
-    rfs::create_symlink("libfoo.rlib", "other");
+    rfs::symlink_file(path("libfoo.rlib"), path("other").join("libfoo.rlib"));
+
     rustc().input("bar.rs").library_search_path(cwd()).run();
-    rustc().input("baz.rs").extern_("foo", "other").library_search_path(cwd()).run();
+    rustc().input("baz.rs").extern_("foo", "other/libfoo.rlib").library_search_path(cwd()).run();
 }
diff --git a/tests/run-make/symlinked-libraries/rmake.rs b/tests/run-make/symlinked-libraries/rmake.rs
index e6449b61a1c..98f156fed8f 100644
--- a/tests/run-make/symlinked-libraries/rmake.rs
+++ b/tests/run-make/symlinked-libraries/rmake.rs
@@ -1,18 +1,15 @@
-// When a directory and a symlink simultaneously exist with the same name,
-// setting that name as the library search path should not cause rustc
-// to avoid looking in the symlink and cause an error. This test creates
-// a directory and a symlink named "other", and places the library in the symlink.
-// If it succeeds, the library was successfully found.
-// See https://github.com/rust-lang/rust/issues/12459
+// Avoid erroring on symlinks pointing to the same file that are present in the library search path.
+//
+// See <https://github.com/rust-lang/rust/issues/12459>.
 
 //@ ignore-cross-compile
 //@ needs-symlink
 
-use run_make_support::{dynamic_lib_name, rfs, rustc};
+use run_make_support::{cwd, dynamic_lib_name, path, rfs, rustc};
 
 fn main() {
     rustc().input("foo.rs").arg("-Cprefer-dynamic").run();
     rfs::create_dir_all("other");
-    rfs::create_symlink(dynamic_lib_name("foo"), "other");
-    rustc().input("bar.rs").library_search_path("other").run();
+    rfs::symlink_file(dynamic_lib_name("foo"), path("other").join(dynamic_lib_name("foo")));
+    rustc().input("bar.rs").library_search_path(cwd()).library_search_path("other").run();
 }
diff --git a/tests/run-make/symlinked-rlib/rmake.rs b/tests/run-make/symlinked-rlib/rmake.rs
index 10ba6ba7cbb..fee432e419e 100644
--- a/tests/run-make/symlinked-rlib/rmake.rs
+++ b/tests/run-make/symlinked-rlib/rmake.rs
@@ -12,6 +12,6 @@ use run_make_support::{cwd, rfs, rustc};
 
 fn main() {
     rustc().input("foo.rs").crate_type("rlib").output("foo.xxx").run();
-    rfs::create_symlink("foo.xxx", "libfoo.rlib");
+    rfs::symlink_file("foo.xxx", "libfoo.rlib");
     rustc().input("bar.rs").library_search_path(cwd()).run();
 }
diff --git a/tests/run-make/thumb-none-cortex-m/rmake.rs b/tests/run-make/thumb-none-cortex-m/rmake.rs
index 0ddb91d378f..9112646290f 100644
--- a/tests/run-make/thumb-none-cortex-m/rmake.rs
+++ b/tests/run-make/thumb-none-cortex-m/rmake.rs
@@ -36,10 +36,10 @@ fn main() {
 
     let path = env_var("PATH");
     let rustc = env_var("RUSTC");
-    let bootstrap_cargo = env_var("BOOTSTRAP_CARGO");
-    // FIXME: extract bootstrap cargo invocations to a proper command
+    let cargo = env_var("CARGO");
+    // FIXME: extract cargo invocations to a proper command
     // https://github.com/rust-lang/rust/issues/128734
-    let mut cmd = cmd(bootstrap_cargo);
+    let mut cmd = cmd(cargo);
     cmd.args(&[
         "build",
         "--manifest-path",
diff --git a/tests/rustdoc-gui/docblock-code-block-line-number.goml b/tests/rustdoc-gui/docblock-code-block-line-number.goml
index 03f8f80b10d..fed916ac246 100644
--- a/tests/rustdoc-gui/docblock-code-block-line-number.goml
+++ b/tests/rustdoc-gui/docblock-code-block-line-number.goml
@@ -39,7 +39,10 @@ define-function: (
             {
                 "color": |color|,
                 "margin": "0px",
-                "padding": "14px 8px",
+                "padding-top": "14px",
+                "padding-bottom": "14px",
+                "padding-left": "8px",
+                "padding-right": "2px",
                 "text-align": "right",
                 // There should not be a radius on the right of the line numbers.
                 "border-top-left-radius": "6px",
@@ -141,3 +144,61 @@ assert-css: (
     },
     ALL,
 )
+
+// Checking line numbers on scraped code examples.
+go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html"
+
+define-function: (
+    "check-padding",
+    [path, padding_bottom],
+    block {
+        assert-css: (|path| + " .src-line-numbers", {
+            "padding-top": "0px",
+            "padding-bottom": "0px",
+            "padding-left": "0px",
+            "padding-right": "0px",
+        })
+        assert-css: (|path| + " .src-line-numbers > pre", {
+            "padding-top": "14px",
+            "padding-bottom": |padding_bottom|,
+            "padding-left": "0px",
+            "padding-right": "0px",
+        })
+        assert-css: (|path| + " .src-line-numbers > pre > span", {
+            "padding-top": "0px",
+            "padding-bottom": "0px",
+            "padding-left": "8px",
+            "padding-right": "8px",
+        })
+    },
+)
+
+call-function: ("check-padding", {
+    "path": ".scraped-example .example-wrap",
+    "padding_bottom": "0px",
+})
+
+move-cursor-to: ".scraped-example .example-wrap .rust"
+wait-for: ".scraped-example .example-wrap .button-holder .expand"
+click: ".scraped-example .example-wrap .button-holder .expand"
+wait-for: ".scraped-example.expanded"
+
+call-function: ("check-padding", {
+    "path": ".scraped-example.expanded .example-wrap",
+    "padding_bottom": "14px",
+})
+
+// Now checking the line numbers in the source code page.
+click: ".src"
+assert-css: (".src-line-numbers", {
+    "padding-top": "20px",
+    "padding-bottom": "20px",
+    "padding-left": "4px",
+    "padding-right": "0px",
+})
+assert-css: (".src-line-numbers > a", {
+    "padding-top": "0px",
+    "padding-bottom": "0px",
+    "padding-left": "8px",
+    "padding-right": "8px",
+})
diff --git a/tests/rustdoc-gui/scrape-examples-layout.goml b/tests/rustdoc-gui/scrape-examples-layout.goml
index 6bea352bce4..be14e202b37 100644
--- a/tests/rustdoc-gui/scrape-examples-layout.goml
+++ b/tests/rustdoc-gui/scrape-examples-layout.goml
@@ -37,6 +37,7 @@ assert-property: (
 
 // The "title" should be located at the right bottom corner of the code example.
 store-position: (".scraped-example .example-wrap", {"x": x, "y": y})
+assert-size: (".scraped-example .example-wrap", {"height": 130})
 store-size: (".scraped-example .example-wrap", {"width": width, "height": height})
 store-size: (".scraped-example .scraped-example-title", {
     "width": title_width,
@@ -47,6 +48,13 @@ assert-position: (".scraped-example .scraped-example-title", {
     "y": |y| + |height| - |title_height| - 8,
 })
 
+store-size: (".more-scraped-examples .scraped-example .example-wrap", {"height": more_height})
+assert: |more_height| > |height|
+assert-size: (".more-scraped-examples .scraped-example .example-wrap", {
+    "height": 250,
+    "width": |width|,
+})
+
 // Check that the expand button works and also that line number aligns with code.
 move-cursor-to: ".scraped-example .rust"
 click: ".scraped-example .button-holder .expand"
diff --git a/tests/rustdoc-ui/doctest/doctest-output-include-fail.md b/tests/rustdoc-ui/doctest/doctest-output-include-fail.md
new file mode 100644
index 00000000000..a8e61238f31
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/doctest-output-include-fail.md
@@ -0,0 +1,7 @@
+With a code sample, that has an error:
+
+```rust
+fn main() {
+    let x = 234 // no semicolon here! oh no!
+}
+```
diff --git a/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs b/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs
new file mode 100644
index 00000000000..4fc0674a0c9
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/doctest-output-include-fail.rs
@@ -0,0 +1,7 @@
+//@ compile-flags:--test --test-args=--test-threads=1
+//@ normalize-stdout-test: "tests/rustdoc-ui/doctest" -> "$$DIR"
+//@ normalize-stdout-test: "finished in \d+\.\d+s" -> "finished in $$TIME"
+//@ failure-status: 101
+
+// https://github.com/rust-lang/rust/issues/130470
+#![doc = include_str!("doctest-output-include-fail.md")]
diff --git a/tests/rustdoc-ui/doctest/doctest-output-include-fail.stdout b/tests/rustdoc-ui/doctest/doctest-output-include-fail.stdout
new file mode 100644
index 00000000000..22d15f8743c
--- /dev/null
+++ b/tests/rustdoc-ui/doctest/doctest-output-include-fail.stdout
@@ -0,0 +1,24 @@
+
+running 1 test
+test $DIR/doctest-output-include-fail.md - (line 3) ... FAILED
+
+failures:
+
+---- $DIR/doctest-output-include-fail.md - (line 3) stdout ----
+error: expected `;`, found `}`
+  --> $DIR/doctest-output-include-fail.md:5:16
+   |
+LL |     let x = 234 // no semicolon here! oh no!
+   |                ^ help: add `;` here
+LL | }
+   | - unexpected token
+
+error: aborting due to 1 previous error
+
+Couldn't compile the test.
+
+failures:
+    $DIR/doctest-output-include-fail.md - (line 3)
+
+test result: FAILED. 0 passed; 1 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
+
diff --git a/tests/rustdoc-ui/doctest/doctest-output.stdout b/tests/rustdoc-ui/doctest/doctest-output.stdout
index 35b0e366fb5..c3b1570c43e 100644
--- a/tests/rustdoc-ui/doctest/doctest-output.stdout
+++ b/tests/rustdoc-ui/doctest/doctest-output.stdout
@@ -1,7 +1,7 @@
 
 running 3 tests
 test $DIR/doctest-output.rs - (line 8) ... ok
-test $DIR/doctest-output.rs - ExpandedStruct (line 24) ... ok
+test $DIR/doctest-output.rs - ExpandedStruct (line 25) ... ok
 test $DIR/doctest-output.rs - foo::bar (line 18) ... ok
 
 test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in $TIME
diff --git a/tests/ui-fulldeps/fluent-messages/many-lines.ftl b/tests/ui-fulldeps/fluent-messages/many-lines.ftl
new file mode 100644
index 00000000000..43660ebeacd
--- /dev/null
+++ b/tests/ui-fulldeps/fluent-messages/many-lines.ftl
@@ -0,0 +1,11 @@
+no_crate_foo = foo
+
+# This file tests error reporting for
+# fluent files with many lines.
+# The error message should point to the correct line number
+# and include no more context than necessary.
+
+no_crate_bar =
+
+no_crate_baz =
+    baz
diff --git a/tests/ui-fulldeps/fluent-messages/test.rs b/tests/ui-fulldeps/fluent-messages/test.rs
index 7bf1252ccf6..3361ebcef01 100644
--- a/tests/ui-fulldeps/fluent-messages/test.rs
+++ b/tests/ui-fulldeps/fluent-messages/test.rs
@@ -80,3 +80,8 @@ mod bad_escape {
     //~| ERROR invalid escape `\"`
     //~| ERROR invalid escape `\'`
 }
+
+mod many_lines {
+    rustc_fluent_macro::fluent_messages! { "./many-lines.ftl" }
+    //~^ ERROR could not parse Fluent resource
+}
diff --git a/tests/ui-fulldeps/fluent-messages/test.stderr b/tests/ui-fulldeps/fluent-messages/test.stderr
index 09d4a384732..0b3bb14ce51 100644
--- a/tests/ui-fulldeps/fluent-messages/test.stderr
+++ b/tests/ui-fulldeps/fluent-messages/test.stderr
@@ -103,5 +103,20 @@ LL |     rustc_fluent_macro::fluent_messages! { "./invalid-escape.ftl" }
    |
    = note: Fluent does not interpret these escape sequences (<https://projectfluent.org/fluent/guide/special.html>)
 
-error: aborting due to 13 previous errors
+error: could not parse Fluent resource
+  --> $DIR/test.rs:85:44
+   |
+LL |     rustc_fluent_macro::fluent_messages! { "./many-lines.ftl" }
+   |                                            ^^^^^^^^^^^^^^^^^^
+   |
+   = help: see additional errors emitted
+
+error: expected a message field for "no_crate_bar"
+ --> ./many-lines.ftl:8:1
+  |
+8 | no_crate_bar =
+  | ^^^^^^^^^^^^^^
+  |
+
+error: aborting due to 14 previous errors
 
diff --git a/tests/ui-fulldeps/run-compiler-twice.rs b/tests/ui-fulldeps/run-compiler-twice.rs
index 720fc42cc57..cce4eac0d7c 100644
--- a/tests/ui-fulldeps/run-compiler-twice.rs
+++ b/tests/ui-fulldeps/run-compiler-twice.rs
@@ -65,7 +65,7 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf, linker: Option<&Path
         output_dir: None,
         ice_file: None,
         file_loader: None,
-        locale_resources: &[],
+        locale_resources: Vec::new(),
         lint_caps: Default::default(),
         psess_created: None,
         hash_untracked_state: None,
diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs
index 9600c8dff67..b439a4bcf86 100644
--- a/tests/ui/abi/compatibility.rs
+++ b/tests/ui/abi/compatibility.rs
@@ -39,7 +39,6 @@
 //@ revisions: loongarch64
 //@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
 //@[loongarch64] needs-llvm-components: loongarch
-//@[loongarch64] min-llvm-version: 18
 //FIXME: wasm is disabled due to <https://github.com/rust-lang/rust/issues/115666>.
 //FIXME @ revisions: wasm
 //FIXME @[wasm] compile-flags: --target wasm32-unknown-unknown
diff --git a/tests/ui/abi/stack-probes-lto.rs b/tests/ui/abi/stack-probes-lto.rs
index 70343b0599a..e6c26c5c4de 100644
--- a/tests/ui/abi/stack-probes-lto.rs
+++ b/tests/ui/abi/stack-probes-lto.rs
@@ -1,7 +1,6 @@
 //@ revisions: aarch64 x32 x64
 //@ run-pass
 //@[aarch64] only-aarch64
-//@[aarch64] min-llvm-version: 18
 //@[x32] only-x86
 //@[x64] only-x86_64
 //@ ignore-sgx no processes
diff --git a/tests/ui/abi/stack-probes.rs b/tests/ui/abi/stack-probes.rs
index 22304257593..1c0e50250d7 100644
--- a/tests/ui/abi/stack-probes.rs
+++ b/tests/ui/abi/stack-probes.rs
@@ -1,7 +1,6 @@
 //@ revisions: aarch64 x32 x64
 //@ run-pass
 //@[aarch64] only-aarch64
-//@[aarch64] min-llvm-version: 18
 //@[x32] only-x86
 //@[x64] only-x86_64
 //@ ignore-emscripten no processes
diff --git a/tests/ui/abi/statics/static-mut-foreign.rs b/tests/ui/abi/statics/static-mut-foreign.rs
index 167b7a4e36e..40cd57637e6 100644
--- a/tests/ui/abi/statics/static-mut-foreign.rs
+++ b/tests/ui/abi/statics/static-mut-foreign.rs
@@ -3,6 +3,9 @@
 // statics cannot. This ensures that there's some form of error if this is
 // attempted.
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use std::ffi::c_int;
 
 #[link(name = "rust_test_helpers", kind = "static")]
@@ -29,9 +32,7 @@ unsafe fn run() {
     rust_dbg_static_mut = -3;
     assert_eq!(rust_dbg_static_mut, -3);
     static_bound(&rust_dbg_static_mut);
-    //~^ WARN shared reference to mutable static is discouraged [static_mut_refs]
     static_bound_set(&mut rust_dbg_static_mut);
-    //~^ WARN mutable reference to mutable static is discouraged [static_mut_refs]
 }
 
 pub fn main() {
diff --git a/tests/ui/abi/statics/static-mut-foreign.stderr b/tests/ui/abi/statics/static-mut-foreign.stderr
deleted file mode 100644
index 0c4bd5382a1..00000000000
--- a/tests/ui/abi/statics/static-mut-foreign.stderr
+++ /dev/null
@@ -1,31 +0,0 @@
-warning: creating a shared reference to mutable static is discouraged
-  --> $DIR/static-mut-foreign.rs:31:18
-   |
-LL |     static_bound(&rust_dbg_static_mut);
-   |                  ^^^^^^^^^^^^^^^^^^^^ shared reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-   = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |     static_bound(addr_of!(rust_dbg_static_mut));
-   |                  ~~~~~~~~~                   +
-
-warning: creating a mutable reference to mutable static is discouraged
-  --> $DIR/static-mut-foreign.rs:33:22
-   |
-LL |     static_bound_set(&mut rust_dbg_static_mut);
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ mutable reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
-help: use `addr_of_mut!` instead to create a raw pointer
-   |
-LL |     static_bound_set(addr_of_mut!(rust_dbg_static_mut));
-   |                      ~~~~~~~~~~~~~                   +
-
-warning: 2 warnings emitted
-
diff --git a/tests/ui/array-slice-vec/slice-panic-1.rs b/tests/ui/array-slice-vec/slice-panic-1.rs
index 4436b633856..d4f584c1632 100644
--- a/tests/ui/array-slice-vec/slice-panic-1.rs
+++ b/tests/ui/array-slice-vec/slice-panic-1.rs
@@ -5,6 +5,8 @@
 
 // Test that if a slicing expr[..] fails, the correct cleanups happen.
 
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
 
 use std::thread;
 
diff --git a/tests/ui/array-slice-vec/slice-panic-2.rs b/tests/ui/array-slice-vec/slice-panic-2.rs
index 4bd13988424..b3d1dc45573 100644
--- a/tests/ui/array-slice-vec/slice-panic-2.rs
+++ b/tests/ui/array-slice-vec/slice-panic-2.rs
@@ -5,6 +5,8 @@
 
 // Test that if a slicing expr[..] fails, the correct cleanups happen.
 
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
 
 use std::thread;
 
diff --git a/tests/ui/array-slice-vec/slice.rs b/tests/ui/array-slice-vec/slice.rs
index 2adcd96f598..ad5db7a2102 100644
--- a/tests/ui/array-slice-vec/slice.rs
+++ b/tests/ui/array-slice-vec/slice.rs
@@ -3,6 +3,9 @@
 
 // Test slicing sugar.
 
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
+
 extern crate core;
 use core::ops::{Index, IndexMut, Range, RangeTo, RangeFrom, RangeFull};
 
diff --git a/tests/ui/asm/inline-syntax.arm.stderr b/tests/ui/asm/inline-syntax.arm.stderr
index 4a50ec8d0d5..61e5078d6d9 100644
--- a/tests/ui/asm/inline-syntax.arm.stderr
+++ b/tests/ui/asm/inline-syntax.arm.stderr
@@ -1,9 +1,11 @@
 error: unknown directive
-.intel_syntax noprefix
-^
-error: unknown directive
-.intel_syntax noprefix
-^
+   |
+note: instantiated into assembly here
+  --> <inline asm>:1:1
+   |
+LL | .intel_syntax noprefix
+   | ^
+
 error: unknown directive
    |
 note: instantiated into assembly here
@@ -13,7 +15,7 @@ LL | .intel_syntax noprefix
    | ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:35:15
+  --> $DIR/inline-syntax.rs:29:15
    |
 LL |         asm!(".intel_syntax noprefix", "nop");
    |               ^
@@ -25,7 +27,7 @@ LL |     .intel_syntax noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:39:15
+  --> $DIR/inline-syntax.rs:32:15
    |
 LL |         asm!(".intel_syntax aaa noprefix", "nop");
    |               ^
@@ -37,7 +39,7 @@ LL |     .intel_syntax aaa noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:43:15
+  --> $DIR/inline-syntax.rs:35:15
    |
 LL |         asm!(".att_syntax noprefix", "nop");
    |               ^
@@ -49,7 +51,7 @@ LL |     .att_syntax noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:47:15
+  --> $DIR/inline-syntax.rs:38:15
    |
 LL |         asm!(".att_syntax bbb noprefix", "nop");
    |               ^
@@ -61,7 +63,7 @@ LL |     .att_syntax bbb noprefix
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:51:15
+  --> $DIR/inline-syntax.rs:41:15
    |
 LL |         asm!(".intel_syntax noprefix; nop");
    |               ^
@@ -73,7 +75,7 @@ LL |     .intel_syntax noprefix; nop
    |     ^
 
 error: unknown directive
-  --> $DIR/inline-syntax.rs:58:13
+  --> $DIR/inline-syntax.rs:47:13
    |
 LL |             .intel_syntax noprefix
    |             ^
@@ -84,5 +86,5 @@ note: instantiated into assembly here
 LL |             .intel_syntax noprefix
    |             ^
 
-error: aborting due to 7 previous errors
+error: aborting due to 8 previous errors
 
diff --git a/tests/ui/asm/inline-syntax.arm_llvm_18.stderr b/tests/ui/asm/inline-syntax.arm_llvm_18.stderr
deleted file mode 100644
index ada3f4891d3..00000000000
--- a/tests/ui/asm/inline-syntax.arm_llvm_18.stderr
+++ /dev/null
@@ -1,90 +0,0 @@
-error: unknown directive
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:1
-   |
-LL | .intel_syntax noprefix
-   | ^
-
-error: unknown directive
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:1
-   |
-LL | .intel_syntax noprefix
-   | ^
-
-error: unknown directive
-  --> $DIR/inline-syntax.rs:35:15
-   |
-LL |         asm!(".intel_syntax noprefix", "nop");
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     .intel_syntax noprefix
-   |     ^
-
-error: unknown directive
-  --> $DIR/inline-syntax.rs:39:15
-   |
-LL |         asm!(".intel_syntax aaa noprefix", "nop");
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     .intel_syntax aaa noprefix
-   |     ^
-
-error: unknown directive
-  --> $DIR/inline-syntax.rs:43:15
-   |
-LL |         asm!(".att_syntax noprefix", "nop");
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     .att_syntax noprefix
-   |     ^
-
-error: unknown directive
-  --> $DIR/inline-syntax.rs:47:15
-   |
-LL |         asm!(".att_syntax bbb noprefix", "nop");
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     .att_syntax bbb noprefix
-   |     ^
-
-error: unknown directive
-  --> $DIR/inline-syntax.rs:51:15
-   |
-LL |         asm!(".intel_syntax noprefix; nop");
-   |               ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:1:2
-   |
-LL |     .intel_syntax noprefix; nop
-   |     ^
-
-error: unknown directive
-  --> $DIR/inline-syntax.rs:58:13
-   |
-LL |             .intel_syntax noprefix
-   |             ^
-   |
-note: instantiated into assembly here
-  --> <inline asm>:2:13
-   |
-LL |             .intel_syntax noprefix
-   |             ^
-
-error: aborting due to 8 previous errors
-
diff --git a/tests/ui/asm/inline-syntax.rs b/tests/ui/asm/inline-syntax.rs
index 4a98d37aca0..b8486527e6f 100644
--- a/tests/ui/asm/inline-syntax.rs
+++ b/tests/ui/asm/inline-syntax.rs
@@ -1,16 +1,10 @@
-//@ revisions: x86_64 arm arm_llvm_18
+//@ revisions: x86_64 arm
 //@[x86_64] compile-flags: --target x86_64-unknown-linux-gnu
 //@[x86_64] check-pass
 //@[x86_64] needs-llvm-components: x86
 //@[arm] compile-flags: --target armv7-unknown-linux-gnueabihf
 //@[arm] build-fail
 //@[arm] needs-llvm-components: arm
-//@[arm] ignore-llvm-version: 18 - 99
-//Newer LLVM produces extra error notes.
-//@[arm_llvm_18] compile-flags: --target armv7-unknown-linux-gnueabihf
-//@[arm_llvm_18] build-fail
-//@[arm_llvm_18] needs-llvm-components: arm
-//@[arm_llvm_18] min-llvm-version: 18
 //@ needs-asm-support
 
 #![feature(no_core, lang_items, rustc_attrs)]
@@ -35,23 +29,18 @@ pub fn main() {
         asm!(".intel_syntax noprefix", "nop");
         //[x86_64]~^ WARN avoid using `.intel_syntax`
         //[arm]~^^ ERROR unknown directive
-        //[arm_llvm_18]~^^^ ERROR unknown directive
         asm!(".intel_syntax aaa noprefix", "nop");
         //[x86_64]~^ WARN avoid using `.intel_syntax`
         //[arm]~^^ ERROR unknown directive
-        //[arm_llvm_18]~^^^ ERROR unknown directive
         asm!(".att_syntax noprefix", "nop");
         //[x86_64]~^ WARN avoid using `.att_syntax`
         //[arm]~^^ ERROR unknown directive
-        //[arm_llvm_18]~^^^ ERROR unknown directive
         asm!(".att_syntax bbb noprefix", "nop");
         //[x86_64]~^ WARN avoid using `.att_syntax`
         //[arm]~^^ ERROR unknown directive
-        //[arm_llvm_18]~^^^ ERROR unknown directive
         asm!(".intel_syntax noprefix; nop");
         //[x86_64]~^ WARN avoid using `.intel_syntax`
         //[arm]~^^ ERROR unknown directive
-        //[arm_llvm_18]~^^^ ERROR unknown directive
 
         asm!(
             r"
@@ -60,7 +49,6 @@ pub fn main() {
         );
         //[x86_64]~^^^ WARN avoid using `.intel_syntax`
         //[arm]~^^^^ ERROR unknown directive
-        //[arm_llvm_18]~^^^^^ ERROR unknown directive
     }
 }
 
diff --git a/tests/ui/asm/inline-syntax.x86_64.stderr b/tests/ui/asm/inline-syntax.x86_64.stderr
index 66dc37f3089..59c95194322 100644
--- a/tests/ui/asm/inline-syntax.x86_64.stderr
+++ b/tests/ui/asm/inline-syntax.x86_64.stderr
@@ -1,5 +1,5 @@
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:67:14
+  --> $DIR/inline-syntax.rs:55:14
    |
 LL | global_asm!(".intel_syntax noprefix", "nop");
    |              ^^^^^^^^^^^^^^^^^^^^^^
@@ -7,37 +7,37 @@ LL | global_asm!(".intel_syntax noprefix", "nop");
    = note: `#[warn(bad_asm_style)]` on by default
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:35:15
+  --> $DIR/inline-syntax.rs:29:15
    |
 LL |         asm!(".intel_syntax noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:39:15
+  --> $DIR/inline-syntax.rs:32:15
    |
 LL |         asm!(".intel_syntax aaa noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
-  --> $DIR/inline-syntax.rs:43:15
+  --> $DIR/inline-syntax.rs:35:15
    |
 LL |         asm!(".att_syntax noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.att_syntax`, prefer using `options(att_syntax)` instead
-  --> $DIR/inline-syntax.rs:47:15
+  --> $DIR/inline-syntax.rs:38:15
    |
 LL |         asm!(".att_syntax bbb noprefix", "nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:51:15
+  --> $DIR/inline-syntax.rs:41:15
    |
 LL |         asm!(".intel_syntax noprefix; nop");
    |               ^^^^^^^^^^^^^^^^^^^^^^
 
 warning: avoid using `.intel_syntax`, Intel syntax is the default
-  --> $DIR/inline-syntax.rs:58:13
+  --> $DIR/inline-syntax.rs:47:13
    |
 LL |             .intel_syntax noprefix
    |             ^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs
index e2fc2961a44..a33d4928f01 100644
--- a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs
+++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.rs
@@ -7,4 +7,5 @@ impl Fail<i32> {
 
 fn main() {
     Fail::<()>::C
+    //~^ ERROR no associated item named `C` found for struct `Fail<()>` in the current scope
 }
diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr
index f0a6ccf243a..c5816393107 100644
--- a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr
+++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg.stderr
@@ -7,6 +7,19 @@ LL | struct Fail<T>;
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
    = help: if you intended `T` to be a const parameter, use `const T: /* Type */` instead
 
-error: aborting due to 1 previous error
+error[E0599]: no associated item named `C` found for struct `Fail<()>` in the current scope
+  --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg.rs:9:17
+   |
+LL | struct Fail<T>;
+   | -------------- associated item `C` not found for this struct
+...
+LL |     Fail::<()>::C
+   |                 ^ associated item not found in `Fail<()>`
+   |
+   = note: the associated item was found for
+           - `Fail<i32>`
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0392`.
+Some errors have detailed explanations: E0392, E0599.
+For more information about an error, try `rustc --explain E0392`.
diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs
index cb53d902ba1..d891b7bd62b 100644
--- a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs
+++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.rs
@@ -14,4 +14,5 @@ impl Fail<i32, i32> {
 fn main() {
     Fail::<i32, u32>::C
     //~^ ERROR: type mismatch
+    //~| ERROR no associated item named `C` found for struct `Fail<i32, u32>` in the current scope
 }
diff --git a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr
index 0d63b7f5b29..18d458aea80 100644
--- a/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr
+++ b/tests/ui/associated-consts/wrong-projection-self-ty-invalid-bivariant-arg2.stderr
@@ -1,3 +1,15 @@
+error[E0599]: no associated item named `C` found for struct `Fail<i32, u32>` in the current scope
+  --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:15:23
+   |
+LL | struct Fail<T: Proj<Assoc = U>, U>(T);
+   | ---------------------------------- associated item `C` not found for this struct
+...
+LL |     Fail::<i32, u32>::C
+   |                       ^ associated item not found in `Fail<i32, u32>`
+   |
+   = note: the associated item was found for
+           - `Fail<i32, i32>`
+
 error[E0271]: type mismatch resolving `<i32 as Proj>::Assoc == u32`
   --> $DIR/wrong-projection-self-ty-invalid-bivariant-arg2.rs:15:5
    |
@@ -15,6 +27,7 @@ note: required by a bound in `Fail`
 LL | struct Fail<T: Proj<Assoc = U>, U>(T);
    |                     ^^^^^^^^^ required by this bound in `Fail`
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0271`.
+Some errors have detailed explanations: E0271, E0599.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/async-await/async-closures/foreign.rs b/tests/ui/async-await/async-closures/foreign.rs
index 50bef9cf11d..ab6fe06a3f4 100644
--- a/tests/ui/async-await/async-closures/foreign.rs
+++ b/tests/ui/async-await/async-closures/foreign.rs
@@ -12,8 +12,13 @@ extern crate foreign;
 
 struct NoCopy;
 
+async fn call_once(f: impl async FnOnce()) {
+    f().await;
+}
+
 fn main() {
     block_on::block_on(async {
         foreign::closure()().await;
+        call_once(foreign::closure()).await;
     });
 }
diff --git a/tests/ui/async-await/async-closures/inline-body.rs b/tests/ui/async-await/async-closures/inline-body.rs
new file mode 100644
index 00000000000..a842d98d1de
--- /dev/null
+++ b/tests/ui/async-await/async-closures/inline-body.rs
@@ -0,0 +1,34 @@
+//@ edition: 2021
+//@ compile-flags: -Zinline-mir
+//@ build-pass
+
+// Ensure that we don't hit a Steal ICE because we forgot to ensure
+// `mir_inliner_callees` for the synthetic by-move coroutine body since
+// its def-id wasn't previously being considered.
+
+#![feature(async_closure, noop_waker)]
+
+use std::future::Future;
+use std::pin::pin;
+use std::task::*;
+
+pub fn block_on<T>(fut: impl Future<Output = T>) -> T {
+    let mut fut = pin!(fut);
+    let ctx = &mut Context::from_waker(Waker::noop());
+
+    loop {
+        match fut.as_mut().poll(ctx) {
+            Poll::Pending => {}
+            Poll::Ready(t) => break t,
+        }
+    }
+}
+
+async fn call_once<T>(f: impl async FnOnce() -> T) -> T {
+    f().await
+}
+
+fn main() {
+    let c = async || {};
+    block_on(call_once(c));
+}
diff --git a/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs b/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs
index 51e85931dbf..547c7414526 100644
--- a/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs
+++ b/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs
@@ -2,6 +2,8 @@
 //@ edition:2018
 
 #![feature(if_let_guard)]
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
 
 static mut A: [i32; 5] = [1, 2, 3, 4, 5];
 
diff --git a/tests/ui/async-await/pin-reborrow-arg.rs b/tests/ui/async-await/pin-reborrow-arg.rs
new file mode 100644
index 00000000000..2008bd1f52d
--- /dev/null
+++ b/tests/ui/async-await/pin-reborrow-arg.rs
@@ -0,0 +1,36 @@
+//@ check-pass
+
+#![feature(pin_ergonomics)]
+#![allow(dead_code, incomplete_features)]
+
+use std::pin::Pin;
+
+struct Foo;
+
+impl Foo {
+    fn baz(self: Pin<&mut Self>) {
+    }
+}
+
+fn foo(_: Pin<&mut Foo>) {
+}
+
+fn foo_const(_: Pin<&Foo>) {
+}
+
+fn bar(x: Pin<&mut Foo>) {
+    foo(x);
+    foo(x); // for this to work we need to automatically reborrow,
+            // as if the user had written `foo(x.as_mut())`.
+
+    Foo::baz(x);
+    Foo::baz(x);
+
+    foo_const(x); // make sure we can reborrow &mut as &.
+
+    let x: Pin<&Foo> = Pin::new(&Foo);
+
+    foo_const(x); // make sure reborrowing from & to & works.
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/pin-reborrow-const-as-mut.rs b/tests/ui/async-await/pin-reborrow-const-as-mut.rs
new file mode 100644
index 00000000000..27c70a7b4df
--- /dev/null
+++ b/tests/ui/async-await/pin-reborrow-const-as-mut.rs
@@ -0,0 +1,18 @@
+#![feature(pin_ergonomics)]
+#![allow(dead_code, incomplete_features)]
+
+// make sure we can't accidentally reborrow Pin<&T> as Pin<&mut T>
+
+use std::pin::Pin;
+
+struct Foo;
+
+fn foo(_: Pin<&mut Foo>) {
+}
+
+fn bar(x: Pin<&Foo>) {
+    foo(x); //~ ERROR mismatched types
+            //| ERROR types differ in mutability
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/pin-reborrow-const-as-mut.stderr b/tests/ui/async-await/pin-reborrow-const-as-mut.stderr
new file mode 100644
index 00000000000..2c2d9ec2717
--- /dev/null
+++ b/tests/ui/async-await/pin-reborrow-const-as-mut.stderr
@@ -0,0 +1,19 @@
+error[E0308]: mismatched types
+  --> $DIR/pin-reborrow-const-as-mut.rs:14:9
+   |
+LL |     foo(x);
+   |     --- ^ types differ in mutability
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected struct `Pin<&mut Foo>`
+              found struct `Pin<&Foo>`
+note: function defined here
+  --> $DIR/pin-reborrow-const-as-mut.rs:10:4
+   |
+LL | fn foo(_: Pin<&mut Foo>) {
+   |    ^^^ ----------------
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/async-await/pin-reborrow-once.rs b/tests/ui/async-await/pin-reborrow-once.rs
new file mode 100644
index 00000000000..241efadef7d
--- /dev/null
+++ b/tests/ui/async-await/pin-reborrow-once.rs
@@ -0,0 +1,13 @@
+#![feature(pin_ergonomics)]
+#![allow(dead_code, incomplete_features)]
+
+// Make sure with pin reborrowing that we can only get one mutable reborrow of a pinned reference.
+
+use std::pin::{pin, Pin};
+
+fn twice(_: Pin<&mut i32>, _: Pin<&mut i32>) {}
+
+fn main() {
+    let x = pin!(42);
+    twice(x, x); //~ ERROR cannot borrow
+}
diff --git a/tests/ui/async-await/pin-reborrow-once.stderr b/tests/ui/async-await/pin-reborrow-once.stderr
new file mode 100644
index 00000000000..b8fde8ffee8
--- /dev/null
+++ b/tests/ui/async-await/pin-reborrow-once.stderr
@@ -0,0 +1,12 @@
+error[E0499]: cannot borrow `*x.__pointer` as mutable more than once at a time
+  --> $DIR/pin-reborrow-once.rs:12:14
+   |
+LL |     twice(x, x);
+   |     ----- -  ^ second mutable borrow occurs here
+   |     |     |
+   |     |     first mutable borrow occurs here
+   |     first borrow later used by call
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0499`.
diff --git a/tests/ui/async-await/pin-reborrow-self.rs b/tests/ui/async-await/pin-reborrow-self.rs
new file mode 100644
index 00000000000..b60b6982bb8
--- /dev/null
+++ b/tests/ui/async-await/pin-reborrow-self.rs
@@ -0,0 +1,24 @@
+//@ check-pass
+//@ignore-test
+
+// Currently ignored due to self reborrowing not being implemented for Pin
+
+#![feature(pin_ergonomics)]
+#![allow(incomplete_features)]
+
+use std::pin::Pin;
+
+struct Foo;
+
+impl Foo {
+    fn foo(self: Pin<&mut Self>) {
+    }
+}
+
+fn bar(x: Pin<&mut Foo>) {
+    x.foo();
+    x.foo(); // for this to work we need to automatically reborrow,
+             // as if the user had written `x.as_mut().foo()`.
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/pin-reborrow-shorter.rs b/tests/ui/async-await/pin-reborrow-shorter.rs
new file mode 100644
index 00000000000..06c266e0035
--- /dev/null
+++ b/tests/ui/async-await/pin-reborrow-shorter.rs
@@ -0,0 +1,14 @@
+//@check-pass
+
+#![feature(pin_ergonomics)]
+#![allow(dead_code, incomplete_features)]
+
+use std::pin::Pin;
+
+fn shorter<'b, T: 'b>(_: Pin<&'b mut T>) {}
+
+fn test<'a: 'b, 'b, T: 'a>(x: Pin<&'a mut T>) {
+    shorter::<'b>(x);
+}
+
+fn main() {}
diff --git a/tests/ui/binding/order-drop-with-match.rs b/tests/ui/binding/order-drop-with-match.rs
index c12c5e4c627..cd0ff73cf12 100644
--- a/tests/ui/binding/order-drop-with-match.rs
+++ b/tests/ui/binding/order-drop-with-match.rs
@@ -5,6 +5,8 @@
 // in ORDER matching up to when it ran.
 // Correct order is: matched, inner, outer
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
 
 static mut ORDER: [usize; 3] = [0, 0, 0];
 static mut INDEX: usize = 0;
diff --git a/tests/ui/borrowck/borrowck-access-permissions.rs b/tests/ui/borrowck/borrowck-access-permissions.rs
index be11286a523..0e9e2bc1354 100644
--- a/tests/ui/borrowck/borrowck-access-permissions.rs
+++ b/tests/ui/borrowck/borrowck-access-permissions.rs
@@ -16,7 +16,6 @@ fn main() {
         let _y1 = &mut static_x; //~ ERROR [E0596]
         unsafe {
             let _y2 = &mut static_x_mut;
-            //~^ WARN mutable reference to mutable static is discouraged [static_mut_refs]
         }
     }
 
diff --git a/tests/ui/borrowck/borrowck-access-permissions.stderr b/tests/ui/borrowck/borrowck-access-permissions.stderr
index 36e259fa6e8..ade10dbbfbd 100644
--- a/tests/ui/borrowck/borrowck-access-permissions.stderr
+++ b/tests/ui/borrowck/borrowck-access-permissions.stderr
@@ -1,18 +1,3 @@
-warning: creating a mutable reference to mutable static is discouraged
-  --> $DIR/borrowck-access-permissions.rs:18:23
-   |
-LL |             let _y2 = &mut static_x_mut;
-   |                       ^^^^^^^^^^^^^^^^^ mutable reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
-   = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of_mut!` instead to create a raw pointer
-   |
-LL |             let _y2 = addr_of_mut!(static_x_mut);
-   |                       ~~~~~~~~~~~~~            +
-
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
   --> $DIR/borrowck-access-permissions.rs:10:19
    |
@@ -31,7 +16,7 @@ LL |         let _y1 = &mut static_x;
    |                   ^^^^^^^^^^^^^ cannot borrow as mutable
 
 error[E0596]: cannot borrow `*box_x` as mutable, as `box_x` is not declared as mutable
-  --> $DIR/borrowck-access-permissions.rs:28:19
+  --> $DIR/borrowck-access-permissions.rs:27:19
    |
 LL |         let _y1 = &mut *box_x;
    |                   ^^^^^^^^^^^ cannot borrow as mutable
@@ -42,7 +27,7 @@ LL |         let mut box_x = Box::new(1);
    |             +++
 
 error[E0596]: cannot borrow `*ref_x` as mutable, as it is behind a `&` reference
-  --> $DIR/borrowck-access-permissions.rs:37:19
+  --> $DIR/borrowck-access-permissions.rs:36:19
    |
 LL |         let _y1 = &mut *ref_x;
    |                   ^^^^^^^^^^^ `ref_x` is a `&` reference, so the data it refers to cannot be borrowed as mutable
@@ -53,7 +38,7 @@ LL |         let ref_x = &mut x;
    |                      +++
 
 error[E0596]: cannot borrow `*ptr_x` as mutable, as it is behind a `*const` pointer
-  --> $DIR/borrowck-access-permissions.rs:47:23
+  --> $DIR/borrowck-access-permissions.rs:46:23
    |
 LL |             let _y1 = &mut *ptr_x;
    |                       ^^^^^^^^^^^ `ptr_x` is a `*const` pointer, so the data it refers to cannot be borrowed as mutable
@@ -64,7 +49,7 @@ LL |         let ptr_x: *const _ = &mut x;
    |                                +++
 
 error[E0596]: cannot borrow `*foo_ref.f` as mutable, as it is behind a `&` reference
-  --> $DIR/borrowck-access-permissions.rs:60:18
+  --> $DIR/borrowck-access-permissions.rs:59:18
    |
 LL |         let _y = &mut *foo_ref.f;
    |                  ^^^^^^^^^^^^^^^ `foo_ref` is a `&` reference, so the data it refers to cannot be borrowed as mutable
@@ -74,6 +59,6 @@ help: consider changing this to be a mutable reference
 LL |         let foo_ref = &mut foo;
    |                        +++
 
-error: aborting due to 6 previous errors; 1 warning emitted
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0596`.
diff --git a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr
index a727c9414c5..e4dfa6d7fba 100644
--- a/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr
+++ b/tests/ui/borrowck/borrowck-unsafe-static-mutable-borrows.stderr
@@ -4,14 +4,13 @@ warning: creating a mutable reference to mutable static is discouraged
 LL |         let sfoo: *mut Foo = &mut SFOO;
    |                              ^^^^^^^^^ mutable reference to mutable static
    |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
    = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of_mut!` instead to create a raw pointer
+help: use `&raw mut` instead to create a raw pointer
    |
-LL |         let sfoo: *mut Foo = addr_of_mut!(SFOO);
-   |                              ~~~~~~~~~~~~~    +
+LL |         let sfoo: *mut Foo = &raw mut SFOO;
+   |                              ~~~~~~~~
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/borrowck/issue-20801.rs b/tests/ui/borrowck/issue-20801.rs
index 7e3d3703dc7..c3f136f2876 100644
--- a/tests/ui/borrowck/issue-20801.rs
+++ b/tests/ui/borrowck/issue-20801.rs
@@ -12,7 +12,6 @@ fn imm_ref() -> &'static T {
 
 fn mut_ref() -> &'static mut T {
     unsafe { &mut GLOBAL_MUT_T }
-    //~^ WARN mutable reference to mutable static is discouraged [static_mut_refs]
 }
 
 fn mut_ptr() -> *mut T {
diff --git a/tests/ui/borrowck/issue-20801.stderr b/tests/ui/borrowck/issue-20801.stderr
index 769b34831c1..5fda92634d8 100644
--- a/tests/ui/borrowck/issue-20801.stderr
+++ b/tests/ui/borrowck/issue-20801.stderr
@@ -1,20 +1,5 @@
-warning: creating a mutable reference to mutable static is discouraged
-  --> $DIR/issue-20801.rs:14:14
-   |
-LL |     unsafe { &mut GLOBAL_MUT_T }
-   |              ^^^^^^^^^^^^^^^^^ mutable reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
-   = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of_mut!` instead to create a raw pointer
-   |
-LL |     unsafe { addr_of_mut!(GLOBAL_MUT_T) }
-   |              ~~~~~~~~~~~~~            +
-
 error[E0507]: cannot move out of a mutable reference
-  --> $DIR/issue-20801.rs:27:22
+  --> $DIR/issue-20801.rs:26:22
    |
 LL |     let a = unsafe { *mut_ref() };
    |                      ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
@@ -34,7 +19,7 @@ LL +     let a = unsafe { mut_ref() };
    |
 
 error[E0507]: cannot move out of a shared reference
-  --> $DIR/issue-20801.rs:30:22
+  --> $DIR/issue-20801.rs:29:22
    |
 LL |     let b = unsafe { *imm_ref() };
    |                      ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
@@ -54,7 +39,7 @@ LL +     let b = unsafe { imm_ref() };
    |
 
 error[E0507]: cannot move out of a raw pointer
-  --> $DIR/issue-20801.rs:33:22
+  --> $DIR/issue-20801.rs:32:22
    |
 LL |     let c = unsafe { *mut_ptr() };
    |                      ^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
@@ -69,7 +54,7 @@ LL |     let c = unsafe { *mut_ptr() };
    |                      ---------- you could clone this value
 
 error[E0507]: cannot move out of a raw pointer
-  --> $DIR/issue-20801.rs:36:22
+  --> $DIR/issue-20801.rs:35:22
    |
 LL |     let d = unsafe { *const_ptr() };
    |                      ^^^^^^^^^^^^ move occurs because value has type `T`, which does not implement the `Copy` trait
@@ -83,6 +68,6 @@ LL | struct T(u8);
 LL |     let d = unsafe { *const_ptr() };
    |                      ------------ you could clone this value
 
-error: aborting due to 4 previous errors; 1 warning emitted
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0507`.
diff --git a/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs b/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs
index c3909d05963..e22bf42e021 100644
--- a/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs
+++ b/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.rs
@@ -10,7 +10,6 @@ mod borrowck_closures_unique {
         //~^ ERROR is not declared as mutable
         unsafe {
             c1(&mut Y);
-            //~^ WARN mutable reference to mutable static is discouraged [static_mut_refs]
         }
     }
 }
@@ -25,7 +24,6 @@ mod borrowck_closures_unique_grandparent {
         };
         unsafe {
             c1(&mut Z);
-            //~^ WARN mutable reference to mutable static is discouraged [static_mut_refs]
         }
     }
 }
@@ -62,7 +60,6 @@ fn main() {
     static mut X: isize = 2;
     unsafe {
         borrowck_closures_unique::e(&mut X);
-        //~^ WARN mutable reference to mutable static is discouraged [static_mut_refs]
     }
 
     mutability_errors::capture_assign_whole((1000,));
diff --git a/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr b/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr
index 72fd0d8ce16..6fc8d3a6c35 100644
--- a/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr
+++ b/tests/ui/borrowck/issue-55492-borrowck-migrate-scans-parents.stderr
@@ -1,46 +1,3 @@
-warning: creating a mutable reference to mutable static is discouraged
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:12:16
-   |
-LL |             c1(&mut Y);
-   |                ^^^^^^ mutable reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
-   = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of_mut!` instead to create a raw pointer
-   |
-LL |             c1(addr_of_mut!(Y));
-   |                ~~~~~~~~~~~~~ +
-
-warning: creating a mutable reference to mutable static is discouraged
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:27:16
-   |
-LL |             c1(&mut Z);
-   |                ^^^^^^ mutable reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
-help: use `addr_of_mut!` instead to create a raw pointer
-   |
-LL |             c1(addr_of_mut!(Z));
-   |                ~~~~~~~~~~~~~ +
-
-warning: creating a mutable reference to mutable static is discouraged
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:64:37
-   |
-LL |         borrowck_closures_unique::e(&mut X);
-   |                                     ^^^^^^ mutable reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
-help: use `addr_of_mut!` instead to create a raw pointer
-   |
-LL |         borrowck_closures_unique::e(addr_of_mut!(X));
-   |                                     ~~~~~~~~~~~~~ +
-
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
   --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:9:46
    |
@@ -53,7 +10,7 @@ LL |     pub fn e(mut x: &'static mut isize) {
    |              +++
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:22:50
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:21:50
    |
 LL |             let mut c2 = |y: &'static mut isize| x = y;
    |                                                  ^^^^^ cannot assign
@@ -64,7 +21,7 @@ LL |     pub fn ee(mut x: &'static mut isize) {
    |               +++
 
 error[E0594]: cannot assign to `x`, as it is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:37:13
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:35:13
    |
 LL |             x = (1,);
    |             ^^^^^^^^ cannot assign
@@ -75,7 +32,7 @@ LL |     pub fn capture_assign_whole(mut x: (i32,)) {
    |                                 +++
 
 error[E0594]: cannot assign to `x.0`, as `x` is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:43:13
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:41:13
    |
 LL |             x.0 = 1;
    |             ^^^^^^^ cannot assign
@@ -86,7 +43,7 @@ LL |     pub fn capture_assign_part(mut x: (i32,)) {
    |                                +++
 
 error[E0596]: cannot borrow `x` as mutable, as it is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:49:13
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:47:13
    |
 LL |             &mut x;
    |             ^^^^^^ cannot borrow as mutable
@@ -97,7 +54,7 @@ LL |     pub fn capture_reborrow_whole(mut x: (i32,)) {
    |                                   +++
 
 error[E0596]: cannot borrow `x.0` as mutable, as `x` is not declared as mutable
-  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:55:13
+  --> $DIR/issue-55492-borrowck-migrate-scans-parents.rs:53:13
    |
 LL |             &mut x.0;
    |             ^^^^^^^^ cannot borrow as mutable
@@ -107,7 +64,7 @@ help: consider changing this to be mutable
 LL |     pub fn capture_reborrow_part(mut x: (i32,)) {
    |                                  +++
 
-error: aborting due to 6 previous errors; 3 warnings emitted
+error: aborting due to 6 previous errors
 
 Some errors have detailed explanations: E0594, E0596.
 For more information about an error, try `rustc --explain E0594`.
diff --git a/tests/ui/cfg/cfg-false-feature.rs b/tests/ui/cfg/cfg-false-feature.rs
index 6645f667d7e..716b18492c7 100644
--- a/tests/ui/cfg/cfg-false-feature.rs
+++ b/tests/ui/cfg/cfg-false-feature.rs
@@ -5,7 +5,7 @@
 
 #![feature(decl_macro)]
 #![cfg(FALSE)]
-#![feature(box_syntax)]
+#![feature(box_patterns)]
 
 macro mac() {} // OK
 
diff --git a/tests/ui/check-cfg/raw-keywords.edition2015.stderr b/tests/ui/check-cfg/raw-keywords.edition2015.stderr
new file mode 100644
index 00000000000..ab7e77686ee
--- /dev/null
+++ b/tests/ui/check-cfg/raw-keywords.edition2015.stderr
@@ -0,0 +1,40 @@
+warning: unexpected `cfg` condition name: `tru`
+  --> $DIR/raw-keywords.rs:14:7
+   |
+LL | #[cfg(tru)]
+   |       ^^^ help: there is a config with a similar name: `r#true`
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(tru)`
+   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
+   = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: unexpected `cfg` condition name: `r#false`
+  --> $DIR/raw-keywords.rs:19:7
+   |
+LL | #[cfg(r#false)]
+   |       ^^^^^^^
+   |
+   = help: expected names are: `async`, `clippy`, `debug_assertions`, `doc`, `doctest`, `edition2015`, `edition2021`, `fmt_debug`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `r#true`, `ub_checks`, `unix`, and `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(r#false)`
+   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
+
+warning: unexpected `cfg` condition name: `await`
+  --> $DIR/raw-keywords.rs:27:29
+   |
+LL | #[cfg_attr(edition2015, cfg(await))]
+   |                             ^^^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(await)`
+   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
+
+warning: unexpected `cfg` condition name: `raw`
+  --> $DIR/raw-keywords.rs:33:7
+   |
+LL | #[cfg(r#raw)]
+   |       ^^^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(raw)`
+   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
+
+warning: 4 warnings emitted
+
diff --git a/tests/ui/check-cfg/raw-keywords.edition2021.stderr b/tests/ui/check-cfg/raw-keywords.edition2021.stderr
new file mode 100644
index 00000000000..1ae1cad4e6b
--- /dev/null
+++ b/tests/ui/check-cfg/raw-keywords.edition2021.stderr
@@ -0,0 +1,40 @@
+warning: unexpected `cfg` condition name: `tru`
+  --> $DIR/raw-keywords.rs:14:7
+   |
+LL | #[cfg(tru)]
+   |       ^^^ help: there is a config with a similar name: `r#true`
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(tru)`
+   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
+   = note: `#[warn(unexpected_cfgs)]` on by default
+
+warning: unexpected `cfg` condition name: `r#false`
+  --> $DIR/raw-keywords.rs:19:7
+   |
+LL | #[cfg(r#false)]
+   |       ^^^^^^^
+   |
+   = help: expected names are: `r#async`, `clippy`, `debug_assertions`, `doc`, `doctest`, `edition2015`, `edition2021`, `fmt_debug`, `miri`, `overflow_checks`, `panic`, `proc_macro`, `relocation_model`, `rustfmt`, `sanitize`, `sanitizer_cfi_generalize_pointers`, `sanitizer_cfi_normalize_integers`, `target_abi`, `target_arch`, `target_endian`, `target_env`, `target_family`, `target_feature`, `target_has_atomic`, `target_has_atomic_equal_alignment`, `target_has_atomic_load_store`, `target_os`, `target_pointer_width`, `target_thread_local`, `target_vendor`, `test`, `r#true`, `ub_checks`, `unix`, and `windows`
+   = help: to expect this configuration use `--check-cfg=cfg(r#false)`
+   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
+
+warning: unexpected `cfg` condition name: `r#await`
+  --> $DIR/raw-keywords.rs:28:29
+   |
+LL | #[cfg_attr(edition2021, cfg(r#await))]
+   |                             ^^^^^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(r#await)`
+   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
+
+warning: unexpected `cfg` condition name: `raw`
+  --> $DIR/raw-keywords.rs:33:7
+   |
+LL | #[cfg(r#raw)]
+   |       ^^^^^
+   |
+   = help: to expect this configuration use `--check-cfg=cfg(raw)`
+   = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
+
+warning: 4 warnings emitted
+
diff --git a/tests/ui/check-cfg/raw-keywords.rs b/tests/ui/check-cfg/raw-keywords.rs
new file mode 100644
index 00000000000..5de13240d7e
--- /dev/null
+++ b/tests/ui/check-cfg/raw-keywords.rs
@@ -0,0 +1,40 @@
+// This test check that using raw keywords works with --cfg and --check-cfg
+// and that the diagnostics suggestions are coherent
+//
+//@ check-pass
+//@ no-auto-check-cfg
+//@ compile-flags: --cfg=true --cfg=async --check-cfg=cfg(r#true,r#async,edition2015,edition2021)
+//
+//@ revisions: edition2015 edition2021
+//@ [edition2021] compile-flags: --edition 2021
+
+#[cfg(r#true)]
+fn foo() {}
+
+#[cfg(tru)]
+//~^ WARNING unexpected `cfg` condition name: `tru`
+//~^^ SUGGESTION r#true
+fn foo() {}
+
+#[cfg(r#false)]
+//~^ WARNING unexpected `cfg` condition name: `r#false`
+fn foo() {}
+
+#[cfg_attr(edition2015, cfg(async))]
+#[cfg_attr(edition2021, cfg(r#async))]
+fn bar() {}
+
+#[cfg_attr(edition2015, cfg(await))]
+#[cfg_attr(edition2021, cfg(r#await))]
+//[edition2015]~^^ WARNING unexpected `cfg` condition name: `await`
+//[edition2021]~^^ WARNING unexpected `cfg` condition name: `r#await`
+fn zoo() {}
+
+#[cfg(r#raw)]
+//~^ WARNING unexpected `cfg` condition name: `raw`
+fn foo() {}
+
+fn main() {
+    foo();
+    bar();
+}
diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr b/tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr
deleted file mode 100644
index ef5633f7134..00000000000
--- a/tests/ui/coercion/coerce-issue-49593-box-never.fallback.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0277]: the trait bound `(): std::error::Error` is not satisfied
-  --> $DIR/coerce-issue-49593-box-never.rs:18:5
-   |
-LL |     Box::<_ /* ! */>::new(x)
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `std::error::Error` is not implemented for `()`
-   |
-   = note: required for the cast from `Box<()>` to `Box<(dyn std::error::Error + 'static)>`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/coercion/coerce-issue-49593-box-never.rs b/tests/ui/coercion/coerce-issue-49593-box-never.rs
index 53071be47dc..e5569592045 100644
--- a/tests/ui/coercion/coerce-issue-49593-box-never.rs
+++ b/tests/ui/coercion/coerce-issue-49593-box-never.rs
@@ -1,5 +1,5 @@
 //@ revisions: nofallback fallback
-//@check-fail
+//@[fallback] check-pass
 
 #![feature(never_type)]
 #![cfg_attr(fallback, feature(never_type_fallback))]
@@ -13,10 +13,10 @@ fn raw_ptr_box<T>(t: T) -> *mut T {
 }
 
 fn foo(x: !) -> Box<dyn Error> {
-    // Subtyping during method resolution will generate new inference vars and
-    // subtype them. Thus fallback will not fall back to `!`, but `()` instead.
+    // Method resolution will generate new inference vars and relate them.
+    // Thus fallback will not fall back to `!`, but `()` instead.
     Box::<_ /* ! */>::new(x)
-    //~^ ERROR trait bound `(): std::error::Error` is not satisfied
+    //[nofallback]~^ ERROR trait bound `(): std::error::Error` is not satisfied
 }
 
 fn foo_raw_ptr(x: !) -> *mut dyn Error {
diff --git a/tests/ui/compiletest-self-test/compile-flags-last.stderr b/tests/ui/compiletest-self-test/compile-flags-last.stderr
index d8d40a7d9f1..72d92206e2b 100644
--- a/tests/ui/compiletest-self-test/compile-flags-last.stderr
+++ b/tests/ui/compiletest-self-test/compile-flags-last.stderr
@@ -1,2 +1,5 @@
 error: Argument to option 'cap-lints' missing
+       Usage:
+           --cap-lints LEVEL   Set the most restrictive lint level. More restrictive
+                               lints are capped at this level
 
diff --git a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr
index 217f609459e..b88fe966b77 100644
--- a/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr
+++ b/tests/ui/const-generics/generic_arg_infer/issue-91614.stderr
@@ -8,7 +8,7 @@ note: required by a const generic parameter in `Mask::<T, N>::splat`
   --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL
 help: consider giving `y` an explicit type, where the value of const parameter `N` is specified
    |
-LL |     let y: Mask<T, N> = Mask::<_, _>::splat(false);
+LL |     let y: Mask<_, N> = Mask::<_, _>::splat(false);
    |          ++++++++++++
 
 error[E0284]: type annotations needed for `Mask<_, _>`
@@ -21,7 +21,7 @@ note: required by a const generic parameter in `Mask`
   --> $SRC_DIR/core/src/../../portable-simd/crates/core_simd/src/masks.rs:LL:COL
 help: consider giving `y` an explicit type, where the value of const parameter `N` is specified
    |
-LL |     let y: Mask<T, N> = Mask::<_, _>::splat(false);
+LL |     let y: Mask<_, N> = Mask::<_, _>::splat(false);
    |          ++++++++++++
 
 error: aborting due to 2 previous errors
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-109141.rs b/tests/ui/const-generics/generic_const_exprs/issue-109141.rs
index c6dd981cced..5303b247173 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-109141.rs
+++ b/tests/ui/const-generics/generic_const_exprs/issue-109141.rs
@@ -3,8 +3,7 @@
 
 impl EntriesBuffer {
     fn a(&self) -> impl Iterator {
-        self.0.iter_mut() //~ ERROR: cannot borrow `*self.0` as mutable, as it is behind a `&` reference
-                          //~| ERROR captures lifetime that does not appear in bounds
+        self.0.iter_mut()
     }
 }
 
diff --git a/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr b/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr
index 24f3ed7cdf1..fcbd6904599 100644
--- a/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr
@@ -1,5 +1,5 @@
 error[E0425]: cannot find value `HashesEntryLEN` in this scope
-  --> $DIR/issue-109141.rs:11:32
+  --> $DIR/issue-109141.rs:10:32
    |
 LL | struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>);
    |                                ^^^^^^^^^^^^^^ not found in this scope
@@ -9,33 +9,6 @@ help: you might be missing a const parameter
 LL | struct EntriesBuffer<const HashesEntryLEN: /* Type */>(Box<[[u8; HashesEntryLEN]; 5]>);
    |                     ++++++++++++++++++++++++++++++++++
 
-error[E0596]: cannot borrow `*self.0` as mutable, as it is behind a `&` reference
-  --> $DIR/issue-109141.rs:6:9
-   |
-LL |         self.0.iter_mut()
-   |         ^^^^^^ `self` is a `&` reference, so the data it refers to cannot be borrowed as mutable
-   |
-help: consider changing this to be a mutable reference
-   |
-LL |     fn a(&mut self) -> impl Iterator {
-   |          ~~~~~~~~~
-
-error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds
-  --> $DIR/issue-109141.rs:6:9
-   |
-LL |     fn a(&self) -> impl Iterator {
-   |          -----     ------------- opaque type defined here
-   |          |
-   |          hidden type `std::slice::IterMut<'_, [u8; {const error}]>` captures the anonymous lifetime defined here
-LL |         self.0.iter_mut()
-   |         ^^^^^^^^^^^^^^^^^
-   |
-help: add a `use<...>` bound to explicitly capture `'_`
-   |
-LL |     fn a(&self) -> impl Iterator + use<'_> {
-   |                                  +++++++++
-
-error: aborting due to 3 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0425, E0596, E0700.
-For more information about an error, try `rustc --explain E0425`.
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs
index 7209290a36e..56b8acbf88c 100644
--- a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs
+++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs
@@ -2,7 +2,6 @@
 #![allow(incomplete_features)]
 
 type Foo = impl Sized;
-//~^ ERROR: unconstrained opaque type
 
 fn with_bound<const N: usize>() -> Foo
 where
diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr
index c7a266205b4..e9fb8c0f403 100644
--- a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr
@@ -1,5 +1,5 @@
 error[E0308]: mismatched types
-  --> $DIR/opaque_type.rs:11:17
+  --> $DIR/opaque_type.rs:10:17
    |
 LL | type Foo = impl Sized;
    |            ---------- the found opaque type
@@ -11,20 +11,12 @@ LL |     let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
            found opaque type `Foo`
 
 error[E0605]: non-primitive cast: `usize` as `Foo`
-  --> $DIR/opaque_type.rs:11:17
+  --> $DIR/opaque_type.rs:10:17
    |
 LL |     let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
    |                 ^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
 
-error: unconstrained opaque type
-  --> $DIR/opaque_type.rs:4:12
-   |
-LL | type Foo = impl Sized;
-   |            ^^^^^^^^^^
-   |
-   = note: `Foo` must be used in combination with a concrete type within the same module
-
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 Some errors have detailed explanations: E0308, E0605.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.rs b/tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.rs
deleted file mode 100644
index 81be8d5c7d7..00000000000
--- a/tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.rs
+++ /dev/null
@@ -1,54 +0,0 @@
-//@ known-bug: #110395
-//@ known-bug: #97156
-
-#![feature(const_type_id, const_trait_impl, generic_const_exprs)]
-#![allow(incomplete_features)]
-
-use std::any::TypeId;
-// `One` and `Two` are currently considered equal types, as both
-// `One <: Two` and `One :> Two` holds.
-type One = for<'a> fn(&'a (), &'a ());
-type Two = for<'a, 'b> fn(&'a (), &'b ());
-trait AssocCt {
-    const ASSOC: usize;
-}
-const fn to_usize<T: 'static>() -> usize {
-    const WHAT_A_TYPE: TypeId = TypeId::of::<One>();
-    match TypeId::of::<T>() {
-        WHAT_A_TYPE => 0,
-        _ => 1000,
-    }
-}
-impl<T: 'static> AssocCt for T {
-    const ASSOC: usize = to_usize::<T>();
-}
-
-trait WithAssoc<U> {
-    type Assoc;
-}
-impl<T: 'static> WithAssoc<()> for T
-where
-    [(); <T as AssocCt>::ASSOC]:,
-{
-    type Assoc = [u8; <T as AssocCt>::ASSOC];
-}
-
-fn generic<T: 'static, U>(x: <T as WithAssoc<U>>::Assoc) -> <T as WithAssoc<U>>::Assoc
-where
-    [(); <T as AssocCt>::ASSOC]:,
-    T: WithAssoc<U>,
-{
-    x
-}
-
-fn unsound<T>(x: <One as WithAssoc<T>>::Assoc) -> <Two as WithAssoc<T>>::Assoc
-where
-    One: WithAssoc<T>,
-{
-    let x: <Two as WithAssoc<T>>::Assoc = generic::<One, T>(x);
-    x
-}
-
-fn main() {
-    println!("{:?}", unsound::<()>([]));
-}
diff --git a/tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.stderr b/tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.stderr
deleted file mode 100644
index 26e724c9061..00000000000
--- a/tests/ui/const-generics/generic_const_exprs/typeid-equality-by-subtyping.stderr
+++ /dev/null
@@ -1,27 +0,0 @@
-error: to use a constant of type `TypeId` in a pattern, `TypeId` must be annotated with `#[derive(PartialEq)]`
-  --> $DIR/typeid-equality-by-subtyping.rs:18:9
-   |
-LL |         WHAT_A_TYPE => 0,
-   |         ^^^^^^^^^^^
-   |
-   = note: the traits must be derived, manual `impl`s are not sufficient
-   = note: see https://doc.rust-lang.org/stable/std/marker/trait.StructuralPartialEq.html for details
-
-error[E0277]: the trait bound `for<'a, 'b> fn(&'a (), &'b ()): WithAssoc<T>` is not satisfied
-  --> $DIR/typeid-equality-by-subtyping.rs:44:51
-   |
-LL | fn unsound<T>(x: <One as WithAssoc<T>>::Assoc) -> <Two as WithAssoc<T>>::Assoc
-   |                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `WithAssoc<T>` is not implemented for `for<'a, 'b> fn(&'a (), &'b ())`
-
-error[E0277]: the trait bound `for<'a, 'b> fn(&'a (), &'b ()): WithAssoc<T>` is not satisfied
-  --> $DIR/typeid-equality-by-subtyping.rs:47:1
-   |
-LL | / {
-LL | |     let x: <Two as WithAssoc<T>>::Assoc = generic::<One, T>(x);
-LL | |     x
-LL | | }
-   | |_^ the trait `WithAssoc<T>` is not implemented for `for<'a, 'b> fn(&'a (), &'b ())`
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/consts/const_let_assign2.stderr b/tests/ui/consts/const_let_assign2.stderr
index 87b94a7be67..9a1b84dbf09 100644
--- a/tests/ui/consts/const_let_assign2.stderr
+++ b/tests/ui/consts/const_let_assign2.stderr
@@ -4,14 +4,13 @@ warning: creating a mutable reference to mutable static is discouraged
 LL |     let ptr = unsafe { &mut BB };
    |                        ^^^^^^^ mutable reference to mutable static
    |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
    = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of_mut!` instead to create a raw pointer
+help: use `&raw mut` instead to create a raw pointer
    |
-LL |     let ptr = unsafe { addr_of_mut!(BB) };
-   |                        ~~~~~~~~~~~~~  +
+LL |     let ptr = unsafe { &raw mut BB };
+   |                        ~~~~~~~~
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/consts/issue-116186.rs b/tests/ui/consts/issue-116186.rs
index a77c38c64dc..8bfb47629e7 100644
--- a/tests/ui/consts/issue-116186.rs
+++ b/tests/ui/consts/issue-116186.rs
@@ -4,7 +4,7 @@
 fn something(path: [usize; N]) -> impl Clone {
     //~^ ERROR cannot find value `N` in this scope
     match path {
-        [] => 0, //~ ERROR cannot pattern-match on an array without a fixed length
+        [] => 0,
         _ => 1,
     };
 }
diff --git a/tests/ui/consts/issue-116186.stderr b/tests/ui/consts/issue-116186.stderr
index e6eae2d9f55..46931f79dd0 100644
--- a/tests/ui/consts/issue-116186.stderr
+++ b/tests/ui/consts/issue-116186.stderr
@@ -9,13 +9,6 @@ help: you might be missing a const parameter
 LL | fn something<const N: /* Type */>(path: [usize; N]) -> impl Clone {
    |             +++++++++++++++++++++
 
-error[E0730]: cannot pattern-match on an array without a fixed length
-  --> $DIR/issue-116186.rs:7:9
-   |
-LL |         [] => 0,
-   |         ^^
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0425, E0730.
-For more information about an error, try `rustc --explain E0425`.
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/consts/static-mut-refs.rs b/tests/ui/consts/static-mut-refs.rs
index d4ebfbbf17a..c0d0bb61332 100644
--- a/tests/ui/consts/static-mut-refs.rs
+++ b/tests/ui/consts/static-mut-refs.rs
@@ -1,6 +1,9 @@
 //@ run-pass
 #![allow(dead_code)]
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 // Checks that mutable static items can have mutable slices and other references
 
 
diff --git a/tests/ui/coroutine/static-mut-reference-across-yield.rs b/tests/ui/coroutine/static-mut-reference-across-yield.rs
index 40d5fdf2d57..d45d6e6428b 100644
--- a/tests/ui/coroutine/static-mut-reference-across-yield.rs
+++ b/tests/ui/coroutine/static-mut-reference-across-yield.rs
@@ -1,6 +1,8 @@
 //@ build-pass
 
 #![feature(coroutines, stmt_expr_attributes)]
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
 
 static mut A: [i32; 5] = [1, 2, 3, 4, 5];
 
diff --git a/tests/ui/drop/drop-struct-as-object.rs b/tests/ui/drop/drop-struct-as-object.rs
index 07c8950f1b2..46633bd7075 100644
--- a/tests/ui/drop/drop-struct-as-object.rs
+++ b/tests/ui/drop/drop-struct-as-object.rs
@@ -5,6 +5,9 @@
 // Test that destructor on a struct runs successfully after the struct
 // is boxed and converted to an object.
 
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
+
 static mut value: usize = 0;
 
 struct Cat {
diff --git a/tests/ui/drop/drop-struct-as-object.stderr b/tests/ui/drop/drop-struct-as-object.stderr
index 10527c968ed..16f6d1110ba 100644
--- a/tests/ui/drop/drop-struct-as-object.stderr
+++ b/tests/ui/drop/drop-struct-as-object.stderr
@@ -1,5 +1,5 @@
 warning: method `get` is never used
-  --> $DIR/drop-struct-as-object.rs:15:8
+  --> $DIR/drop-struct-as-object.rs:18:8
    |
 LL | trait Dummy {
    |       ----- method in this trait
diff --git a/tests/ui/drop/issue-23338-ensure-param-drop-order.rs b/tests/ui/drop/issue-23338-ensure-param-drop-order.rs
index 1fa68a2e738..6fee4520cbc 100644
--- a/tests/ui/drop/issue-23338-ensure-param-drop-order.rs
+++ b/tests/ui/drop/issue-23338-ensure-param-drop-order.rs
@@ -1,5 +1,7 @@
 //@ run-pass
 #![allow(non_upper_case_globals)]
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
 
 // This test is ensuring that parameters are indeed dropped after
 // temporaries in a fn body.
@@ -91,7 +93,6 @@ pub mod d {
     pub fn max_width() -> u32 {
         unsafe {
             (mem::size_of_val(&trails) * 8) as u32
-            //~^ WARN shared reference to mutable static is discouraged [static_mut_refs]
         }
     }
 
diff --git a/tests/ui/drop/issue-23338-ensure-param-drop-order.stderr b/tests/ui/drop/issue-23338-ensure-param-drop-order.stderr
deleted file mode 100644
index 9126e602391..00000000000
--- a/tests/ui/drop/issue-23338-ensure-param-drop-order.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-warning: creating a shared reference to mutable static is discouraged
-  --> $DIR/issue-23338-ensure-param-drop-order.rs:93:31
-   |
-LL |             (mem::size_of_val(&trails) * 8) as u32
-   |                               ^^^^^^^ shared reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-   = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |             (mem::size_of_val(addr_of!(trails)) * 8) as u32
-   |                               ~~~~~~~~~      +
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/drop/issue-23611-enum-swap-in-drop.rs b/tests/ui/drop/issue-23611-enum-swap-in-drop.rs
index 1afaff0f735..410b07b16fc 100644
--- a/tests/ui/drop/issue-23611-enum-swap-in-drop.rs
+++ b/tests/ui/drop/issue-23611-enum-swap-in-drop.rs
@@ -1,5 +1,7 @@
 //@ run-pass
 #![allow(non_upper_case_globals)]
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
 
 // Issue 23611: this test is ensuring that, for an instance `X` of the
 // enum `E`, if you swap in a different variant during the execution
@@ -187,7 +189,6 @@ pub mod d {
     pub fn max_width() -> u32 {
         unsafe {
             (mem::size_of_val(&trails) * 8) as u32
-            //~^ WARN shared reference to mutable static is discouraged [static_mut_refs]
         }
     }
 
diff --git a/tests/ui/drop/issue-23611-enum-swap-in-drop.stderr b/tests/ui/drop/issue-23611-enum-swap-in-drop.stderr
deleted file mode 100644
index 6da87416802..00000000000
--- a/tests/ui/drop/issue-23611-enum-swap-in-drop.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-warning: creating a shared reference to mutable static is discouraged
-  --> $DIR/issue-23611-enum-swap-in-drop.rs:189:31
-   |
-LL |             (mem::size_of_val(&trails) * 8) as u32
-   |                               ^^^^^^^ shared reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-   = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |             (mem::size_of_val(addr_of!(trails)) * 8) as u32
-   |                               ~~~~~~~~~      +
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/drop/issue-48962.rs b/tests/ui/drop/issue-48962.rs
index 428a6ca6cd2..98d3af49ac1 100644
--- a/tests/ui/drop/issue-48962.rs
+++ b/tests/ui/drop/issue-48962.rs
@@ -1,6 +1,9 @@
 //@ run-pass
 #![allow(unused_must_use)]
 // Test that we are able to reinitialize box with moved referent
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 static mut ORDER: [usize; 3] = [0, 0, 0];
 static mut INDEX: usize = 0;
 
diff --git a/tests/ui/drop/repeat-drop.rs b/tests/ui/drop/repeat-drop.rs
index b83bee8c1bf..7488d9113b0 100644
--- a/tests/ui/drop/repeat-drop.rs
+++ b/tests/ui/drop/repeat-drop.rs
@@ -3,6 +3,9 @@
 
 #![allow(dropping_references, dropping_copy_types)]
 
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
+
 static mut CHECK: usize = 0;
 
 struct DropChecker(usize);
diff --git a/tests/ui/issues/issue-17302.rs b/tests/ui/drop/static-issue-17302.rs
index c499cc5281f..060f5564efd 100644
--- a/tests/ui/issues/issue-17302.rs
+++ b/tests/ui/drop/static-issue-17302.rs
@@ -1,5 +1,8 @@
 //@ run-pass
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 static mut DROPPED: [bool; 2] = [false, false];
 
 struct A(usize);
diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs b/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs
new file mode 100644
index 00000000000..8d36981b41b
--- /dev/null
+++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive.rs
@@ -0,0 +1,19 @@
+// Here, there are two types with the same name. One of these has a `derive` annotation, but in the
+// expansion these `impl`s are associated to the the *other* type. There is a suggestion to remove
+// unneded type parameters, but because we're now point at a type with no type parameters, the
+// suggestion would suggest removing code from an empty span, which would ICE in nightly.
+//
+// issue: rust-lang/rust#108748
+
+struct NotSM;
+
+#[derive(PartialEq, Eq)]
+//~^ ERROR struct takes 0 generic arguments
+//~| ERROR struct takes 0 generic arguments
+//~| ERROR struct takes 0 generic arguments
+//~| ERROR struct takes 0 generic arguments
+struct NotSM<T>(T);
+//~^ ERROR the name `NotSM` is defined multiple times
+//~| ERROR no field `0`
+
+fn main() {}
diff --git a/tests/ui/duplicate/multiple-types-with-same-name-and-derive.stderr b/tests/ui/duplicate/multiple-types-with-same-name-and-derive.stderr
new file mode 100644
index 00000000000..32c3cf44031
--- /dev/null
+++ b/tests/ui/duplicate/multiple-types-with-same-name-and-derive.stderr
@@ -0,0 +1,71 @@
+error[E0428]: the name `NotSM` is defined multiple times
+  --> $DIR/multiple-types-with-same-name-and-derive.rs:15:1
+   |
+LL | struct NotSM;
+   | ------------- previous definition of the type `NotSM` here
+...
+LL | struct NotSM<T>(T);
+   | ^^^^^^^^^^^^^^^^^^^ `NotSM` redefined here
+   |
+   = note: `NotSM` must be defined only once in the type namespace of this module
+
+error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/multiple-types-with-same-name-and-derive.rs:10:10
+   |
+LL | #[derive(PartialEq, Eq)]
+   |          ^^^^^^^^^ expected 0 generic arguments
+   |
+note: struct defined here, with 0 generic parameters
+  --> $DIR/multiple-types-with-same-name-and-derive.rs:8:8
+   |
+LL | struct NotSM;
+   |        ^^^^^
+
+error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/multiple-types-with-same-name-and-derive.rs:10:10
+   |
+LL | #[derive(PartialEq, Eq)]
+   |          ^^^^^^^^^ expected 0 generic arguments
+   |
+note: struct defined here, with 0 generic parameters
+  --> $DIR/multiple-types-with-same-name-and-derive.rs:8:8
+   |
+LL | struct NotSM;
+   |        ^^^^^
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/multiple-types-with-same-name-and-derive.rs:10:21
+   |
+LL | #[derive(PartialEq, Eq)]
+   |                     ^^ expected 0 generic arguments
+   |
+note: struct defined here, with 0 generic parameters
+  --> $DIR/multiple-types-with-same-name-and-derive.rs:8:8
+   |
+LL | struct NotSM;
+   |        ^^^^^
+
+error[E0107]: struct takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/multiple-types-with-same-name-and-derive.rs:10:10
+   |
+LL | #[derive(PartialEq, Eq)]
+   |          ^^^^^^^^^ expected 0 generic arguments
+   |
+note: struct defined here, with 0 generic parameters
+  --> $DIR/multiple-types-with-same-name-and-derive.rs:8:8
+   |
+LL | struct NotSM;
+   |        ^^^^^
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0609]: no field `0` on type `&NotSM`
+  --> $DIR/multiple-types-with-same-name-and-derive.rs:15:17
+   |
+LL | struct NotSM<T>(T);
+   |                 ^ unknown field
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0107, E0428, E0609.
+For more information about an error, try `rustc --explain E0107`.
diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs
new file mode 100644
index 00000000000..d694531d53a
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.rs
@@ -0,0 +1,15 @@
+#![allow(dead_code, incomplete_features)]
+
+use std::pin::Pin;
+
+struct Foo;
+
+fn foo(_: Pin<&mut Foo>) {
+}
+
+fn bar(mut x: Pin<&mut Foo>) {
+    foo(x);
+    foo(x); //~ ERROR use of moved value: `x`
+}
+
+fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr
new file mode 100644
index 00000000000..6c9029d8176
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-pin_ergonomics.stderr
@@ -0,0 +1,21 @@
+error[E0382]: use of moved value: `x`
+  --> $DIR/feature-gate-pin_ergonomics.rs:12:9
+   |
+LL | fn bar(mut x: Pin<&mut Foo>) {
+   |        ----- move occurs because `x` has type `Pin<&mut Foo>`, which does not implement the `Copy` trait
+LL |     foo(x);
+   |         - value moved here
+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:7:11
+   |
+LL | fn foo(_: Pin<&mut Foo>) {
+   |    ---    ^^^^^^^^^^^^^ this parameter takes ownership of the value
+   |    |
+   |    in this function
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs
index ca60bc62b51..afffb3b1443 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs
+++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.rs
@@ -164,4 +164,28 @@ mod repr {
     //~| NOTE not a struct, enum, or union
 }
 
+
+#[repr(Rust)]
+//~^ ERROR: attribute should be applied to a struct, enum, or union
+mod repr_rust {
+//~^ NOTE not a struct, enum, or union
+    mod inner { #![repr(Rust)] }
+    //~^ ERROR: attribute should be applied to a struct, enum, or union
+    //~| NOTE not a struct, enum, or union
+
+    #[repr(Rust)] fn f() { }
+    //~^ ERROR: attribute should be applied to a struct, enum, or union
+    //~| NOTE not a struct, enum, or union
+
+    struct S;
+
+    #[repr(Rust)] type T = S;
+    //~^ ERROR: attribute should be applied to a struct, enum, or union
+    //~| NOTE not a struct, enum, or union
+
+    #[repr(Rust)] impl S { }
+    //~^ ERROR: attribute should be applied to a struct, enum, or union
+    //~| NOTE not a struct, enum, or union
+}
+
 fn main() {}
diff --git a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr
index ac2bf78157d..fe764ff4925 100644
--- a/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr
+++ b/tests/ui/feature-gates/issue-43106-gating-of-builtin-attrs-error.stderr
@@ -107,6 +107,21 @@ LL | |
 LL | | }
    | |_- not a struct, enum, or union
 
+error[E0517]: attribute should be applied to a struct, enum, or union
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:168:8
+   |
+LL |   #[repr(Rust)]
+   |          ^^^^
+LL |
+LL | / mod repr_rust {
+LL | |
+LL | |     mod inner { #![repr(Rust)] }
+LL | |
+...  |
+LL | |
+LL | | }
+   | |_- not a struct, enum, or union
+
 error: attribute should be applied to an `extern crate` item
   --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:26:1
    |
@@ -329,7 +344,31 @@ error[E0517]: attribute should be applied to a struct, enum, or union
 LL |     #[repr(C)] impl S { }
    |            ^   ---------- not a struct, enum, or union
 
-error: aborting due to 39 previous errors
+error[E0517]: attribute should be applied to a struct, enum, or union
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:172:25
+   |
+LL |     mod inner { #![repr(Rust)] }
+   |     --------------------^^^^---- not a struct, enum, or union
+
+error[E0517]: attribute should be applied to a struct, enum, or union
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:176:12
+   |
+LL |     #[repr(Rust)] fn f() { }
+   |            ^^^^   ---------- not a struct, enum, or union
+
+error[E0517]: attribute should be applied to a struct, enum, or union
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:182:12
+   |
+LL |     #[repr(Rust)] type T = S;
+   |            ^^^^   ----------- not a struct, enum, or union
+
+error[E0517]: attribute should be applied to a struct, enum, or union
+  --> $DIR/issue-43106-gating-of-builtin-attrs-error.rs:186:12
+   |
+LL |     #[repr(Rust)] impl S { }
+   |            ^^^^   ---------- not a struct, enum, or union
+
+error: aborting due to 44 previous errors
 
 Some errors have detailed explanations: E0517, E0518, E0658.
 For more information about an error, try `rustc --explain E0517`.
diff --git a/tests/ui/for-loop-while/cleanup-rvalue-during-if-and-while.rs b/tests/ui/for-loop-while/cleanup-rvalue-during-if-and-while.rs
index fef9f24d462..57e8b228649 100644
--- a/tests/ui/for-loop-while/cleanup-rvalue-during-if-and-while.rs
+++ b/tests/ui/for-loop-while/cleanup-rvalue-during-if-and-while.rs
@@ -2,6 +2,9 @@
 // This test verifies that temporaries created for `while`'s and `if`
 // conditions are dropped after the condition is evaluated.
 
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
+
 struct Temporary;
 
 static mut DROPPED: isize = 0;
diff --git a/tests/ui/functional-struct-update/functional-struct-update-respects-privacy.rs b/tests/ui/functional-struct-update/functional-struct-update-respects-privacy.rs
index 500633edf12..a05d20ffbd2 100644
--- a/tests/ui/functional-struct-update/functional-struct-update-respects-privacy.rs
+++ b/tests/ui/functional-struct-update/functional-struct-update-respects-privacy.rs
@@ -2,6 +2,10 @@
 
 // The `foo` module attempts to maintains an invariant that each `S`
 // has a unique `u64` id.
+
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use self::foo::S;
 mod foo {
     use std::cell::{UnsafeCell};
diff --git a/tests/ui/functional-struct-update/functional-struct-update-respects-privacy.stderr b/tests/ui/functional-struct-update/functional-struct-update-respects-privacy.stderr
index 692d98bc53c..8924800ef27 100644
--- a/tests/ui/functional-struct-update/functional-struct-update-respects-privacy.stderr
+++ b/tests/ui/functional-struct-update/functional-struct-update-respects-privacy.stderr
@@ -1,5 +1,5 @@
 error[E0451]: field `secret_uid` of struct `S` is private
-  --> $DIR/functional-struct-update-respects-privacy.rs:28:49
+  --> $DIR/functional-struct-update-respects-privacy.rs:32:49
    |
 LL |     let s_2 = foo::S { b: format!("ess two"), ..s_1 }; // FRU ...
    |                                                 ^^^ field `secret_uid` is private
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
index c14021e009b..9831348de75 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions1.stderr
@@ -3,6 +3,17 @@ error: expected a pattern range bound, found an expression
    |
 LL |             0..5+1 => errors_only.push(x),
    |                ^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider extracting the expression into a `const`
+   |
+LL +         const VAL: /* Type */ = 5+1;
+LL ~         match x as i32 {
+LL ~             0..VAL => errors_only.push(x),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |             0..const { 5+1 } => errors_only.push(x),
+   |                +++++++     +
 
 error[E0408]: variable `n` is not bound in all patterns
   --> $DIR/range_pat_interactions1.rs:10:25
diff --git a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
index 136296fa5b0..1b5e875cccb 100644
--- a/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
+++ b/tests/ui/half-open-range-patterns/range_pat_interactions2.stderr
@@ -1,9 +1,3 @@
-error: expected a pattern range bound, found an expression
-  --> $DIR/range_pat_interactions2.rs:10:18
-   |
-LL |             0..=(5+1) => errors_only.push(x),
-   |                  ^^^ arbitrary expressions are not allowed in patterns
-
 error: range pattern bounds cannot have parentheses
   --> $DIR/range_pat_interactions2.rs:10:17
    |
@@ -16,6 +10,23 @@ LL -             0..=(5+1) => errors_only.push(x),
 LL +             0..=5+1 => errors_only.push(x),
    |
 
+error: expected a pattern range bound, found an expression
+  --> $DIR/range_pat_interactions2.rs:10:18
+   |
+LL |             0..=(5+1) => errors_only.push(x),
+   |                  ^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider extracting the expression into a `const`
+   |
+LL +         const VAL: /* Type */ = 5+1;
+LL ~         match x as i32 {
+LL ~             0..=(VAL) => errors_only.push(x),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |             0..=(const { 5+1 }) => errors_only.push(x),
+   |                  +++++++     +
+
 error[E0658]: inline-const in pattern position is experimental
   --> $DIR/range_pat_interactions2.rs:15:20
    |
diff --git a/tests/ui/impl-trait/issues/issue-62742.rs b/tests/ui/impl-trait/issues/issue-62742.rs
index 56c63a1daa8..c64278c2c5b 100644
--- a/tests/ui/impl-trait/issues/issue-62742.rs
+++ b/tests/ui/impl-trait/issues/issue-62742.rs
@@ -2,7 +2,8 @@ use std::marker::PhantomData;
 
 fn a() {
     WrongImpl::foo(0i32);
-    //~^ ERROR overflow assigning `_` to `[_]`
+    //~^ ERROR the function or associated item `foo` exists for struct `SafeImpl<_, RawImpl<_>>`, but its trait bounds were not satisfied
+    //~| ERROR the trait bound `RawImpl<_>: Raw<_>` is not satisfied
 }
 
 fn b() {
diff --git a/tests/ui/impl-trait/issues/issue-62742.stderr b/tests/ui/impl-trait/issues/issue-62742.stderr
index 7a1bcfc70d5..94822e41ccd 100644
--- a/tests/ui/impl-trait/issues/issue-62742.stderr
+++ b/tests/ui/impl-trait/issues/issue-62742.stderr
@@ -1,11 +1,43 @@
-error[E0275]: overflow assigning `_` to `[_]`
+error[E0599]: the function or associated item `foo` exists for struct `SafeImpl<_, RawImpl<_>>`, but its trait bounds were not satisfied
   --> $DIR/issue-62742.rs:4:16
    |
 LL |     WrongImpl::foo(0i32);
-   |                ^^^
+   |                ^^^ function or associated item cannot be called on `SafeImpl<_, RawImpl<_>>` due to unsatisfied trait bounds
+...
+LL | pub struct RawImpl<T>(PhantomData<T>);
+   | --------------------- doesn't satisfy `RawImpl<_>: Raw<_>`
+...
+LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
+   | ----------------------------------------- function or associated item `foo` not found for this struct
+   |
+note: trait bound `RawImpl<_>: Raw<_>` was not satisfied
+  --> $DIR/issue-62742.rs:35:20
+   |
+LL | impl<T: ?Sized, A: Raw<T>> SafeImpl<T, A> {
+   |                    ^^^^^^  --------------
+   |                    |
+   |                    unsatisfied trait bound introduced here
+note: the trait `Raw` must be implemented
+  --> $DIR/issue-62742.rs:19:1
+   |
+LL | pub trait Raw<T: ?Sized> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0277]: the trait bound `RawImpl<_>: Raw<_>` is not satisfied
+  --> $DIR/issue-62742.rs:4:5
+   |
+LL |     WrongImpl::foo(0i32);
+   |     ^^^^^^^^^ the trait `Raw<_>` is not implemented for `RawImpl<_>`
+   |
+   = help: the trait `Raw<[_]>` is implemented for `RawImpl<_>`
+note: required by a bound in `SafeImpl`
+  --> $DIR/issue-62742.rs:33:35
+   |
+LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
+   |                                   ^^^^^^ required by this bound in `SafeImpl`
 
 error[E0599]: the function or associated item `foo` exists for struct `SafeImpl<(), RawImpl<()>>`, but its trait bounds were not satisfied
-  --> $DIR/issue-62742.rs:9:22
+  --> $DIR/issue-62742.rs:10:22
    |
 LL |     WrongImpl::<()>::foo(0i32);
    |                      ^^^ function or associated item cannot be called on `SafeImpl<(), RawImpl<()>>` due to unsatisfied trait bounds
@@ -17,20 +49,20 @@ LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
    | ----------------------------------------- function or associated item `foo` not found for this struct
    |
 note: trait bound `RawImpl<()>: Raw<()>` was not satisfied
-  --> $DIR/issue-62742.rs:34:20
+  --> $DIR/issue-62742.rs:35:20
    |
 LL | impl<T: ?Sized, A: Raw<T>> SafeImpl<T, A> {
    |                    ^^^^^^  --------------
    |                    |
    |                    unsatisfied trait bound introduced here
 note: the trait `Raw` must be implemented
-  --> $DIR/issue-62742.rs:18:1
+  --> $DIR/issue-62742.rs:19:1
    |
 LL | pub trait Raw<T: ?Sized> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `RawImpl<()>: Raw<()>` is not satisfied
-  --> $DIR/issue-62742.rs:9:5
+  --> $DIR/issue-62742.rs:10:5
    |
 LL |     WrongImpl::<()>::foo(0i32);
    |     ^^^^^^^^^^^^^^^ the trait `Raw<()>` is not implemented for `RawImpl<()>`
@@ -38,12 +70,12 @@ LL |     WrongImpl::<()>::foo(0i32);
    = help: the trait `Raw<[()]>` is implemented for `RawImpl<()>`
    = help: for that trait implementation, expected `[()]`, found `()`
 note: required by a bound in `SafeImpl`
-  --> $DIR/issue-62742.rs:32:35
+  --> $DIR/issue-62742.rs:33:35
    |
 LL | pub struct SafeImpl<T: ?Sized, A: Raw<T>>(PhantomData<(A, T)>);
    |                                   ^^^^^^ required by this bound in `SafeImpl`
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0275, E0277, E0599.
-For more information about an error, try `rustc --explain E0275`.
+Some errors have detailed explanations: E0277, E0599.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/opaque-hidden-inferred-rpitit.rs b/tests/ui/impl-trait/opaque-hidden-inferred-rpitit.rs
new file mode 100644
index 00000000000..1582cca5cd2
--- /dev/null
+++ b/tests/ui/impl-trait/opaque-hidden-inferred-rpitit.rs
@@ -0,0 +1,16 @@
+//@ check-pass
+
+// Make sure that the `opaque_hidden_inferred_bound` lint doesn't fire on
+// RPITITs with no hidden type.
+
+trait T0 {}
+
+trait T1 {
+    type A: Send;
+}
+
+trait T2 {
+    fn foo() -> impl T1<A = ((), impl T0)>;
+}
+
+fn main() {}
diff --git a/tests/ui/inference/need_type_info/type-alias-indirect.stderr b/tests/ui/inference/need_type_info/type-alias-indirect.stderr
index 5c5b4c149c1..535c0044aec 100644
--- a/tests/ui/inference/need_type_info/type-alias-indirect.stderr
+++ b/tests/ui/inference/need_type_info/type-alias-indirect.stderr
@@ -2,7 +2,7 @@ error[E0282]: type annotations needed
   --> $DIR/type-alias-indirect.rs:14:5
    |
 LL |     IndirectAlias::new();
-   |     ^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
+   |     ^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/inference/need_type_info/type-alias.stderr b/tests/ui/inference/need_type_info/type-alias.stderr
index fd9bcf2fe3f..2c39a3f5646 100644
--- a/tests/ui/inference/need_type_info/type-alias.stderr
+++ b/tests/ui/inference/need_type_info/type-alias.stderr
@@ -2,19 +2,19 @@ error[E0282]: type annotations needed
   --> $DIR/type-alias.rs:12:5
    |
 LL |     DirectAlias::new()
-   |     ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `DirectAlias`
+   |     ^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
 
 error[E0282]: type annotations needed
   --> $DIR/type-alias.rs:18:5
    |
 LL |     IndirectAlias::new();
-   |     ^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
+   |     ^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `IndirectAlias`
 
 error[E0282]: type annotations needed
   --> $DIR/type-alias.rs:32:5
    |
 LL |     DirectButWithDefaultAlias::new();
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T` declared on the type alias `DirectButWithDefaultAlias`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for type parameter `T`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/instrument-coverage/mcdc-condition-limit.bad.stderr b/tests/ui/instrument-coverage/mcdc-condition-limit.bad.stderr
index 15fa3f6ee11..b8b7d6e1a5e 100644
--- a/tests/ui/instrument-coverage/mcdc-condition-limit.bad.stderr
+++ b/tests/ui/instrument-coverage/mcdc-condition-limit.bad.stderr
@@ -1,5 +1,5 @@
 warning: number of conditions in decision (7) exceeds limit (6), so MC/DC analysis will not count this expression
-  --> $DIR/mcdc-condition-limit.rs:29:8
+  --> $DIR/mcdc-condition-limit.rs:28:8
    |
 LL |     if a && b && c && d && e && f && g {
    |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/instrument-coverage/mcdc-condition-limit.rs b/tests/ui/instrument-coverage/mcdc-condition-limit.rs
index eb19ddec78f..91ff6381df7 100644
--- a/tests/ui/instrument-coverage/mcdc-condition-limit.rs
+++ b/tests/ui/instrument-coverage/mcdc-condition-limit.rs
@@ -1,5 +1,4 @@
 //@ edition: 2021
-//@ min-llvm-version: 18
 //@ revisions: good bad
 //@ check-pass
 //@ compile-flags: -Cinstrument-coverage -Zcoverage-options=mcdc -Zno-profiler-runtime
diff --git a/tests/ui/invalid-compile-flags/print-without-arg.rs b/tests/ui/invalid-compile-flags/print-without-arg.rs
new file mode 100644
index 00000000000..a762cb22275
--- /dev/null
+++ b/tests/ui/invalid-compile-flags/print-without-arg.rs
@@ -0,0 +1 @@
+//@ compile-flags: --print
diff --git a/tests/ui/invalid-compile-flags/print-without-arg.stderr b/tests/ui/invalid-compile-flags/print-without-arg.stderr
new file mode 100644
index 00000000000..a18d2779cad
--- /dev/null
+++ b/tests/ui/invalid-compile-flags/print-without-arg.stderr
@@ -0,0 +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]
+                               Compiler information to print on stdout
+
diff --git a/tests/ui/issues/issue-10734.rs b/tests/ui/issues/issue-10734.rs
index 8daa401748c..6d815aeca07 100644
--- a/tests/ui/issues/issue-10734.rs
+++ b/tests/ui/issues/issue-10734.rs
@@ -1,6 +1,9 @@
 //@ run-pass
 #![allow(non_upper_case_globals)]
 
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
+
 static mut drop_count: usize = 0;
 
 struct Foo {
diff --git a/tests/ui/issues/issue-15858.rs b/tests/ui/issues/issue-15858.rs
index 2d4aac01fbe..27887d49e3e 100644
--- a/tests/ui/issues/issue-15858.rs
+++ b/tests/ui/issues/issue-15858.rs
@@ -1,4 +1,6 @@
 //@ run-pass
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
 static mut DROP_RAN: bool = false;
 
 trait Bar {
diff --git a/tests/ui/issues/issue-15858.stderr b/tests/ui/issues/issue-15858.stderr
index f36bcc21bd7..0c082cc0862 100644
--- a/tests/ui/issues/issue-15858.stderr
+++ b/tests/ui/issues/issue-15858.stderr
@@ -1,5 +1,5 @@
 warning: method `do_something` is never used
-  --> $DIR/issue-15858.rs:5:8
+  --> $DIR/issue-15858.rs:7:8
    |
 LL | trait Bar {
    |       --- method in this trait
diff --git a/tests/ui/issues/issue-16151.rs b/tests/ui/issues/issue-16151.rs
index 20a3b5a04da..b18108e0a8a 100644
--- a/tests/ui/issues/issue-16151.rs
+++ b/tests/ui/issues/issue-16151.rs
@@ -1,5 +1,8 @@
 //@ run-pass
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 use std::mem;
 
 static mut DROP_COUNT: usize = 0;
diff --git a/tests/ui/issues/issue-39367.rs b/tests/ui/issues/issue-39367.rs
index dd16d4da1bd..937d6c4b9e0 100644
--- a/tests/ui/issues/issue-39367.rs
+++ b/tests/ui/issues/issue-39367.rs
@@ -20,6 +20,7 @@ fn arena() -> &'static ArenaSet<Vec<u8>> {
 
             static mut ONCE: Once = Once::new();
             ONCE.call_once(|| {
+            //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
                 DATA = transmute
                     ::<Box<ArenaSet<Vec<u8>>>, *const ArenaSet<Vec<u8>>>
                     (Box::new(__static_ref_initialize()));
diff --git a/tests/ui/issues/issue-39367.stderr b/tests/ui/issues/issue-39367.stderr
new file mode 100644
index 00000000000..333c9f9634a
--- /dev/null
+++ b/tests/ui/issues/issue-39367.stderr
@@ -0,0 +1,17 @@
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/issue-39367.rs:22:13
+   |
+LL | /             ONCE.call_once(|| {
+LL | |
+LL | |                 DATA = transmute
+LL | |                     ::<Box<ArenaSet<Vec<u8>>>, *const ArenaSet<Vec<u8>>>
+LL | |                     (Box::new(__static_ref_initialize()));
+LL | |             });
+   | |______________^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+   = note: `#[warn(static_mut_refs)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/issues/issue-4734.rs b/tests/ui/issues/issue-4734.rs
index 938d7064789..58aa0179693 100644
--- a/tests/ui/issues/issue-4734.rs
+++ b/tests/ui/issues/issue-4734.rs
@@ -3,7 +3,8 @@
 // Ensures that destructors are run for expressions of the form "e;" where
 // `e` is a type which requires a destructor.
 
-
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
 #![allow(path_statements)]
 
 struct A { n: isize }
diff --git a/tests/ui/issues/issue-54410.rs b/tests/ui/issues/issue-54410.rs
index 208be6f221c..e3e8ca985b9 100644
--- a/tests/ui/issues/issue-54410.rs
+++ b/tests/ui/issues/issue-54410.rs
@@ -5,5 +5,4 @@ extern "C" {
 
 fn main() {
     println!("{:p}", unsafe { &symbol });
-    //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
 }
diff --git a/tests/ui/issues/issue-54410.stderr b/tests/ui/issues/issue-54410.stderr
index 6cc5cd95e2f..97e5990750e 100644
--- a/tests/ui/issues/issue-54410.stderr
+++ b/tests/ui/issues/issue-54410.stderr
@@ -6,21 +6,6 @@ LL |     pub static mut symbol: [i8];
    |
    = help: the trait `Sized` is not implemented for `[i8]`
 
-warning: creating a shared reference to mutable static is discouraged
-  --> $DIR/issue-54410.rs:7:31
-   |
-LL |     println!("{:p}", unsafe { &symbol });
-   |                               ^^^^^^^ shared reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-   = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |     println!("{:p}", unsafe { addr_of!(symbol) });
-   |                               ~~~~~~~~~      +
-
-error: aborting due to 1 previous error; 1 warning emitted
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/issues/issue-6892.rs b/tests/ui/issues/issue-6892.rs
index aff00cf60ba..7d99aef4ac5 100644
--- a/tests/ui/issues/issue-6892.rs
+++ b/tests/ui/issues/issue-6892.rs
@@ -3,6 +3,8 @@
 // Ensures that destructors are run for expressions of the form "let _ = e;"
 // where `e` is a type which requires a destructor.
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
 
 struct Foo;
 struct Bar { x: isize }
diff --git a/tests/ui/issues/issue-8860.rs b/tests/ui/issues/issue-8860.rs
index 67e9a276ae4..3af61576fe1 100644
--- a/tests/ui/issues/issue-8860.rs
+++ b/tests/ui/issues/issue-8860.rs
@@ -1,4 +1,6 @@
 //@ run-pass
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
 #![allow(dead_code)]
 
 static mut DROP: isize = 0;
diff --git a/tests/ui/link-section.rs b/tests/ui/link-section.rs
index 1a791b88ef9..a8de8c2e1e7 100644
--- a/tests/ui/link-section.rs
+++ b/tests/ui/link-section.rs
@@ -1,5 +1,8 @@
 //@ run-pass
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 #![allow(non_upper_case_globals)]
 #[cfg(not(target_vendor = "apple"))]
 #[link_section = ".moretext"]
diff --git a/tests/ui/linkage-attr/linkage-attr-mutable-static.rs b/tests/ui/linkage-attr/linkage-attr-mutable-static.rs
index ed11947f59e..cc93f61e28f 100644
--- a/tests/ui/linkage-attr/linkage-attr-mutable-static.rs
+++ b/tests/ui/linkage-attr/linkage-attr-mutable-static.rs
@@ -2,6 +2,8 @@
 //! them at runtime, so deny mutable statics with #[linkage].
 
 #![feature(linkage)]
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
 
 fn main() {
     #[rustfmt::skip]
diff --git a/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr b/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr
index ad999769047..50d5d812196 100644
--- a/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr
+++ b/tests/ui/linkage-attr/linkage-attr-mutable-static.stderr
@@ -1,5 +1,5 @@
 error: extern mutable statics are not allowed with `#[linkage]`
-  --> $DIR/linkage-attr-mutable-static.rs:9:9
+  --> $DIR/linkage-attr-mutable-static.rs:11:9
    |
 LL |         #[linkage = "extern_weak"]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/improper-types-stack-overflow-130310.rs b/tests/ui/lint/improper-types-stack-overflow-130310.rs
new file mode 100644
index 00000000000..60eb8739817
--- /dev/null
+++ b/tests/ui/lint/improper-types-stack-overflow-130310.rs
@@ -0,0 +1,20 @@
+// Regression test for #130310
+// Tests that we do not fall into infinite
+// recursion while checking FFI safety of
+// recursive types like `A<T>` below
+
+//@ build-pass
+use std::marker::PhantomData;
+
+#[repr(C)]
+struct A<T> {
+    a: *const A<A<T>>, // Recursive because of this field
+    p: PhantomData<T>,
+}
+
+extern "C" {
+    fn f(a: *const A<()>);
+    //~^ WARN `extern` block uses type `*const A<()>`, which is not FFI-safe
+}
+
+fn main() {}
diff --git a/tests/ui/lint/improper-types-stack-overflow-130310.stderr b/tests/ui/lint/improper-types-stack-overflow-130310.stderr
new file mode 100644
index 00000000000..6981bb25755
--- /dev/null
+++ b/tests/ui/lint/improper-types-stack-overflow-130310.stderr
@@ -0,0 +1,11 @@
+warning: `extern` block uses type `*const A<()>`, which is not FFI-safe
+  --> $DIR/improper-types-stack-overflow-130310.rs:16:13
+   |
+LL |     fn f(a: *const A<()>);
+   |             ^^^^^^^^^^^^ not FFI-safe
+   |
+   = note: type is infinitely recursive
+   = note: `#[warn(improper_ctypes)]` on by default
+
+warning: 1 warning emitted
+
diff --git a/tests/ui/lint/static-mut-refs.e2021.stderr b/tests/ui/lint/static-mut-refs.e2021.stderr
new file mode 100644
index 00000000000..09f560652e7
--- /dev/null
+++ b/tests/ui/lint/static-mut-refs.e2021.stderr
@@ -0,0 +1,143 @@
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:39:18
+   |
+LL |         let _y = &X;
+   |                  ^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+   = note: `#[warn(static_mut_refs)]` on by default
+help: use `&raw const` instead to create a raw pointer
+   |
+LL |         let _y = &raw const X;
+   |                  ~~~~~~~~~~
+
+warning: creating a mutable reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:43:18
+   |
+LL |         let _y = &mut X;
+   |                  ^^^^^^ mutable reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
+help: use `&raw mut` instead to create a raw pointer
+   |
+LL |         let _y = &raw mut X;
+   |                  ~~~~~~~~
+
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:51:22
+   |
+LL |         let ref _a = X;
+   |                      ^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:55:25
+   |
+LL |         let (_b, _c) = (&X, &Y);
+   |                         ^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+help: use `&raw const` instead to create a raw pointer
+   |
+LL |         let (_b, _c) = (&raw const X, &Y);
+   |                         ~~~~~~~~~~
+
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:55:29
+   |
+LL |         let (_b, _c) = (&X, &Y);
+   |                             ^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+help: use `&raw const` instead to create a raw pointer
+   |
+LL |         let (_b, _c) = (&X, &raw const Y);
+   |                             ~~~~~~~~~~
+
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:61:13
+   |
+LL |         foo(&X);
+   |             ^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+help: use `&raw const` instead to create a raw pointer
+   |
+LL |         foo(&raw const X);
+   |             ~~~~~~~~~~
+
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:67:17
+   |
+LL |         let _ = Z.len();
+   |                 ^^^^^^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:73:33
+   |
+LL |         let _ = format!("{:?}", Z);
+   |                                 ^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:77:18
+   |
+LL |         let _v = &A.value;
+   |                  ^^^^^^^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+help: use `&raw const` instead to create a raw pointer
+   |
+LL |         let _v = &raw const A.value;
+   |                  ~~~~~~~~~~
+
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:81:18
+   |
+LL |         let _s = &A.s.value;
+   |                  ^^^^^^^^^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+help: use `&raw const` instead to create a raw pointer
+   |
+LL |         let _s = &raw const A.s.value;
+   |                  ~~~~~~~~~~
+
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:85:22
+   |
+LL |         let ref _v = A.value;
+   |                      ^^^^^^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+
+warning: creating a mutable reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:15:14
+   |
+LL |         &mut ($x.0)
+   |              ^^^^^^ mutable reference to mutable static
+...
+LL |         let _x = bar!(FOO);
+   |                  --------- in this macro invocation
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
+   = note: this warning originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+warning: 12 warnings emitted
+
diff --git a/tests/ui/lint/static-mut-refs.e2024.stderr b/tests/ui/lint/static-mut-refs.e2024.stderr
new file mode 100644
index 00000000000..2d2a4f7afe0
--- /dev/null
+++ b/tests/ui/lint/static-mut-refs.e2024.stderr
@@ -0,0 +1,143 @@
+error: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:39:18
+   |
+LL |         let _y = &X;
+   |                  ^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+   = note: `#[deny(static_mut_refs)]` on by default
+help: use `&raw const` instead to create a raw pointer
+   |
+LL |         let _y = &raw const X;
+   |                  ~~~~~~~~~~
+
+error: creating a mutable reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:43:18
+   |
+LL |         let _y = &mut X;
+   |                  ^^^^^^ mutable reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
+help: use `&raw mut` instead to create a raw pointer
+   |
+LL |         let _y = &raw mut X;
+   |                  ~~~~~~~~
+
+error: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:51:22
+   |
+LL |         let ref _a = X;
+   |                      ^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+
+error: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:55:25
+   |
+LL |         let (_b, _c) = (&X, &Y);
+   |                         ^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+help: use `&raw const` instead to create a raw pointer
+   |
+LL |         let (_b, _c) = (&raw const X, &Y);
+   |                         ~~~~~~~~~~
+
+error: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:55:29
+   |
+LL |         let (_b, _c) = (&X, &Y);
+   |                             ^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+help: use `&raw const` instead to create a raw pointer
+   |
+LL |         let (_b, _c) = (&X, &raw const Y);
+   |                             ~~~~~~~~~~
+
+error: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:61:13
+   |
+LL |         foo(&X);
+   |             ^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+help: use `&raw const` instead to create a raw pointer
+   |
+LL |         foo(&raw const X);
+   |             ~~~~~~~~~~
+
+error: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:67:17
+   |
+LL |         let _ = Z.len();
+   |                 ^^^^^^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+
+error: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:73:33
+   |
+LL |         let _ = format!("{:?}", Z);
+   |                                 ^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+
+error: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:77:18
+   |
+LL |         let _v = &A.value;
+   |                  ^^^^^^^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+help: use `&raw const` instead to create a raw pointer
+   |
+LL |         let _v = &raw const A.value;
+   |                  ~~~~~~~~~~
+
+error: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:81:18
+   |
+LL |         let _s = &A.s.value;
+   |                  ^^^^^^^^^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+help: use `&raw const` instead to create a raw pointer
+   |
+LL |         let _s = &raw const A.s.value;
+   |                  ~~~~~~~~~~
+
+error: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:85:22
+   |
+LL |         let ref _v = A.value;
+   |                      ^^^^^^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+
+error: creating a mutable reference to mutable static is discouraged
+  --> $DIR/static-mut-refs.rs:15:14
+   |
+LL |         &mut ($x.0)
+   |              ^^^^^^ mutable reference to mutable static
+...
+LL |         let _x = bar!(FOO);
+   |                  --------- in this macro invocation
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
+   = note: this error originates in the macro `bar` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 12 previous errors
+
diff --git a/tests/ui/lint/static-mut-refs.rs b/tests/ui/lint/static-mut-refs.rs
new file mode 100644
index 00000000000..3d84d7dbf40
--- /dev/null
+++ b/tests/ui/lint/static-mut-refs.rs
@@ -0,0 +1,95 @@
+// Test `static_mut_refs` lint.
+
+//@ revisions: e2021 e2024
+
+//@ [e2021] edition:2021
+//@ [e2021] run-pass
+
+//@ [e2024] edition:2024
+//@ [e2024] compile-flags: -Zunstable-options
+
+static mut FOO: (u32, u32) = (1, 2);
+
+macro_rules! bar {
+    ($x:expr) => {
+        &mut ($x.0)
+        //[e2021]~^ WARN creating a mutable reference to mutable static is discouraged [static_mut_refs]
+        //[e2024]~^^ ERROR creating a mutable reference to mutable static is discouraged [static_mut_refs]
+    };
+}
+
+static mut STATIC: i64 = 1;
+
+fn main() {
+    static mut X: i32 = 1;
+
+    static mut Y: i32 = 1;
+
+    struct TheStruct {
+        pub value: i32,
+    }
+    struct MyStruct {
+        pub value: i32,
+        pub s: TheStruct,
+    }
+
+    static mut A: MyStruct = MyStruct { value: 1, s: TheStruct { value: 2 } };
+
+    unsafe {
+        let _y = &X;
+        //[e2021]~^ WARN shared reference to mutable static is discouraged [static_mut_refs]
+        //[e2024]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
+
+        let _y = &mut X;
+        //[e2021]~^ WARN mutable reference to mutable static is discouraged [static_mut_refs]
+        //[e2024]~^^ ERROR mutable reference to mutable static is discouraged [static_mut_refs]
+
+        let _z = &raw mut X;
+
+        let _p = &raw const X;
+
+        let ref _a = X;
+        //[e2021]~^ WARN shared reference to mutable static is discouraged [static_mut_refs]
+        //[e2024]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
+
+        let (_b, _c) = (&X, &Y);
+        //[e2021]~^ WARN shared reference to mutable static is discouraged [static_mut_refs]
+        //[e2024]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
+        //[e2021]~^^^ WARN shared reference to mutable static is discouraged [static_mut_refs]
+        //[e2024]~^^^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
+
+        foo(&X);
+        //[e2021]~^ WARN shared reference to mutable static is discouraged [static_mut_refs]
+        //[e2024]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
+
+        static mut Z: &[i32; 3] = &[0, 1, 2];
+
+        let _ = Z.len();
+        //[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
+        //[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs]
+
+        let _ = Z[0];
+
+        let _ = format!("{:?}", Z);
+        //[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
+        //[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs]
+
+        let _v = &A.value;
+        //[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
+        //[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs]
+
+        let _s = &A.s.value;
+        //[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
+        //[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs]
+
+        let ref _v = A.value;
+        //[e2021]~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
+        //[e2024]~^^ ERROR creating a shared reference to mutable static is discouraged [static_mut_refs]
+
+        let _x = bar!(FOO);
+
+        STATIC += 1;
+    }
+}
+
+fn foo<'a>(_x: &'a i32) {}
diff --git a/tests/ui/lto/lto-still-runs-thread-dtors.rs b/tests/ui/lto/lto-still-runs-thread-dtors.rs
index 504923a93c2..900368496eb 100644
--- a/tests/ui/lto/lto-still-runs-thread-dtors.rs
+++ b/tests/ui/lto/lto-still-runs-thread-dtors.rs
@@ -3,6 +3,9 @@
 //@ no-prefer-dynamic
 //@ needs-threads
 
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
+
 use std::thread;
 
 static mut HIT: usize = 0;
diff --git a/tests/ui/macros/auxiliary/metavar_2018.rs b/tests/ui/macros/auxiliary/metavar_2018.rs
new file mode 100644
index 00000000000..7e8523a9edf
--- /dev/null
+++ b/tests/ui/macros/auxiliary/metavar_2018.rs
@@ -0,0 +1,14 @@
+//@ edition: 2018
+#[macro_export]
+macro_rules! make_matcher {
+    ($name:ident, $fragment_type:ident, $d:tt) => {
+        #[macro_export]
+        macro_rules! $name {
+            ($d _:$fragment_type) => { true };
+            (const { 0 }) => { false };
+            (A | B) => { false };
+        }
+    };
+}
+make_matcher!(is_expr_from_2018, expr, $);
+make_matcher!(is_pat_from_2018, pat, $);
diff --git a/tests/ui/macros/metavar_cross_edition_recursive_macros.rs b/tests/ui/macros/metavar_cross_edition_recursive_macros.rs
new file mode 100644
index 00000000000..3eec1208b89
--- /dev/null
+++ b/tests/ui/macros/metavar_cross_edition_recursive_macros.rs
@@ -0,0 +1,38 @@
+//@ compile-flags: --edition=2024 -Z unstable-options
+//@ aux-build: metavar_2018.rs
+//@ known-bug: #130484
+//@ run-pass
+
+// This test captures the behavior of macro-generating-macros with fragment
+// specifiers across edition boundaries.
+
+#![feature(expr_fragment_specifier_2024)]
+#![feature(macro_metavar_expr)]
+#![allow(incomplete_features)]
+
+extern crate metavar_2018;
+
+use metavar_2018::{is_expr_from_2018, is_pat_from_2018, make_matcher};
+
+make_matcher!(is_expr_from_2024, expr, $);
+make_matcher!(is_pat_from_2024, pat, $);
+
+fn main() {
+    // Check expr
+    let from_2018 = is_expr_from_2018!(const { 0 });
+    dbg!(from_2018);
+    let from_2024 = is_expr_from_2024!(const { 0 });
+    dbg!(from_2024);
+
+    assert!(!from_2018);
+    assert!(!from_2024); // from_2024 will be true once #130484 is fixed
+
+    // Check pat
+    let from_2018 = is_pat_from_2018!(A | B);
+    dbg!(from_2018);
+    let from_2024 = is_pat_from_2024!(A | B);
+    dbg!(from_2024);
+
+    assert!(!from_2018);
+    assert!(!from_2024); // from_2024 will be true once #130484 is fixed
+}
diff --git a/tests/ui/methods/method-self-arg-trait.rs b/tests/ui/methods/method-self-arg-trait.rs
index 63594380753..ccffe02328b 100644
--- a/tests/ui/methods/method-self-arg-trait.rs
+++ b/tests/ui/methods/method-self-arg-trait.rs
@@ -1,6 +1,9 @@
 //@ run-pass
 // Test method calls with self as an argument
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 static mut COUNT: u64 = 1;
 
 #[derive(Copy, Clone)]
diff --git a/tests/ui/methods/method-self-arg.rs b/tests/ui/methods/method-self-arg.rs
index d26b9663fd0..2e058ee1077 100644
--- a/tests/ui/methods/method-self-arg.rs
+++ b/tests/ui/methods/method-self-arg.rs
@@ -1,6 +1,9 @@
 //@ run-pass
 // Test method calls with self as an argument
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 static mut COUNT: usize = 1;
 
 #[derive(Copy, Clone)]
diff --git a/tests/ui/methods/receiver-equality.rs b/tests/ui/methods/receiver-equality.rs
new file mode 100644
index 00000000000..891435a425e
--- /dev/null
+++ b/tests/ui/methods/receiver-equality.rs
@@ -0,0 +1,16 @@
+// Tests that we probe receivers invariantly when using path-based method lookup.
+
+struct B<T>(T);
+
+impl B<fn(&'static ())> {
+    fn method(self) {
+        println!("hey");
+    }
+}
+
+fn foo(y: B<fn(&'static ())>) {
+    B::<for<'a> fn(&'a ())>::method(y);
+    //~^ ERROR no function or associated item named `method` found
+}
+
+fn main() {}
diff --git a/tests/ui/methods/receiver-equality.stderr b/tests/ui/methods/receiver-equality.stderr
new file mode 100644
index 00000000000..cea3340e386
--- /dev/null
+++ b/tests/ui/methods/receiver-equality.stderr
@@ -0,0 +1,12 @@
+error[E0599]: no function or associated item named `method` found for struct `B<for<'a> fn(&'a ())>` in the current scope
+  --> $DIR/receiver-equality.rs:12:30
+   |
+LL | struct B<T>(T);
+   | ----------- function or associated item `method` not found for this struct
+...
+LL |     B::<for<'a> fn(&'a ())>::method(y);
+   |                              ^^^^^^ function or associated item not found in `B<fn(&())>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/mir/mir_early_return_scope.rs b/tests/ui/mir/mir_early_return_scope.rs
index 6dc3f8bc39b..42f1cc50d15 100644
--- a/tests/ui/mir/mir_early_return_scope.rs
+++ b/tests/ui/mir/mir_early_return_scope.rs
@@ -1,5 +1,7 @@
 //@ run-pass
 #![allow(unused_variables)]
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
 static mut DROP: bool = false;
 
 struct ConnWrap(Conn);
diff --git a/tests/ui/mismatched_types/mismatch-args-crash-issue-130400.rs b/tests/ui/mismatched_types/mismatch-args-crash-issue-130400.rs
new file mode 100644
index 00000000000..16c4e639c29
--- /dev/null
+++ b/tests/ui/mismatched_types/mismatch-args-crash-issue-130400.rs
@@ -0,0 +1,8 @@
+trait Bar {
+    fn foo(&mut self) -> _ {
+        //~^ ERROR the placeholder `_` is not allowed within types on item signatures for return types
+        Self::foo() //~ ERROR  this function takes 1 argument but 0 arguments were supplied
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/mismatched_types/mismatch-args-crash-issue-130400.stderr b/tests/ui/mismatched_types/mismatch-args-crash-issue-130400.stderr
new file mode 100644
index 00000000000..0e4b94b98e2
--- /dev/null
+++ b/tests/ui/mismatched_types/mismatch-args-crash-issue-130400.stderr
@@ -0,0 +1,26 @@
+error[E0061]: this function takes 1 argument but 0 arguments were supplied
+  --> $DIR/mismatch-args-crash-issue-130400.rs:4:9
+   |
+LL |         Self::foo()
+   |         ^^^^^^^^^-- argument #1 is missing
+   |
+note: method defined here
+  --> $DIR/mismatch-args-crash-issue-130400.rs:2:8
+   |
+LL |     fn foo(&mut self) -> _ {
+   |        ^^^ ---------
+help: provide the argument
+   |
+LL |         Self::foo(/* value */)
+   |                  ~~~~~~~~~~~~~
+
+error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types
+  --> $DIR/mismatch-args-crash-issue-130400.rs:2:26
+   |
+LL |     fn foo(&mut self) -> _ {
+   |                          ^ not allowed in type signatures
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0061, E0121.
+For more information about an error, try `rustc --explain E0061`.
diff --git a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr
index a6d4f9a2a5c..1f01d3e8260 100644
--- a/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr
+++ b/tests/ui/nll/borrowck-thread-local-static-mut-borrow-outlives-fn.stderr
@@ -4,14 +4,13 @@ warning: creating a mutable reference to mutable static is discouraged
 LL |         S1 { a: unsafe { &mut X1 } }
    |                          ^^^^^^^ mutable reference to mutable static
    |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
    = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of_mut!` instead to create a raw pointer
+help: use `&raw mut` instead to create a raw pointer
    |
-LL |         S1 { a: unsafe { addr_of_mut!(X1) } }
-   |                          ~~~~~~~~~~~~~  +
+LL |         S1 { a: unsafe { &raw mut X1 } }
+   |                          ~~~~~~~~
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/nll/issue-69114-static-mut-ty.rs b/tests/ui/nll/issue-69114-static-mut-ty.rs
index ce37da053e3..95c787488c0 100644
--- a/tests/ui/nll/issue-69114-static-mut-ty.rs
+++ b/tests/ui/nll/issue-69114-static-mut-ty.rs
@@ -1,5 +1,8 @@
 // Check that borrowck ensures that `static mut` items have the expected type.
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 static FOO: u8 = 42;
 static mut BAR: &'static u8 = &FOO;
 static mut BAR_ELIDED: &u8 = &FOO;
diff --git a/tests/ui/nll/issue-69114-static-mut-ty.stderr b/tests/ui/nll/issue-69114-static-mut-ty.stderr
index 1b41230d7ba..eebfdee2896 100644
--- a/tests/ui/nll/issue-69114-static-mut-ty.stderr
+++ b/tests/ui/nll/issue-69114-static-mut-ty.stderr
@@ -1,5 +1,5 @@
 error[E0597]: `n` does not live long enough
-  --> $DIR/issue-69114-static-mut-ty.rs:19:15
+  --> $DIR/issue-69114-static-mut-ty.rs:22:15
    |
 LL |     let n = 42;
    |         - binding `n` declared here
@@ -14,7 +14,7 @@ LL | }
    | - `n` dropped here while still borrowed
 
 error[E0597]: `n` does not live long enough
-  --> $DIR/issue-69114-static-mut-ty.rs:27:22
+  --> $DIR/issue-69114-static-mut-ty.rs:30:22
    |
 LL |     let n = 42;
    |         - binding `n` declared here
diff --git a/tests/ui/numbers-arithmetic/shift-near-oflo.rs b/tests/ui/numbers-arithmetic/shift-near-oflo.rs
index 5cca31af0e3..97227bd843f 100644
--- a/tests/ui/numbers-arithmetic/shift-near-oflo.rs
+++ b/tests/ui/numbers-arithmetic/shift-near-oflo.rs
@@ -1,6 +1,9 @@
 //@ run-pass
 //@ compile-flags: -C debug-assertions
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 // Check that we do *not* overflow on a number of edge cases.
 // (compare with test/run-fail/overflowing-{lsh,rsh}*.rs)
 
diff --git a/tests/ui/parser/bad-name.rs b/tests/ui/parser/bad-name.rs
index 59432a1d9a5..fefe9122a08 100644
--- a/tests/ui/parser/bad-name.rs
+++ b/tests/ui/parser/bad-name.rs
@@ -1,5 +1,6 @@
-//@ error-pattern: expected
-
 fn main() {
   let x.y::<isize>.z foo;
+  //~^ error: field expressions cannot have generic arguments
+  //~| error: expected a pattern, found an expression
+  //~| error: expected one of `(`, `.`, `::`, `:`, `;`, `=`, `?`, `|`, or an operator, found `foo`
 }
diff --git a/tests/ui/parser/bad-name.stderr b/tests/ui/parser/bad-name.stderr
index e133d4e4839..3fc416dd531 100644
--- a/tests/ui/parser/bad-name.stderr
+++ b/tests/ui/parser/bad-name.stderr
@@ -1,8 +1,20 @@
-error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
-  --> $DIR/bad-name.rs:4:8
+error: field expressions cannot have generic arguments
+  --> $DIR/bad-name.rs:2:12
    |
 LL |   let x.y::<isize>.z foo;
-   |        ^ expected one of `:`, `;`, `=`, `@`, or `|`
+   |            ^^^^^^^
 
-error: aborting due to 1 previous error
+error: expected a pattern, found an expression
+  --> $DIR/bad-name.rs:2:7
+   |
+LL |   let x.y::<isize>.z foo;
+   |       ^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected one of `(`, `.`, `::`, `:`, `;`, `=`, `?`, `|`, or an operator, found `foo`
+  --> $DIR/bad-name.rs:2:22
+   |
+LL |   let x.y::<isize>.z foo;
+   |                      ^^^ expected one of 9 possible tokens
+
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/parser/issues/issue-24375.stderr b/tests/ui/parser/issues/issue-24375.stderr
index e6ef07d13fd..a25c277d78a 100644
--- a/tests/ui/parser/issues/issue-24375.stderr
+++ b/tests/ui/parser/issues/issue-24375.stderr
@@ -3,6 +3,21 @@ error: expected a pattern, found an expression
    |
 LL |         tmp[0] => {}
    |         ^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == tmp[0] => {}
+   |         ~~~ ++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = tmp[0];
+LL ~     match z {
+LL ~         VAL => {}
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { tmp[0] } => {}
+   |         +++++++        +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr b/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr
index 00f372bc008..c2c0faa21d1 100644
--- a/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr
+++ b/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr
@@ -14,10 +14,6 @@ help: there is a keyword `mut` with a similar name
    |
 LL |     fn foo(&mut Self) {}
    |             ~~~
-help: declare the type after the parameter binding
-   |
-LL |     fn foo(<identifier>: <type>) {}
-   |            ~~~~~~~~~~~~~~~~~~~~
 
 error: unexpected lifetime `'static` in pattern
   --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:13
@@ -47,10 +43,6 @@ help: there is a keyword `mut` with a similar name
    |
 LL |     fn bar(&'static mut Self) {}
    |                     ~~~
-help: declare the type after the parameter binding
-   |
-LL |     fn bar(<identifier>: <type>) {}
-   |            ~~~~~~~~~~~~~~~~~~~~
 
 error: expected one of `:`, `@`, or `|`, found keyword `Self`
   --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:14:17
diff --git a/tests/ui/parser/misspelled-keywords/impl-trait.stderr b/tests/ui/parser/misspelled-keywords/impl-trait.stderr
index 15a8f99b8b1..02a0c808311 100644
--- a/tests/ui/parser/misspelled-keywords/impl-trait.stderr
+++ b/tests/ui/parser/misspelled-keywords/impl-trait.stderr
@@ -8,10 +8,6 @@ help: there is a keyword `impl` with a similar name
    |
 LL | fn code<T: impl Debug>() -> u8 {}
    |            ~~~~
-help: you might have meant to end the type parameters here
-   |
-LL | fn code<T: impll> Debug>() -> u8 {}
-   |                 +
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/misspelled-keywords/ref.stderr b/tests/ui/parser/misspelled-keywords/ref.stderr
index 3a79b7bdb00..b8b52702314 100644
--- a/tests/ui/parser/misspelled-keywords/ref.stderr
+++ b/tests/ui/parser/misspelled-keywords/ref.stderr
@@ -8,10 +8,6 @@ help: there is a keyword `ref` with a similar name
    |
 LL |         Some(ref list) => println!("{list:?}"),
    |              ~~~
-help: missing `,`
-   |
-LL |         Some(refe, list) => println!("{list:?}"),
-   |                  +
 
 error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
   --> $DIR/ref.rs:4:14
diff --git a/tests/ui/parser/pat-lt-bracket-6.stderr b/tests/ui/parser/pat-lt-bracket-6.stderr
index 10c638a63e4..892883c4aed 100644
--- a/tests/ui/parser/pat-lt-bracket-6.stderr
+++ b/tests/ui/parser/pat-lt-bracket-6.stderr
@@ -1,8 +1,8 @@
 error: expected a pattern, found an expression
-  --> $DIR/pat-lt-bracket-6.rs:5:15
+  --> $DIR/pat-lt-bracket-6.rs:5:14
    |
 LL |     let Test(&desc[..]) = x;
-   |               ^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |              ^^^^^^^^^ arbitrary expressions are not allowed in patterns
 
 error[E0308]: mismatched types
   --> $DIR/pat-lt-bracket-6.rs:10:30
diff --git a/tests/ui/parser/pat-recover-exprs.rs b/tests/ui/parser/pat-recover-exprs.rs
deleted file mode 100644
index ecd471467e3..00000000000
--- a/tests/ui/parser/pat-recover-exprs.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-fn main() {
-    match u8::MAX {
-        u8::MAX.abs() => (),
-        //~^ error: expected a pattern, found a method call
-        x.sqrt() @ .. => (),
-        //~^ error: expected a pattern, found a method call
-        //~| error: left-hand side of `@` must be a binding
-        z @ w @ v.u() => (),
-        //~^ error: expected a pattern, found a method call
-        y.ilog(3) => (),
-        //~^ error: expected a pattern, found a method call
-        n + 1 => (),
-        //~^ error: expected a pattern, found an expression
-        ("".f() + 14 * 8) => (),
-        //~^ error: expected a pattern, found an expression
-        0 | ((1) | 2) | 3 => (),
-        f?() => (),
-        //~^ error: expected a pattern, found an expression
-        (_ + 1) => (),
-        //~^ error: expected one of `)`, `,`, or `|`, found `+`
-    }
-
-    let 1 + 1 = 2;
-    //~^ error: expected a pattern, found an expression
-
-    let b = matches!(x, (x * x | x.f()) | x[0]);
-    //~^ error: expected one of `)`, `,`, `@`, or `|`, found `*`
-}
diff --git a/tests/ui/parser/pat-recover-exprs.stderr b/tests/ui/parser/pat-recover-exprs.stderr
deleted file mode 100644
index 787fd03b0c3..00000000000
--- a/tests/ui/parser/pat-recover-exprs.stderr
+++ /dev/null
@@ -1,76 +0,0 @@
-error: expected a pattern, found a method call
-  --> $DIR/pat-recover-exprs.rs:3:9
-   |
-LL |         u8::MAX.abs() => (),
-   |         ^^^^^^^^^^^^^ method calls are not allowed in patterns
-
-error: expected a pattern, found a method call
-  --> $DIR/pat-recover-exprs.rs:5:9
-   |
-LL |         x.sqrt() @ .. => (),
-   |         ^^^^^^^^ method calls are not allowed in patterns
-
-error: left-hand side of `@` must be a binding
-  --> $DIR/pat-recover-exprs.rs:5:9
-   |
-LL |         x.sqrt() @ .. => (),
-   |         --------^^^--
-   |         |          |
-   |         |          also a pattern
-   |         interpreted as a pattern, not a binding
-   |
-   = note: bindings are `x`, `mut x`, `ref x`, and `ref mut x`
-
-error: expected a pattern, found a method call
-  --> $DIR/pat-recover-exprs.rs:8:17
-   |
-LL |         z @ w @ v.u() => (),
-   |                 ^^^^^ method calls are not allowed in patterns
-
-error: expected a pattern, found a method call
-  --> $DIR/pat-recover-exprs.rs:10:9
-   |
-LL |         y.ilog(3) => (),
-   |         ^^^^^^^^^ method calls are not allowed in patterns
-
-error: expected a pattern, found an expression
-  --> $DIR/pat-recover-exprs.rs:12:9
-   |
-LL |         n + 1 => (),
-   |         ^^^^^ arbitrary expressions are not allowed in patterns
-
-error: expected a pattern, found an expression
-  --> $DIR/pat-recover-exprs.rs:14:10
-   |
-LL |         ("".f() + 14 * 8) => (),
-   |          ^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
-
-error: expected a pattern, found an expression
-  --> $DIR/pat-recover-exprs.rs:17:9
-   |
-LL |         f?() => (),
-   |         ^^^^ arbitrary expressions are not allowed in patterns
-
-error: expected one of `)`, `,`, or `|`, found `+`
-  --> $DIR/pat-recover-exprs.rs:19:12
-   |
-LL |         (_ + 1) => (),
-   |            ^ expected one of `)`, `,`, or `|`
-
-error: expected a pattern, found an expression
-  --> $DIR/pat-recover-exprs.rs:23:9
-   |
-LL |     let 1 + 1 = 2;
-   |         ^^^^^ arbitrary expressions are not allowed in patterns
-
-error: expected one of `)`, `,`, `@`, or `|`, found `*`
-  --> $DIR/pat-recover-exprs.rs:26:28
-   |
-LL |     let b = matches!(x, (x * x | x.f()) | x[0]);
-   |                            ^ expected one of `)`, `,`, `@`, or `|`
-  --> $SRC_DIR/core/src/macros/mod.rs:LL:COL
-   |
-   = note: while parsing argument for this `pat` macro fragment
-
-error: aborting due to 11 previous errors
-
diff --git a/tests/ui/parser/pat-recover-methodcalls.rs b/tests/ui/parser/pat-recover-methodcalls.rs
deleted file mode 100644
index 54104e9a535..00000000000
--- a/tests/ui/parser/pat-recover-methodcalls.rs
+++ /dev/null
@@ -1,37 +0,0 @@
-struct Foo(String);
-struct Bar { baz: String }
-
-fn foo(foo: Foo) -> bool {
-    match foo {
-        Foo("hi".to_owned()) => true,
-        //~^ error: expected a pattern, found a method call
-        _ => false
-    }
-}
-
-fn bar(bar: Bar) -> bool {
-    match bar {
-        Bar { baz: "hi".to_owned() } => true,
-        //~^ error: expected a pattern, found a method call
-        _ => false
-    }
-}
-
-fn baz() { // issue #90121
-    let foo = vec!["foo".to_string()];
-
-    match foo.as_slice() {
-        &["foo".to_string()] => {}
-        //~^ error: expected a pattern, found a method call
-        _ => {}
-    };
-}
-
-fn main() {
-    if let (-1.some(4)) = (0, Some(4)) {}
-    //~^ error: expected a pattern, found a method call
-
-    if let (-1.Some(4)) = (0, Some(4)) {}
-    //~^ error: expected one of `)`, `,`, `...`, `..=`, `..`, or `|`, found `.`
-    //~| help: missing `,`
-}
diff --git a/tests/ui/parser/pat-recover-methodcalls.stderr b/tests/ui/parser/pat-recover-methodcalls.stderr
deleted file mode 100644
index 1f9ae81dc0c..00000000000
--- a/tests/ui/parser/pat-recover-methodcalls.stderr
+++ /dev/null
@@ -1,35 +0,0 @@
-error: expected a pattern, found a method call
-  --> $DIR/pat-recover-methodcalls.rs:6:13
-   |
-LL |         Foo("hi".to_owned()) => true,
-   |             ^^^^^^^^^^^^^^^ method calls are not allowed in patterns
-
-error: expected a pattern, found a method call
-  --> $DIR/pat-recover-methodcalls.rs:14:20
-   |
-LL |         Bar { baz: "hi".to_owned() } => true,
-   |                    ^^^^^^^^^^^^^^^ method calls are not allowed in patterns
-
-error: expected a pattern, found a method call
-  --> $DIR/pat-recover-methodcalls.rs:24:11
-   |
-LL |         &["foo".to_string()] => {}
-   |           ^^^^^^^^^^^^^^^^^ method calls are not allowed in patterns
-
-error: expected a pattern, found a method call
-  --> $DIR/pat-recover-methodcalls.rs:31:13
-   |
-LL |     if let (-1.some(4)) = (0, Some(4)) {}
-   |             ^^^^^^^^^^ method calls are not allowed in patterns
-
-error: expected one of `)`, `,`, `...`, `..=`, `..`, or `|`, found `.`
-  --> $DIR/pat-recover-methodcalls.rs:34:15
-   |
-LL |     if let (-1.Some(4)) = (0, Some(4)) {}
-   |               ^
-   |               |
-   |               expected one of `)`, `,`, `...`, `..=`, `..`, or `|`
-   |               help: missing `,`
-
-error: aborting due to 5 previous errors
-
diff --git a/tests/ui/parser/pat-recover-ranges.stderr b/tests/ui/parser/pat-recover-ranges.stderr
deleted file mode 100644
index a7d62bd7f8a..00000000000
--- a/tests/ui/parser/pat-recover-ranges.stderr
+++ /dev/null
@@ -1,132 +0,0 @@
-error: range pattern bounds cannot have parentheses
-  --> $DIR/pat-recover-ranges.rs:4:13
-   |
-LL |         0..=(1) => (),
-   |             ^ ^
-   |
-help: remove these parentheses
-   |
-LL -         0..=(1) => (),
-LL +         0..=1 => (),
-   |
-
-error: range pattern bounds cannot have parentheses
-  --> $DIR/pat-recover-ranges.rs:6:9
-   |
-LL |         (-12)..=4 => (),
-   |         ^   ^
-   |
-help: remove these parentheses
-   |
-LL -         (-12)..=4 => (),
-LL +         -12..=4 => (),
-   |
-
-error: range pattern bounds cannot have parentheses
-  --> $DIR/pat-recover-ranges.rs:8:9
-   |
-LL |         (0)..=(-4) => (),
-   |         ^ ^
-   |
-help: remove these parentheses
-   |
-LL -         (0)..=(-4) => (),
-LL +         0..=(-4) => (),
-   |
-
-error: range pattern bounds cannot have parentheses
-  --> $DIR/pat-recover-ranges.rs:8:15
-   |
-LL |         (0)..=(-4) => (),
-   |               ^  ^
-   |
-help: remove these parentheses
-   |
-LL -         (0)..=(-4) => (),
-LL +         (0)..=-4 => (),
-   |
-
-error: expected a pattern range bound, found an expression
-  --> $DIR/pat-recover-ranges.rs:11:12
-   |
-LL |         ..=1 + 2 => (),
-   |            ^^^^^ arbitrary expressions are not allowed in patterns
-
-error: range pattern bounds cannot have parentheses
-  --> $DIR/pat-recover-ranges.rs:13:9
-   |
-LL |         (4).. => (),
-   |         ^ ^
-   |
-help: remove these parentheses
-   |
-LL -         (4).. => (),
-LL +         4.. => (),
-   |
-
-error: expected a pattern range bound, found an expression
-  --> $DIR/pat-recover-ranges.rs:15:10
-   |
-LL |         (-4 + 0).. => (),
-   |          ^^^^^^ arbitrary expressions are not allowed in patterns
-
-error: range pattern bounds cannot have parentheses
-  --> $DIR/pat-recover-ranges.rs:15:9
-   |
-LL |         (-4 + 0).. => (),
-   |         ^      ^
-   |
-help: remove these parentheses
-   |
-LL -         (-4 + 0).. => (),
-LL +         -4 + 0.. => (),
-   |
-
-error: expected a pattern range bound, found an expression
-  --> $DIR/pat-recover-ranges.rs:18:10
-   |
-LL |         (1 + 4)...1 * 2 => (),
-   |          ^^^^^ arbitrary expressions are not allowed in patterns
-
-error: range pattern bounds cannot have parentheses
-  --> $DIR/pat-recover-ranges.rs:18:9
-   |
-LL |         (1 + 4)...1 * 2 => (),
-   |         ^     ^
-   |
-help: remove these parentheses
-   |
-LL -         (1 + 4)...1 * 2 => (),
-LL +         1 + 4...1 * 2 => (),
-   |
-
-error: expected a pattern range bound, found an expression
-  --> $DIR/pat-recover-ranges.rs:18:19
-   |
-LL |         (1 + 4)...1 * 2 => (),
-   |                   ^^^^^ arbitrary expressions are not allowed in patterns
-
-error: expected a pattern range bound, found a method call
-  --> $DIR/pat-recover-ranges.rs:24:9
-   |
-LL |         0.x()..="y".z() => (),
-   |         ^^^^^ method calls are not allowed in patterns
-
-error: expected a pattern range bound, found a method call
-  --> $DIR/pat-recover-ranges.rs:24:17
-   |
-LL |         0.x()..="y".z() => (),
-   |                 ^^^^^^^ method calls are not allowed in patterns
-
-warning: `...` range patterns are deprecated
-  --> $DIR/pat-recover-ranges.rs:18:16
-   |
-LL |         (1 + 4)...1 * 2 => (),
-   |                ^^^ help: use `..=` for an inclusive range
-   |
-   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
-   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
-   = note: `#[warn(ellipsis_inclusive_range_patterns)]` on by default
-
-error: aborting due to 13 previous errors; 1 warning emitted
-
diff --git a/tests/ui/parser/recover/recover-pat-exprs.rs b/tests/ui/parser/recover/recover-pat-exprs.rs
new file mode 100644
index 00000000000..e5e25df0c01
--- /dev/null
+++ b/tests/ui/parser/recover/recover-pat-exprs.rs
@@ -0,0 +1,106 @@
+// FieldExpression, TupleIndexingExpression
+fn field_access() {
+    match 0 {
+        x => (),
+        x.y => (), //~ error: expected a pattern, found an expression
+        x.0 => (), //~ error: expected a pattern, found an expression
+        x._0 => (), //~ error: expected a pattern, found an expression
+        x.0.1 => (), //~ error: expected a pattern, found an expression
+        x.4.y.17.__z => (), //~ error: expected a pattern, found an expression
+    }
+
+    { let x.0e0; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
+    { let x.-0.0; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
+    { let x.-0; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
+
+    { let x.0u32; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
+    { let x.0.0_f64; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
+}
+
+// IndexExpression, ArrayExpression
+fn array_indexing() {
+    match 0 {
+        x[0] => (), //~ error: expected a pattern, found an expression
+        x[..] => (), //~ error: expected a pattern, found an expression
+    }
+
+    { let x[0, 1, 2]; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
+    { let x[0; 20]; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
+    { let x[]; } //~ error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
+    { let (x[]); } //~ error: expected one of `)`, `,`, `@`, or `|`, found `[`
+    //~^ missing `,`
+}
+
+// MethodCallExpression, CallExpression, ErrorPropagationExpression
+fn method_call() {
+    match 0 {
+        x.f() => (), //~ error: expected a pattern, found an expression
+        x._f() => (), //~ error: expected a pattern, found an expression
+        x? => (), //~ error: expected a pattern, found an expression
+        ().f() => (), //~ error: expected a pattern, found an expression
+        (0, x)?.f() => (), //~ error: expected a pattern, found an expression
+        x.f().g() => (), //~ error: expected a pattern, found an expression
+        0.f()?.g()?? => (), //~ error: expected a pattern, found an expression
+    }
+}
+
+// TypeCastExpression
+fn type_cast() {
+    match 0 {
+        x as usize => (), //~ error: expected a pattern, found an expression
+        0 as usize => (), //~ error: expected a pattern, found an expression
+        x.f().0.4 as f32 => (), //~ error: expected a pattern, found an expression
+    }
+}
+
+// ArithmeticOrLogicalExpression, also check if parentheses are added as needed
+fn operator() {
+    match 0 {
+        1 + 1 => (), //~ error: expected a pattern, found an expression
+        (1 + 2) * 3 => (),
+        //~^ error: expected a pattern, found an expression
+        //~| error: expected a pattern, found an expression
+        x.0 > 2 => (), //~ error: expected a pattern, found an expression
+        x.0 == 2 => (), //~ error: expected a pattern, found an expression
+    }
+
+    // preexisting match arm guard
+    match (0, 0) {
+        (x, y.0 > 2) if x != 0 => (), //~ error: expected a pattern, found an expression
+        (x, y.0 > 2) if x != 0 || x != 1 => (), //~ error: expected a pattern, found an expression
+    }
+}
+
+const _: u32 = match 12 {
+    1 + 2 * PI.cos() => 2, //~ error: expected a pattern, found an expression
+    _ => 0,
+};
+
+fn main() {
+    match u8::MAX {
+        u8::MAX.abs() => (),
+        //~^ error: expected a pattern, found an expression
+        x.sqrt() @ .. => (),
+        //~^ error: expected a pattern, found an expression
+        //~| error: left-hand side of `@` must be a binding
+        z @ w @ v.u() => (),
+        //~^ error: expected a pattern, found an expression
+        y.ilog(3) => (),
+        //~^ error: expected a pattern, found an expression
+        n + 1 => (),
+        //~^ error: expected a pattern, found an expression
+        ("".f() + 14 * 8) => (),
+        //~^ error: expected a pattern, found an expression
+        0 | ((1) | 2) | 3 => (),
+        f?() => (),
+        //~^ error: expected a pattern, found an expression
+        (_ + 1) => (),
+        //~^ error: expected one of `)`, `,`, or `|`, found `+`
+    }
+
+    let 1 + 1 = 2;
+    //~^ error: expected a pattern, found an expression
+
+    let b = matches!(x, (x * x | x.f()) | x[0]);
+    //~^ error: expected one of `)`, `,`, `@`, or `|`, found `*`
+}
diff --git a/tests/ui/parser/recover/recover-pat-exprs.stderr b/tests/ui/parser/recover/recover-pat-exprs.stderr
new file mode 100644
index 00000000000..63956f35c07
--- /dev/null
+++ b/tests/ui/parser/recover/recover-pat-exprs.stderr
@@ -0,0 +1,772 @@
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:5:9
+   |
+LL |         x.y => (),
+   |         ^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == x.y => (),
+   |         ~~~ +++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x.y;
+LL ~     match 0 {
+LL |         x => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x.y } => (),
+   |         +++++++     +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:6:9
+   |
+LL |         x.0 => (),
+   |         ^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == x.0 => (),
+   |         ~~~ +++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x.0;
+LL ~     match 0 {
+LL |         x => (),
+LL |         x.y => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x.0 } => (),
+   |         +++++++     +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:7:9
+   |
+LL |         x._0 => (),
+   |         ^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == x._0 => (),
+   |         ~~~ ++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x._0;
+LL ~     match 0 {
+LL |         x => (),
+LL |         x.y => (),
+LL |         x.0 => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x._0 } => (),
+   |         +++++++      +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:8:9
+   |
+LL |         x.0.1 => (),
+   |         ^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == x.0.1 => (),
+   |         ~~~ +++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x.0.1;
+LL ~     match 0 {
+LL |         x => (),
+...
+LL |         x._0 => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x.0.1 } => (),
+   |         +++++++       +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:9:9
+   |
+LL |         x.4.y.17.__z => (),
+   |         ^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == x.4.y.17.__z => (),
+   |         ~~~ ++++++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x.4.y.17.__z;
+LL ~     match 0 {
+LL |         x => (),
+...
+LL |         x.0.1 => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x.4.y.17.__z } => (),
+   |         +++++++              +
+
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
+  --> $DIR/recover-pat-exprs.rs:12:12
+   |
+LL |     { let x.0e0; }
+   |            ^ expected one of `:`, `;`, `=`, `@`, or `|`
+
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
+  --> $DIR/recover-pat-exprs.rs:13:12
+   |
+LL |     { let x.-0.0; }
+   |            ^ expected one of `:`, `;`, `=`, `@`, or `|`
+
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
+  --> $DIR/recover-pat-exprs.rs:14:12
+   |
+LL |     { let x.-0; }
+   |            ^ expected one of `:`, `;`, `=`, `@`, or `|`
+
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
+  --> $DIR/recover-pat-exprs.rs:16:12
+   |
+LL |     { let x.0u32; }
+   |            ^ expected one of `:`, `;`, `=`, `@`, or `|`
+
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `.`
+  --> $DIR/recover-pat-exprs.rs:17:12
+   |
+LL |     { let x.0.0_f64; }
+   |            ^ expected one of `:`, `;`, `=`, `@`, or `|`
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:23:9
+   |
+LL |         x[0] => (),
+   |         ^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == x[0] => (),
+   |         ~~~ ++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x[0];
+LL ~     match 0 {
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x[0] } => (),
+   |         +++++++      +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:24:9
+   |
+LL |         x[..] => (),
+   |         ^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == x[..] => (),
+   |         ~~~ +++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x[..];
+LL ~     match 0 {
+LL |         x[0] => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x[..] } => (),
+   |         +++++++       +
+
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
+  --> $DIR/recover-pat-exprs.rs:27:12
+   |
+LL |     { let x[0, 1, 2]; }
+   |            ^ expected one of `:`, `;`, `=`, `@`, or `|`
+
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
+  --> $DIR/recover-pat-exprs.rs:28:12
+   |
+LL |     { let x[0; 20]; }
+   |            ^ expected one of `:`, `;`, `=`, `@`, or `|`
+
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `[`
+  --> $DIR/recover-pat-exprs.rs:29:12
+   |
+LL |     { let x[]; }
+   |            ^ expected one of `:`, `;`, `=`, `@`, or `|`
+
+error: expected one of `)`, `,`, `@`, or `|`, found `[`
+  --> $DIR/recover-pat-exprs.rs:30:13
+   |
+LL |     { let (x[]); }
+   |             ^
+   |             |
+   |             expected one of `)`, `,`, `@`, or `|`
+   |             help: missing `,`
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:37:9
+   |
+LL |         x.f() => (),
+   |         ^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == x.f() => (),
+   |         ~~~ +++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x.f();
+LL ~     match 0 {
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x.f() } => (),
+   |         +++++++       +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:38:9
+   |
+LL |         x._f() => (),
+   |         ^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == x._f() => (),
+   |         ~~~ ++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x._f();
+LL ~     match 0 {
+LL |         x.f() => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x._f() } => (),
+   |         +++++++        +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:39:9
+   |
+LL |         x? => (),
+   |         ^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == x? => (),
+   |         ~~~ ++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x?;
+LL ~     match 0 {
+LL |         x.f() => (),
+LL |         x._f() => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x? } => (),
+   |         +++++++    +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:40:9
+   |
+LL |         ().f() => (),
+   |         ^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == ().f() => (),
+   |         ~~~ ++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = ().f();
+LL ~     match 0 {
+LL |         x.f() => (),
+LL |         x._f() => (),
+LL |         x? => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { ().f() } => (),
+   |         +++++++        +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:41:9
+   |
+LL |         (0, x)?.f() => (),
+   |         ^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == (0, x)?.f() => (),
+   |         ~~~ +++++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = (0, x)?.f();
+LL ~     match 0 {
+LL |         x.f() => (),
+...
+LL |         ().f() => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { (0, x)?.f() } => (),
+   |         +++++++             +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:42:9
+   |
+LL |         x.f().g() => (),
+   |         ^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == x.f().g() => (),
+   |         ~~~ +++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x.f().g();
+LL ~     match 0 {
+LL |         x.f() => (),
+...
+LL |         (0, x)?.f() => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x.f().g() } => (),
+   |         +++++++           +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:43:9
+   |
+LL |         0.f()?.g()?? => (),
+   |         ^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == 0.f()?.g()?? => (),
+   |         ~~~ ++++++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = 0.f()?.g()??;
+LL ~     match 0 {
+LL |         x.f() => (),
+...
+LL |         x.f().g() => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { 0.f()?.g()?? } => (),
+   |         +++++++              +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:50:9
+   |
+LL |         x as usize => (),
+   |         ^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == x as usize => (),
+   |         ~~~ ++++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x as usize;
+LL ~     match 0 {
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x as usize } => (),
+   |         +++++++            +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:51:9
+   |
+LL |         0 as usize => (),
+   |         ^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == 0 as usize => (),
+   |         ~~~ ++++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = 0 as usize;
+LL ~     match 0 {
+LL |         x as usize => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { 0 as usize } => (),
+   |         +++++++            +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:52:9
+   |
+LL |         x.f().0.4 as f32 => (),
+   |         ^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == x.f().0.4 as f32 => (),
+   |         ~~~ ++++++++++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x.f().0.4 as f32;
+LL ~     match 0 {
+LL |         x as usize => (),
+LL |         0 as usize => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x.f().0.4 as f32 } => (),
+   |         +++++++                  +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:59:9
+   |
+LL |         1 + 1 => (),
+   |         ^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == 1 + 1 => (),
+   |         ~~~ +++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = 1 + 1;
+LL ~     match 0 {
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { 1 + 1 } => (),
+   |         +++++++       +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:60:9
+   |
+LL |         (1 + 2) * 3 => (),
+   |         ^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == (1 + 2) * 3 => (),
+   |         ~~~ +++++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = (1 + 2) * 3;
+LL ~     match 0 {
+LL |         1 + 1 => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { (1 + 2) * 3 } => (),
+   |         +++++++             +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:63:9
+   |
+LL |         x.0 > 2 => (),
+   |         ^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == (x.0 > 2) => (),
+   |         ~~~ +++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x.0 > 2;
+LL ~     match 0 {
+LL |         1 + 1 => (),
+...
+LL |
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x.0 > 2 } => (),
+   |         +++++++         +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:64:9
+   |
+LL |         x.0 == 2 => (),
+   |         ^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == (x.0 == 2) => (),
+   |         ~~~ ++++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = x.0 == 2;
+LL ~     match 0 {
+LL |         1 + 1 => (),
+...
+LL |         x.0 > 2 => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { x.0 == 2 } => (),
+   |         +++++++          +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:69:13
+   |
+LL |         (x, y.0 > 2) if x != 0 => (),
+   |             ^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to the match arm guard
+   |
+LL |         (x, val) if x != 0 && val == (y.0 > 2) => (),
+   |             ~~~            +++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = y.0 > 2;
+LL ~     match (0, 0) {
+LL ~         (x, VAL) if x != 0 => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         (x, const { y.0 > 2 }) if x != 0 => (),
+   |             +++++++         +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:70:13
+   |
+LL |         (x, y.0 > 2) if x != 0 || x != 1 => (),
+   |             ^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to the match arm guard
+   |
+LL |         (x, val) if (x != 0 || x != 1) && val == (y.0 > 2) => (),
+   |             ~~~     +                +++++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = y.0 > 2;
+LL ~     match (0, 0) {
+LL |         (x, y.0 > 2) if x != 0 => (),
+LL ~         (x, VAL) if x != 0 || x != 1 => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         (x, const { y.0 > 2 }) if x != 0 || x != 1 => (),
+   |             +++++++         +
+
+error: left-hand side of `@` must be a binding
+  --> $DIR/recover-pat-exprs.rs:83:9
+   |
+LL |         x.sqrt() @ .. => (),
+   |         --------^^^--
+   |         |          |
+   |         |          also a pattern
+   |         interpreted as a pattern, not a binding
+   |
+   = note: bindings are `x`, `mut x`, `ref x`, and `ref mut x`
+
+error: expected one of `)`, `,`, or `|`, found `+`
+  --> $DIR/recover-pat-exprs.rs:97:12
+   |
+LL |         (_ + 1) => (),
+   |            ^ expected one of `)`, `,`, or `|`
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:81:9
+   |
+LL |         u8::MAX.abs() => (),
+   |         ^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == u8::MAX.abs() => (),
+   |         ~~~ +++++++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = u8::MAX.abs();
+LL ~     match u8::MAX {
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { u8::MAX.abs() } => (),
+   |         +++++++               +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:86:17
+   |
+LL |         z @ w @ v.u() => (),
+   |                 ^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         z @ w @ val if val == v.u() => (),
+   |                 ~~~ +++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = v.u();
+LL ~     match u8::MAX {
+LL |         u8::MAX.abs() => (),
+...
+LL |
+LL ~         z @ w @ VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         z @ w @ const { v.u() } => (),
+   |                 +++++++       +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:88:9
+   |
+LL |         y.ilog(3) => (),
+   |         ^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == y.ilog(3) => (),
+   |         ~~~ +++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = y.ilog(3);
+LL ~     match u8::MAX {
+LL |         u8::MAX.abs() => (),
+...
+LL |
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { y.ilog(3) } => (),
+   |         +++++++           +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:90:9
+   |
+LL |         n + 1 => (),
+   |         ^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == n + 1 => (),
+   |         ~~~ +++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = n + 1;
+LL ~     match u8::MAX {
+LL |         u8::MAX.abs() => (),
+...
+LL |
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { n + 1 } => (),
+   |         +++++++       +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:92:10
+   |
+LL |         ("".f() + 14 * 8) => (),
+   |          ^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         (val) if val == "".f() + 14 * 8 => (),
+   |          ~~~  +++++++++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = "".f() + 14 * 8;
+LL ~     match u8::MAX {
+LL |         u8::MAX.abs() => (),
+...
+LL |
+LL ~         (VAL) => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         (const { "".f() + 14 * 8 }) => (),
+   |          +++++++                 +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:95:9
+   |
+LL |         f?() => (),
+   |         ^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         val if val == f?() => (),
+   |         ~~~ ++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = f?();
+LL ~     match u8::MAX {
+LL |         u8::MAX.abs() => (),
+...
+LL |         0 | ((1) | 2) | 3 => (),
+LL ~         VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { f?() } => (),
+   |         +++++++      +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:101:9
+   |
+LL |     let 1 + 1 = 2;
+   |         ^^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected one of `)`, `,`, `@`, or `|`, found `*`
+  --> $DIR/recover-pat-exprs.rs:104:28
+   |
+LL |     let b = matches!(x, (x * x | x.f()) | x[0]);
+   |                            ^ expected one of `)`, `,`, `@`, or `|`
+  --> $SRC_DIR/core/src/macros/mod.rs:LL:COL
+   |
+   = note: while parsing argument for this `pat` macro fragment
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:60:10
+   |
+LL |         (1 + 2) * 3 => (),
+   |          ^^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:75:5
+   |
+LL |     1 + 2 * PI.cos() => 2,
+   |     ^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-exprs.rs:83:9
+   |
+LL |         x.sqrt() @ .. => (),
+   |         ^^^^^^^^ arbitrary expressions are not allowed in patterns
+
+error: aborting due to 45 previous errors
+
diff --git a/tests/ui/parser/recover/recover-pat-issues.rs b/tests/ui/parser/recover/recover-pat-issues.rs
new file mode 100644
index 00000000000..5b900fe80e5
--- /dev/null
+++ b/tests/ui/parser/recover/recover-pat-issues.rs
@@ -0,0 +1,46 @@
+struct Foo(String);
+struct Bar { baz: String }
+
+fn foo(foo: Foo) -> bool {
+    match foo {
+        Foo("hi".to_owned()) => true,
+        //~^ error: expected a pattern, found an expression
+        _ => false
+    }
+}
+
+fn bar(bar: Bar) -> bool {
+    match bar {
+        Bar { baz: "hi".to_owned() } => true,
+        //~^ error: expected a pattern, found an expression
+        _ => false
+    }
+}
+
+/// Issue #90121
+fn baz() {
+    let foo = vec!["foo".to_string()];
+
+    match foo.as_slice() {
+        &["foo".to_string()] => {}
+        //~^ error: expected a pattern, found an expression
+        _ => {}
+    };
+}
+
+/// Issue #104996
+fn qux() {
+    struct Magic(pub u16);
+    const MAGIC: Magic = Magic(42);
+
+    if let Some(MAGIC.0 as usize) = None::<usize> {}
+    //~^ error: expected a pattern, found an expression
+}
+
+fn main() {
+    if let (-1.some(4)) = (0, Some(4)) {}
+    //~^ error: expected a pattern, found an expression
+
+    if let (-1.Some(4)) = (0, Some(4)) {}
+    //~^ error: expected a pattern, found an expression
+}
diff --git a/tests/ui/parser/recover/recover-pat-issues.stderr b/tests/ui/parser/recover/recover-pat-issues.stderr
new file mode 100644
index 00000000000..596bff21395
--- /dev/null
+++ b/tests/ui/parser/recover/recover-pat-issues.stderr
@@ -0,0 +1,113 @@
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-issues.rs:6:13
+   |
+LL |         Foo("hi".to_owned()) => true,
+   |             ^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         Foo(val) if val == "hi".to_owned() => true,
+   |             ~~~  +++++++++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = "hi".to_owned();
+LL ~     match foo {
+LL ~         Foo(VAL) => true,
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         Foo(const { "hi".to_owned() }) => true,
+   |             +++++++                 +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-issues.rs:14:20
+   |
+LL |         Bar { baz: "hi".to_owned() } => true,
+   |                    ^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         Bar { baz } if baz == "hi".to_owned() => true,
+   |               ~~~   +++++++++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const BAZ: /* Type */ = "hi".to_owned();
+LL ~     match bar {
+LL ~         Bar { baz: BAZ } => true,
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         Bar { baz: const { "hi".to_owned() } } => true,
+   |                    +++++++                 +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-issues.rs:25:11
+   |
+LL |         &["foo".to_string()] => {}
+   |           ^^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider moving the expression to a match arm guard
+   |
+LL |         &[val] if val == "foo".to_string() => {}
+   |           ~~~  +++++++++++++++++++++++++++
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = "foo".to_string();
+LL ~     match foo.as_slice() {
+LL ~         &[VAL] => {}
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         &[const { "foo".to_string() }] => {}
+   |           +++++++                   +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-issues.rs:36:17
+   |
+LL |     if let Some(MAGIC.0 as usize) = None::<usize> {}
+   |                 ^^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = MAGIC.0 as usize;
+LL ~     if let Some(VAL) = None::<usize> {}
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |     if let Some(const { MAGIC.0 as usize }) = None::<usize> {}
+   |                 +++++++                  +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-issues.rs:41:13
+   |
+LL |     if let (-1.some(4)) = (0, Some(4)) {}
+   |             ^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = -1.some(4);
+LL ~     if let (VAL) = (0, Some(4)) {}
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |     if let (const { -1.some(4) }) = (0, Some(4)) {}
+   |             +++++++            +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-issues.rs:44:13
+   |
+LL |     if let (-1.Some(4)) = (0, Some(4)) {}
+   |             ^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = -1.Some(4);
+LL ~     if let (VAL) = (0, Some(4)) {}
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |     if let (const { -1.Some(4) }) = (0, Some(4)) {}
+   |             +++++++            +
+
+error: aborting due to 6 previous errors
+
diff --git a/tests/ui/parser/recover/recover-pat-lets.rs b/tests/ui/parser/recover/recover-pat-lets.rs
new file mode 100644
index 00000000000..6681cc25db3
--- /dev/null
+++ b/tests/ui/parser/recover/recover-pat-lets.rs
@@ -0,0 +1,20 @@
+fn main() {
+    let x = Some(2);
+
+    let x.expect("foo");
+    //~^ error: expected a pattern, found an expression
+
+    let x.unwrap(): u32;
+    //~^ error: expected a pattern, found an expression
+
+    let x[0] = 1;
+    //~^ error: expected a pattern, found an expression
+
+    let Some(1 + 1) = x else { //~ error: expected a pattern, found an expression
+        return;
+    };
+
+    if let Some(1 + 1) = x { //~ error: expected a pattern, found an expression
+        return;
+    }
+}
diff --git a/tests/ui/parser/recover/recover-pat-lets.stderr b/tests/ui/parser/recover/recover-pat-lets.stderr
new file mode 100644
index 00000000000..e54586b0924
--- /dev/null
+++ b/tests/ui/parser/recover/recover-pat-lets.stderr
@@ -0,0 +1,52 @@
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-lets.rs:4:9
+   |
+LL |     let x.expect("foo");
+   |         ^^^^^^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-lets.rs:7:9
+   |
+LL |     let x.unwrap(): u32;
+   |         ^^^^^^^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-lets.rs:10:9
+   |
+LL |     let x[0] = 1;
+   |         ^^^^ arbitrary expressions are not allowed in patterns
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-lets.rs:13:14
+   |
+LL |     let Some(1 + 1) = x else {
+   |              ^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = 1 + 1;
+LL ~     let Some(VAL) = x else {
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |     let Some(const { 1 + 1 }) = x else {
+   |              +++++++       +
+
+error: expected a pattern, found an expression
+  --> $DIR/recover-pat-lets.rs:17:17
+   |
+LL |     if let Some(1 + 1) = x {
+   |                 ^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = 1 + 1;
+LL ~     if let Some(VAL) = x {
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |     if let Some(const { 1 + 1 }) = x {
+   |                 +++++++       +
+
+error: aborting due to 5 previous errors
+
diff --git a/tests/ui/parser/pat-recover-ranges.rs b/tests/ui/parser/recover/recover-pat-ranges.rs
index 7d77e950d90..e3f061c625d 100644
--- a/tests/ui/parser/pat-recover-ranges.rs
+++ b/tests/ui/parser/recover/recover-pat-ranges.rs
@@ -22,8 +22,8 @@ fn main() {
         //~| warning: `...` range patterns are deprecated
         //~| warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
         0.x()..="y".z() => (),
-        //~^ error: expected a pattern range bound, found a method call
-        //~| error: expected a pattern range bound, found a method call
+        //~^ error: expected a pattern range bound, found an expression
+        //~| error: expected a pattern range bound, found an expression
     };
 }
 
diff --git a/tests/ui/parser/recover/recover-pat-ranges.stderr b/tests/ui/parser/recover/recover-pat-ranges.stderr
new file mode 100644
index 00000000000..088f83b0ccb
--- /dev/null
+++ b/tests/ui/parser/recover/recover-pat-ranges.stderr
@@ -0,0 +1,216 @@
+error: range pattern bounds cannot have parentheses
+  --> $DIR/recover-pat-ranges.rs:4:13
+   |
+LL |         0..=(1) => (),
+   |             ^ ^
+   |
+help: remove these parentheses
+   |
+LL -         0..=(1) => (),
+LL +         0..=1 => (),
+   |
+
+error: range pattern bounds cannot have parentheses
+  --> $DIR/recover-pat-ranges.rs:6:9
+   |
+LL |         (-12)..=4 => (),
+   |         ^   ^
+   |
+help: remove these parentheses
+   |
+LL -         (-12)..=4 => (),
+LL +         -12..=4 => (),
+   |
+
+error: range pattern bounds cannot have parentheses
+  --> $DIR/recover-pat-ranges.rs:8:9
+   |
+LL |         (0)..=(-4) => (),
+   |         ^ ^
+   |
+help: remove these parentheses
+   |
+LL -         (0)..=(-4) => (),
+LL +         0..=(-4) => (),
+   |
+
+error: range pattern bounds cannot have parentheses
+  --> $DIR/recover-pat-ranges.rs:8:15
+   |
+LL |         (0)..=(-4) => (),
+   |               ^  ^
+   |
+help: remove these parentheses
+   |
+LL -         (0)..=(-4) => (),
+LL +         (0)..=-4 => (),
+   |
+
+error: range pattern bounds cannot have parentheses
+  --> $DIR/recover-pat-ranges.rs:13:9
+   |
+LL |         (4).. => (),
+   |         ^ ^
+   |
+help: remove these parentheses
+   |
+LL -         (4).. => (),
+LL +         4.. => (),
+   |
+
+error: range pattern bounds cannot have parentheses
+  --> $DIR/recover-pat-ranges.rs:15:9
+   |
+LL |         (-4 + 0).. => (),
+   |         ^      ^
+   |
+help: remove these parentheses
+   |
+LL -         (-4 + 0).. => (),
+LL +         -4 + 0.. => (),
+   |
+
+error: range pattern bounds cannot have parentheses
+  --> $DIR/recover-pat-ranges.rs:18:9
+   |
+LL |         (1 + 4)...1 * 2 => (),
+   |         ^     ^
+   |
+help: remove these parentheses
+   |
+LL -         (1 + 4)...1 * 2 => (),
+LL +         1 + 4...1 * 2 => (),
+   |
+
+error: expected a pattern range bound, found an expression
+  --> $DIR/recover-pat-ranges.rs:11:12
+   |
+LL |         ..=1 + 2 => (),
+   |            ^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = 1 + 2;
+LL ~     match -1 {
+LL |         0..=1 => (),
+...
+LL |
+LL ~         ..=VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         ..=const { 1 + 2 } => (),
+   |            +++++++       +
+
+error: expected a pattern range bound, found an expression
+  --> $DIR/recover-pat-ranges.rs:15:10
+   |
+LL |         (-4 + 0).. => (),
+   |          ^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = -4 + 0;
+LL ~     match -1 {
+LL |         0..=1 => (),
+...
+LL |
+LL ~         (VAL).. => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         (const { -4 + 0 }).. => (),
+   |          +++++++        +
+
+error: expected a pattern range bound, found an expression
+  --> $DIR/recover-pat-ranges.rs:18:10
+   |
+LL |         (1 + 4)...1 * 2 => (),
+   |          ^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = 1 + 4;
+LL ~     match -1 {
+LL |         0..=1 => (),
+...
+LL |
+LL ~         (VAL)...1 * 2 => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         (const { 1 + 4 })...1 * 2 => (),
+   |          +++++++       +
+
+error: expected a pattern range bound, found an expression
+  --> $DIR/recover-pat-ranges.rs:18:19
+   |
+LL |         (1 + 4)...1 * 2 => (),
+   |                   ^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = 1 * 2;
+LL ~     match -1 {
+LL |         0..=1 => (),
+...
+LL |
+LL ~         (1 + 4)...VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         (1 + 4)...const { 1 * 2 } => (),
+   |                   +++++++       +
+
+error: expected a pattern range bound, found an expression
+  --> $DIR/recover-pat-ranges.rs:24:9
+   |
+LL |         0.x()..="y".z() => (),
+   |         ^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = 0.x();
+LL ~     match -1 {
+LL |         0..=1 => (),
+...
+LL |
+LL ~         VAL..="y".z() => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         const { 0.x() }..="y".z() => (),
+   |         +++++++       +
+
+error: expected a pattern range bound, found an expression
+  --> $DIR/recover-pat-ranges.rs:24:17
+   |
+LL |         0.x()..="y".z() => (),
+   |                 ^^^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = "y".z();
+LL ~     match -1 {
+LL |         0..=1 => (),
+...
+LL |
+LL ~         0.x()..=VAL => (),
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         0.x()..=const { "y".z() } => (),
+   |                 +++++++         +
+
+warning: `...` range patterns are deprecated
+  --> $DIR/recover-pat-ranges.rs:18:16
+   |
+LL |         (1 + 4)...1 * 2 => (),
+   |                ^^^ help: use `..=` for an inclusive range
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021!
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2021/warnings-promoted-to-error.html>
+   = note: `#[warn(ellipsis_inclusive_range_patterns)]` on by default
+
+error: aborting due to 13 previous errors; 1 warning emitted
+
diff --git a/tests/ui/parser/pat-recover-wildcards.rs b/tests/ui/parser/recover/recover-pat-wildcards.rs
index f506e2223d6..f506e2223d6 100644
--- a/tests/ui/parser/pat-recover-wildcards.rs
+++ b/tests/ui/parser/recover/recover-pat-wildcards.rs
diff --git a/tests/ui/parser/pat-recover-wildcards.stderr b/tests/ui/parser/recover/recover-pat-wildcards.stderr
index e36ff237bb0..30307726a97 100644
--- a/tests/ui/parser/pat-recover-wildcards.stderr
+++ b/tests/ui/parser/recover/recover-pat-wildcards.stderr
@@ -1,35 +1,35 @@
 error: expected one of `=>`, `if`, or `|`, found `+`
-  --> $DIR/pat-recover-wildcards.rs:5:11
+  --> $DIR/recover-pat-wildcards.rs:5:11
    |
 LL |         _ + 1 => ()
    |           ^ expected one of `=>`, `if`, or `|`
 
 error: expected one of `)`, `,`, or `|`, found `%`
-  --> $DIR/pat-recover-wildcards.rs:11:12
+  --> $DIR/recover-pat-wildcards.rs:11:12
    |
 LL |         (_ % 4) => ()
    |            ^ expected one of `)`, `,`, or `|`
 
 error: expected one of `=>`, `if`, or `|`, found `.`
-  --> $DIR/pat-recover-wildcards.rs:17:10
+  --> $DIR/recover-pat-wildcards.rs:17:10
    |
 LL |         _.x() => ()
    |          ^ expected one of `=>`, `if`, or `|`
 
 error: expected one of `=>`, `if`, or `|`, found `..=`
-  --> $DIR/pat-recover-wildcards.rs:23:10
+  --> $DIR/recover-pat-wildcards.rs:23:10
    |
 LL |         _..=4 => ()
    |          ^^^ expected one of `=>`, `if`, or `|`
 
 error: expected one of `=>`, `if`, or `|`, found reserved identifier `_`
-  --> $DIR/pat-recover-wildcards.rs:29:11
+  --> $DIR/recover-pat-wildcards.rs:29:11
    |
 LL |         .._ => ()
    |           ^ expected one of `=>`, `if`, or `|`
 
 error[E0586]: inclusive range with no end
-  --> $DIR/pat-recover-wildcards.rs:35:10
+  --> $DIR/recover-pat-wildcards.rs:35:10
    |
 LL |         0..._ => ()
    |          ^^^
@@ -42,31 +42,25 @@ LL +         0.._ => ()
    |
 
 error: expected one of `=>`, `if`, or `|`, found reserved identifier `_`
-  --> $DIR/pat-recover-wildcards.rs:35:13
+  --> $DIR/recover-pat-wildcards.rs:35:13
    |
 LL |         0..._ => ()
    |             ^ expected one of `=>`, `if`, or `|`
 
 error: expected one of `)`, `,`, or `|`, found `*`
-  --> $DIR/pat-recover-wildcards.rs:43:12
+  --> $DIR/recover-pat-wildcards.rs:43:12
    |
 LL |         (_ * 0)..5 => ()
    |            ^ expected one of `)`, `,`, or `|`
 
 error: expected one of `=>`, `if`, or `|`, found `(`
-  --> $DIR/pat-recover-wildcards.rs:49:11
+  --> $DIR/recover-pat-wildcards.rs:49:11
    |
 LL |         ..(_) => ()
    |           ^ expected one of `=>`, `if`, or `|`
 
-error: expected a pattern range bound, found an expression
-  --> $DIR/pat-recover-wildcards.rs:55:14
-   |
-LL |         4..=(2 + _) => ()
-   |              ^^^^^ arbitrary expressions are not allowed in patterns
-
 error: range pattern bounds cannot have parentheses
-  --> $DIR/pat-recover-wildcards.rs:55:13
+  --> $DIR/recover-pat-wildcards.rs:55:13
    |
 LL |         4..=(2 + _) => ()
    |             ^     ^
@@ -77,6 +71,23 @@ LL -         4..=(2 + _) => ()
 LL +         4..=2 + _ => ()
    |
 
+error: expected a pattern range bound, found an expression
+  --> $DIR/recover-pat-wildcards.rs:55:14
+   |
+LL |         4..=(2 + _) => ()
+   |              ^^^^^ arbitrary expressions are not allowed in patterns
+   |
+help: consider extracting the expression into a `const`
+   |
+LL +     const VAL: /* Type */ = 2 + _;
+LL ~     match 9 {
+LL ~         4..=(VAL) => ()
+   |
+help: consider wrapping the expression in an inline `const` (requires `#![feature(inline_const_pat)]`)
+   |
+LL |         4..=(const { 2 + _ }) => ()
+   |              +++++++       +
+
 error: aborting due to 11 previous errors
 
 For more information about this error, try `rustc --explain E0586`.
diff --git a/tests/ui/parser/triple-colon-delegation.fixed b/tests/ui/parser/triple-colon-delegation.fixed
new file mode 100644
index 00000000000..fbb614b57da
--- /dev/null
+++ b/tests/ui/parser/triple-colon-delegation.fixed
@@ -0,0 +1,44 @@
+//@ run-rustfix
+
+#![feature(fn_delegation)]
+#![allow(incomplete_features, unused)]
+
+trait Trait {
+    fn foo(&self) {}
+}
+
+struct F;
+impl Trait for F {}
+
+pub mod to_reuse {
+    pub fn bar() {}
+}
+
+mod fn_to_other {
+    use super::*;
+
+    reuse Trait::foo; //~ ERROR path separator must be a double colon
+    reuse to_reuse::bar; //~ ERROR path separator must be a double colon
+}
+
+impl Trait for u8 {}
+
+struct S(u8);
+
+mod to_import {
+    pub fn check(arg: &u8) -> &u8 { arg }
+}
+
+impl Trait for S {
+    reuse Trait::* { //~ ERROR path separator must be a double colon
+        use to_import::check;
+
+        let _arr = Some(self.0).map(|x| [x * 2; 3]);
+        check(&self.0)
+    }
+}
+
+fn main() {
+    let s = S(0);
+    s.foo();
+}
diff --git a/tests/ui/parser/triple-colon-delegation.rs b/tests/ui/parser/triple-colon-delegation.rs
new file mode 100644
index 00000000000..9fbaa4477ae
--- /dev/null
+++ b/tests/ui/parser/triple-colon-delegation.rs
@@ -0,0 +1,44 @@
+//@ run-rustfix
+
+#![feature(fn_delegation)]
+#![allow(incomplete_features, unused)]
+
+trait Trait {
+    fn foo(&self) {}
+}
+
+struct F;
+impl Trait for F {}
+
+pub mod to_reuse {
+    pub fn bar() {}
+}
+
+mod fn_to_other {
+    use super::*;
+
+    reuse Trait:::foo; //~ ERROR path separator must be a double colon
+    reuse to_reuse:::bar; //~ ERROR path separator must be a double colon
+}
+
+impl Trait for u8 {}
+
+struct S(u8);
+
+mod to_import {
+    pub fn check(arg: &u8) -> &u8 { arg }
+}
+
+impl Trait for S {
+    reuse Trait:::* { //~ ERROR path separator must be a double colon
+        use to_import::check;
+
+        let _arr = Some(self.0).map(|x| [x * 2; 3]);
+        check(&self.0)
+    }
+}
+
+fn main() {
+    let s = S(0);
+    s.foo();
+}
diff --git a/tests/ui/parser/triple-colon-delegation.stderr b/tests/ui/parser/triple-colon-delegation.stderr
new file mode 100644
index 00000000000..d748c7d92b5
--- /dev/null
+++ b/tests/ui/parser/triple-colon-delegation.stderr
@@ -0,0 +1,38 @@
+error: path separator must be a double colon
+  --> $DIR/triple-colon-delegation.rs:20:18
+   |
+LL |     reuse Trait:::foo;
+   |                  ^
+   |
+help: use a double colon instead
+   |
+LL -     reuse Trait:::foo;
+LL +     reuse Trait::foo;
+   |
+
+error: path separator must be a double colon
+  --> $DIR/triple-colon-delegation.rs:21:21
+   |
+LL |     reuse to_reuse:::bar;
+   |                     ^
+   |
+help: use a double colon instead
+   |
+LL -     reuse to_reuse:::bar;
+LL +     reuse to_reuse::bar;
+   |
+
+error: path separator must be a double colon
+  --> $DIR/triple-colon-delegation.rs:33:18
+   |
+LL |     reuse Trait:::* {
+   |                  ^
+   |
+help: use a double colon instead
+   |
+LL -     reuse Trait:::* {
+LL +     reuse Trait::* {
+   |
+
+error: aborting due to 3 previous errors
+
diff --git a/tests/ui/parser/triple-colon.fixed b/tests/ui/parser/triple-colon.fixed
new file mode 100644
index 00000000000..168e4c1f618
--- /dev/null
+++ b/tests/ui/parser/triple-colon.fixed
@@ -0,0 +1,23 @@
+//@ run-rustfix
+
+#![allow(unused)]
+
+use ::std::{cell as _}; //~ ERROR path separator must be a double colon
+use std::cell::*; //~ ERROR path separator must be a double colon
+use std::cell::Cell; //~ ERROR path separator must be a double colon
+use std::{cell as _}; //~ ERROR path separator must be a double colon
+
+mod foo{
+    use ::{}; //~ ERROR path separator must be a double colon
+    use ::*; //~ ERROR path separator must be a double colon
+}
+
+fn main() {
+    let c: ::std::cell::Cell::<u8> = Cell::<u8>::new(0);
+    //~^ ERROR path separator must be a double colon
+    //~| ERROR path separator must be a double colon
+    //~| ERROR path separator must be a double colon
+    //~| ERROR path separator must be a double colon
+    //~| ERROR path separator must be a double colon
+    //~| ERROR path separator must be a double colon
+}
diff --git a/tests/ui/parser/triple-colon.rs b/tests/ui/parser/triple-colon.rs
new file mode 100644
index 00000000000..1a70012685f
--- /dev/null
+++ b/tests/ui/parser/triple-colon.rs
@@ -0,0 +1,23 @@
+//@ run-rustfix
+
+#![allow(unused)]
+
+use :::std::{cell as _}; //~ ERROR path separator must be a double colon
+use std::cell:::*; //~ ERROR path separator must be a double colon
+use std::cell:::Cell; //~ ERROR path separator must be a double colon
+use std:::{cell as _}; //~ ERROR path separator must be a double colon
+
+mod foo{
+    use :::{}; //~ ERROR path separator must be a double colon
+    use :::*; //~ ERROR path separator must be a double colon
+}
+
+fn main() {
+    let c: :::std:::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+    //~^ ERROR path separator must be a double colon
+    //~| ERROR path separator must be a double colon
+    //~| ERROR path separator must be a double colon
+    //~| ERROR path separator must be a double colon
+    //~| ERROR path separator must be a double colon
+    //~| ERROR path separator must be a double colon
+}
diff --git a/tests/ui/parser/triple-colon.stderr b/tests/ui/parser/triple-colon.stderr
new file mode 100644
index 00000000000..8d57fd7ebc9
--- /dev/null
+++ b/tests/ui/parser/triple-colon.stderr
@@ -0,0 +1,146 @@
+error: path separator must be a double colon
+  --> $DIR/triple-colon.rs:5:7
+   |
+LL | use :::std::{cell as _};
+   |       ^
+   |
+help: use a double colon instead
+   |
+LL - use :::std::{cell as _};
+LL + use ::std::{cell as _};
+   |
+
+error: path separator must be a double colon
+  --> $DIR/triple-colon.rs:6:16
+   |
+LL | use std::cell:::*;
+   |                ^
+   |
+help: use a double colon instead
+   |
+LL - use std::cell:::*;
+LL + use std::cell::*;
+   |
+
+error: path separator must be a double colon
+  --> $DIR/triple-colon.rs:7:16
+   |
+LL | use std::cell:::Cell;
+   |                ^
+   |
+help: use a double colon instead
+   |
+LL - use std::cell:::Cell;
+LL + use std::cell::Cell;
+   |
+
+error: path separator must be a double colon
+  --> $DIR/triple-colon.rs:8:10
+   |
+LL | use std:::{cell as _};
+   |          ^
+   |
+help: use a double colon instead
+   |
+LL - use std:::{cell as _};
+LL + use std::{cell as _};
+   |
+
+error: path separator must be a double colon
+  --> $DIR/triple-colon.rs:11:11
+   |
+LL |     use :::{};
+   |           ^
+   |
+help: use a double colon instead
+   |
+LL -     use :::{};
+LL +     use ::{};
+   |
+
+error: path separator must be a double colon
+  --> $DIR/triple-colon.rs:12:11
+   |
+LL |     use :::*;
+   |           ^
+   |
+help: use a double colon instead
+   |
+LL -     use :::*;
+LL +     use ::*;
+   |
+
+error: path separator must be a double colon
+  --> $DIR/triple-colon.rs:16:14
+   |
+LL |     let c: :::std:::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+   |              ^
+   |
+help: use a double colon instead
+   |
+LL -     let c: :::std:::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+LL +     let c: ::std:::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+   |
+
+error: path separator must be a double colon
+  --> $DIR/triple-colon.rs:16:20
+   |
+LL |     let c: :::std:::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+   |                    ^
+   |
+help: use a double colon instead
+   |
+LL -     let c: :::std:::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+LL +     let c: :::std::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+   |
+
+error: path separator must be a double colon
+  --> $DIR/triple-colon.rs:16:27
+   |
+LL |     let c: :::std:::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+   |                           ^
+   |
+help: use a double colon instead
+   |
+LL -     let c: :::std:::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+LL +     let c: :::std:::cell::Cell:::<u8> = Cell:::<u8>:::new(0);
+   |
+
+error: path separator must be a double colon
+  --> $DIR/triple-colon.rs:16:34
+   |
+LL |     let c: :::std:::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+   |                                  ^
+   |
+help: use a double colon instead
+   |
+LL -     let c: :::std:::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+LL +     let c: :::std:::cell:::Cell::<u8> = Cell:::<u8>:::new(0);
+   |
+
+error: path separator must be a double colon
+  --> $DIR/triple-colon.rs:16:48
+   |
+LL |     let c: :::std:::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+   |                                                ^
+   |
+help: use a double colon instead
+   |
+LL -     let c: :::std:::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+LL +     let c: :::std:::cell:::Cell:::<u8> = Cell::<u8>:::new(0);
+   |
+
+error: path separator must be a double colon
+  --> $DIR/triple-colon.rs:16:55
+   |
+LL |     let c: :::std:::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+   |                                                       ^
+   |
+help: use a double colon instead
+   |
+LL -     let c: :::std:::cell:::Cell:::<u8> = Cell:::<u8>:::new(0);
+LL +     let c: :::std:::cell:::Cell:::<u8> = Cell:::<u8>::new(0);
+   |
+
+error: aborting due to 12 previous errors
+
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs
new file mode 100644
index 00000000000..a66c4464417
--- /dev/null
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.rs
@@ -0,0 +1,16 @@
+// Make sure we consider `!` to be a union read.
+
+#![feature(never_type, never_patterns)]
+//~^ WARN the feature `never_patterns` is incomplete
+
+union U {
+    a: !,
+    b: usize,
+}
+
+fn foo<T>(u: U) -> ! {
+    let U { a: ! } = u;
+    //~^ ERROR access to union field is unsafe
+}
+
+fn main() {}
diff --git a/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr
new file mode 100644
index 00000000000..d7dc7a47e72
--- /dev/null
+++ b/tests/ui/rfcs/rfc-0000-never_patterns/never-pattern-is-a-read.stderr
@@ -0,0 +1,20 @@
+warning: the feature `never_patterns` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/never-pattern-is-a-read.rs:3:24
+   |
+LL | #![feature(never_type, never_patterns)]
+   |                        ^^^^^^^^^^^^^^
+   |
+   = note: see issue #118155 <https://github.com/rust-lang/rust/issues/118155> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/never-pattern-is-a-read.rs:12:16
+   |
+LL |     let U { a: ! } = u;
+   |                ^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/rust-2024/raw-gen-lt.rs b/tests/ui/rust-2024/raw-gen-lt.rs
new file mode 100644
index 00000000000..b2df217d1a1
--- /dev/null
+++ b/tests/ui/rust-2024/raw-gen-lt.rs
@@ -0,0 +1,8 @@
+//@ edition: 2021
+//@ check-pass
+
+#![deny(keyword_idents_2024)]
+
+fn foo<'r#gen>() {}
+
+fn main() {}
diff --git a/tests/ui/self/where-for-self.rs b/tests/ui/self/where-for-self.rs
index 9b4e8325664..d31bb1f22c4 100644
--- a/tests/ui/self/where-for-self.rs
+++ b/tests/ui/self/where-for-self.rs
@@ -2,6 +2,8 @@
 // Test that we can quantify lifetimes outside a constraint (i.e., including
 // the self type) in a where clause.
 
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
 
 static mut COUNT: u32 = 1;
 
diff --git a/tests/ui/simd/simd-bitmask-notpow2.rs b/tests/ui/simd/simd-bitmask-notpow2.rs
index ff43206a3fd..3499bf33ed5 100644
--- a/tests/ui/simd/simd-bitmask-notpow2.rs
+++ b/tests/ui/simd/simd-bitmask-notpow2.rs
@@ -1,7 +1,6 @@
 //@run-pass
-// SEGFAULTS on LLVM 17. This should be merged into `simd-bitmask` once we require LLVM 18.
-//@ min-llvm-version: 18
 // FIXME: broken codegen on big-endian (https://github.com/rust-lang/rust/issues/127205)
+// This should be merged into `simd-bitmask` once that's fixed.
 //@ ignore-endian-big
 #![feature(repr_simd, intrinsics)]
 
diff --git a/tests/ui/static/reference-to-mut-static-safe.e2021.stderr b/tests/ui/static/reference-to-mut-static-safe.e2021.stderr
deleted file mode 100644
index 9fdfc00dfcd..00000000000
--- a/tests/ui/static/reference-to-mut-static-safe.e2021.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-warning: creating a shared reference to mutable static is discouraged
-  --> $DIR/reference-to-mut-static-safe.rs:9:14
-   |
-LL |     let _x = &X;
-   |              ^^ shared reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-   = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |     let _x = addr_of!(X);
-   |              ~~~~~~~~~ +
-
-error[E0133]: use of mutable static is unsafe and requires unsafe function or block
-  --> $DIR/reference-to-mut-static-safe.rs:9:15
-   |
-LL |     let _x = &X;
-   |               ^ use of mutable static
-   |
-   = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
-
-error: aborting due to 1 previous error; 1 warning emitted
-
-For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/static/reference-to-mut-static-safe.e2024.stderr b/tests/ui/static/reference-to-mut-static-safe.e2024.stderr
deleted file mode 100644
index b3e0c84d1d8..00000000000
--- a/tests/ui/static/reference-to-mut-static-safe.e2024.stderr
+++ /dev/null
@@ -1,24 +0,0 @@
-error[E0796]: creating a shared reference to a mutable static
-  --> $DIR/reference-to-mut-static-safe.rs:9:14
-   |
-LL |     let _x = &X;
-   |              ^^ shared reference to mutable static
-   |
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |     let _x = addr_of!(X);
-   |              ~~~~~~~~~ +
-
-error[E0133]: use of mutable static is unsafe and requires unsafe block
-  --> $DIR/reference-to-mut-static-safe.rs:9:15
-   |
-LL |     let _x = &X;
-   |               ^ use of mutable static
-   |
-   = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0133, E0796.
-For more information about an error, try `rustc --explain E0133`.
diff --git a/tests/ui/static/reference-to-mut-static-safe.rs b/tests/ui/static/reference-to-mut-static-safe.rs
deleted file mode 100644
index 98afdadf4d2..00000000000
--- a/tests/ui/static/reference-to-mut-static-safe.rs
+++ /dev/null
@@ -1,13 +0,0 @@
-//@ revisions: e2021 e2024
-
-//@ [e2021] edition:2021
-//@ [e2024] compile-flags: --edition 2024 -Z unstable-options
-
-fn main() {
-    static mut X: i32 = 1;
-
-    let _x = &X;
-    //[e2024]~^ creating a shared reference to a mutable static [E0796]
-    //~^^ use of mutable static is unsafe and requires unsafe
-    //[e2021]~^^^ shared reference to mutable static is discouraged [static_mut_refs]
-}
diff --git a/tests/ui/static/reference-to-mut-static-unsafe-fn.rs b/tests/ui/static/reference-to-mut-static-unsafe-fn.rs
deleted file mode 100644
index d63fd5460d8..00000000000
--- a/tests/ui/static/reference-to-mut-static-unsafe-fn.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-//@ compile-flags: --edition 2024 -Z unstable-options
-
-fn main() {}
-
-unsafe fn _foo() {
-    unsafe {
-        static mut X: i32 = 1;
-        static mut Y: i32 = 1;
-
-        let _y = &X;
-        //~^ ERROR creating a shared reference to a mutable static [E0796]
-
-        let ref _a = X;
-        //~^ ERROR creating a shared reference to a mutable static [E0796]
-
-        let ref mut _a = X;
-        //~^ ERROR creating a mutable reference to a mutable static [E0796]
-
-        let (_b, _c) = (&X, &mut Y);
-        //~^ ERROR creating a shared reference to a mutable static [E0796]
-        //~^^ ERROR creating a mutable reference to a mutable static [E0796]
-
-        foo(&X);
-        //~^ ERROR creating a shared reference to a mutable static [E0796]
-    }
-}
-
-fn foo<'a>(_x: &'a i32) {}
diff --git a/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr b/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr
deleted file mode 100644
index ca9cfbf7ac7..00000000000
--- a/tests/ui/static/reference-to-mut-static-unsafe-fn.stderr
+++ /dev/null
@@ -1,75 +0,0 @@
-error[E0796]: creating a shared reference to a mutable static
-  --> $DIR/reference-to-mut-static-unsafe-fn.rs:10:18
-   |
-LL |         let _y = &X;
-   |                  ^^ shared reference to mutable static
-   |
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |         let _y = addr_of!(X);
-   |                  ~~~~~~~~~ +
-
-error[E0796]: creating a shared reference to a mutable static
-  --> $DIR/reference-to-mut-static-unsafe-fn.rs:13:22
-   |
-LL |         let ref _a = X;
-   |                      ^ shared reference to mutable static
-   |
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |         let ref _a = addr_of!(X);
-   |                      +++++++++ +
-
-error[E0796]: creating a mutable reference to a mutable static
-  --> $DIR/reference-to-mut-static-unsafe-fn.rs:16:26
-   |
-LL |         let ref mut _a = X;
-   |                          ^ mutable reference to mutable static
-   |
-   = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
-help: use `addr_of_mut!` instead to create a raw pointer
-   |
-LL |         let ref mut _a = addr_of_mut!(X);
-   |                          +++++++++++++ +
-
-error[E0796]: creating a shared reference to a mutable static
-  --> $DIR/reference-to-mut-static-unsafe-fn.rs:19:25
-   |
-LL |         let (_b, _c) = (&X, &mut Y);
-   |                         ^^ shared reference to mutable static
-   |
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |         let (_b, _c) = (addr_of!(X), &mut Y);
-   |                         ~~~~~~~~~ +
-
-error[E0796]: creating a mutable reference to a mutable static
-  --> $DIR/reference-to-mut-static-unsafe-fn.rs:19:29
-   |
-LL |         let (_b, _c) = (&X, &mut Y);
-   |                             ^^^^^^ mutable reference to mutable static
-   |
-   = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
-help: use `addr_of_mut!` instead to create a raw pointer
-   |
-LL |         let (_b, _c) = (&X, addr_of_mut!(Y));
-   |                             ~~~~~~~~~~~~~ +
-
-error[E0796]: creating a shared reference to a mutable static
-  --> $DIR/reference-to-mut-static-unsafe-fn.rs:23:13
-   |
-LL |         foo(&X);
-   |             ^^ shared reference to mutable static
-   |
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |         foo(addr_of!(X));
-   |             ~~~~~~~~~ +
-
-error: aborting due to 6 previous errors
-
-For more information about this error, try `rustc --explain E0796`.
diff --git a/tests/ui/static/reference-to-mut-static.e2021.stderr b/tests/ui/static/reference-to-mut-static.e2021.stderr
deleted file mode 100644
index 667d7602f34..00000000000
--- a/tests/ui/static/reference-to-mut-static.e2021.stderr
+++ /dev/null
@@ -1,91 +0,0 @@
-error: creating a shared reference to mutable static is discouraged
-  --> $DIR/reference-to-mut-static.rs:16:18
-   |
-LL |         let _y = &X;
-   |                  ^^ shared reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-note: the lint level is defined here
-  --> $DIR/reference-to-mut-static.rs:6:9
-   |
-LL | #![deny(static_mut_refs)]
-   |         ^^^^^^^^^^^^^^^
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |         let _y = addr_of!(X);
-   |                  ~~~~~~~~~ +
-
-error: creating a mutable reference to mutable static is discouraged
-  --> $DIR/reference-to-mut-static.rs:20:18
-   |
-LL |         let _y = &mut X;
-   |                  ^^^^^^ mutable reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
-help: use `addr_of_mut!` instead to create a raw pointer
-   |
-LL |         let _y = addr_of_mut!(X);
-   |                  ~~~~~~~~~~~~~ +
-
-error: creating a shared reference to mutable static is discouraged
-  --> $DIR/reference-to-mut-static.rs:28:22
-   |
-LL |         let ref _a = X;
-   |                      ^ shared reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |         let ref _a = addr_of!(X);
-   |                      +++++++++ +
-
-error: creating a shared reference to mutable static is discouraged
-  --> $DIR/reference-to-mut-static.rs:32:25
-   |
-LL |         let (_b, _c) = (&X, &Y);
-   |                         ^^ shared reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |         let (_b, _c) = (addr_of!(X), &Y);
-   |                         ~~~~~~~~~ +
-
-error: creating a shared reference to mutable static is discouraged
-  --> $DIR/reference-to-mut-static.rs:32:29
-   |
-LL |         let (_b, _c) = (&X, &Y);
-   |                             ^^ shared reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |         let (_b, _c) = (&X, addr_of!(Y));
-   |                             ~~~~~~~~~ +
-
-error: creating a shared reference to mutable static is discouraged
-  --> $DIR/reference-to-mut-static.rs:38:13
-   |
-LL |         foo(&X);
-   |             ^^ shared reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |         foo(addr_of!(X));
-   |             ~~~~~~~~~ +
-
-error: aborting due to 6 previous errors
-
diff --git a/tests/ui/static/reference-to-mut-static.e2024.stderr b/tests/ui/static/reference-to-mut-static.e2024.stderr
deleted file mode 100644
index e77f4355466..00000000000
--- a/tests/ui/static/reference-to-mut-static.e2024.stderr
+++ /dev/null
@@ -1,75 +0,0 @@
-error[E0796]: creating a shared reference to a mutable static
-  --> $DIR/reference-to-mut-static.rs:16:18
-   |
-LL |         let _y = &X;
-   |                  ^^ shared reference to mutable static
-   |
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |         let _y = addr_of!(X);
-   |                  ~~~~~~~~~ +
-
-error[E0796]: creating a mutable reference to a mutable static
-  --> $DIR/reference-to-mut-static.rs:20:18
-   |
-LL |         let _y = &mut X;
-   |                  ^^^^^^ mutable reference to mutable static
-   |
-   = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
-help: use `addr_of_mut!` instead to create a raw pointer
-   |
-LL |         let _y = addr_of_mut!(X);
-   |                  ~~~~~~~~~~~~~ +
-
-error[E0796]: creating a shared reference to a mutable static
-  --> $DIR/reference-to-mut-static.rs:28:22
-   |
-LL |         let ref _a = X;
-   |                      ^ shared reference to mutable static
-   |
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |         let ref _a = addr_of!(X);
-   |                      +++++++++ +
-
-error[E0796]: creating a shared reference to a mutable static
-  --> $DIR/reference-to-mut-static.rs:32:25
-   |
-LL |         let (_b, _c) = (&X, &Y);
-   |                         ^^ shared reference to mutable static
-   |
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |         let (_b, _c) = (addr_of!(X), &Y);
-   |                         ~~~~~~~~~ +
-
-error[E0796]: creating a shared reference to a mutable static
-  --> $DIR/reference-to-mut-static.rs:32:29
-   |
-LL |         let (_b, _c) = (&X, &Y);
-   |                             ^^ shared reference to mutable static
-   |
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |         let (_b, _c) = (&X, addr_of!(Y));
-   |                             ~~~~~~~~~ +
-
-error[E0796]: creating a shared reference to a mutable static
-  --> $DIR/reference-to-mut-static.rs:38:13
-   |
-LL |         foo(&X);
-   |             ^^ shared reference to mutable static
-   |
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |         foo(addr_of!(X));
-   |             ~~~~~~~~~ +
-
-error: aborting due to 6 previous errors
-
-For more information about this error, try `rustc --explain E0796`.
diff --git a/tests/ui/static/reference-to-mut-static.rs b/tests/ui/static/reference-to-mut-static.rs
deleted file mode 100644
index af2cab7dd87..00000000000
--- a/tests/ui/static/reference-to-mut-static.rs
+++ /dev/null
@@ -1,50 +0,0 @@
-//@ revisions: e2021 e2024
-
-//@ [e2021] edition:2021
-//@ [e2024] compile-flags: --edition 2024 -Z unstable-options
-
-#![deny(static_mut_refs)]
-
-use std::ptr::{addr_of, addr_of_mut};
-
-fn main() {
-    static mut X: i32 = 1;
-
-    static mut Y: i32 = 1;
-
-    unsafe {
-        let _y = &X;
-        //[e2024]~^ ERROR creating a shared reference to a mutable static [E0796]
-        //[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
-
-        let _y = &mut X;
-        //[e2024]~^ ERROR creating a mutable reference to a mutable static [E0796]
-        //[e2021]~^^ ERROR mutable reference to mutable static is discouraged [static_mut_refs]
-
-        let _z = addr_of_mut!(X);
-
-        let _p = addr_of!(X);
-
-        let ref _a = X;
-        //[e2024]~^ ERROR creating a shared reference to a mutable static [E0796]
-        //[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
-
-        let (_b, _c) = (&X, &Y);
-        //[e2024]~^ ERROR creating a shared reference to a mutable static [E0796]
-        //[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
-        //[e2024]~^^^ ERROR creating a shared reference to a mutable static [E0796]
-        //[e2021]~^^^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
-
-        foo(&X);
-        //[e2024]~^ ERROR creating a shared reference to a mutable static [E0796]
-        //[e2021]~^^ ERROR shared reference to mutable static is discouraged [static_mut_refs]
-
-        static mut Z: &[i32; 3] = &[0, 1, 2];
-
-        let _ = Z.len();
-        let _ = Z[0];
-        let _ = format!("{:?}", Z);
-    }
-}
-
-fn foo<'a>(_x: &'a i32) {}
diff --git a/tests/ui/static/safe-extern-statics-mut.rs b/tests/ui/static/safe-extern-statics-mut.rs
index 05a1bee8891..4dfcd41b73c 100644
--- a/tests/ui/static/safe-extern-statics-mut.rs
+++ b/tests/ui/static/safe-extern-statics-mut.rs
@@ -10,8 +10,6 @@ extern "C" {
 fn main() {
     let b = B; //~ ERROR use of mutable static is unsafe
     let rb = &B; //~ ERROR use of mutable static is unsafe
-    //~^ WARN shared reference to mutable static is discouraged [static_mut_refs]
     let xb = XB; //~ ERROR use of mutable static is unsafe
     let xrb = &XB; //~ ERROR use of mutable static is unsafe
-    //~^ WARN shared reference to mutable static is discouraged [static_mut_refs]
 }
diff --git a/tests/ui/static/safe-extern-statics-mut.stderr b/tests/ui/static/safe-extern-statics-mut.stderr
index 7705a897e27..e390625f20a 100644
--- a/tests/ui/static/safe-extern-statics-mut.stderr
+++ b/tests/ui/static/safe-extern-statics-mut.stderr
@@ -1,32 +1,3 @@
-warning: creating a shared reference to mutable static is discouraged
-  --> $DIR/safe-extern-statics-mut.rs:12:14
-   |
-LL |     let rb = &B;
-   |              ^^ shared reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-   = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |     let rb = addr_of!(B);
-   |              ~~~~~~~~~ +
-
-warning: creating a shared reference to mutable static is discouraged
-  --> $DIR/safe-extern-statics-mut.rs:15:15
-   |
-LL |     let xrb = &XB;
-   |               ^^^ shared reference to mutable static
-   |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-help: use `addr_of!` instead to create a raw pointer
-   |
-LL |     let xrb = addr_of!(XB);
-   |               ~~~~~~~~~  +
-
 error[E0133]: use of mutable static is unsafe and requires unsafe function or block
   --> $DIR/safe-extern-statics-mut.rs:11:13
    |
@@ -44,7 +15,7 @@ LL |     let rb = &B;
    = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
 
 error[E0133]: use of mutable static is unsafe and requires unsafe function or block
-  --> $DIR/safe-extern-statics-mut.rs:14:14
+  --> $DIR/safe-extern-statics-mut.rs:13:14
    |
 LL |     let xb = XB;
    |              ^^ use of mutable static
@@ -52,13 +23,13 @@ LL |     let xb = XB;
    = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
 
 error[E0133]: use of mutable static is unsafe and requires unsafe function or block
-  --> $DIR/safe-extern-statics-mut.rs:15:16
+  --> $DIR/safe-extern-statics-mut.rs:14:16
    |
 LL |     let xrb = &XB;
    |                ^^ use of mutable static
    |
    = note: mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
 
-error: aborting due to 4 previous errors; 2 warnings emitted
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/statics/issue-15261.stderr b/tests/ui/statics/issue-15261.stderr
index 6035eef5b71..417dbae9db1 100644
--- a/tests/ui/statics/issue-15261.stderr
+++ b/tests/ui/statics/issue-15261.stderr
@@ -4,14 +4,13 @@ warning: creating a shared reference to mutable static is discouraged
 LL | static n: &'static usize = unsafe { &n_mut };
    |                                     ^^^^^^ shared reference to mutable static
    |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
    = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of!` instead to create a raw pointer
+help: use `&raw const` instead to create a raw pointer
    |
-LL | static n: &'static usize = unsafe { addr_of!(n_mut) };
-   |                                     ~~~~~~~~~     +
+LL | static n: &'static usize = unsafe { &raw const n_mut };
+   |                                     ~~~~~~~~~~
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/statics/static-mut-xc.rs b/tests/ui/statics/static-mut-xc.rs
index a772d4151f7..c23cc822ce7 100644
--- a/tests/ui/statics/static-mut-xc.rs
+++ b/tests/ui/statics/static-mut-xc.rs
@@ -17,14 +17,19 @@ fn static_bound_set(a: &'static mut isize) {
 
 unsafe fn run() {
     assert_eq!(static_mut_xc::a, 3);
+    //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
     static_mut_xc::a = 4;
     assert_eq!(static_mut_xc::a, 4);
+    //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
     static_mut_xc::a += 1;
     assert_eq!(static_mut_xc::a, 5);
+    //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
     static_mut_xc::a *= 3;
     assert_eq!(static_mut_xc::a, 15);
+    //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
     static_mut_xc::a = -3;
     assert_eq!(static_mut_xc::a, -3);
+    //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
     static_bound(&static_mut_xc::a);
     //~^ WARN shared reference to mutable static is discouraged [static_mut_refs]
     static_bound_set(&mut static_mut_xc::a);
diff --git a/tests/ui/statics/static-mut-xc.stderr b/tests/ui/statics/static-mut-xc.stderr
index 9751f754332..176deb518fc 100644
--- a/tests/ui/statics/static-mut-xc.stderr
+++ b/tests/ui/statics/static-mut-xc.stderr
@@ -1,31 +1,74 @@
 warning: creating a shared reference to mutable static is discouraged
-  --> $DIR/static-mut-xc.rs:28:18
+  --> $DIR/static-mut-xc.rs:19:16
+   |
+LL |     assert_eq!(static_mut_xc::a, 3);
+   |                ^^^^^^^^^^^^^^^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+   = note: `#[warn(static_mut_refs)]` on by default
+
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-xc.rs:22:16
+   |
+LL |     assert_eq!(static_mut_xc::a, 4);
+   |                ^^^^^^^^^^^^^^^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-xc.rs:25:16
+   |
+LL |     assert_eq!(static_mut_xc::a, 5);
+   |                ^^^^^^^^^^^^^^^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-xc.rs:28:16
+   |
+LL |     assert_eq!(static_mut_xc::a, 15);
+   |                ^^^^^^^^^^^^^^^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-xc.rs:31:16
+   |
+LL |     assert_eq!(static_mut_xc::a, -3);
+   |                ^^^^^^^^^^^^^^^^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-mut-xc.rs:33:18
    |
 LL |     static_bound(&static_mut_xc::a);
    |                  ^^^^^^^^^^^^^^^^^ shared reference to mutable static
    |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
-   = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of!` instead to create a raw pointer
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+help: use `&raw const` instead to create a raw pointer
    |
-LL |     static_bound(addr_of!(static_mut_xc::a));
-   |                  ~~~~~~~~~                +
+LL |     static_bound(&raw const static_mut_xc::a);
+   |                  ~~~~~~~~~~
 
 warning: creating a mutable reference to mutable static is discouraged
-  --> $DIR/static-mut-xc.rs:30:22
+  --> $DIR/static-mut-xc.rs:35:22
    |
 LL |     static_bound_set(&mut static_mut_xc::a);
    |                      ^^^^^^^^^^^^^^^^^^^^^ mutable reference to mutable static
    |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this mutable reference has lifetime `'static`, but if the static gets accessed (read or written) by any other means, or any other reference is created, then any further use of this mutable reference is Undefined Behavior
-help: use `addr_of_mut!` instead to create a raw pointer
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: mutable references to mutable statics are dangerous; it's undefined behavior if any other pointer to the static is used or if any other reference is created for the static while the mutable reference lives
+help: use `&raw mut` instead to create a raw pointer
    |
-LL |     static_bound_set(addr_of_mut!(static_mut_xc::a));
-   |                      ~~~~~~~~~~~~~                +
+LL |     static_bound_set(&raw mut static_mut_xc::a);
+   |                      ~~~~~~~~
 
-warning: 2 warnings emitted
+warning: 7 warnings emitted
 
diff --git a/tests/ui/statics/static-recursive.rs b/tests/ui/statics/static-recursive.rs
index 29b80818b7d..da23b54d1fc 100644
--- a/tests/ui/statics/static-recursive.rs
+++ b/tests/ui/statics/static-recursive.rs
@@ -17,6 +17,7 @@ static L3: StaticDoubleLinked = StaticDoubleLinked { prev: &L2, next: &L1, data:
 pub fn main() {
     unsafe {
         assert_eq!(S, *(S as *const *const u8));
+        //~^ WARN creating a shared reference to mutable static is discouraged [static_mut_refs]
     }
 
     let mut test_vec = Vec::new();
diff --git a/tests/ui/statics/static-recursive.stderr b/tests/ui/statics/static-recursive.stderr
index a7a1a1610af..f2dd5b8a6cf 100644
--- a/tests/ui/statics/static-recursive.stderr
+++ b/tests/ui/statics/static-recursive.stderr
@@ -4,14 +4,22 @@ warning: creating a shared reference to mutable static is discouraged
 LL | static mut S: *const u8 = unsafe { &S as *const *const u8 as *const u8 };
    |                                    ^^ shared reference to mutable static
    |
-   = note: for more information, see issue #114447 <https://github.com/rust-lang/rust/issues/114447>
-   = note: this will be a hard error in the 2024 edition
-   = note: this shared reference has lifetime `'static`, but if the static ever gets mutated, or a mutable reference is created, then any further use of this shared reference is Undefined Behavior
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
    = note: `#[warn(static_mut_refs)]` on by default
-help: use `addr_of!` instead to create a raw pointer
+help: use `&raw const` instead to create a raw pointer
    |
-LL | static mut S: *const u8 = unsafe { addr_of!(S) as *const *const u8 as *const u8 };
-   |                                    ~~~~~~~~~ +
+LL | static mut S: *const u8 = unsafe { &raw const S as *const *const u8 as *const u8 };
+   |                                    ~~~~~~~~~~
 
-warning: 1 warning emitted
+warning: creating a shared reference to mutable static is discouraged
+  --> $DIR/static-recursive.rs:19:20
+   |
+LL |         assert_eq!(S, *(S as *const *const u8));
+   |                    ^ shared reference to mutable static
+   |
+   = note: for more information, see <https://doc.rust-lang.org/nightly/edition-guide/rust-2024/static-mut-references.html>
+   = note: shared references to mutable statics are dangerous; it's undefined behavior if the static is mutated or if a mutable reference is created for it while the shared reference lives
+
+warning: 2 warnings emitted
 
diff --git a/tests/ui/structs-enums/type-sizes.rs b/tests/ui/structs-enums/type-sizes.rs
index 5ca9c8678b7..f49ce33841a 100644
--- a/tests/ui/structs-enums/type-sizes.rs
+++ b/tests/ui/structs-enums/type-sizes.rs
@@ -209,6 +209,23 @@ struct ReorderEndNiche {
     b: MiddleNiche4,
 }
 
+// We want that the niche selection doesn't depend on order of the fields. See issue #125630.
+pub enum NicheFieldOrder1 {
+    A {
+        x: NonZero<u64>,
+        y: [NonZero<u64>; 2],
+    },
+    B([u64; 2]),
+}
+
+pub enum NicheFieldOrder2 {
+    A {
+        y: [NonZero<u64>; 2],
+        x: NonZero<u64>,
+    },
+    B([u64; 2]),
+}
+
 
 // standins for std types which we want to be laid out in a reasonable way
 struct RawVecDummy {
@@ -260,6 +277,9 @@ pub fn main() {
                size_of::<EnumWithMaybeUninhabitedVariant<()>>());
     assert_eq!(size_of::<NicheFilledEnumWithAbsentVariant>(), size_of::<&'static ()>());
 
+    assert_eq!(size_of::<NicheFieldOrder1>(), 24);
+    assert_eq!(size_of::<NicheFieldOrder2>(), 24);
+
     assert_eq!(size_of::<Option<Option<(bool, &())>>>(), size_of::<(bool, &())>());
     assert_eq!(size_of::<Option<Option<(&(), bool)>>>(), size_of::<(bool, &())>());
     assert_eq!(size_of::<Option<Option2<bool, &()>>>(), size_of::<(bool, &())>());
diff --git a/tests/ui/suggestions/mut-borrow-needed-by-trait.rs b/tests/ui/suggestions/mut-borrow-needed-by-trait.rs
index 924bfd82eb8..66e1e77c905 100644
--- a/tests/ui/suggestions/mut-borrow-needed-by-trait.rs
+++ b/tests/ui/suggestions/mut-borrow-needed-by-trait.rs
@@ -17,7 +17,6 @@ fn main() {
     let fp = BufWriter::new(fp);
     //~^ ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
     //~| ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
-    //~| ERROR the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
 
     writeln!(fp, "hello world").unwrap(); //~ ERROR the method
 }
diff --git a/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr b/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr
index b2f9150142f..09a9b1d3b34 100644
--- a/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr
+++ b/tests/ui/suggestions/mut-borrow-needed-by-trait.stderr
@@ -14,16 +14,6 @@ error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satis
   --> $DIR/mut-borrow-needed-by-trait.rs:17:14
    |
 LL |     let fp = BufWriter::new(fp);
-   |              ^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
-   |
-   = note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write`
-note: required by a bound in `BufWriter`
-  --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
-
-error[E0277]: the trait bound `&dyn std::io::Write: std::io::Write` is not satisfied
-  --> $DIR/mut-borrow-needed-by-trait.rs:17:14
-   |
-LL |     let fp = BufWriter::new(fp);
    |              ^^^^^^^^^^^^^^^^^^ the trait `std::io::Write` is not implemented for `&dyn std::io::Write`
    |
    = note: `std::io::Write` is implemented for `&mut dyn std::io::Write`, but not for `&dyn std::io::Write`
@@ -31,13 +21,13 @@ note: required by a bound in `BufWriter`
   --> $SRC_DIR/std/src/io/buffered/bufwriter.rs:LL:COL
 
 error[E0599]: the method `write_fmt` exists for struct `BufWriter<&dyn Write>`, but its trait bounds were not satisfied
-  --> $DIR/mut-borrow-needed-by-trait.rs:22:14
+  --> $DIR/mut-borrow-needed-by-trait.rs:21:14
    |
 LL |     writeln!(fp, "hello world").unwrap();
    |     ---------^^---------------- method cannot be called on `BufWriter<&dyn Write>` due to unsatisfied trait bounds
    |
 note: must implement `io::Write`, `fmt::Write`, or have a `write_fmt` method
-  --> $DIR/mut-borrow-needed-by-trait.rs:22:14
+  --> $DIR/mut-borrow-needed-by-trait.rs:21:14
    |
 LL |     writeln!(fp, "hello world").unwrap();
    |              ^^
@@ -45,7 +35,7 @@ LL |     writeln!(fp, "hello world").unwrap();
            `&dyn std::io::Write: std::io::Write`
            which is required by `BufWriter<&dyn std::io::Write>: std::io::Write`
 
-error: aborting due to 4 previous errors
+error: aborting due to 3 previous errors
 
 Some errors have detailed explanations: E0277, E0599.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/thread-local/thread-local-issue-37508.rs b/tests/ui/thread-local/thread-local-issue-37508.rs
index db430a3229c..34c39453451 100644
--- a/tests/ui/thread-local/thread-local-issue-37508.rs
+++ b/tests/ui/thread-local/thread-local-issue-37508.rs
@@ -4,6 +4,9 @@
 //
 // Regression test for issue #37508
 
+// FIXME(static_mut_refs): Do not allow `static_mut_refs` lint
+#![allow(static_mut_refs)]
+
 #![no_main]
 #![no_std]
 #![feature(thread_local, lang_items)]
diff --git a/tests/ui/traits/coherence-alias-hang.rs b/tests/ui/traits/coherence-alias-hang.rs
index 37b80739589..c2b4d2e42d2 100644
--- a/tests/ui/traits/coherence-alias-hang.rs
+++ b/tests/ui/traits/coherence-alias-hang.rs
@@ -1,4 +1,6 @@
 //@ check-pass
+//@ revisions: current next
+//[next]@ compile-flags: -Znext-solver
 
 // Regression test for nalgebra hang <https://github.com/rust-lang/rust/issues/130056>.
 
diff --git a/tests/ui/traits/impl.rs b/tests/ui/traits/impl.rs
index 348096f37f7..b45935fd86a 100644
--- a/tests/ui/traits/impl.rs
+++ b/tests/ui/traits/impl.rs
@@ -3,6 +3,9 @@
 
 //@ aux-build:traitimpl.rs
 
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
+
 extern crate traitimpl;
 use traitimpl::Bar;
 
diff --git a/tests/ui/traits/impl.stderr b/tests/ui/traits/impl.stderr
index 98b6fb03d83..9216a33c1d0 100644
--- a/tests/ui/traits/impl.stderr
+++ b/tests/ui/traits/impl.stderr
@@ -1,5 +1,5 @@
 warning: method `t` is never used
-  --> $DIR/impl.rs:12:8
+  --> $DIR/impl.rs:15:8
    |
 LL | trait T {
    |       - method in this trait
diff --git a/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
index 8d7d8cee08a..150100f2c53 100644
--- a/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
+++ b/tests/ui/traits/next-solver/cycles/coinduction/fixpoint-exponential-growth.stderr
@@ -4,6 +4,7 @@ error[E0275]: overflow evaluating the requirement `W<_>: Trait`
 LL |     impls::<W<_>>();
    |             ^^^^
    |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`fixpoint_exponential_growth`)
 note: required by a bound in `impls`
   --> $DIR/fixpoint-exponential-growth.rs:30:13
    |
diff --git a/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs
index 1b80287d9da..86d428cc0f0 100644
--- a/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs
+++ b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.rs
@@ -1,6 +1,7 @@
+//~ ERROR overflow evaluating the requirement `Self: Trait`
+//~^ ERROR overflow evaluating the requirement `Self well-formed`
 // This is a non-regression test for issue #115351, where a recursion limit of 0 caused an ICE.
 //@ compile-flags: -Znext-solver --crate-type=lib
-//@ check-pass
 
 #![recursion_limit = "0"]
 trait Trait {}
diff --git a/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr
new file mode 100644
index 00000000000..2eed7e8f723
--- /dev/null
+++ b/tests/ui/traits/next-solver/overflow/recursion-limit-zero-issue-115351.stderr
@@ -0,0 +1,11 @@
+error[E0275]: overflow evaluating the requirement `Self: Trait`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
+
+error[E0275]: overflow evaluating the requirement `Self well-formed`
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "2"]` attribute to your crate (`recursion_limit_zero_issue_115351`)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/sized-coniductive.rs b/tests/ui/traits/sized-coniductive.rs
new file mode 100644
index 00000000000..5f63b166f98
--- /dev/null
+++ b/tests/ui/traits/sized-coniductive.rs
@@ -0,0 +1,14 @@
+//@ check-pass
+// https://github.com/rust-lang/rust/issues/129541
+
+#[derive(Clone)]
+struct Test {
+    field: std::borrow::Cow<'static, [Self]>,
+}
+
+#[derive(Clone)]
+struct Hello {
+    a: <[Hello] as std::borrow::ToOwned>::Owned,
+}
+
+fn main(){}
diff --git a/tests/ui/typeck/auxiliary/foreign_struct_trait_unimplemented.rs b/tests/ui/typeck/auxiliary/foreign_struct_trait_unimplemented.rs
new file mode 100644
index 00000000000..097a269e8ee
--- /dev/null
+++ b/tests/ui/typeck/auxiliary/foreign_struct_trait_unimplemented.rs
@@ -0,0 +1 @@
+pub struct B;
diff --git a/tests/ui/typeck/foreign_struct_trait_unimplemented.rs b/tests/ui/typeck/foreign_struct_trait_unimplemented.rs
new file mode 100644
index 00000000000..8ac56bac9b0
--- /dev/null
+++ b/tests/ui/typeck/foreign_struct_trait_unimplemented.rs
@@ -0,0 +1,15 @@
+//@ aux-build:foreign_struct_trait_unimplemented.rs
+
+extern crate foreign_struct_trait_unimplemented;
+
+pub trait Test {}
+
+struct A;
+impl Test for A {}
+
+fn needs_test(_: impl Test) {}
+
+fn main() {
+    needs_test(foreign_struct_trait_unimplemented::B);
+    //~^ ERROR the trait bound `B: Test` is not satisfied
+}
diff --git a/tests/ui/typeck/foreign_struct_trait_unimplemented.stderr b/tests/ui/typeck/foreign_struct_trait_unimplemented.stderr
new file mode 100644
index 00000000000..b9bb97548f6
--- /dev/null
+++ b/tests/ui/typeck/foreign_struct_trait_unimplemented.stderr
@@ -0,0 +1,23 @@
+error[E0277]: the trait bound `B: Test` is not satisfied
+  --> $DIR/foreign_struct_trait_unimplemented.rs:13:16
+   |
+LL |     needs_test(foreign_struct_trait_unimplemented::B);
+   |     ---------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Test` is not implemented for `B`
+   |     |
+   |     required by a bound introduced by this call
+   |
+help: there are multiple different versions of crate `foreign_struct_trait_unimplemented` in the dependency graph
+  --> $DIR/foreign_struct_trait_unimplemented.rs:3:1
+   |
+LL | extern crate foreign_struct_trait_unimplemented;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one version of crate `foreign_struct_trait_unimplemented` is used here, as a direct dependency of the current crate
+   = help: you can use `cargo tree` to explore your dependency tree
+note: required by a bound in `needs_test`
+  --> $DIR/foreign_struct_trait_unimplemented.rs:10:23
+   |
+LL | fn needs_test(_: impl Test) {}
+   |                       ^^^^ required by this bound in `needs_test`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/union/union-drop-assign.rs b/tests/ui/union/union-drop-assign.rs
index e9165fddc51..451fb14eddf 100644
--- a/tests/ui/union/union-drop-assign.rs
+++ b/tests/ui/union/union-drop-assign.rs
@@ -3,6 +3,9 @@
 
 // Drop works for union itself.
 
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
+
 use std::mem::ManuallyDrop;
 
 struct S;
diff --git a/tests/ui/union/union-drop.rs b/tests/ui/union/union-drop.rs
index e467eda2935..6f6d5c14165 100644
--- a/tests/ui/union/union-drop.rs
+++ b/tests/ui/union/union-drop.rs
@@ -2,6 +2,8 @@
 
 #![allow(dead_code)]
 #![allow(unused_variables)]
+// FIXME(static_mut_refs): this could use an atomic
+#![allow(static_mut_refs)]
 
 // Drop works for union itself.
 
diff --git a/tests/ui/unsafe/union-pat-in-param.rs b/tests/ui/unsafe/union-pat-in-param.rs
new file mode 100644
index 00000000000..8454bfb20dc
--- /dev/null
+++ b/tests/ui/unsafe/union-pat-in-param.rs
@@ -0,0 +1,19 @@
+union U {
+    a: &'static i32,
+    b: usize,
+}
+
+fn fun(U { a }: U) {
+    //~^ ERROR access to union field is unsafe
+    dbg!(*a);
+}
+
+fn main() {
+    fun(U { b: 0 });
+
+    let closure = |U { a }| {
+        //~^ ERROR access to union field is unsafe
+        dbg!(*a);
+    };
+    closure(U { b: 0 });
+}
diff --git a/tests/ui/unsafe/union-pat-in-param.stderr b/tests/ui/unsafe/union-pat-in-param.stderr
new file mode 100644
index 00000000000..b9709b7cc9b
--- /dev/null
+++ b/tests/ui/unsafe/union-pat-in-param.stderr
@@ -0,0 +1,19 @@
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-pat-in-param.rs:6:12
+   |
+LL | fn fun(U { a }: U) {
+   |            ^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error[E0133]: access to union field is unsafe and requires unsafe function or block
+  --> $DIR/union-pat-in-param.rs:14:24
+   |
+LL |     let closure = |U { a }| {
+   |                        ^ access to union field
+   |
+   = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/triagebot.toml b/triagebot.toml
index 467e64bb8b0..a6a0b02d7b7 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -966,6 +966,7 @@ libs = [
     "@jhpratt",
     "@tgross35",
     "@thomcc",
+    "@ibraheemdev",
 ]
 bootstrap = [
     "@Mark-Simulacrum",