about summary refs log tree commit diff
diff options
context:
space:
mode:
authorThe Miri Cronjob Bot <miri@cron.bot>2024-09-11 05:12:24 +0000
committerThe Miri Cronjob Bot <miri@cron.bot>2024-09-11 05:12:24 +0000
commit19fa141a6d3a74ad1ca4bd47f906746d65b91daa (patch)
tree3fc432d81bf88c421a989a5e00cc47d0f307c84c
parent4712e572558f02a80a4d9702baf417d0513f0881 (diff)
parentd4ac759542ec9789ad5ba9a12abe112e7158ecab (diff)
downloadrust-19fa141a6d3a74ad1ca4bd47f906746d65b91daa.tar.gz
rust-19fa141a6d3a74ad1ca4bd47f906746d65b91daa.zip
Merge from rustc
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs38
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/test_harness.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs12
-rw-r--r--compiler/rustc_codegen_cranelift/example/std_example.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/back/lto.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/lto.rs12
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0074.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0075.md18
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0076.md10
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0077.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0511.md4
-rw-r--r--compiler/rustc_hir/src/hir.rs13
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs42
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs18
-rw-r--r--compiler/rustc_lint/src/builtin.rs6
-rw-r--r--compiler/rustc_middle/src/ty/context.rs4
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs38
-rw-r--r--compiler/rustc_mir_transform/src/add_call_guards.rs6
-rw-r--r--compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs45
-rw-r--r--compiler/rustc_mir_transform/src/add_retag.rs10
-rw-r--r--compiler/rustc_mir_transform/src/add_subtyping_projections.rs18
-rw-r--r--compiler/rustc_mir_transform/src/check_const_item_mutation.rs1
-rw-r--r--compiler/rustc_mir_transform/src/copy_prop.rs48
-rw-r--r--compiler/rustc_mir_transform/src/coverage/counters.rs234
-rw-r--r--compiler/rustc_mir_transform/src/coverage/mod.rs3
-rw-r--r--compiler/rustc_mir_transform/src/dataflow_const_prop.rs3
-rw-r--r--compiler/rustc_mir_transform/src/deduce_param_attrs.rs6
-rw-r--r--compiler/rustc_mir_transform/src/deduplicate_blocks.rs7
-rw-r--r--compiler/rustc_mir_transform/src/dest_prop.rs14
-rw-r--r--compiler/rustc_mir_transform/src/early_otherwise_branch.rs4
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs16
-rw-r--r--compiler/rustc_mir_transform/src/ffi_unwind_calls.rs5
-rw-r--r--compiler/rustc_mir_transform/src/function_item_references.rs4
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs97
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs3
-rw-r--r--compiler/rustc_mir_transform/src/instsimplify.rs8
-rw-r--r--compiler/rustc_mir_transform/src/jump_threading.rs42
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs11
-rw-r--r--compiler/rustc_mir_transform/src/large_enums.rs350
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs50
-rw-r--r--compiler/rustc_mir_transform/src/lower_slice_len.rs26
-rw-r--r--compiler/rustc_mir_transform/src/match_branches.rs14
-rw-r--r--compiler/rustc_mir_transform/src/mentioned_items.rs12
-rw-r--r--compiler/rustc_mir_transform/src/post_drop_elaboration.rs13
-rw-r--r--compiler/rustc_mir_transform/src/prettify.rs4
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs39
-rw-r--r--compiler/rustc_mir_transform/src/ref_prop.rs15
-rw-r--r--compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs113
-rw-r--r--compiler/rustc_mir_transform/src/remove_uninit_drops.rs5
-rw-r--r--compiler/rustc_mir_transform/src/required_consts.rs19
-rw-r--r--compiler/rustc_mir_transform/src/reveal_all.rs6
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs8
-rw-r--r--compiler/rustc_mir_transform/src/simplify.rs48
-rw-r--r--compiler/rustc_mir_transform/src/simplify_comparison_integral.rs22
-rw-r--r--compiler/rustc_mir_transform/src/unreachable_enum_branching.rs6
-rw-r--r--compiler/rustc_mir_transform/src/unreachable_prop.rs8
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs30
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/region.rs13
-rw-r--r--compiler/rustc_type_ir/src/elaborate.rs2
-rw-r--r--compiler/rustc_type_ir/src/interner.rs5
-rw-r--r--compiler/rustc_type_ir/src/search_graph/global_cache.rs14
-rw-r--r--compiler/rustc_type_ir/src/search_graph/mod.rs2
-rw-r--r--config.example.toml5
-rw-r--r--library/alloc/benches/slice.rs4
-rw-r--r--library/alloc/src/slice.rs2
-rw-r--r--library/alloc/src/string.rs1
-rw-r--r--library/core/src/arch.rs14
-rw-r--r--library/core/src/mem/maybe_uninit.rs3
-rw-r--r--library/core/src/ptr/const_ptr.rs8
-rw-r--r--library/core/src/ptr/mut_ptr.rs16
-rw-r--r--library/core/src/ptr/non_null.rs8
-rw-r--r--library/std/src/io/buffered/bufreader.rs1
-rw-r--r--library/std/src/io/error.rs32
-rw-r--r--library/std/src/sys/pal/unix/stack_overflow.rs15
-rw-r--r--src/bootstrap/defaults/config.compiler.toml3
-rw-r--r--src/bootstrap/download-ci-llvm-stamp2
-rw-r--r--src/bootstrap/mk/Makefile.in8
-rw-r--r--src/bootstrap/src/core/config/config.rs3
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/librustdoc/config.rs125
-rw-r--r--src/librustdoc/core.rs4
-rw-r--r--src/librustdoc/doctest.rs10
-rw-r--r--src/librustdoc/doctest/markdown.rs11
-rw-r--r--src/librustdoc/html/render/context.rs175
-rw-r--r--src/librustdoc/html/render/mod.rs1
-rw-r--r--src/librustdoc/html/render/write_shared.rs178
-rw-r--r--src/librustdoc/html/render/write_shared/tests.rs10
-rw-r--r--src/librustdoc/lib.rs90
-rw-r--r--src/librustdoc/passes/lint.rs33
-rw-r--r--src/librustdoc/passes/lint/bare_urls.rs68
-rw-r--r--src/librustdoc/passes/lint/check_code_block_syntax.rs6
-rw-r--r--src/librustdoc/passes/lint/html_tags.rs248
-rw-r--r--src/librustdoc/passes/lint/redundant_explicit_links.rs7
-rw-r--r--src/librustdoc/passes/lint/unescaped_backticks.rs12
-rw-r--r--src/librustdoc/passes/lint/unportable_markdown.rs12
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-div-by-zero.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-div-overflow.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-reduce-invalid-bool.rs4
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-rem-by-zero.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-select-bitmask-invalid.rs4
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-select-invalid-bool.rs4
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-shl-too-far.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-shr-too-far.rs6
-rw-r--r--src/tools/miri/tests/pass/simd-intrinsic-generic-elements.rs18
-rw-r--r--src/tools/run-make-support/src/external_deps/cargo.rs7
-rw-r--r--src/tools/run-make-support/src/external_deps/mod.rs1
-rw-r--r--src/tools/run-make-support/src/external_deps/rustc.rs7
-rw-r--r--src/tools/run-make-support/src/lib.rs4
-rw-r--r--tests/assembly/asm/aarch64-types.rs31
-rw-r--r--tests/assembly/asm/arm-modifiers.rs5
-rw-r--r--tests/assembly/asm/arm-types.rs27
-rw-r--r--tests/assembly/asm/x86-types.rs209
-rw-r--r--tests/codegen/align-byval-vector.rs8
-rw-r--r--tests/codegen/const-vector.rs36
-rw-r--r--tests/codegen/naked-asan.rs1
-rw-r--r--tests/codegen/repr/transparent.rs2
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs19
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs19
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs19
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs19
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs19
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs19
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs19
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs19
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs19
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs19
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs19
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs2
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs19
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs19
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs19
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs146
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs10
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs6
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs25
-rw-r--r--tests/codegen/simd/unpadded-simd.rs2
-rw-r--r--tests/codegen/union-abi.rs2
-rw-r--r--tests/codegen/zst-offset.rs2
-rw-r--r--tests/debuginfo/simd.rs64
-rw-r--r--tests/incremental/issue-61530.rs6
-rw-r--r--tests/pretty/tests-are-sorted.pp1
-rw-r--r--tests/run-make/rustc-crates-on-stable/rmake.rs36
-rw-r--r--tests/run-make/rustdoc-default-output/output-default.stdout17
-rw-r--r--tests/run-make/simd-ffi/simd.rs6
-rw-r--r--tests/rustdoc-ui/projection-as-union-type-error.rs14
-rw-r--r--tests/rustdoc-ui/projection-as-union-type-error.stderr15
-rw-r--r--tests/rustdoc-ui/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs23
-rw-r--r--tests/rustdoc/inline_cross/auxiliary/repr.rs2
-rw-r--r--tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs5
-rw-r--r--tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs8
-rw-r--r--tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs25
-rw-r--r--tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs7
-rw-r--r--tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs10
-rw-r--r--tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs11
-rw-r--r--tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs10
-rw-r--r--tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs35
-rw-r--r--tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs6
-rw-r--r--tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs9
-rw-r--r--tests/rustdoc/merge-cross-crate-info/no-merge-separate/sierra.rs17
-rw-r--r--tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs6
-rw-r--r--tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs9
-rw-r--r--tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/sierra.rs18
-rw-r--r--tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs6
-rw-r--r--tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs9
-rw-r--r--tests/rustdoc/merge-cross-crate-info/overwrite-but-include/sierra.rs22
-rw-r--r--tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs7
-rw-r--r--tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs10
-rw-r--r--tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/sierra.rs25
-rw-r--r--tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/quebec.rs5
-rw-r--r--tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/tango.rs8
-rw-r--r--tests/rustdoc/merge-cross-crate-info/overwrite/sierra.rs20
-rw-r--r--tests/rustdoc/merge-cross-crate-info/single-crate-finalize/quebec.rs13
-rw-r--r--tests/rustdoc/merge-cross-crate-info/single-crate-read-write/quebec.rs12
-rw-r--r--tests/rustdoc/merge-cross-crate-info/single-crate-write-anyway/quebec.rs13
-rw-r--r--tests/rustdoc/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs11
-rw-r--r--tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs5
-rw-r--r--tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs8
-rw-r--r--tests/rustdoc/merge-cross-crate-info/transitive-finalize/sierra.rs20
-rw-r--r--tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs6
-rw-r--r--tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs9
-rw-r--r--tests/rustdoc/merge-cross-crate-info/transitive-merge-none/sierra.rs27
-rw-r--r--tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs5
-rw-r--r--tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs8
-rw-r--r--tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/sierra.rs25
-rw-r--r--tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs5
-rw-r--r--tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs8
-rw-r--r--tests/rustdoc/merge-cross-crate-info/transitive-no-info/sierra.rs17
-rw-r--r--tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs5
-rw-r--r--tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/echo.rs16
-rw-r--r--tests/ui/abi/arm-unadjusted-intrinsic.rs9
-rw-r--r--tests/ui/abi/compatibility.rs52
-rw-r--r--tests/ui/abi/homogenous-floats-target-feature-mixup.rs30
-rw-r--r--tests/ui/asm/aarch64/type-check-2-2.rs4
-rw-r--r--tests/ui/asm/aarch64/type-check-2.rs8
-rw-r--r--tests/ui/asm/aarch64/type-check-2.stderr4
-rw-r--r--tests/ui/asm/aarch64/type-check-3.rs4
-rw-r--r--tests/ui/asm/aarch64/type-check-4.rs2
-rw-r--r--tests/ui/asm/naked-functions-inline.rs12
-rw-r--r--tests/ui/asm/x86_64/type-check-2.rs4
-rw-r--r--tests/ui/asm/x86_64/type-check-2.stderr4
-rw-r--r--tests/ui/asm/x86_64/type-check-5.rs5
-rw-r--r--tests/ui/asm/x86_64/type-check-5.stderr6
-rw-r--r--tests/ui/consts/const-eval/simd/insert_extract.rs23
-rw-r--r--tests/ui/error-codes/E0075.rs3
-rw-r--r--tests/ui/error-codes/E0075.stderr8
-rw-r--r--tests/ui/error-codes/E0076.rs2
-rw-r--r--tests/ui/error-codes/E0076.stderr6
-rw-r--r--tests/ui/error-codes/E0077.rs2
-rw-r--r--tests/ui/error-codes/E0077.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-repr-simd.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-simd-ffi.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-simd.rs5
-rw-r--r--tests/ui/layout/debug.rs2
-rw-r--r--tests/ui/lint/lint-missing-doc-crate.rs4
-rw-r--r--tests/ui/lint/lint-missing-doc-crate.stderr10
-rw-r--r--tests/ui/lint/lint-missing-doc-expect.rs13
-rw-r--r--tests/ui/lint/lint-missing-doc-test.rs5
-rw-r--r--tests/ui/repr/attr-usage-repr.rs2
-rw-r--r--tests/ui/repr/explicit-rust-repr-conflicts.rs2
-rw-r--r--tests/ui/simd/const-err-trumps-simd-err.rs4
-rw-r--r--tests/ui/simd/const-err-trumps-simd-err.stderr4
-rw-r--r--tests/ui/simd/generics.rs6
-rw-r--r--tests/ui/simd/intrinsic/float-math-pass.rs18
-rw-r--r--tests/ui/simd/intrinsic/float-minmax-pass.rs12
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-2.rs12
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-pass.rs168
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs12
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs12
-rw-r--r--tests/ui/simd/intrinsic/generic-bitmask-pass.rs16
-rw-r--r--tests/ui/simd/intrinsic/generic-cast.rs12
-rw-r--r--tests/ui/simd/intrinsic/generic-cast.stderr8
-rw-r--r--tests/ui/simd/intrinsic/generic-comparison-pass.rs34
-rw-r--r--tests/ui/simd/intrinsic/generic-comparison.rs7
-rw-r--r--tests/ui/simd/intrinsic/generic-comparison.stderr36
-rw-r--r--tests/ui/simd/intrinsic/generic-elements-pass.rs65
-rw-r--r--tests/ui/simd/intrinsic/generic-elements.rs14
-rw-r--r--tests/ui/simd/intrinsic/generic-gather-pass.rs40
-rw-r--r--tests/ui/simd/intrinsic/generic-reduction-pass.rs28
-rw-r--r--tests/ui/simd/intrinsic/generic-reduction.rs8
-rw-r--r--tests/ui/simd/intrinsic/generic-select-pass.rs80
-rw-r--r--tests/ui/simd/intrinsic/generic-select.rs16
-rw-r--r--tests/ui/simd/intrinsic/inlining-issue67557-ice.rs4
-rw-r--r--tests/ui/simd/intrinsic/inlining-issue67557.rs10
-rw-r--r--tests/ui/simd/issue-17170.rs4
-rw-r--r--tests/ui/simd/issue-32947.rs4
-rw-r--r--tests/ui/simd/issue-39720.rs6
-rw-r--r--tests/ui/simd/issue-89193.rs20
-rw-r--r--tests/ui/simd/monomorphize-heterogeneous.rs6
-rw-r--r--tests/ui/simd/monomorphize-heterogeneous.stderr15
-rw-r--r--tests/ui/simd/monomorphize-too-long.rs11
-rw-r--r--tests/ui/simd/monomorphize-too-long.stderr4
-rw-r--r--tests/ui/simd/monomorphize-zero-length.rs11
-rw-r--r--tests/ui/simd/monomorphize-zero-length.stderr4
-rw-r--r--tests/ui/simd/target-feature-mixup.rs30
-rw-r--r--tests/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs4
-rw-r--r--tests/ui/simd/type-generic-monomorphisation-wide-ptr.rs6
-rw-r--r--tests/ui/simd/type-generic-monomorphisation-wide-ptr.stderr2
-rw-r--r--tests/ui/simd/type-generic-monomorphisation.rs4
-rw-r--r--tests/ui/simd/type-len.rs9
-rw-r--r--tests/ui/simd/type-len.stderr30
-rw-r--r--tests/ui/span/gated-features-attr-spans.rs3
-rw-r--r--tests/ui/traits/next-solver/global-cache-and-parallel-frontend.rs27
-rw-r--r--tests/ui/traits/next-solver/global-cache-and-parallel-frontend.stderr24
270 files changed, 3050 insertions, 2374 deletions
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index ae2627d6938..e313016e3d8 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -812,6 +812,44 @@ pub(super) fn expand_asm<'cx>(
     })
 }
 
+pub(super) fn expand_naked_asm<'cx>(
+    ecx: &'cx mut ExtCtxt<'_>,
+    sp: Span,
+    tts: TokenStream,
+) -> MacroExpanderResult<'cx> {
+    ExpandResult::Ready(match parse_args(ecx, sp, tts, false) {
+        Ok(args) => {
+            let ExpandResult::Ready(mac) = expand_preparsed_asm(ecx, args) else {
+                return ExpandResult::Retry(());
+            };
+            let expr = match mac {
+                Ok(mut inline_asm) => {
+                    // for future compatibility, we always set the NORETURN option.
+                    //
+                    // When we turn `asm!` into `naked_asm!` with this implementation, we can drop
+                    // the `options(noreturn)`, which makes the upgrade smooth when `naked_asm!`
+                    // starts disallowing the `noreturn` option in the future
+                    inline_asm.options |= ast::InlineAsmOptions::NORETURN;
+
+                    P(ast::Expr {
+                        id: ast::DUMMY_NODE_ID,
+                        kind: ast::ExprKind::InlineAsm(P(inline_asm)),
+                        span: sp,
+                        attrs: ast::AttrVec::new(),
+                        tokens: None,
+                    })
+                }
+                Err(guar) => DummyResult::raw_expr(sp, Some(guar)),
+            };
+            MacEager::expr(expr)
+        }
+        Err(err) => {
+            let guar = err.emit();
+            DummyResult::any(sp, guar)
+        }
+    })
+}
+
 pub(super) fn expand_global_asm<'cx>(
     ecx: &'cx mut ExtCtxt<'_>,
     sp: Span,
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index 30e1c8d2622..ebe5e2b5442 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -94,6 +94,7 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
         line: source_util::expand_line,
         log_syntax: log_syntax::expand_log_syntax,
         module_path: source_util::expand_mod,
+        naked_asm: asm::expand_naked_asm,
         option_env: env::expand_option_env,
         pattern_type: pattern_type::expand,
         std_panic: edition_panic::expand_panic,
diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs
index a9e44345811..a694d3b8c28 100644
--- a/compiler/rustc_builtin_macros/src/test_harness.rs
+++ b/compiler/rustc_builtin_macros/src/test_harness.rs
@@ -326,6 +326,8 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
     let main_attr = ecx.attr_word(sym::rustc_main, sp);
     // #[coverage(off)]
     let coverage_attr = ecx.attr_nested_word(sym::coverage, sym::off, sp);
+    // #[allow(missing_docs)]
+    let missing_docs_attr = ecx.attr_nested_word(sym::allow, sym::missing_docs, sp);
 
     // pub fn main() { ... }
     let main_ret_ty = ecx.ty(sp, ast::TyKind::Tup(ThinVec::new()));
@@ -355,7 +357,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
 
     let main = P(ast::Item {
         ident: main_id,
-        attrs: thin_vec![main_attr, coverage_attr],
+        attrs: thin_vec![main_attr, coverage_attr, missing_docs_attr],
         id: ast::DUMMY_NODE_ID,
         kind: main,
         vis: ast::Visibility { span: sp, kind: ast::VisibilityKind::Public, tokens: None },
diff --git a/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs b/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs
index c54574d801d..ad46e18c11c 100644
--- a/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs
+++ b/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs
@@ -9,13 +9,13 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-struct f32x4(pub f32, pub f32, pub f32, pub f32);
+struct f32x4(pub [f32; 4]);
 
 use std::intrinsics::simd::*;
 
 fn main() {
-    let x = f32x4(1.0, 2.0, 3.0, 4.0);
-    let y = f32x4(2.0, 1.0, 4.0, 3.0);
+    let x = f32x4([1.0, 2.0, 3.0, 4.0]);
+    let y = f32x4([2.0, 1.0, 4.0, 3.0]);
 
     #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))]
     let nan = f32::NAN;
@@ -24,13 +24,13 @@ fn main() {
     #[cfg(any(target_arch = "mips", target_arch = "mips64"))]
     let nan = f32::from_bits(f32::NAN.to_bits() - 1);
 
-    let n = f32x4(nan, nan, nan, nan);
+    let n = f32x4([nan, nan, nan, nan]);
 
     unsafe {
         let min0 = simd_fmin(x, y);
         let min1 = simd_fmin(y, x);
         assert_eq!(min0, min1);
-        let e = f32x4(1.0, 1.0, 3.0, 3.0);
+        let e = f32x4([1.0, 1.0, 3.0, 3.0]);
         assert_eq!(min0, e);
         let minn = simd_fmin(x, n);
         assert_eq!(minn, x);
@@ -40,7 +40,7 @@ fn main() {
         let max0 = simd_fmax(x, y);
         let max1 = simd_fmax(y, x);
         assert_eq!(max0, max1);
-        let e = f32x4(2.0, 2.0, 4.0, 4.0);
+        let e = f32x4([2.0, 2.0, 4.0, 4.0]);
         assert_eq!(max0, e);
         let maxn = simd_fmax(x, n);
         assert_eq!(maxn, x);
diff --git a/compiler/rustc_codegen_cranelift/example/std_example.rs b/compiler/rustc_codegen_cranelift/example/std_example.rs
index e99763e2722..f27d4ef57e0 100644
--- a/compiler/rustc_codegen_cranelift/example/std_example.rs
+++ b/compiler/rustc_codegen_cranelift/example/std_example.rs
@@ -166,7 +166,7 @@ fn main() {
         enum Never {}
     }
 
-    foo(I64X2(0, 0));
+    foo(I64X2([0, 0]));
 
     transmute_fat_pointer();
 
@@ -204,7 +204,7 @@ fn rust_call_abi() {
 }
 
 #[repr(simd)]
-struct I64X2(i64, i64);
+struct I64X2([i64; 2]);
 
 #[allow(improper_ctypes_definitions)]
 extern "C" fn foo(_a: I64X2) {}
diff --git a/compiler/rustc_codegen_gcc/src/back/lto.rs b/compiler/rustc_codegen_gcc/src/back/lto.rs
index 6b2dbbbed67..c2adab7137f 100644
--- a/compiler/rustc_codegen_gcc/src/back/lto.rs
+++ b/compiler/rustc_codegen_gcc/src/back/lto.rs
@@ -272,7 +272,6 @@ fn fat_lto(
             }*/
         }
     };
-    let mut serialized_bitcode = Vec::new();
     {
         info!("using {:?} as a base module", module.name);
 
@@ -317,7 +316,6 @@ fn fat_lto(
                     unimplemented!("from uncompressed file")
                 }
             }
-            serialized_bitcode.push(bc_decoded);
         }
         save_temp_bitcode(cgcx, &module, "lto.input");
 
@@ -337,7 +335,7 @@ fn fat_lto(
     // of now.
     module.module_llvm.temp_dir = Some(tmp_path);
 
-    Ok(LtoModuleCodegen::Fat { module, _serialized_bitcode: serialized_bitcode })
+    Ok(LtoModuleCodegen::Fat(module))
 }
 
 pub struct ModuleBuffer(PathBuf);
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index aa6842c75ce..09896b89ebf 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -314,7 +314,6 @@ fn fat_lto(
             }
         }
     };
-    let mut serialized_bitcode = Vec::new();
     {
         let (llcx, llmod) = {
             let llvm = &module.module_llvm;
@@ -342,9 +341,7 @@ fn fat_lto(
         serialized_modules.sort_by(|module1, module2| module1.1.cmp(&module2.1));
 
         // For all serialized bitcode files we parse them and link them in as we did
-        // above, this is all mostly handled in C++. Like above, though, we don't
-        // know much about the memory management here so we err on the side of being
-        // save and persist everything with the original module.
+        // above, this is all mostly handled in C++.
         let mut linker = Linker::new(llmod);
         for (bc_decoded, name) in serialized_modules {
             let _timer = cgcx
@@ -355,7 +352,6 @@ fn fat_lto(
             info!("linking {:?}", name);
             let data = bc_decoded.data();
             linker.add(data).map_err(|()| write::llvm_err(dcx, LlvmError::LoadBitcode { name }))?;
-            serialized_bitcode.push(bc_decoded);
         }
         drop(linker);
         save_temp_bitcode(cgcx, &module, "lto.input");
@@ -372,7 +368,7 @@ fn fat_lto(
         }
     }
 
-    Ok(LtoModuleCodegen::Fat { module, _serialized_bitcode: serialized_bitcode })
+    Ok(LtoModuleCodegen::Fat(module))
 }
 
 pub(crate) struct Linker<'a>(&'a mut llvm::Linker<'a>);
diff --git a/compiler/rustc_codegen_ssa/src/back/lto.rs b/compiler/rustc_codegen_ssa/src/back/lto.rs
index 8b6f6b5a220..1e1e039882b 100644
--- a/compiler/rustc_codegen_ssa/src/back/lto.rs
+++ b/compiler/rustc_codegen_ssa/src/back/lto.rs
@@ -41,18 +41,14 @@ pub struct ThinShared<B: WriteBackendMethods> {
 }
 
 pub enum LtoModuleCodegen<B: WriteBackendMethods> {
-    Fat {
-        module: ModuleCodegen<B::Module>,
-        _serialized_bitcode: Vec<SerializedModule<B::ModuleBuffer>>,
-    },
-
+    Fat(ModuleCodegen<B::Module>),
     Thin(ThinModule<B>),
 }
 
 impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
     pub fn name(&self) -> &str {
         match *self {
-            LtoModuleCodegen::Fat { .. } => "everything",
+            LtoModuleCodegen::Fat(_) => "everything",
             LtoModuleCodegen::Thin(ref m) => m.name(),
         }
     }
@@ -68,7 +64,7 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
         cgcx: &CodegenContext<B>,
     ) -> Result<ModuleCodegen<B::Module>, FatalError> {
         match self {
-            LtoModuleCodegen::Fat { mut module, .. } => {
+            LtoModuleCodegen::Fat(mut module) => {
                 B::optimize_fat(cgcx, &mut module)?;
                 Ok(module)
             }
@@ -81,7 +77,7 @@ impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
     pub fn cost(&self) -> u64 {
         match *self {
             // Only one module with fat LTO, so the cost doesn't matter.
-            LtoModuleCodegen::Fat { .. } => 0,
+            LtoModuleCodegen::Fat(_) => 0,
             LtoModuleCodegen::Thin(ref m) => m.cost(),
         }
     }
diff --git a/compiler/rustc_error_codes/src/error_codes/E0074.md b/compiler/rustc_error_codes/src/error_codes/E0074.md
index 785d6de226d..71d89f5eb60 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0074.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0074.md
@@ -11,7 +11,7 @@ This will cause an error:
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Bad<T>(T, T, T, T);
+struct Bad<T>([T; 4]);
 ```
 
 This will not:
@@ -20,5 +20,5 @@ This will not:
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Good(u32, u32, u32, u32);
+struct Good([u32; 4]);
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0075.md b/compiler/rustc_error_codes/src/error_codes/E0075.md
index 969c1ee7131..b58018eafc3 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0075.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0075.md
@@ -1,6 +1,6 @@
-A `#[simd]` attribute was applied to an empty tuple struct.
+A `#[simd]` attribute was applied to an empty or multi-field struct.
 
-Erroneous code example:
+Erroneous code examples:
 
 ```compile_fail,E0075
 #![feature(repr_simd)]
@@ -9,9 +9,15 @@ Erroneous code example:
 struct Bad; // error!
 ```
 
-The `#[simd]` attribute can only be applied to non empty tuple structs, because
-it doesn't make sense to try to use SIMD operations when there are no values to
-operate on.
+```compile_fail,E0075
+#![feature(repr_simd)]
+
+#[repr(simd)]
+struct Bad([u32; 1], [u32; 1]); // error!
+```
+
+The `#[simd]` attribute can only be applied to a single-field struct, because
+the one field must be the array of values in the vector.
 
 Fixed example:
 
@@ -19,5 +25,5 @@ Fixed example:
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Good(u32); // ok!
+struct Good([u32; 2]); // ok!
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0076.md b/compiler/rustc_error_codes/src/error_codes/E0076.md
index 1da8caa9506..b1943de63e5 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0076.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0076.md
@@ -1,4 +1,4 @@
-All types in a tuple struct aren't the same when using the `#[simd]`
+The type of the field in a tuple struct isn't an array when using the `#[simd]`
 attribute.
 
 Erroneous code example:
@@ -7,12 +7,12 @@ Erroneous code example:
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Bad(u16, u32, u32 u32); // error!
+struct Bad(u16); // error!
 ```
 
 When using the `#[simd]` attribute to automatically use SIMD operations in tuple
-struct, the types in the struct must all be of the same type, or the compiler
-will trigger this error.
+structs, if you want a single-lane vector then the field must be a 1-element
+array, or the compiler will trigger this error.
 
 Fixed example:
 
@@ -20,5 +20,5 @@ Fixed example:
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Good(u32, u32, u32, u32); // ok!
+struct Good([u16; 1]); // ok!
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0077.md b/compiler/rustc_error_codes/src/error_codes/E0077.md
index 91aa24d1f52..688bfd3e727 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0077.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0077.md
@@ -7,7 +7,7 @@ Erroneous code example:
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Bad(String); // error!
+struct Bad([String; 2]); // error!
 ```
 
 When using the `#[simd]` attribute on a tuple struct, the elements in the tuple
@@ -19,5 +19,5 @@ Fixed example:
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Good(u32, u32, u32, u32); // ok!
+struct Good([u32; 4]); // ok!
 ```
diff --git a/compiler/rustc_error_codes/src/error_codes/E0511.md b/compiler/rustc_error_codes/src/error_codes/E0511.md
index 681f4e611c3..45ff49bdebb 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0511.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0511.md
@@ -23,11 +23,11 @@ The generic type has to be a SIMD type. Example:
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct i32x2(i32, i32);
+struct i32x2([i32; 2]);
 
 extern "rust-intrinsic" {
     fn simd_add<T>(a: T, b: T) -> T;
 }
 
-unsafe { simd_add(i32x2(0, 0), i32x2(1, 2)); } // ok!
+unsafe { simd_add(i32x2([0, 0]), i32x2([1, 2])); } // ok!
 ```
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 57c47d29857..b01c24cf305 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -168,6 +168,19 @@ impl Lifetime {
             (LifetimeSuggestionPosition::Normal, self.ident.span)
         }
     }
+
+    pub fn suggestion(&self, new_lifetime: &str) -> (Span, String) {
+        debug_assert!(new_lifetime.starts_with('\''));
+        let (pos, span) = self.suggestion_position();
+        let code = match pos {
+            LifetimeSuggestionPosition::Normal => format!("{new_lifetime}"),
+            LifetimeSuggestionPosition::Ampersand => format!("{new_lifetime} "),
+            LifetimeSuggestionPosition::ElidedPath => format!("<{new_lifetime}>"),
+            LifetimeSuggestionPosition::ElidedPathArgument => format!("{new_lifetime}, "),
+            LifetimeSuggestionPosition::ObjectDefault => format!("+ {new_lifetime}"),
+        };
+        (span, code)
+    }
 }
 
 /// A `Path` is essentially Rust's notion of a name; for instance,
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index e47c707ee18..d7b2510a1df 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -1064,20 +1064,29 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
             struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot be empty").emit();
             return;
         }
-        let e = fields[FieldIdx::ZERO].ty(tcx, args);
-        if !fields.iter().all(|f| f.ty(tcx, args) == e) {
-            struct_span_code_err!(tcx.dcx(), sp, E0076, "SIMD vector should be homogeneous")
-                .with_span_label(sp, "SIMD elements must have the same type")
+
+        let array_field = &fields[FieldIdx::ZERO];
+        let array_ty = array_field.ty(tcx, args);
+        let ty::Array(element_ty, len_const) = array_ty.kind() else {
+            struct_span_code_err!(
+                tcx.dcx(),
+                sp,
+                E0076,
+                "SIMD vector's only field must be an array"
+            )
+            .with_span_label(tcx.def_span(array_field.did), "not an array")
+            .emit();
+            return;
+        };
+
+        if let Some(second_field) = fields.get(FieldIdx::from_u32(1)) {
+            struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot have multiple fields")
+                .with_span_label(tcx.def_span(second_field.did), "excess field")
                 .emit();
             return;
         }
 
-        let len = if let ty::Array(_ty, c) = e.kind() {
-            c.try_eval_target_usize(tcx, tcx.param_env(def.did()))
-        } else {
-            Some(fields.len() as u64)
-        };
-        if let Some(len) = len {
+        if let Some(len) = len_const.try_eval_target_usize(tcx, tcx.param_env(def.did())) {
             if len == 0 {
                 struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot be empty").emit();
                 return;
@@ -1097,16 +1106,9 @@ fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
         // These are scalar types which directly match a "machine" type
         // Yes: Integers, floats, "thin" pointers
         // No: char, "fat" pointers, compound types
-        match e.kind() {
-            ty::Param(_) => (), // pass struct<T>(T, T, T, T) through, let monomorphization catch errors
-            ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_, _) => (), // struct(u8, u8, u8, u8) is ok
-            ty::Array(t, _) if matches!(t.kind(), ty::Param(_)) => (), // pass struct<T>([T; N]) through, let monomorphization catch errors
-            ty::Array(t, _clen)
-                if matches!(
-                    t.kind(),
-                    ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_, _)
-                ) =>
-            { /* struct([f32; 4]) is ok */ }
+        match element_ty.kind() {
+            ty::Param(_) => (), // pass struct<T>([T; 4]) through, let monomorphization catch errors
+            ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::RawPtr(_, _) => (), // struct([u8; 4]) is ok
             _ => {
                 struct_span_code_err!(
                     tcx.dcx(),
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index fe46eb583f1..b4cbd1f309c 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -1191,23 +1191,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                                     (generics.span, "<'a>".to_owned())
                                 };
 
-                            let lifetime_sugg = match lifetime_ref.suggestion_position() {
-                                (hir::LifetimeSuggestionPosition::Normal, span) => {
-                                    (span, "'a".to_owned())
-                                }
-                                (hir::LifetimeSuggestionPosition::Ampersand, span) => {
-                                    (span, "'a ".to_owned())
-                                }
-                                (hir::LifetimeSuggestionPosition::ElidedPath, span) => {
-                                    (span, "<'a>".to_owned())
-                                }
-                                (hir::LifetimeSuggestionPosition::ElidedPathArgument, span) => {
-                                    (span, "'a, ".to_owned())
-                                }
-                                (hir::LifetimeSuggestionPosition::ObjectDefault, span) => {
-                                    (span, "+ 'a".to_owned())
-                                }
-                            };
+                            let lifetime_sugg = lifetime_ref.suggestion("'a");
                             let suggestions = vec![lifetime_sugg, new_param_sugg];
 
                             diag.span_label(
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 824a1868c55..7de92a43a9a 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -426,12 +426,6 @@ impl MissingDoc {
         article: &'static str,
         desc: &'static str,
     ) {
-        // If we're building a test harness, then warning about
-        // documentation is probably not really relevant right now.
-        if cx.sess().opts.test {
-            return;
-        }
-
         // Only check publicly-visible items, using the result from the privacy pass.
         // It's an option so the crate root can also use this function (it doesn't
         // have a `NodeId`).
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 5334e767766..56fcfe8e798 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -181,6 +181,10 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         }
     }
 
+    fn evaluation_is_concurrent(&self) -> bool {
+        self.sess.threads() > 1
+    }
+
     fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
         self.expand_abstract_consts(t)
     }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 730ba265b19..44309697ba9 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1091,29 +1091,21 @@ impl<'tcx> Ty<'tcx> {
     }
 
     pub fn simd_size_and_type(self, tcx: TyCtxt<'tcx>) -> (u64, Ty<'tcx>) {
-        match self.kind() {
-            Adt(def, args) => {
-                assert!(def.repr().simd(), "`simd_size_and_type` called on non-SIMD type");
-                let variant = def.non_enum_variant();
-                let f0_ty = variant.fields[FieldIdx::ZERO].ty(tcx, args);
-
-                match f0_ty.kind() {
-                    // If the first field is an array, we assume it is the only field and its
-                    // elements are the SIMD components.
-                    Array(f0_elem_ty, f0_len) => {
-                        // FIXME(repr_simd): https://github.com/rust-lang/rust/pull/78863#discussion_r522784112
-                        // The way we evaluate the `N` in `[T; N]` here only works since we use
-                        // `simd_size_and_type` post-monomorphization. It will probably start to ICE
-                        // if we use it in generic code. See the `simd-array-trait` ui test.
-                        (f0_len.eval_target_usize(tcx, ParamEnv::empty()), *f0_elem_ty)
-                    }
-                    // Otherwise, the fields of this Adt are the SIMD components (and we assume they
-                    // all have the same type).
-                    _ => (variant.fields.len() as u64, f0_ty),
-                }
-            }
-            _ => bug!("`simd_size_and_type` called on invalid type"),
-        }
+        let Adt(def, args) = self.kind() else {
+            bug!("`simd_size_and_type` called on invalid type")
+        };
+        assert!(def.repr().simd(), "`simd_size_and_type` called on non-SIMD type");
+        let variant = def.non_enum_variant();
+        assert_eq!(variant.fields.len(), 1);
+        let field_ty = variant.fields[FieldIdx::ZERO].ty(tcx, args);
+        let Array(f0_elem_ty, f0_len) = field_ty.kind() else {
+            bug!("Simd type has non-array field type {field_ty:?}")
+        };
+        // FIXME(repr_simd): https://github.com/rust-lang/rust/pull/78863#discussion_r522784112
+        // The way we evaluate the `N` in `[T; N]` here only works since we use
+        // `simd_size_and_type` post-monomorphization. It will probably start to ICE
+        // if we use it in generic code. See the `simd-array-trait` ui test.
+        (f0_len.eval_target_usize(tcx, ParamEnv::empty()), *f0_elem_ty)
     }
 
     #[inline]
diff --git a/compiler/rustc_mir_transform/src/add_call_guards.rs b/compiler/rustc_mir_transform/src/add_call_guards.rs
index 18a0746f54f..24c955c0c78 100644
--- a/compiler/rustc_mir_transform/src/add_call_guards.rs
+++ b/compiler/rustc_mir_transform/src/add_call_guards.rs
@@ -32,12 +32,6 @@ pub(super) use self::AddCallGuards::*;
 
 impl<'tcx> crate::MirPass<'tcx> for AddCallGuards {
     fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        self.add_call_guards(body);
-    }
-}
-
-impl AddCallGuards {
-    pub(super) fn add_call_guards(&self, body: &mut Body<'_>) {
         let mut pred_count: IndexVec<_, _> =
             body.basic_blocks.predecessors().iter().map(|ps| ps.len()).collect();
         pred_count[START_BLOCK] += 1;
diff --git a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
index 47572d8d3b2..74df5f7479e 100644
--- a/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
+++ b/compiler/rustc_mir_transform/src/add_moves_for_packed_drops.rs
@@ -40,35 +40,34 @@ pub(super) struct AddMovesForPackedDrops;
 impl<'tcx> crate::MirPass<'tcx> for AddMovesForPackedDrops {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         debug!("add_moves_for_packed_drops({:?} @ {:?})", body.source, body.span);
-        add_moves_for_packed_drops(tcx, body);
-    }
-}
-
-fn add_moves_for_packed_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-    let patch = add_moves_for_packed_drops_patch(tcx, body);
-    patch.apply(body);
-}
 
-fn add_moves_for_packed_drops_patch<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> MirPatch<'tcx> {
-    let def_id = body.source.def_id();
-    let mut patch = MirPatch::new(body);
-    let param_env = tcx.param_env(def_id);
+        let def_id = body.source.def_id();
+        let mut patch = MirPatch::new(body);
+        let param_env = tcx.param_env(def_id);
 
-    for (bb, data) in body.basic_blocks.iter_enumerated() {
-        let loc = Location { block: bb, statement_index: data.statements.len() };
-        let terminator = data.terminator();
+        for (bb, data) in body.basic_blocks.iter_enumerated() {
+            let loc = Location { block: bb, statement_index: data.statements.len() };
+            let terminator = data.terminator();
 
-        match terminator.kind {
-            TerminatorKind::Drop { place, .. }
-                if util::is_disaligned(tcx, body, param_env, place) =>
-            {
-                add_move_for_packed_drop(tcx, body, &mut patch, terminator, loc, data.is_cleanup);
+            match terminator.kind {
+                TerminatorKind::Drop { place, .. }
+                    if util::is_disaligned(tcx, body, param_env, place) =>
+                {
+                    add_move_for_packed_drop(
+                        tcx,
+                        body,
+                        &mut patch,
+                        terminator,
+                        loc,
+                        data.is_cleanup,
+                    );
+                }
+                _ => {}
             }
-            _ => {}
         }
-    }
 
-    patch
+        patch.apply(body);
+    }
 }
 
 fn add_move_for_packed_drop<'tcx>(
diff --git a/compiler/rustc_mir_transform/src/add_retag.rs b/compiler/rustc_mir_transform/src/add_retag.rs
index 794e85fbfed..8ad364ed055 100644
--- a/compiler/rustc_mir_transform/src/add_retag.rs
+++ b/compiler/rustc_mir_transform/src/add_retag.rs
@@ -60,7 +60,9 @@ impl<'tcx> crate::MirPass<'tcx> for AddRetag {
         let basic_blocks = body.basic_blocks.as_mut();
         let local_decls = &body.local_decls;
         let needs_retag = |place: &Place<'tcx>| {
-            !place.is_indirect_first_projection() // we're not really interested in stores to "outside" locations, they are hard to keep track of anyway
+            // We're not really interested in stores to "outside" locations, they are hard to keep
+            // track of anyway.
+            !place.is_indirect_first_projection()
                 && may_contain_reference(place.ty(&*local_decls, tcx).ty, /*depth*/ 3, tcx)
                 && !local_decls[place.local].is_deref_temp()
         };
@@ -129,9 +131,9 @@ impl<'tcx> crate::MirPass<'tcx> for AddRetag {
                     StatementKind::Assign(box (ref place, ref rvalue)) => {
                         let add_retag = match rvalue {
                             // Ptr-creating operations already do their own internal retagging, no
-                            // need to also add a retag statement.
-                            // *Except* if we are deref'ing a Box, because those get desugared to directly working
-                            // with the inner raw pointer! That's relevant for `RawPtr` as Miri otherwise makes it
+                            // need to also add a retag statement. *Except* if we are deref'ing a
+                            // Box, because those get desugared to directly working with the inner
+                            // raw pointer! That's relevant for `RawPtr` as Miri otherwise makes it
                             // a NOP when the original pointer is already raw.
                             Rvalue::RawPtr(_mutbl, place) => {
                                 // Using `is_box_global` here is a bit sketchy: if this code is
diff --git a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs
index ab6bf18b30c..e585e338613 100644
--- a/compiler/rustc_mir_transform/src/add_subtyping_projections.rs
+++ b/compiler/rustc_mir_transform/src/add_subtyping_projections.rs
@@ -51,18 +51,14 @@ impl<'a, 'tcx> MutVisitor<'tcx> for SubTypeChecker<'a, 'tcx> {
 // // gets transformed to
 // let temp: rval_ty = rval;
 // let place: place_ty = temp as place_ty;
-fn subtype_finder<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-    let patch = MirPatch::new(body);
-    let mut checker = SubTypeChecker { tcx, patcher: patch, local_decls: &body.local_decls };
-
-    for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
-        checker.visit_basic_block_data(bb, data);
-    }
-    checker.patcher.apply(body);
-}
-
 impl<'tcx> crate::MirPass<'tcx> for Subtyper {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        subtype_finder(tcx, body);
+        let patch = MirPatch::new(body);
+        let mut checker = SubTypeChecker { tcx, patcher: patch, local_decls: &body.local_decls };
+
+        for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
+            checker.visit_basic_block_data(bb, data);
+        }
+        checker.patcher.apply(body);
     }
 }
diff --git a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
index 234ed8206f5..048dd9ccb8f 100644
--- a/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
+++ b/compiler/rustc_mir_transform/src/check_const_item_mutation.rs
@@ -123,6 +123,7 @@ impl<'tcx> Visitor<'tcx> for ConstMutationChecker<'_, 'tcx> {
         self.super_statement(stmt, loc);
         self.target_local = None;
     }
+
     fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, loc: Location) {
         if let Rvalue::Ref(_, BorrowKind::Mut { .. }, place) = rvalue {
             let local = place.local;
diff --git a/compiler/rustc_mir_transform/src/copy_prop.rs b/compiler/rustc_mir_transform/src/copy_prop.rs
index dc4ee58ea83..b3db5669121 100644
--- a/compiler/rustc_mir_transform/src/copy_prop.rs
+++ b/compiler/rustc_mir_transform/src/copy_prop.rs
@@ -27,37 +27,34 @@ impl<'tcx> crate::MirPass<'tcx> for CopyProp {
     #[instrument(level = "trace", skip(self, tcx, body))]
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         debug!(def_id = ?body.source.def_id());
-        propagate_ssa(tcx, body);
-    }
-}
 
-fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-    let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
-    let ssa = SsaLocals::new(tcx, body, param_env);
+        let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
+        let ssa = SsaLocals::new(tcx, body, param_env);
 
-    let fully_moved = fully_moved_locals(&ssa, body);
-    debug!(?fully_moved);
+        let fully_moved = fully_moved_locals(&ssa, body);
+        debug!(?fully_moved);
 
-    let mut storage_to_remove = BitSet::new_empty(fully_moved.domain_size());
-    for (local, &head) in ssa.copy_classes().iter_enumerated() {
-        if local != head {
-            storage_to_remove.insert(head);
+        let mut storage_to_remove = BitSet::new_empty(fully_moved.domain_size());
+        for (local, &head) in ssa.copy_classes().iter_enumerated() {
+            if local != head {
+                storage_to_remove.insert(head);
+            }
         }
-    }
 
-    let any_replacement = ssa.copy_classes().iter_enumerated().any(|(l, &h)| l != h);
+        let any_replacement = ssa.copy_classes().iter_enumerated().any(|(l, &h)| l != h);
 
-    Replacer {
-        tcx,
-        copy_classes: ssa.copy_classes(),
-        fully_moved,
-        borrowed_locals: ssa.borrowed_locals(),
-        storage_to_remove,
-    }
-    .visit_body_preserves_cfg(body);
+        Replacer {
+            tcx,
+            copy_classes: ssa.copy_classes(),
+            fully_moved,
+            borrowed_locals: ssa.borrowed_locals(),
+            storage_to_remove,
+        }
+        .visit_body_preserves_cfg(body);
 
-    if any_replacement {
-        crate::simplify::remove_unused_definitions(body);
+        if any_replacement {
+            crate::simplify::remove_unused_definitions(body);
+        }
     }
 }
 
@@ -140,7 +137,8 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
 
     fn visit_operand(&mut self, operand: &mut Operand<'tcx>, loc: Location) {
         if let Operand::Move(place) = *operand
-            // A move out of a projection of a copy is equivalent to a copy of the original projection.
+            // A move out of a projection of a copy is equivalent to a copy of the original
+            // projection.
             && !place.is_indirect_first_projection()
             && !self.fully_moved.contains(place.local)
         {
diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs
index ea1c0d2df45..1c240366afa 100644
--- a/compiler/rustc_mir_transform/src/coverage/counters.rs
+++ b/compiler/rustc_mir_transform/src/coverage/counters.rs
@@ -74,12 +74,11 @@ pub(super) struct CoverageCounters {
 }
 
 impl CoverageCounters {
-    /// Makes [`BcbCounter`] `Counter`s and `Expressions` for the `BasicCoverageBlock`s directly or
-    /// indirectly associated with coverage spans, and accumulates additional `Expression`s
-    /// representing intermediate values.
+    /// Ensures that each BCB node needing a counter has one, by creating physical
+    /// counters or counter expressions for nodes and edges as required.
     pub(super) fn make_bcb_counters(
         basic_coverage_blocks: &CoverageGraph,
-        bcb_has_coverage_spans: impl Fn(BasicCoverageBlock) -> bool,
+        bcb_needs_counter: impl Fn(BasicCoverageBlock) -> bool,
     ) -> Self {
         let num_bcbs = basic_coverage_blocks.num_nodes();
 
@@ -91,8 +90,7 @@ impl CoverageCounters {
             expressions_memo: FxHashMap::default(),
         };
 
-        MakeBcbCounters::new(&mut this, basic_coverage_blocks)
-            .make_bcb_counters(bcb_has_coverage_spans);
+        MakeBcbCounters::new(&mut this, basic_coverage_blocks).make_bcb_counters(bcb_needs_counter);
 
         this
     }
@@ -241,10 +239,7 @@ impl CoverageCounters {
     }
 }
 
-/// Traverse the `CoverageGraph` and add either a `Counter` or `Expression` to every BCB, to be
-/// injected with coverage spans. `Expressions` have no runtime overhead, so if a viable expression
-/// (adding or subtracting two other counters or expressions) can compute the same result as an
-/// embedded counter, an `Expression` should be used.
+/// Helper struct that allows counter creation to inspect the BCB graph.
 struct MakeBcbCounters<'a> {
     coverage_counters: &'a mut CoverageCounters,
     basic_coverage_blocks: &'a CoverageGraph,
@@ -258,36 +253,21 @@ impl<'a> MakeBcbCounters<'a> {
         Self { coverage_counters, basic_coverage_blocks }
     }
 
-    /// If two `BasicCoverageBlock`s branch from another `BasicCoverageBlock`, one of the branches
-    /// can be counted by `Expression` by subtracting the other branch from the branching
-    /// block. Otherwise, the `BasicCoverageBlock` executed the least should have the `Counter`.
-    /// One way to predict which branch executes the least is by considering loops. A loop is exited
-    /// at a branch, so the branch that jumps to a `BasicCoverageBlock` outside the loop is almost
-    /// always executed less than the branch that does not exit the loop.
-    fn make_bcb_counters(&mut self, bcb_has_coverage_spans: impl Fn(BasicCoverageBlock) -> bool) {
+    fn make_bcb_counters(&mut self, bcb_needs_counter: impl Fn(BasicCoverageBlock) -> bool) {
         debug!("make_bcb_counters(): adding a counter or expression to each BasicCoverageBlock");
 
-        // Walk the `CoverageGraph`. For each `BasicCoverageBlock` node with an associated
-        // coverage span, add a counter. If the `BasicCoverageBlock` branches, add a counter or
-        // expression to each branch `BasicCoverageBlock` (if the branch BCB has only one incoming
-        // edge) or edge from the branching BCB to the branch BCB (if the branch BCB has multiple
-        // incoming edges).
+        // Traverse the coverage graph, ensuring that every node that needs a
+        // coverage counter has one.
         //
-        // The `TraverseCoverageGraphWithLoops` traversal ensures that, when a loop is encountered,
-        // all `BasicCoverageBlock` nodes in the loop are visited before visiting any node outside
-        // the loop. The `traversal` state includes a `context_stack`, providing a way to know if
-        // the current BCB is in one or more nested loops or not.
+        // The traversal tries to ensure that, when a loop is encountered, all
+        // nodes within the loop are visited before visiting any nodes outside
+        // the loop. It also keeps track of which loop(s) the traversal is
+        // currently inside.
         let mut traversal = TraverseCoverageGraphWithLoops::new(self.basic_coverage_blocks);
         while let Some(bcb) = traversal.next() {
-            if bcb_has_coverage_spans(bcb) {
-                debug!("{:?} has at least one coverage span. Get or make its counter", bcb);
-                self.make_node_and_branch_counters(&traversal, bcb);
-            } else {
-                debug!(
-                    "{:?} does not have any coverage spans. A counter will only be added if \
-                    and when a covered BCB has an expression dependency.",
-                    bcb,
-                );
+            let _span = debug_span!("traversal", ?bcb).entered();
+            if bcb_needs_counter(bcb) {
+                self.make_node_counter_and_out_edge_counters(&traversal, bcb);
             }
         }
 
@@ -298,73 +278,66 @@ impl<'a> MakeBcbCounters<'a> {
         );
     }
 
-    fn make_node_and_branch_counters(
+    /// Make sure the given node has a node counter, and then make sure each of
+    /// its out-edges has an edge counter (if appropriate).
+    #[instrument(level = "debug", skip(self, traversal))]
+    fn make_node_counter_and_out_edge_counters(
         &mut self,
         traversal: &TraverseCoverageGraphWithLoops<'_>,
         from_bcb: BasicCoverageBlock,
     ) {
         // First, ensure that this node has a counter of some kind.
-        // We might also use its term later to compute one of the branch counters.
-        let from_bcb_operand = self.get_or_make_counter_operand(from_bcb);
+        // We might also use that counter to compute one of the out-edge counters.
+        let node_counter = self.get_or_make_node_counter(from_bcb);
 
-        let branch_target_bcbs = self.basic_coverage_blocks.successors[from_bcb].as_slice();
+        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_branch_counters = branch_target_bcbs.len() > 1
-            && branch_target_bcbs
-                .iter()
-                .any(|&to_bcb| self.branch_has_no_counter(from_bcb, to_bcb));
-        if !needs_branch_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 {
             return;
         }
 
-        debug!(
-            "{from_bcb:?} has some branch(es) without counters:\n  {}",
-            branch_target_bcbs
-                .iter()
-                .map(|&to_bcb| {
-                    format!("{from_bcb:?}->{to_bcb:?}: {:?}", self.branch_counter(from_bcb, to_bcb))
-                })
-                .collect::<Vec<_>>()
-                .join("\n  "),
-        );
+        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));
+            }
+        }
 
-        // Of the branch edges that don't have counters yet, one can be given an expression
-        // (computed from the other edges) instead of a dedicated counter.
-        let expression_to_bcb = self.choose_preferred_expression_branch(traversal, from_bcb);
+        // 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);
 
-        // For each branch arm other than the one that was chosen to get an expression,
+        // 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),
-        // and accumulate the corresponding terms into a single sum term.
-        let sum_of_all_other_branches: BcbCounter = {
-            let _span = debug_span!("sum_of_all_other_branches", ?expression_to_bcb).entered();
-            branch_target_bcbs
+        // and accumulate the corresponding counters into a single sum expression.
+        let sum_of_all_other_out_edges: BcbCounter = {
+            let _span = debug_span!("sum_of_all_other_out_edges", ?expression_to_bcb).entered();
+            successors
                 .iter()
                 .copied()
-                // Skip the chosen branch, since we'll calculate it from the other branches.
+                // Skip the chosen edge, since we'll calculate its count from this sum.
                 .filter(|&to_bcb| to_bcb != expression_to_bcb)
                 .fold(None, |accum, to_bcb| {
                     let _span = debug_span!("to_bcb", ?accum, ?to_bcb).entered();
-                    let branch_counter = self.get_or_make_edge_counter_operand(from_bcb, to_bcb);
-                    Some(self.coverage_counters.make_sum_expression(accum, branch_counter))
+                    let edge_counter = self.get_or_make_edge_counter(from_bcb, to_bcb);
+                    Some(self.coverage_counters.make_sum_expression(accum, edge_counter))
                 })
-                .expect("there must be at least one other branch")
+                .expect("there must be at least one other out-edge")
         };
 
-        // For the branch that was chosen to get an expression, create that expression
-        // by taking the count of the node we're branching from, and subtracting the
-        // sum of all the other branches.
-        debug!(
-            "Making an expression for the selected expression_branch: \
-            {expression_to_bcb:?} (expression_branch predecessors: {:?})",
-            self.bcb_predecessors(expression_to_bcb),
-        );
+        // Now create an expression for the chosen edge, by taking the counter
+        // for its source node and subtracting the sum of its sibling out-edges.
         let expression = self.coverage_counters.make_expression(
-            from_bcb_operand,
+            node_counter,
             Op::Subtract,
-            sum_of_all_other_branches,
+            sum_of_all_other_out_edges,
         );
+
         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);
@@ -374,7 +347,7 @@ impl<'a> MakeBcbCounters<'a> {
     }
 
     #[instrument(level = "debug", skip(self))]
-    fn get_or_make_counter_operand(&mut self, bcb: BasicCoverageBlock) -> BcbCounter {
+    fn get_or_make_node_counter(&mut self, bcb: BasicCoverageBlock) -> BcbCounter {
         // If the BCB already has a counter, return it.
         if let Some(counter_kind) = self.coverage_counters.bcb_counters[bcb] {
             debug!("{bcb:?} already has a counter: {counter_kind:?}");
@@ -411,7 +384,7 @@ impl<'a> MakeBcbCounters<'a> {
                 .copied()
                 .fold(None, |accum, from_bcb| {
                     let _span = debug_span!("from_bcb", ?accum, ?from_bcb).entered();
-                    let edge_counter = self.get_or_make_edge_counter_operand(from_bcb, bcb);
+                    let edge_counter = self.get_or_make_edge_counter(from_bcb, bcb);
                     Some(self.coverage_counters.make_sum_expression(accum, edge_counter))
                 })
                 .expect("there must be at least one in-edge")
@@ -422,7 +395,7 @@ impl<'a> MakeBcbCounters<'a> {
     }
 
     #[instrument(level = "debug", skip(self))]
-    fn get_or_make_edge_counter_operand(
+    fn get_or_make_edge_counter(
         &mut self,
         from_bcb: BasicCoverageBlock,
         to_bcb: BasicCoverageBlock,
@@ -431,13 +404,13 @@ impl<'a> MakeBcbCounters<'a> {
         // 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]);
-            return self.get_or_make_counter_operand(to_bcb);
+            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 {
-            return self.get_or_make_counter_operand(from_bcb);
+            return self.get_or_make_node_counter(from_bcb);
         }
 
         // If the edge already has a counter, return it.
@@ -455,82 +428,79 @@ impl<'a> MakeBcbCounters<'a> {
         self.coverage_counters.set_bcb_edge_counter(from_bcb, to_bcb, counter_kind)
     }
 
-    /// Select a branch for the expression, either the recommended `reloop_branch`, or if none was
-    /// found, select any branch.
-    fn choose_preferred_expression_branch(
+    /// 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.
+    fn choose_out_edge_for_expression(
         &self,
         traversal: &TraverseCoverageGraphWithLoops<'_>,
         from_bcb: BasicCoverageBlock,
     ) -> BasicCoverageBlock {
-        let good_reloop_branch = self.find_good_reloop_branch(traversal, from_bcb);
-        if let Some(reloop_target) = good_reloop_branch {
-            assert!(self.branch_has_no_counter(from_bcb, reloop_target));
+        if let Some(reloop_target) = self.find_good_reloop_edge(traversal, from_bcb) {
+            assert!(self.edge_has_no_counter(from_bcb, reloop_target));
             debug!("Selecting reloop target {reloop_target:?} to get an expression");
-            reloop_target
-        } else {
-            let &branch_without_counter = self
-                .bcb_successors(from_bcb)
-                .iter()
-                .find(|&&to_bcb| self.branch_has_no_counter(from_bcb, to_bcb))
-                .expect(
-                    "needs_branch_counters was `true` so there should be at least one \
-                    branch",
-                );
-            debug!(
-                "Selecting any branch={:?} that still needs a counter, to get the \
-                `Expression` because there was no `reloop_branch`, or it already had a \
-                counter",
-                branch_without_counter
-            );
-            branch_without_counter
+            return 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");
+        debug!(?arbitrary_target, "selecting arbitrary out-edge to get an expression");
+        arbitrary_target
     }
 
-    /// Tries to find a branch that leads back to the top of a loop, and that
-    /// doesn't already have a counter. Such branches are good candidates to
+    /// 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 branch.
-    fn find_good_reloop_branch(
+    /// will tend to be executed more times than a loop-exit edge.
+    fn find_good_reloop_edge(
         &self,
         traversal: &TraverseCoverageGraphWithLoops<'_>,
         from_bcb: BasicCoverageBlock,
     ) -> Option<BasicCoverageBlock> {
-        let branch_target_bcbs = self.bcb_successors(from_bcb);
+        let successors = self.bcb_successors(from_bcb);
 
         // Consider each loop on the current traversal context stack, top-down.
         for reloop_bcbs in traversal.reloop_bcbs_per_loop() {
-            let mut all_branches_exit_this_loop = true;
+            let mut all_edges_exit_this_loop = true;
 
-            // Try to find a branch that doesn't exit this loop and doesn't
+            // Try to find an out-edge that doesn't exit this loop and doesn't
             // already have a counter.
-            for &branch_target_bcb in branch_target_bcbs {
-                // A branch is a reloop branch if it dominates any BCB that has
-                // an edge back to the loop header. (Other branches are exits.)
-                let is_reloop_branch = reloop_bcbs.iter().any(|&reloop_bcb| {
-                    self.basic_coverage_blocks.dominates(branch_target_bcb, reloop_bcb)
+            for &target_bcb in 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_branch {
-                    all_branches_exit_this_loop = false;
-                    if self.branch_has_no_counter(from_bcb, branch_target_bcb) {
-                        // We found a good branch to be given an expression.
-                        return Some(branch_target_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 branch without a counter.
+                    // Keep looking for another reloop edge without a counter.
                 } else {
-                    // This branch exits the loop.
+                    // This edge exits the loop.
                 }
             }
 
-            if !all_branches_exit_this_loop {
-                // We found one or more reloop branches, but all of them already
-                // have counters. Let the caller choose one of the exit branches.
-                debug!("All reloop branches had counters; skip checking the other loops");
+            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 branches exit this loop, so keep looking for a good
-            // reloop branch for one of the outer loops.
+            // All of the out-edges exit this loop, so keep looking for a good
+            // reloop edge for one of the outer loops.
         }
 
         None
@@ -547,15 +517,15 @@ impl<'a> MakeBcbCounters<'a> {
     }
 
     #[inline]
-    fn branch_has_no_counter(
+    fn edge_has_no_counter(
         &self,
         from_bcb: BasicCoverageBlock,
         to_bcb: BasicCoverageBlock,
     ) -> bool {
-        self.branch_counter(from_bcb, to_bcb).is_none()
+        self.edge_counter(from_bcb, to_bcb).is_none()
     }
 
-    fn branch_counter(
+    fn edge_counter(
         &self,
         from_bcb: BasicCoverageBlock,
         to_bcb: BasicCoverageBlock,
diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs
index 042f589768a..f78fc7931f9 100644
--- a/compiler/rustc_mir_transform/src/coverage/mod.rs
+++ b/compiler/rustc_mir_transform/src/coverage/mod.rs
@@ -279,7 +279,8 @@ fn inject_mcdc_statements<'tcx>(
     basic_coverage_blocks: &CoverageGraph,
     extracted_mappings: &ExtractedMappings,
 ) {
-    // Inject test vector update first because `inject_statement` always insert new statement at head.
+    // Inject test vector update first because `inject_statement` always insert new statement at
+    // head.
     for &mappings::MCDCDecision {
         span: _,
         ref end_bcbs,
diff --git a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
index 79f12be4bc3..7ac019ce812 100644
--- a/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
+++ b/compiler/rustc_mir_transform/src/dataflow_const_prop.rs
@@ -647,7 +647,8 @@ fn try_write_constant<'tcx>(
         ty::FnDef(..) => {}
 
         // Those are scalars, must be handled above.
-        ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char => throw_machine_stop_str!("primitive type with provenance"),
+        ty::Bool | ty::Int(_) | ty::Uint(_) | ty::Float(_) | ty::Char =>
+            throw_machine_stop_str!("primitive type with provenance"),
 
         ty::Tuple(elem_tys) => {
             for (i, elem) in elem_tys.iter().enumerate() {
diff --git a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
index e870a71b05a..c645bbee08a 100644
--- a/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
+++ b/compiler/rustc_mir_transform/src/deduce_param_attrs.rs
@@ -42,9 +42,9 @@ impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
             }
             PlaceContext::NonMutatingUse(NonMutatingUseContext::RawBorrow) => {
                 // Whether mutating though a `&raw const` is allowed is still undecided, so we
-                // disable any sketchy `readonly` optimizations for now.
-                // But we only need to do this if the pointer would point into the argument.
-                // IOW: for indirect places, like `&raw (*local).field`, this surely cannot mutate `local`.
+                // disable any sketchy `readonly` optimizations for now. But we only need to do
+                // this if the pointer would point into the argument. IOW: for indirect places,
+                // like `&raw (*local).field`, this surely cannot mutate `local`.
                 !place.is_indirect()
             }
             PlaceContext::NonMutatingUse(..) | PlaceContext::NonUse(..) => {
diff --git a/compiler/rustc_mir_transform/src/deduplicate_blocks.rs b/compiler/rustc_mir_transform/src/deduplicate_blocks.rs
index c8179d513c7..ad204e76d0d 100644
--- a/compiler/rustc_mir_transform/src/deduplicate_blocks.rs
+++ b/compiler/rustc_mir_transform/src/deduplicate_blocks.rs
@@ -69,8 +69,8 @@ fn find_duplicates(body: &Body<'_>) -> FxHashMap<BasicBlock, BasicBlock> {
     // For example, if bb1, bb2 and bb3 are duplicates, we will first insert bb3 in same_hashes.
     // Then we will see that bb2 is a duplicate of bb3,
     // and insert bb2 with the replacement bb3 in the duplicates list.
-    // When we see bb1, we see that it is a duplicate of bb3, and therefore insert it in the duplicates list
-    // with replacement bb3.
+    // When we see bb1, we see that it is a duplicate of bb3, and therefore insert it in the
+    // duplicates list with replacement bb3.
     // When the duplicates are removed, we will end up with only bb3.
     for (bb, bbd) in body.basic_blocks.iter_enumerated().rev().filter(|(_, bbd)| !bbd.is_cleanup) {
         // Basic blocks can get really big, so to avoid checking for duplicates in basic blocks
@@ -105,7 +105,8 @@ struct BasicBlockHashable<'tcx, 'a> {
 impl Hash for BasicBlockHashable<'_, '_> {
     fn hash<H: Hasher>(&self, state: &mut H) {
         hash_statements(state, self.basic_block_data.statements.iter());
-        // Note that since we only hash the kind, we lose span information if we deduplicate the blocks
+        // Note that since we only hash the kind, we lose span information if we deduplicate the
+        // blocks.
         self.basic_block_data.terminator().kind.hash(state);
     }
 }
diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs
index 175097e30ee..f123658580d 100644
--- a/compiler/rustc_mir_transform/src/dest_prop.rs
+++ b/compiler/rustc_mir_transform/src/dest_prop.rs
@@ -242,7 +242,7 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
             }
             round_count += 1;
 
-            apply_merges(body, tcx, &merges, &merged_locals);
+            apply_merges(body, tcx, merges, merged_locals);
         }
 
         trace!(round_count);
@@ -281,20 +281,20 @@ struct Candidates {
 fn apply_merges<'tcx>(
     body: &mut Body<'tcx>,
     tcx: TyCtxt<'tcx>,
-    merges: &FxIndexMap<Local, Local>,
-    merged_locals: &BitSet<Local>,
+    merges: FxIndexMap<Local, Local>,
+    merged_locals: BitSet<Local>,
 ) {
     let mut merger = Merger { tcx, merges, merged_locals };
     merger.visit_body_preserves_cfg(body);
 }
 
-struct Merger<'a, 'tcx> {
+struct Merger<'tcx> {
     tcx: TyCtxt<'tcx>,
-    merges: &'a FxIndexMap<Local, Local>,
-    merged_locals: &'a BitSet<Local>,
+    merges: FxIndexMap<Local, Local>,
+    merged_locals: BitSet<Local>,
 }
 
-impl<'a, 'tcx> MutVisitor<'tcx> for Merger<'a, 'tcx> {
+impl<'tcx> MutVisitor<'tcx> for Merger<'tcx> {
     fn tcx(&self) -> TyCtxt<'tcx> {
         self.tcx
     }
diff --git a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
index 3884321df2a..704ed508b22 100644
--- a/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
+++ b/compiler/rustc_mir_transform/src/early_otherwise_branch.rs
@@ -261,8 +261,8 @@ fn evaluate_candidate<'tcx>(
         // };
         // ```
         //
-        // Hoisting the `discriminant(Q)` out of the `A` arm causes us to compute the discriminant of an
-        // invalid value, which is UB.
+        // Hoisting the `discriminant(Q)` out of the `A` arm causes us to compute the discriminant
+        // of an invalid value, which is UB.
         // In order to fix this, **we would either need to show that the discriminant computation of
         // `place` is computed in all branches**.
         // FIXME(#95162) For the moment, we adopt a conservative approach and
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index cb729792dc5..42d13fa3613 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -20,8 +20,8 @@ use tracing::{debug, instrument};
 use crate::deref_separator::deref_finder;
 
 /// During MIR building, Drop terminators are inserted in every place where a drop may occur.
-/// However, in this phase, the presence of these terminators does not guarantee that a destructor will run,
-/// as the target of the drop may be uninitialized.
+/// However, in this phase, the presence of these terminators does not guarantee that a destructor
+/// will run, as the target of the drop may be uninitialized.
 /// In general, the compiler cannot determine at compile time whether a destructor will run or not.
 ///
 /// At a high level, this pass refines Drop to only run the destructor if the
@@ -30,10 +30,10 @@ use crate::deref_separator::deref_finder;
 /// Once this is complete, Drop terminators in the MIR correspond to a call to the "drop glue" or
 /// "drop shim" for the type of the dropped place.
 ///
-/// This pass relies on dropped places having an associated move path, which is then used to determine
-/// the initialization status of the place and its descendants.
-/// It's worth noting that a MIR containing a Drop without an associated move path is probably ill formed,
-/// as it would allow running a destructor on a place behind a reference:
+/// This pass relies on dropped places having an associated move path, which is then used to
+/// determine the initialization status of the place and its descendants.
+/// It's worth noting that a MIR containing a Drop without an associated move path is probably ill
+/// formed, as it would allow running a destructor on a place behind a reference:
 ///
 /// ```text
 /// fn drop_term<T>(t: &mut T) {
@@ -377,8 +377,8 @@ impl<'a, 'tcx> ElaborateDropsCtxt<'a, 'tcx> {
                         );
                     }
                     // A drop and replace behind a pointer/array/whatever.
-                    // The borrow checker requires that these locations are initialized before the assignment,
-                    // so we just leave an unconditional drop.
+                    // The borrow checker requires that these locations are initialized before the
+                    // assignment, so we just leave an unconditional drop.
                     assert!(!data.is_cleanup);
                 }
             }
diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
index 81875e3d012..8490b7e2358 100644
--- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
+++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
@@ -60,8 +60,9 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool {
         let fn_def_id = match ty.kind() {
             ty::FnPtr(..) => None,
             &ty::FnDef(def_id, _) => {
-                // Rust calls cannot themselves create foreign unwinds (even if they use a non-Rust ABI).
-                // So the leak of the foreign unwind into Rust can only be elsewhere, not here.
+                // Rust calls cannot themselves create foreign unwinds (even if they use a non-Rust
+                // ABI). So the leak of the foreign unwind into Rust can only be elsewhere, not
+                // here.
                 if !tcx.is_foreign_item(def_id) {
                     continue;
                 }
diff --git a/compiler/rustc_mir_transform/src/function_item_references.rs b/compiler/rustc_mir_transform/src/function_item_references.rs
index 0efaa172e0c..eb09a7d3b21 100644
--- a/compiler/rustc_mir_transform/src/function_item_references.rs
+++ b/compiler/rustc_mir_transform/src/function_item_references.rs
@@ -92,8 +92,8 @@ impl<'tcx> FunctionItemRefChecker<'_, 'tcx> {
                             {
                                 let mut span = self.nth_arg_span(args, arg_num);
                                 if span.from_expansion() {
-                                    // The operand's ctxt wouldn't display the lint since it's inside a macro so
-                                    // we have to use the callsite's ctxt.
+                                    // The operand's ctxt wouldn't display the lint since it's
+                                    // inside a macro so we have to use the callsite's ctxt.
                                     let callsite_ctxt = span.source_callsite().ctxt();
                                     span = span.with_ctxt(callsite_ctxt);
                                 }
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index e5d2b13efd8..598bf61483d 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -119,53 +119,50 @@ impl<'tcx> crate::MirPass<'tcx> for GVN {
     #[instrument(level = "trace", skip(self, tcx, body))]
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         debug!(def_id = ?body.source.def_id());
-        propagate_ssa(tcx, body);
-    }
-}
 
-fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-    let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
-    let ssa = SsaLocals::new(tcx, body, param_env);
-    // Clone dominators as we need them while mutating the body.
-    let dominators = body.basic_blocks.dominators().clone();
-
-    let mut state = VnState::new(tcx, body, param_env, &ssa, &dominators, &body.local_decls);
-    ssa.for_each_assignment_mut(
-        body.basic_blocks.as_mut_preserves_cfg(),
-        |local, value, location| {
-            let value = match value {
-                // We do not know anything of this assigned value.
-                AssignedValue::Arg | AssignedValue::Terminator => None,
-                // Try to get some insight.
-                AssignedValue::Rvalue(rvalue) => {
-                    let value = state.simplify_rvalue(rvalue, location);
-                    // FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark `local` as
-                    // reusable if we have an exact type match.
-                    if state.local_decls[local].ty != rvalue.ty(state.local_decls, tcx) {
-                        return;
+        let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
+        let ssa = SsaLocals::new(tcx, body, param_env);
+        // Clone dominators because we need them while mutating the body.
+        let dominators = body.basic_blocks.dominators().clone();
+
+        let mut state = VnState::new(tcx, body, param_env, &ssa, dominators, &body.local_decls);
+        ssa.for_each_assignment_mut(
+            body.basic_blocks.as_mut_preserves_cfg(),
+            |local, value, location| {
+                let value = match value {
+                    // We do not know anything of this assigned value.
+                    AssignedValue::Arg | AssignedValue::Terminator => None,
+                    // Try to get some insight.
+                    AssignedValue::Rvalue(rvalue) => {
+                        let value = state.simplify_rvalue(rvalue, location);
+                        // FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark
+                        // `local` as reusable if we have an exact type match.
+                        if state.local_decls[local].ty != rvalue.ty(state.local_decls, tcx) {
+                            return;
+                        }
+                        value
                     }
-                    value
-                }
-            };
-            // `next_opaque` is `Some`, so `new_opaque` must return `Some`.
-            let value = value.or_else(|| state.new_opaque()).unwrap();
-            state.assign(local, value);
-        },
-    );
-
-    // Stop creating opaques during replacement as it is useless.
-    state.next_opaque = None;
-
-    let reverse_postorder = body.basic_blocks.reverse_postorder().to_vec();
-    for bb in reverse_postorder {
-        let data = &mut body.basic_blocks.as_mut_preserves_cfg()[bb];
-        state.visit_basic_block_data(bb, data);
-    }
+                };
+                // `next_opaque` is `Some`, so `new_opaque` must return `Some`.
+                let value = value.or_else(|| state.new_opaque()).unwrap();
+                state.assign(local, value);
+            },
+        );
+
+        // Stop creating opaques during replacement as it is useless.
+        state.next_opaque = None;
 
-    // For each local that is reused (`y` above), we remove its storage statements do avoid any
-    // difficulty. Those locals are SSA, so should be easy to optimize by LLVM without storage
-    // statements.
-    StorageRemover { tcx, reused_locals: state.reused_locals }.visit_body_preserves_cfg(body);
+        let reverse_postorder = body.basic_blocks.reverse_postorder().to_vec();
+        for bb in reverse_postorder {
+            let data = &mut body.basic_blocks.as_mut_preserves_cfg()[bb];
+            state.visit_basic_block_data(bb, data);
+        }
+
+        // For each local that is reused (`y` above), we remove its storage statements do avoid any
+        // difficulty. Those locals are SSA, so should be easy to optimize by LLVM without storage
+        // statements.
+        StorageRemover { tcx, reused_locals: state.reused_locals }.visit_body_preserves_cfg(body);
+    }
 }
 
 newtype_index! {
@@ -261,7 +258,7 @@ struct VnState<'body, 'tcx> {
     /// Cache the value of the `unsized_locals` features, to avoid fetching it repeatedly in a loop.
     feature_unsized_locals: bool,
     ssa: &'body SsaLocals,
-    dominators: &'body Dominators<BasicBlock>,
+    dominators: Dominators<BasicBlock>,
     reused_locals: BitSet<Local>,
 }
 
@@ -271,7 +268,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
         body: &Body<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         ssa: &'body SsaLocals,
-        dominators: &'body Dominators<BasicBlock>,
+        dominators: Dominators<BasicBlock>,
         local_decls: &'body LocalDecls<'tcx>,
     ) -> Self {
         // Compute a rough estimate of the number of values in the body from the number of
@@ -480,7 +477,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 let pointer = self.evaluated[local].as_ref()?;
                 let mut mplace = self.ecx.deref_pointer(pointer).ok()?;
                 for proj in place.projection.iter().skip(1) {
-                    // We have no call stack to associate a local with a value, so we cannot interpret indexing.
+                    // We have no call stack to associate a local with a value, so we cannot
+                    // interpret indexing.
                     if matches!(proj, ProjectionElem::Index(_)) {
                         return None;
                     }
@@ -1382,7 +1380,8 @@ fn op_to_prop_const<'tcx>(
         return Some(ConstValue::ZeroSized);
     }
 
-    // Do not synthetize too large constants. Codegen will just memcpy them, which we'd like to avoid.
+    // Do not synthetize too large constants. Codegen will just memcpy them, which we'd like to
+    // avoid.
     if !matches!(op.layout.abi, Abi::Scalar(..) | Abi::ScalarPair(..)) {
         return None;
     }
@@ -1491,7 +1490,7 @@ impl<'tcx> VnState<'_, 'tcx> {
         let other = self.rev_locals.get(index)?;
         other
             .iter()
-            .find(|&&other| self.ssa.assignment_dominates(self.dominators, other, loc))
+            .find(|&&other| self.ssa.assignment_dominates(&self.dominators, other, loc))
             .copied()
     }
 }
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 03ef808efec..870cb180ce1 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -568,7 +568,8 @@ impl<'tcx> Inliner<'tcx> {
                 // if the no-attribute function ends up with the same instruction set anyway.
                 return Err("Cannot move inline-asm across instruction sets");
             } else if let TerminatorKind::TailCall { .. } = term.kind {
-                // FIXME(explicit_tail_calls): figure out how exactly functions containing tail calls can be inlined (and if they even should)
+                // FIXME(explicit_tail_calls): figure out how exactly functions containing tail
+                // calls can be inlined (and if they even should)
                 return Err("can't inline functions with tail calls");
             } else {
                 work_list.extend(term.successors())
diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index a9591bf3984..0b344f29b07 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -18,19 +18,13 @@ pub(super) enum InstSimplify {
     AfterSimplifyCfg,
 }
 
-impl InstSimplify {
+impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
     fn name(&self) -> &'static str {
         match self {
             InstSimplify::BeforeInline => "InstSimplify-before-inline",
             InstSimplify::AfterSimplifyCfg => "InstSimplify-after-simplifycfg",
         }
     }
-}
-
-impl<'tcx> crate::MirPass<'tcx> for InstSimplify {
-    fn name(&self) -> &'static str {
-        self.name()
-    }
 
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() > 0
diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs
index e950c2cb72a..d48df59ada8 100644
--- a/compiler/rustc_mir_transform/src/jump_threading.rs
+++ b/compiler/rustc_mir_transform/src/jump_threading.rs
@@ -78,18 +78,16 @@ impl<'tcx> crate::MirPass<'tcx> for JumpThreading {
         }
 
         let param_env = tcx.param_env_reveal_all_normalized(def_id);
-        let map = Map::new(tcx, body, Some(MAX_PLACES));
-        let loop_headers = loop_headers(body);
 
-        let arena = DroplessArena::default();
+        let arena = &DroplessArena::default();
         let mut finder = TOFinder {
             tcx,
             param_env,
             ecx: InterpCx::new(tcx, DUMMY_SP, param_env, DummyMachine),
             body,
-            arena: &arena,
-            map: &map,
-            loop_headers: &loop_headers,
+            arena,
+            map: Map::new(tcx, body, Some(MAX_PLACES)),
+            loop_headers: loop_headers(body),
             opportunities: Vec::new(),
         };
 
@@ -105,7 +103,7 @@ impl<'tcx> crate::MirPass<'tcx> for JumpThreading {
 
         // Verify that we do not thread through a loop header.
         for to in opportunities.iter() {
-            assert!(to.chain.iter().all(|&block| !loop_headers.contains(block)));
+            assert!(to.chain.iter().all(|&block| !finder.loop_headers.contains(block)));
         }
         OpportunitySet::new(body, opportunities).apply(body);
     }
@@ -124,8 +122,8 @@ struct TOFinder<'tcx, 'a> {
     param_env: ty::ParamEnv<'tcx>,
     ecx: InterpCx<'tcx, DummyMachine>,
     body: &'a Body<'tcx>,
-    map: &'a Map<'tcx>,
-    loop_headers: &'a BitSet<BasicBlock>,
+    map: Map<'tcx>,
+    loop_headers: BitSet<BasicBlock>,
     /// We use an arena to avoid cloning the slices when cloning `state`.
     arena: &'a DroplessArena,
     opportunities: Vec<ThreadingOpportunity>,
@@ -223,7 +221,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
             }))
         };
         let conds = ConditionSet(conds);
-        state.insert_value_idx(discr, conds, self.map);
+        state.insert_value_idx(discr, conds, &self.map);
 
         self.find_opportunity(bb, state, cost, 0);
     }
@@ -264,7 +262,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
             //   _1 = 5 // Whatever happens here, it won't change the result of a `SwitchInt`.
             //   _1 = 6
             if let Some((lhs, tail)) = self.mutated_statement(stmt) {
-                state.flood_with_tail_elem(lhs.as_ref(), tail, self.map, ConditionSet::BOTTOM);
+                state.flood_with_tail_elem(lhs.as_ref(), tail, &self.map, ConditionSet::BOTTOM);
             }
         }
 
@@ -370,7 +368,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
             self.opportunities.push(ThreadingOpportunity { chain: vec![bb], target: c.target })
         };
 
-        if let Some(conditions) = state.try_get_idx(lhs, self.map)
+        if let Some(conditions) = state.try_get_idx(lhs, &self.map)
             && let Immediate::Scalar(Scalar::Int(int)) = *rhs
         {
             conditions.iter_matches(int).for_each(register_opportunity);
@@ -406,7 +404,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
                 }
             },
             &mut |place, op| {
-                if let Some(conditions) = state.try_get_idx(place, self.map)
+                if let Some(conditions) = state.try_get_idx(place, &self.map)
                     && let Ok(imm) = self.ecx.read_immediate_raw(op)
                     && let Some(imm) = imm.right()
                     && let Immediate::Scalar(Scalar::Int(int)) = *imm
@@ -441,7 +439,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
             // Transfer the conditions on the copied rhs.
             Operand::Move(rhs) | Operand::Copy(rhs) => {
                 let Some(rhs) = self.map.find(rhs.as_ref()) else { return };
-                state.insert_place_idx(rhs, lhs, self.map);
+                state.insert_place_idx(rhs, lhs, &self.map);
             }
         }
     }
@@ -461,7 +459,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
             Rvalue::CopyForDeref(rhs) => self.process_operand(bb, lhs, &Operand::Copy(*rhs), state),
             Rvalue::Discriminant(rhs) => {
                 let Some(rhs) = self.map.find_discr(rhs.as_ref()) else { return };
-                state.insert_place_idx(rhs, lhs, self.map);
+                state.insert_place_idx(rhs, lhs, &self.map);
             }
             // If we expect `lhs ?= A`, we have an opportunity if we assume `constant == A`.
             Rvalue::Aggregate(box ref kind, ref operands) => {
@@ -492,10 +490,10 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
             }
             // Transfer the conditions on the copy rhs, after inversing polarity.
             Rvalue::UnaryOp(UnOp::Not, Operand::Move(place) | Operand::Copy(place)) => {
-                let Some(conditions) = state.try_get_idx(lhs, self.map) else { return };
+                let Some(conditions) = state.try_get_idx(lhs, &self.map) else { return };
                 let Some(place) = self.map.find(place.as_ref()) else { return };
                 let conds = conditions.map(self.arena, Condition::inv);
-                state.insert_value_idx(place, conds, self.map);
+                state.insert_value_idx(place, conds, &self.map);
             }
             // We expect `lhs ?= A`. We found `lhs = Eq(rhs, B)`.
             // Create a condition on `rhs ?= B`.
@@ -504,7 +502,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
                 box (Operand::Move(place) | Operand::Copy(place), Operand::Constant(value))
                 | box (Operand::Constant(value), Operand::Move(place) | Operand::Copy(place)),
             ) => {
-                let Some(conditions) = state.try_get_idx(lhs, self.map) else { return };
+                let Some(conditions) = state.try_get_idx(lhs, &self.map) else { return };
                 let Some(place) = self.map.find(place.as_ref()) else { return };
                 let equals = match op {
                     BinOp::Eq => ScalarInt::TRUE,
@@ -528,7 +526,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
                     polarity: if c.matches(equals) { Polarity::Eq } else { Polarity::Ne },
                     ..c
                 });
-                state.insert_value_idx(place, conds, self.map);
+                state.insert_value_idx(place, conds, &self.map);
             }
 
             _ => {}
@@ -583,7 +581,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
             StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(
                 Operand::Copy(place) | Operand::Move(place),
             )) => {
-                let Some(conditions) = state.try_get(place.as_ref(), self.map) else { return };
+                let Some(conditions) = state.try_get(place.as_ref(), &self.map) else { return };
                 conditions.iter_matches(ScalarInt::TRUE).for_each(register_opportunity);
             }
             StatementKind::Assign(box (lhs_place, rhs)) => {
@@ -631,7 +629,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
         // We can recurse through this terminator.
         let mut state = state();
         if let Some(place_to_flood) = place_to_flood {
-            state.flood_with(place_to_flood.as_ref(), self.map, ConditionSet::BOTTOM);
+            state.flood_with(place_to_flood.as_ref(), &self.map, ConditionSet::BOTTOM);
         }
         self.find_opportunity(bb, state, cost.clone(), depth + 1);
     }
@@ -650,7 +648,7 @@ impl<'tcx, 'a> TOFinder<'tcx, 'a> {
         let Some(discr) = discr.place() else { return };
         let discr_ty = discr.ty(self.body, self.tcx).ty;
         let Ok(discr_layout) = self.ecx.layout_of(discr_ty) else { return };
-        let Some(conditions) = state.try_get(discr.as_ref(), self.map) else { return };
+        let Some(conditions) = state.try_get(discr.as_ref(), &self.map) else { return };
 
         if let Some((value, _)) = targets.iter().find(|&(_, target)| target == target_bb) {
             let Some(value) = ScalarInt::try_from_uint(value, discr_layout.size) else { return };
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index e964310c542..46b17c3c7e0 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -1,8 +1,6 @@
-//! A lint that checks for known panics like
-//! overflows, division by zero,
-//! out-of-bound access etc.
-//! Uses const propagation to determine the
-//! values of operands during checks.
+//! A lint that checks for known panics like overflows, division by zero,
+//! out-of-bound access etc. Uses const propagation to determine the values of
+//! operands during checks.
 
 use std::fmt::Debug;
 
@@ -562,7 +560,8 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
 
                 let val = self.use_ecx(|this| this.ecx.binary_op(bin_op, &left, &right))?;
                 if matches!(val.layout.abi, Abi::ScalarPair(..)) {
-                    // FIXME `Value` should properly support pairs in `Immediate`... but currently it does not.
+                    // FIXME `Value` should properly support pairs in `Immediate`... but currently
+                    // it does not.
                     let (val, overflow) = val.to_pair(&self.ecx);
                     Value::Aggregate {
                         variant: VariantIdx::ZERO,
diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs
index f61cf236f77..3e263aa4067 100644
--- a/compiler/rustc_mir_transform/src/large_enums.rs
+++ b/compiler/rustc_mir_transform/src/large_enums.rs
@@ -16,8 +16,7 @@ use rustc_target::abi::{HasDataLayout, Size, TagEncoding, Variants};
 ///   Large([u32; 1024]),
 /// }
 /// ```
-/// Instead of emitting moves of the large variant,
-/// Perform a memcpy instead.
+/// Instead of emitting moves of the large variant, perform a memcpy instead.
 /// Based off of [this HackMD](https://hackmd.io/@ft4bxUsFT5CEUBmRKYHr7w/rJM8BBPzD).
 ///
 /// In summary, what this does is at runtime determine which enum variant is active,
@@ -34,10 +33,173 @@ impl<'tcx> crate::MirPass<'tcx> for EnumSizeOpt {
         // https://github.com/rust-lang/rust/pull/85158#issuecomment-1101836457
         sess.opts.unstable_opts.unsound_mir_opts || sess.mir_opt_level() >= 3
     }
+
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         // NOTE: This pass may produce different MIR based on the alignment of the target
         // platform, but it will still be valid.
-        self.optim(tcx, body);
+
+        let mut alloc_cache = FxHashMap::default();
+        let body_did = body.source.def_id();
+        let param_env = tcx.param_env_reveal_all_normalized(body_did);
+
+        let blocks = body.basic_blocks.as_mut();
+        let local_decls = &mut body.local_decls;
+
+        for bb in blocks {
+            bb.expand_statements(|st| {
+                let StatementKind::Assign(box (
+                    lhs,
+                    Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)),
+                )) = &st.kind
+                else {
+                    return None;
+                };
+
+                let ty = lhs.ty(local_decls, tcx).ty;
+
+                let (adt_def, num_variants, alloc_id) =
+                    self.candidate(tcx, param_env, ty, &mut alloc_cache)?;
+
+                let source_info = st.source_info;
+                let span = source_info.span;
+
+                let tmp_ty = Ty::new_array(tcx, tcx.types.usize, num_variants as u64);
+                let size_array_local = local_decls.push(LocalDecl::new(tmp_ty, span));
+                let store_live =
+                    Statement { source_info, kind: StatementKind::StorageLive(size_array_local) };
+
+                let place = Place::from(size_array_local);
+                let constant_vals = ConstOperand {
+                    span,
+                    user_ty: None,
+                    const_: Const::Val(
+                        ConstValue::Indirect { alloc_id, offset: Size::ZERO },
+                        tmp_ty,
+                    ),
+                };
+                let rval = Rvalue::Use(Operand::Constant(Box::new(constant_vals)));
+                let const_assign =
+                    Statement { source_info, kind: StatementKind::Assign(Box::new((place, rval))) };
+
+                let discr_place = Place::from(
+                    local_decls.push(LocalDecl::new(adt_def.repr().discr_type().to_ty(tcx), span)),
+                );
+                let store_discr = Statement {
+                    source_info,
+                    kind: StatementKind::Assign(Box::new((
+                        discr_place,
+                        Rvalue::Discriminant(*rhs),
+                    ))),
+                };
+
+                let discr_cast_place =
+                    Place::from(local_decls.push(LocalDecl::new(tcx.types.usize, span)));
+                let cast_discr = Statement {
+                    source_info,
+                    kind: StatementKind::Assign(Box::new((
+                        discr_cast_place,
+                        Rvalue::Cast(
+                            CastKind::IntToInt,
+                            Operand::Copy(discr_place),
+                            tcx.types.usize,
+                        ),
+                    ))),
+                };
+
+                let size_place =
+                    Place::from(local_decls.push(LocalDecl::new(tcx.types.usize, span)));
+                let store_size = Statement {
+                    source_info,
+                    kind: StatementKind::Assign(Box::new((
+                        size_place,
+                        Rvalue::Use(Operand::Copy(Place {
+                            local: size_array_local,
+                            projection: tcx
+                                .mk_place_elems(&[PlaceElem::Index(discr_cast_place.local)]),
+                        })),
+                    ))),
+                };
+
+                let dst =
+                    Place::from(local_decls.push(LocalDecl::new(Ty::new_mut_ptr(tcx, ty), span)));
+                let dst_ptr = Statement {
+                    source_info,
+                    kind: StatementKind::Assign(Box::new((
+                        dst,
+                        Rvalue::RawPtr(Mutability::Mut, *lhs),
+                    ))),
+                };
+
+                let dst_cast_ty = Ty::new_mut_ptr(tcx, tcx.types.u8);
+                let dst_cast_place =
+                    Place::from(local_decls.push(LocalDecl::new(dst_cast_ty, span)));
+                let dst_cast = Statement {
+                    source_info,
+                    kind: StatementKind::Assign(Box::new((
+                        dst_cast_place,
+                        Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(dst), dst_cast_ty),
+                    ))),
+                };
+
+                let src =
+                    Place::from(local_decls.push(LocalDecl::new(Ty::new_imm_ptr(tcx, ty), span)));
+                let src_ptr = Statement {
+                    source_info,
+                    kind: StatementKind::Assign(Box::new((
+                        src,
+                        Rvalue::RawPtr(Mutability::Not, *rhs),
+                    ))),
+                };
+
+                let src_cast_ty = Ty::new_imm_ptr(tcx, tcx.types.u8);
+                let src_cast_place =
+                    Place::from(local_decls.push(LocalDecl::new(src_cast_ty, span)));
+                let src_cast = Statement {
+                    source_info,
+                    kind: StatementKind::Assign(Box::new((
+                        src_cast_place,
+                        Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(src), src_cast_ty),
+                    ))),
+                };
+
+                let deinit_old =
+                    Statement { source_info, kind: StatementKind::Deinit(Box::new(dst)) };
+
+                let copy_bytes = Statement {
+                    source_info,
+                    kind: StatementKind::Intrinsic(Box::new(
+                        NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping {
+                            src: Operand::Copy(src_cast_place),
+                            dst: Operand::Copy(dst_cast_place),
+                            count: Operand::Copy(size_place),
+                        }),
+                    )),
+                };
+
+                let store_dead =
+                    Statement { source_info, kind: StatementKind::StorageDead(size_array_local) };
+
+                let iter = [
+                    store_live,
+                    const_assign,
+                    store_discr,
+                    cast_discr,
+                    store_size,
+                    dst_ptr,
+                    dst_cast,
+                    src_ptr,
+                    src_cast,
+                    deinit_old,
+                    copy_bytes,
+                    store_dead,
+                ]
+                .into_iter();
+
+                st.make_nop();
+
+                Some(iter)
+            });
+        }
     }
 }
 
@@ -82,6 +244,8 @@ impl EnumSizeOpt {
         let ptr_sized_int = data_layout.ptr_sized_integer();
         let target_bytes = ptr_sized_int.size().bytes() as usize;
         let mut data = vec![0; target_bytes * num_discrs];
+
+        // We use a macro because `$bytes` can be u32 or u64.
         macro_rules! encode_store {
             ($curr_idx: expr, $endian: expr, $bytes: expr) => {
                 let bytes = match $endian {
@@ -116,184 +280,4 @@ impl EnumSizeOpt {
         let alloc = tcx.reserve_and_set_memory_alloc(tcx.mk_const_alloc(alloc));
         Some((*adt_def, num_discrs, *alloc_cache.entry(ty).or_insert(alloc)))
     }
-    fn optim<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        let mut alloc_cache = FxHashMap::default();
-        let body_did = body.source.def_id();
-        let param_env = tcx.param_env_reveal_all_normalized(body_did);
-
-        let blocks = body.basic_blocks.as_mut();
-        let local_decls = &mut body.local_decls;
-
-        for bb in blocks {
-            bb.expand_statements(|st| {
-                if let StatementKind::Assign(box (
-                    lhs,
-                    Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)),
-                )) = &st.kind
-                {
-                    let ty = lhs.ty(local_decls, tcx).ty;
-
-                    let source_info = st.source_info;
-                    let span = source_info.span;
-
-                    let (adt_def, num_variants, alloc_id) =
-                        self.candidate(tcx, param_env, ty, &mut alloc_cache)?;
-
-                    let tmp_ty = Ty::new_array(tcx, tcx.types.usize, num_variants as u64);
-
-                    let size_array_local = local_decls.push(LocalDecl::new(tmp_ty, span));
-                    let store_live = Statement {
-                        source_info,
-                        kind: StatementKind::StorageLive(size_array_local),
-                    };
-
-                    let place = Place::from(size_array_local);
-                    let constant_vals = ConstOperand {
-                        span,
-                        user_ty: None,
-                        const_: Const::Val(
-                            ConstValue::Indirect { alloc_id, offset: Size::ZERO },
-                            tmp_ty,
-                        ),
-                    };
-                    let rval = Rvalue::Use(Operand::Constant(Box::new(constant_vals)));
-
-                    let const_assign = Statement {
-                        source_info,
-                        kind: StatementKind::Assign(Box::new((place, rval))),
-                    };
-
-                    let discr_place = Place::from(
-                        local_decls
-                            .push(LocalDecl::new(adt_def.repr().discr_type().to_ty(tcx), span)),
-                    );
-
-                    let store_discr = Statement {
-                        source_info,
-                        kind: StatementKind::Assign(Box::new((
-                            discr_place,
-                            Rvalue::Discriminant(*rhs),
-                        ))),
-                    };
-
-                    let discr_cast_place =
-                        Place::from(local_decls.push(LocalDecl::new(tcx.types.usize, span)));
-
-                    let cast_discr = Statement {
-                        source_info,
-                        kind: StatementKind::Assign(Box::new((
-                            discr_cast_place,
-                            Rvalue::Cast(
-                                CastKind::IntToInt,
-                                Operand::Copy(discr_place),
-                                tcx.types.usize,
-                            ),
-                        ))),
-                    };
-
-                    let size_place =
-                        Place::from(local_decls.push(LocalDecl::new(tcx.types.usize, span)));
-
-                    let store_size = Statement {
-                        source_info,
-                        kind: StatementKind::Assign(Box::new((
-                            size_place,
-                            Rvalue::Use(Operand::Copy(Place {
-                                local: size_array_local,
-                                projection: tcx
-                                    .mk_place_elems(&[PlaceElem::Index(discr_cast_place.local)]),
-                            })),
-                        ))),
-                    };
-
-                    let dst = Place::from(
-                        local_decls.push(LocalDecl::new(Ty::new_mut_ptr(tcx, ty), span)),
-                    );
-
-                    let dst_ptr = Statement {
-                        source_info,
-                        kind: StatementKind::Assign(Box::new((
-                            dst,
-                            Rvalue::RawPtr(Mutability::Mut, *lhs),
-                        ))),
-                    };
-
-                    let dst_cast_ty = Ty::new_mut_ptr(tcx, tcx.types.u8);
-                    let dst_cast_place =
-                        Place::from(local_decls.push(LocalDecl::new(dst_cast_ty, span)));
-
-                    let dst_cast = Statement {
-                        source_info,
-                        kind: StatementKind::Assign(Box::new((
-                            dst_cast_place,
-                            Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(dst), dst_cast_ty),
-                        ))),
-                    };
-
-                    let src = Place::from(
-                        local_decls.push(LocalDecl::new(Ty::new_imm_ptr(tcx, ty), span)),
-                    );
-
-                    let src_ptr = Statement {
-                        source_info,
-                        kind: StatementKind::Assign(Box::new((
-                            src,
-                            Rvalue::RawPtr(Mutability::Not, *rhs),
-                        ))),
-                    };
-
-                    let src_cast_ty = Ty::new_imm_ptr(tcx, tcx.types.u8);
-                    let src_cast_place =
-                        Place::from(local_decls.push(LocalDecl::new(src_cast_ty, span)));
-
-                    let src_cast = Statement {
-                        source_info,
-                        kind: StatementKind::Assign(Box::new((
-                            src_cast_place,
-                            Rvalue::Cast(CastKind::PtrToPtr, Operand::Copy(src), src_cast_ty),
-                        ))),
-                    };
-
-                    let deinit_old =
-                        Statement { source_info, kind: StatementKind::Deinit(Box::new(dst)) };
-
-                    let copy_bytes = Statement {
-                        source_info,
-                        kind: StatementKind::Intrinsic(Box::new(
-                            NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping {
-                                src: Operand::Copy(src_cast_place),
-                                dst: Operand::Copy(dst_cast_place),
-                                count: Operand::Copy(size_place),
-                            }),
-                        )),
-                    };
-
-                    let store_dead = Statement {
-                        source_info,
-                        kind: StatementKind::StorageDead(size_array_local),
-                    };
-                    let iter = [
-                        store_live,
-                        const_assign,
-                        store_discr,
-                        cast_discr,
-                        store_size,
-                        dst_ptr,
-                        dst_cast,
-                        src_ptr,
-                        src_cast,
-                        deinit_old,
-                        copy_bytes,
-                        store_dead,
-                    ]
-                    .into_iter();
-
-                    st.make_nop();
-                    Some(iter)
-                } else {
-                    None
-                }
-            });
-        }
-    }
 }
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 0bbbf047f63..84d07d38330 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -87,6 +87,7 @@ mod match_branches;
 mod mentioned_items;
 mod multiple_return_terminators;
 mod nrvo;
+mod post_drop_elaboration;
 mod prettify;
 mod promote_consts;
 mod ref_prop;
@@ -168,8 +169,9 @@ fn remap_mir_for_const_eval_select<'tcx>(
                 let (method, place): (fn(Place<'tcx>) -> Operand<'tcx>, Place<'tcx>) =
                     match tupled_args.node {
                         Operand::Constant(_) => {
-                            // there is no good way of extracting a tuple arg from a constant (const generic stuff)
-                            // so we just create a temporary and deconstruct that.
+                            // There is no good way of extracting a tuple arg from a constant
+                            // (const generic stuff) so we just create a temporary and deconstruct
+                            // that.
                             let local = body.local_decls.push(LocalDecl::new(ty, fn_span));
                             bb.statements.push(Statement {
                                 source_info: SourceInfo::outermost(fn_span),
@@ -222,14 +224,14 @@ 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 mut set: FxIndexSet<_> = tcx.hir().body_owners().collect();
+    let 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<'a> {
-        set: &'a mut FxIndexSet<LocalDefId>,
+    struct GatherCtors {
+        set: FxIndexSet<LocalDefId>,
     }
-    impl<'tcx> Visitor<'tcx> for GatherCtors<'_> {
+    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);
@@ -237,9 +239,11 @@ fn mir_keys(tcx: TyCtxt<'_>, (): ()) -> FxIndexSet<LocalDefId> {
             intravisit::walk_struct_def(self, v)
         }
     }
-    tcx.hir().visit_all_item_likes_in_crate(&mut GatherCtors { set: &mut set });
 
-    set
+    let mut gather_ctors = GatherCtors { set };
+    tcx.hir().visit_all_item_likes_in_crate(&mut gather_ctors);
+
+    gather_ctors.set
 }
 
 fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
@@ -477,10 +481,13 @@ pub fn run_analysis_to_runtime_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'
         pm::run_passes(
             tcx,
             body,
-            &[&remove_uninit_drops::RemoveUninitDrops, &simplify::SimplifyCfg::RemoveFalseEdges],
+            &[
+                &remove_uninit_drops::RemoveUninitDrops,
+                &simplify::SimplifyCfg::RemoveFalseEdges,
+                &Lint(post_drop_elaboration::CheckLiveDrops),
+            ],
             None,
         );
-        check_consts::post_drop_elaboration::check_live_drops(tcx, body); // FIXME: make this a MIR lint
     }
 
     debug!("runtime_mir_lowering({:?})", did);
@@ -509,10 +516,12 @@ fn run_analysis_cleanup_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
 /// Returns the sequence of passes that lowers analysis to runtime MIR.
 fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     let passes: &[&dyn MirPass<'tcx>] = &[
-        // These next passes must be executed together
+        // These next passes must be executed together.
         &add_call_guards::CriticalCallEdges,
-        &reveal_all::RevealAll, // has to be done before drop elaboration, since we need to drop opaque types, too.
-        &add_subtyping_projections::Subtyper, // calling this after reveal_all ensures that we don't deal with opaque types
+        // Must be done before drop elaboration because we need to drop opaque types, too.
+        &reveal_all::RevealAll,
+        // Calling this after reveal_all ensures that we don't deal with opaque types.
+        &add_subtyping_projections::Subtyper,
         &elaborate_drops::ElaborateDrops,
         // This will remove extraneous landing pads which are no longer
         // necessary as well as forcing any call in a non-unwinding
@@ -521,8 +530,8 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         // AddMovesForPackedDrops needs to run after drop
         // elaboration.
         &add_moves_for_packed_drops::AddMovesForPackedDrops,
-        // `AddRetag` needs to run after `ElaborateDrops` but before `ElaborateBoxDerefs`. Otherwise it should run fairly late,
-        // but before optimizations begin.
+        // `AddRetag` needs to run after `ElaborateDrops` but before `ElaborateBoxDerefs`.
+        // Otherwise it should run fairly late, but before optimizations begin.
         &add_retag::AddRetag,
         &elaborate_box_derefs::ElaborateBoxDerefs,
         &coroutine::StateTransform,
@@ -563,13 +572,15 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
             // Before inlining: trim down MIR with passes to reduce inlining work.
 
             // Has to be done before inlining, otherwise actual call will be almost always inlined.
-            // Also simple, so can just do first
+            // Also simple, so can just do first.
             &lower_slice_len::LowerSliceLenCalls,
-            // Perform instsimplify before inline to eliminate some trivial calls (like clone shims).
+            // Perform instsimplify before inline to eliminate some trivial calls (like clone
+            // shims).
             &instsimplify::InstSimplify::BeforeInline,
             // Perform inlining, which may add a lot of code.
             &inline::Inline,
-            // Code from other crates may have storage markers, so this needs to happen after inlining.
+            // Code from other crates may have storage markers, so this needs to happen after
+            // inlining.
             &remove_storage_markers::RemoveStorageMarkers,
             // Inlining and instantiation may introduce ZST and useless drops.
             &remove_zsts::RemoveZsts,
@@ -586,7 +597,8 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
             &match_branches::MatchBranchSimplification,
             // inst combine is after MatchBranchSimplification to clean up Ne(_1, false)
             &multiple_return_terminators::MultipleReturnTerminators,
-            // After simplifycfg, it allows us to discover new opportunities for peephole optimizations.
+            // After simplifycfg, it allows us to discover new opportunities for peephole
+            // optimizations.
             &instsimplify::InstSimplify::AfterSimplifyCfg,
             &simplify::SimplifyLocals::BeforeConstProp,
             &dead_store_elimination::DeadStoreElimination::Initial,
diff --git a/compiler/rustc_mir_transform/src/lower_slice_len.rs b/compiler/rustc_mir_transform/src/lower_slice_len.rs
index ca59d4d12ac..420661f29c8 100644
--- a/compiler/rustc_mir_transform/src/lower_slice_len.rs
+++ b/compiler/rustc_mir_transform/src/lower_slice_len.rs
@@ -13,22 +13,18 @@ impl<'tcx> crate::MirPass<'tcx> for LowerSliceLenCalls {
     }
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        lower_slice_len_calls(tcx, body)
-    }
-}
-
-fn lower_slice_len_calls<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-    let language_items = tcx.lang_items();
-    let Some(slice_len_fn_item_def_id) = language_items.slice_len_fn() else {
-        // there is no lang item to compare to :)
-        return;
-    };
+        let language_items = tcx.lang_items();
+        let Some(slice_len_fn_item_def_id) = language_items.slice_len_fn() else {
+            // there is no lang item to compare to :)
+            return;
+        };
 
-    // The one successor remains unchanged, so no need to invalidate
-    let basic_blocks = body.basic_blocks.as_mut_preserves_cfg();
-    for block in basic_blocks {
-        // lower `<[_]>::len` calls
-        lower_slice_len_call(block, slice_len_fn_item_def_id);
+        // The one successor remains unchanged, so no need to invalidate
+        let basic_blocks = body.basic_blocks.as_mut_preserves_cfg();
+        for block in basic_blocks {
+            // lower `<[_]>::len` calls
+            lower_slice_len_call(block, slice_len_fn_item_def_id);
+        }
     }
 }
 
diff --git a/compiler/rustc_mir_transform/src/match_branches.rs b/compiler/rustc_mir_transform/src/match_branches.rs
index 2a2616b20a6..0f981425cfd 100644
--- a/compiler/rustc_mir_transform/src/match_branches.rs
+++ b/compiler/rustc_mir_transform/src/match_branches.rs
@@ -57,8 +57,9 @@ impl<'tcx> crate::MirPass<'tcx> for MatchBranchSimplification {
 }
 
 trait SimplifyMatch<'tcx> {
-    /// Simplifies a match statement, returning true if the simplification succeeds, false otherwise.
-    /// Generic code is written here, and we generally don't need a custom implementation.
+    /// Simplifies a match statement, returning true if the simplification succeeds, false
+    /// otherwise. Generic code is written here, and we generally don't need a custom
+    /// implementation.
     fn simplify(
         &mut self,
         tcx: TyCtxt<'tcx>,
@@ -240,7 +241,8 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToIf {
                         // Same value in both blocks. Use statement as is.
                         patch.add_statement(parent_end, f.kind.clone());
                     } else {
-                        // Different value between blocks. Make value conditional on switch condition.
+                        // Different value between blocks. Make value conditional on switch
+                        // condition.
                         let size = tcx.layout_of(param_env.and(discr_ty)).unwrap().size;
                         let const_cmp = Operand::const_from_scalar(
                             tcx,
@@ -394,14 +396,16 @@ impl<'tcx> SimplifyMatch<'tcx> for SimplifyToExp {
             return None;
         }
 
-        // We first compare the two branches, and then the other branches need to fulfill the same conditions.
+        // We first compare the two branches, and then the other branches need to fulfill the same
+        // conditions.
         let mut expected_transform_kinds = Vec::new();
         for (f, s) in iter::zip(first_stmts, second_stmts) {
             let compare_type = match (&f.kind, &s.kind) {
                 // If two statements are exactly the same, we can optimize.
                 (f_s, s_s) if f_s == s_s => ExpectedTransformKind::Same(f_s),
 
-                // If two statements are assignments with the match values to the same place, we can optimize.
+                // If two statements are assignments with the match values to the same place, we
+                // can optimize.
                 (
                     StatementKind::Assign(box (lhs_f, Rvalue::Use(Operand::Constant(f_c)))),
                     StatementKind::Assign(box (lhs_s, Rvalue::Use(Operand::Constant(s_c)))),
diff --git a/compiler/rustc_mir_transform/src/mentioned_items.rs b/compiler/rustc_mir_transform/src/mentioned_items.rs
index 7f9d0a5b698..f24de609e6b 100644
--- a/compiler/rustc_mir_transform/src/mentioned_items.rs
+++ b/compiler/rustc_mir_transform/src/mentioned_items.rs
@@ -10,7 +10,7 @@ pub(super) struct MentionedItems;
 struct MentionedItemsVisitor<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
     body: &'a mir::Body<'tcx>,
-    mentioned_items: &'a mut Vec<Spanned<MentionedItem<'tcx>>>,
+    mentioned_items: Vec<Spanned<MentionedItem<'tcx>>>,
 }
 
 impl<'tcx> crate::MirPass<'tcx> for MentionedItems {
@@ -23,9 +23,9 @@ impl<'tcx> crate::MirPass<'tcx> for MentionedItems {
     }
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) {
-        let mut mentioned_items = Vec::new();
-        MentionedItemsVisitor { tcx, body, mentioned_items: &mut mentioned_items }.visit_body(body);
-        body.set_mentioned_items(mentioned_items);
+        let mut visitor = MentionedItemsVisitor { tcx, body, mentioned_items: Vec::new() };
+        visitor.visit_body(body);
+        body.set_mentioned_items(visitor.mentioned_items);
     }
 }
 
@@ -82,7 +82,9 @@ impl<'tcx> Visitor<'tcx> for MentionedItemsVisitor<'_, 'tcx> {
                     source_ty.builtin_deref(true).map(|t| t.kind()),
                     target_ty.builtin_deref(true).map(|t| t.kind()),
                 ) {
-                    (Some(ty::Array(..)), Some(ty::Str | ty::Slice(..))) => false, // &str/&[T] unsizing
+                    // &str/&[T] unsizing
+                    (Some(ty::Array(..)), Some(ty::Str | ty::Slice(..))) => false,
+
                     _ => true,
                 };
                 if may_involve_vtable {
diff --git a/compiler/rustc_mir_transform/src/post_drop_elaboration.rs b/compiler/rustc_mir_transform/src/post_drop_elaboration.rs
new file mode 100644
index 00000000000..75721d46076
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/post_drop_elaboration.rs
@@ -0,0 +1,13 @@
+use rustc_const_eval::check_consts;
+use rustc_middle::mir::*;
+use rustc_middle::ty::TyCtxt;
+
+use crate::MirLint;
+
+pub(super) struct CheckLiveDrops;
+
+impl<'tcx> MirLint<'tcx> for CheckLiveDrops {
+    fn run_lint(&self, tcx: TyCtxt<'tcx>, body: &Body<'tcx>) {
+        check_consts::post_drop_elaboration::check_live_drops(tcx, body);
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/prettify.rs b/compiler/rustc_mir_transform/src/prettify.rs
index ef011d230c2..937c207776b 100644
--- a/compiler/rustc_mir_transform/src/prettify.rs
+++ b/compiler/rustc_mir_transform/src/prettify.rs
@@ -63,7 +63,7 @@ impl<'tcx> crate::MirPass<'tcx> for ReorderLocals {
             finder.visit_basic_block_data(bb, bbd);
         }
 
-        // track everything in case there are some locals that we never saw,
+        // Track everything in case there are some locals that we never saw,
         // such as in non-block things like debug info or in non-uses.
         for local in body.local_decls.indices() {
             finder.track(local);
@@ -87,7 +87,7 @@ impl<'tcx> crate::MirPass<'tcx> for ReorderLocals {
 
 fn permute<I: rustc_index::Idx + Ord, T>(data: &mut IndexVec<I, T>, map: &IndexSlice<I, I>) {
     // FIXME: It would be nice to have a less-awkward way to apply permutations,
-    // but I don't know one that exists.  `sort_by_cached_key` has logic for it
+    // but I don't know one that exists. `sort_by_cached_key` has logic for it
     // internally, but not in a way that we're allowed to use here.
     let mut enumerated: Vec<_> = std::mem::take(data).into_iter_enumerated().collect();
     enumerated.sort_by_key(|p| map[p.0]);
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index 65309f63d59..59df99f858d 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -1,16 +1,14 @@
 //! A pass that promotes borrows of constant rvalues.
 //!
-//! The rvalues considered constant are trees of temps,
-//! each with exactly one initialization, and holding
-//! a constant value with no interior mutability.
-//! They are placed into a new MIR constant body in
-//! `promoted` and the borrow rvalue is replaced with
-//! a `Literal::Promoted` using the index into `promoted`
-//! of that constant MIR.
+//! The rvalues considered constant are trees of temps, each with exactly one
+//! initialization, and holding a constant value with no interior mutability.
+//! They are placed into a new MIR constant body in `promoted` and the borrow
+//! rvalue is replaced with a `Literal::Promoted` using the index into
+//! `promoted` of that constant MIR.
 //!
-//! This pass assumes that every use is dominated by an
-//! initialization and can otherwise silence errors, if
-//! move analysis runs after promotion on broken MIR.
+//! This pass assumes that every use is dominated by an initialization and can
+//! otherwise silence errors, if move analysis runs after promotion on broken
+//! MIR.
 
 use std::assert_matches::assert_matches;
 use std::cell::Cell;
@@ -38,6 +36,7 @@ use tracing::{debug, instrument};
 /// newly created `Constant`.
 #[derive(Default)]
 pub(super) struct PromoteTemps<'tcx> {
+    // Must use `Cell` because `run_pass` takes `&self`, not `&mut self`.
     pub promoted_fragments: Cell<IndexVec<Promoted, Body<'tcx>>>,
 }
 
@@ -386,7 +385,8 @@ impl<'tcx> Validator<'_, 'tcx> {
     fn validate_ref(&mut self, kind: BorrowKind, place: &Place<'tcx>) -> Result<(), Unpromotable> {
         match kind {
             // Reject these borrow types just to be safe.
-            // FIXME(RalfJung): could we allow them? Should we? No point in it until we have a usecase.
+            // FIXME(RalfJung): could we allow them? Should we? No point in it until we have a
+            // usecase.
             BorrowKind::Fake(_) | BorrowKind::Mut { kind: MutBorrowKind::ClosureCapture } => {
                 return Err(Unpromotable);
             }
@@ -468,7 +468,8 @@ impl<'tcx> Validator<'_, 'tcx> {
                 let lhs_ty = lhs.ty(self.body, self.tcx);
 
                 if let ty::RawPtr(_, _) | ty::FnPtr(..) = lhs_ty.kind() {
-                    // Raw and fn pointer operations are not allowed inside consts and thus not promotable.
+                    // Raw and fn pointer operations are not allowed inside consts and thus not
+                    // promotable.
                     assert_matches!(
                         op,
                         BinOp::Eq
@@ -498,7 +499,8 @@ impl<'tcx> Validator<'_, 'tcx> {
                                 Some(x) if x != 0 => {}        // okay
                                 _ => return Err(Unpromotable), // value not known or 0 -- not okay
                             }
-                            // Furthermore, for signed division, we also have to exclude `int::MIN / -1`.
+                            // Furthermore, for signed division, we also have to exclude `int::MIN /
+                            // -1`.
                             if lhs_ty.is_signed() {
                                 match rhs_val.map(|x| x.to_int(sz)) {
                                     Some(-1) | None => {
@@ -512,8 +514,11 @@ impl<'tcx> Validator<'_, 'tcx> {
                                         };
                                         let lhs_min = sz.signed_int_min();
                                         match lhs_val.map(|x| x.to_int(sz)) {
-                                            Some(x) if x != lhs_min => {}  // okay
-                                            _ => return Err(Unpromotable), // value not known or int::MIN -- not okay
+                                            // okay
+                                            Some(x) if x != lhs_min => {}
+
+                                            // value not known or int::MIN -- not okay
+                                            _ => return Err(Unpromotable),
                                         }
                                     }
                                     _ => {}
@@ -815,8 +820,8 @@ impl<'a, 'tcx> Promoter<'a, 'tcx> {
                 TerminatorKind::Call {
                     mut func, mut args, call_source: desugar, fn_span, ..
                 } => {
-                    // This promoted involves a function call, so it may fail to evaluate.
-                    // Let's make sure it is added to `required_consts` so that failure cannot get lost.
+                    // This promoted involves a function call, so it may fail to evaluate. Let's
+                    // make sure it is added to `required_consts` so that failure cannot get lost.
                     self.add_to_required = true;
 
                     self.visit_operand(&mut func, loc);
diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs
index 25b98786c66..4c3a99b79d4 100644
--- a/compiler/rustc_mir_transform/src/ref_prop.rs
+++ b/compiler/rustc_mir_transform/src/ref_prop.rs
@@ -253,11 +253,8 @@ fn compute_replacement<'tcx>(
 
     debug!(?targets);
 
-    let mut finder = ReplacementFinder {
-        targets: &mut targets,
-        can_perform_opt,
-        allowed_replacements: FxHashSet::default(),
-    };
+    let mut finder =
+        ReplacementFinder { targets, can_perform_opt, allowed_replacements: FxHashSet::default() };
     let reachable_blocks = traversal::reachable_as_bitset(body);
     for (bb, bbdata) in body.basic_blocks.iter_enumerated() {
         // Only visit reachable blocks as we rely on dataflow.
@@ -269,19 +266,19 @@ fn compute_replacement<'tcx>(
     let allowed_replacements = finder.allowed_replacements;
     return Replacer {
         tcx,
-        targets,
+        targets: finder.targets,
         storage_to_remove,
         allowed_replacements,
         any_replacement: false,
     };
 
-    struct ReplacementFinder<'a, 'tcx, F> {
-        targets: &'a mut IndexVec<Local, Value<'tcx>>,
+    struct ReplacementFinder<'tcx, F> {
+        targets: IndexVec<Local, Value<'tcx>>,
         can_perform_opt: F,
         allowed_replacements: FxHashSet<(Local, Location)>,
     }
 
-    impl<'tcx, F> Visitor<'tcx> for ReplacementFinder<'_, 'tcx, F>
+    impl<'tcx, F> Visitor<'tcx> for ReplacementFinder<'tcx, F>
     where
         F: FnMut(Place<'tcx>, Location) -> bool,
     {
diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
index 37197c3f573..55394e93a5c 100644
--- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
+++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs
@@ -18,7 +18,61 @@ impl<'tcx> crate::MirPass<'tcx> for RemoveNoopLandingPads {
     fn run_pass(&self, _tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         let def_id = body.source.def_id();
         debug!(?def_id);
-        self.remove_nop_landing_pads(body)
+
+        // Skip the pass if there are no blocks with a resume terminator.
+        let has_resume = body
+            .basic_blocks
+            .iter_enumerated()
+            .any(|(_bb, block)| matches!(block.terminator().kind, TerminatorKind::UnwindResume));
+        if !has_resume {
+            debug!("remove_noop_landing_pads: no resume block in MIR");
+            return;
+        }
+
+        // make sure there's a resume block without any statements
+        let resume_block = {
+            let mut patch = MirPatch::new(body);
+            let resume_block = patch.resume_block();
+            patch.apply(body);
+            resume_block
+        };
+        debug!("remove_noop_landing_pads: resume block is {:?}", resume_block);
+
+        let mut jumps_folded = 0;
+        let mut landing_pads_removed = 0;
+        let mut nop_landing_pads = BitSet::new_empty(body.basic_blocks.len());
+
+        // This is a post-order traversal, so that if A post-dominates B
+        // then A will be visited before B.
+        let postorder: Vec<_> = traversal::postorder(body).map(|(bb, _)| bb).collect();
+        for bb in postorder {
+            debug!("  processing {:?}", bb);
+            if let Some(unwind) = body[bb].terminator_mut().unwind_mut() {
+                if let UnwindAction::Cleanup(unwind_bb) = *unwind {
+                    if nop_landing_pads.contains(unwind_bb) {
+                        debug!("    removing noop landing pad");
+                        landing_pads_removed += 1;
+                        *unwind = UnwindAction::Continue;
+                    }
+                }
+            }
+
+            for target in body[bb].terminator_mut().successors_mut() {
+                if *target != resume_block && nop_landing_pads.contains(*target) {
+                    debug!("    folding noop jump to {:?} to resume block", target);
+                    *target = resume_block;
+                    jumps_folded += 1;
+                }
+            }
+
+            let is_nop_landing_pad = self.is_nop_landing_pad(bb, body, &nop_landing_pads);
+            if is_nop_landing_pad {
+                nop_landing_pads.insert(bb);
+            }
+            debug!("    is_nop_landing_pad({:?}) = {}", bb, is_nop_landing_pad);
+        }
+
+        debug!("removed {:?} jumps and {:?} landing pads", jumps_folded, landing_pads_removed);
     }
 }
 
@@ -82,61 +136,4 @@ impl RemoveNoopLandingPads {
             | TerminatorKind::InlineAsm { .. } => false,
         }
     }
-
-    fn remove_nop_landing_pads(&self, body: &mut Body<'_>) {
-        // Skip the pass if there are no blocks with a resume terminator.
-        let has_resume = body
-            .basic_blocks
-            .iter_enumerated()
-            .any(|(_bb, block)| matches!(block.terminator().kind, TerminatorKind::UnwindResume));
-        if !has_resume {
-            debug!("remove_noop_landing_pads: no resume block in MIR");
-            return;
-        }
-
-        // make sure there's a resume block without any statements
-        let resume_block = {
-            let mut patch = MirPatch::new(body);
-            let resume_block = patch.resume_block();
-            patch.apply(body);
-            resume_block
-        };
-        debug!("remove_noop_landing_pads: resume block is {:?}", resume_block);
-
-        let mut jumps_folded = 0;
-        let mut landing_pads_removed = 0;
-        let mut nop_landing_pads = BitSet::new_empty(body.basic_blocks.len());
-
-        // This is a post-order traversal, so that if A post-dominates B
-        // then A will be visited before B.
-        let postorder: Vec<_> = traversal::postorder(body).map(|(bb, _)| bb).collect();
-        for bb in postorder {
-            debug!("  processing {:?}", bb);
-            if let Some(unwind) = body[bb].terminator_mut().unwind_mut() {
-                if let UnwindAction::Cleanup(unwind_bb) = *unwind {
-                    if nop_landing_pads.contains(unwind_bb) {
-                        debug!("    removing noop landing pad");
-                        landing_pads_removed += 1;
-                        *unwind = UnwindAction::Continue;
-                    }
-                }
-            }
-
-            for target in body[bb].terminator_mut().successors_mut() {
-                if *target != resume_block && nop_landing_pads.contains(*target) {
-                    debug!("    folding noop jump to {:?} to resume block", target);
-                    *target = resume_block;
-                    jumps_folded += 1;
-                }
-            }
-
-            let is_nop_landing_pad = self.is_nop_landing_pad(bb, body, &nop_landing_pads);
-            if is_nop_landing_pad {
-                nop_landing_pads.insert(bb);
-            }
-            debug!("    is_nop_landing_pad({:?}) = {}", bb, is_nop_landing_pad);
-        }
-
-        debug!("removed {:?} jumps and {:?} landing pads", jumps_folded, landing_pads_removed);
-    }
 }
diff --git a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
index c58f492655a..d80a4edecdf 100644
--- a/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
+++ b/compiler/rustc_mir_transform/src/remove_uninit_drops.rs
@@ -106,8 +106,9 @@ fn is_needs_drop_and_init<'tcx>(
             // If its projection *is* present in `MoveData`, then the field may have been moved
             // from separate from its parent. Recurse.
             adt.variants().iter_enumerated().any(|(vid, variant)| {
-                // Enums have multiple variants, which are discriminated with a `Downcast` projection.
-                // Structs have a single variant, and don't use a `Downcast` projection.
+                // Enums have multiple variants, which are discriminated with a `Downcast`
+                // projection. Structs have a single variant, and don't use a `Downcast`
+                // projection.
                 let mpi = if adt.is_enum() {
                     let downcast =
                         move_path_children_matching(move_data, mpi, |x| x.is_downcast_to(vid));
diff --git a/compiler/rustc_mir_transform/src/required_consts.rs b/compiler/rustc_mir_transform/src/required_consts.rs
index ebcf5b5d27b..99d1cd6f63e 100644
--- a/compiler/rustc_mir_transform/src/required_consts.rs
+++ b/compiler/rustc_mir_transform/src/required_consts.rs
@@ -1,26 +1,21 @@
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::{traversal, Body, ConstOperand, Location};
 
-pub(super) struct RequiredConstsVisitor<'a, 'tcx> {
-    required_consts: &'a mut Vec<ConstOperand<'tcx>>,
+pub(super) struct RequiredConstsVisitor<'tcx> {
+    required_consts: Vec<ConstOperand<'tcx>>,
 }
 
-impl<'a, 'tcx> RequiredConstsVisitor<'a, 'tcx> {
-    fn new(required_consts: &'a mut Vec<ConstOperand<'tcx>>) -> Self {
-        RequiredConstsVisitor { required_consts }
-    }
-
+impl<'tcx> RequiredConstsVisitor<'tcx> {
     pub(super) fn compute_required_consts(body: &mut Body<'tcx>) {
-        let mut required_consts = Vec::new();
-        let mut required_consts_visitor = RequiredConstsVisitor::new(&mut required_consts);
+        let mut visitor = RequiredConstsVisitor { required_consts: Vec::new() };
         for (bb, bb_data) in traversal::reverse_postorder(&body) {
-            required_consts_visitor.visit_basic_block_data(bb, bb_data);
+            visitor.visit_basic_block_data(bb, bb_data);
         }
-        body.set_required_consts(required_consts);
+        body.set_required_consts(visitor.required_consts);
     }
 }
 
-impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'_, 'tcx> {
+impl<'tcx> Visitor<'tcx> for RequiredConstsVisitor<'tcx> {
     fn visit_const_operand(&mut self, constant: &ConstOperand<'tcx>, _: Location) {
         if constant.const_.is_required_const() {
             self.required_consts.push(*constant);
diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs
index 3db962bd94a..f3b2f78b31c 100644
--- a/compiler/rustc_mir_transform/src/reveal_all.rs
+++ b/compiler/rustc_mir_transform/src/reveal_all.rs
@@ -35,9 +35,9 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
         if place.projection.iter().all(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) {
             return;
         }
-        // `OpaqueCast` projections are only needed if there are opaque types on which projections are performed.
-        // After the `RevealAll` pass, all opaque types are replaced with their hidden types, so we don't need these
-        // projections anymore.
+        // `OpaqueCast` projections are only needed if there are opaque types on which projections
+        // are performed. After the `RevealAll` pass, all opaque types are replaced with their
+        // hidden types, so we don't need these projections anymore.
         place.projection = self.tcx.mk_place_elems(
             &place
                 .projection
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index cf8ef580b27..f1bd803d835 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -404,8 +404,7 @@ fn build_thread_local_shim<'tcx>(
     let span = tcx.def_span(def_id);
     let source_info = SourceInfo::outermost(span);
 
-    let mut blocks = IndexVec::with_capacity(1);
-    blocks.push(BasicBlockData {
+    let blocks = IndexVec::from_raw(vec![BasicBlockData {
         statements: vec![Statement {
             source_info,
             kind: StatementKind::Assign(Box::new((
@@ -415,7 +414,7 @@ fn build_thread_local_shim<'tcx>(
         }],
         terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }),
         is_cleanup: false,
-    });
+    }]);
 
     new_body(
         MirSource::from_instance(instance),
@@ -1003,7 +1002,8 @@ fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'t
     let locals = local_decls_for_sig(&sig, span);
 
     let source_info = SourceInfo::outermost(span);
-    // FIXME: use `expose_provenance` once we figure out whether function pointers have meaningful provenance.
+    // FIXME: use `expose_provenance` once we figure out whether function pointers have meaningful
+    // provenance.
     let rvalue = Rvalue::Cast(
         CastKind::FnPtrToPtr,
         Operand::Move(Place::from(Local::new(1))),
diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs
index cb8e1dfda98..7ed43547e11 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -381,23 +381,33 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyLocals {
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         trace!("running SimplifyLocals on {:?}", body.source);
-        simplify_locals(body, tcx);
-    }
-}
 
-pub(super) fn remove_unused_definitions<'tcx>(body: &mut Body<'tcx>) {
-    // First, we're going to get a count of *actual* uses for every `Local`.
-    let mut used_locals = UsedLocals::new(body);
+        // First, we're going to get a count of *actual* uses for every `Local`.
+        let mut used_locals = UsedLocals::new(body);
 
-    // Next, we're going to remove any `Local` with zero actual uses. When we remove those
-    // `Locals`, we're also going to subtract any uses of other `Locals` from the `used_locals`
-    // count. For example, if we removed `_2 = discriminant(_1)`, then we'll subtract one from
-    // `use_counts[_1]`. That in turn might make `_1` unused, so we loop until we hit a
-    // fixedpoint where there are no more unused locals.
-    remove_unused_definitions_helper(&mut used_locals, body);
+        // Next, we're going to remove any `Local` with zero actual uses. When we remove those
+        // `Locals`, we're also going to subtract any uses of other `Locals` from the `used_locals`
+        // count. For example, if we removed `_2 = discriminant(_1)`, then we'll subtract one from
+        // `use_counts[_1]`. That in turn might make `_1` unused, so we loop until we hit a
+        // fixedpoint where there are no more unused locals.
+        remove_unused_definitions_helper(&mut used_locals, body);
+
+        // Finally, we'll actually do the work of shrinking `body.local_decls` and remapping the
+        // `Local`s.
+        let map = make_local_map(&mut body.local_decls, &used_locals);
+
+        // Only bother running the `LocalUpdater` if we actually found locals to remove.
+        if map.iter().any(Option::is_none) {
+            // Update references to all vars and tmps now
+            let mut updater = LocalUpdater { map, tcx };
+            updater.visit_body_preserves_cfg(body);
+
+            body.local_decls.shrink_to_fit();
+        }
+    }
 }
 
-fn simplify_locals<'tcx>(body: &mut Body<'tcx>, tcx: TyCtxt<'tcx>) {
+pub(super) fn remove_unused_definitions<'tcx>(body: &mut Body<'tcx>) {
     // First, we're going to get a count of *actual* uses for every `Local`.
     let mut used_locals = UsedLocals::new(body);
 
@@ -407,18 +417,6 @@ fn simplify_locals<'tcx>(body: &mut Body<'tcx>, tcx: TyCtxt<'tcx>) {
     // `use_counts[_1]`. That in turn might make `_1` unused, so we loop until we hit a
     // fixedpoint where there are no more unused locals.
     remove_unused_definitions_helper(&mut used_locals, body);
-
-    // Finally, we'll actually do the work of shrinking `body.local_decls` and remapping the `Local`s.
-    let map = make_local_map(&mut body.local_decls, &used_locals);
-
-    // Only bother running the `LocalUpdater` if we actually found locals to remove.
-    if map.iter().any(Option::is_none) {
-        // Update references to all vars and tmps now
-        let mut updater = LocalUpdater { map, tcx };
-        updater.visit_body_preserves_cfg(body);
-
-        body.local_decls.shrink_to_fit();
-    }
 }
 
 /// Construct the mapping while swapping out unused stuff out from the `vec`.
diff --git a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
index 644bcb58d56..e8d8335b136 100644
--- a/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
+++ b/compiler/rustc_mir_transform/src/simplify_comparison_integral.rs
@@ -73,12 +73,13 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral {
                 _ => unreachable!(),
             }
 
-            // delete comparison statement if it the value being switched on was moved, which means it can not be user later on
+            // delete comparison statement if it the value being switched on was moved, which means
+            // it can not be user later on
             if opt.can_remove_bin_op_stmt {
                 bb.statements[opt.bin_op_stmt_idx].make_nop();
             } else {
-                // if the integer being compared to a const integral is being moved into the comparison,
-                // e.g `_2 = Eq(move _3, const 'x');`
+                // if the integer being compared to a const integral is being moved into the
+                // comparison, e.g `_2 = Eq(move _3, const 'x');`
                 // we want to avoid making a double move later on in the switchInt on _3.
                 // So to avoid `switchInt(move _3) -> ['x': bb2, otherwise: bb1];`,
                 // we convert the move in the comparison statement to a copy.
@@ -102,12 +103,15 @@ impl<'tcx> crate::MirPass<'tcx> for SimplifyComparisonIntegral {
 
             // remove StorageDead (if it exists) being used in the assign of the comparison
             for (stmt_idx, stmt) in bb.statements.iter().enumerate() {
-                if !matches!(stmt.kind, StatementKind::StorageDead(local) if local == opt.to_switch_on.local)
-                {
+                if !matches!(
+                    stmt.kind,
+                    StatementKind::StorageDead(local) if local == opt.to_switch_on.local
+                ) {
                     continue;
                 }
                 storage_deads_to_remove.push((stmt_idx, opt.bb_idx));
-                // if we have StorageDeads to remove then make sure to insert them at the top of each target
+                // if we have StorageDeads to remove then make sure to insert them at the top of
+                // each target
                 for bb_idx in new_targets.all_targets() {
                     storage_deads_to_insert.push((
                         *bb_idx,
@@ -207,7 +211,8 @@ fn find_branch_value_info<'tcx>(
         (Constant(branch_value), Copy(to_switch_on) | Move(to_switch_on))
         | (Copy(to_switch_on) | Move(to_switch_on), Constant(branch_value)) => {
             let branch_value_ty = branch_value.const_.ty();
-            // we only want to apply this optimization if we are matching on integrals (and chars), as it is not possible to switch on floats
+            // we only want to apply this optimization if we are matching on integrals (and chars),
+            // as it is not possible to switch on floats
             if !branch_value_ty.is_integral() && !branch_value_ty.is_char() {
                 return None;
             };
@@ -222,7 +227,8 @@ fn find_branch_value_info<'tcx>(
 struct OptimizationInfo<'tcx> {
     /// Basic block to apply the optimization
     bb_idx: BasicBlock,
-    /// Statement index of Eq/Ne assignment that can be removed. None if the assignment can not be removed - i.e the statement is used later on
+    /// Statement index of Eq/Ne assignment that can be removed. None if the assignment can not be
+    /// removed - i.e the statement is used later on
     bin_op_stmt_idx: usize,
     /// Can remove Eq/Ne assignment
     can_remove_bin_op_stmt: bool,
diff --git a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs
index 6957394ed10..5612e779d6b 100644
--- a/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs
+++ b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs
@@ -156,9 +156,9 @@ impl<'tcx> crate::MirPass<'tcx> for UnreachableEnumBranching {
                 };
                 true
             }
-            // If and only if there is a variant that does not have a branch set,
-            // change the current of otherwise as the variant branch and set otherwise to unreachable.
-            // It transforms following code
+            // If and only if there is a variant that does not have a branch set, change the
+            // current of otherwise as the variant branch and set otherwise to unreachable. It
+            // transforms following code
             // ```rust
             // match c {
             //     Ordering::Less => 1,
diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs
index c60cbae2142..f3dafd13824 100644
--- a/compiler/rustc_mir_transform/src/unreachable_prop.rs
+++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs
@@ -26,7 +26,8 @@ impl crate::MirPass<'_> for UnreachablePropagation {
             let terminator = bb_data.terminator();
             let is_unreachable = match &terminator.kind {
                 TerminatorKind::Unreachable => true,
-                // This will unconditionally run into an unreachable and is therefore unreachable as well.
+                // This will unconditionally run into an unreachable and is therefore unreachable
+                // as well.
                 TerminatorKind::Goto { target } if unreachable_blocks.contains(target) => {
                     patch.patch_terminator(bb, TerminatorKind::Unreachable);
                     true
@@ -85,8 +86,9 @@ fn remove_successors_from_switch<'tcx>(
     //     }
     // }
     //
-    // This generates a `switchInt() -> [0: 0, 1: 1, otherwise: unreachable]`, which allows us or LLVM to
-    // turn it into just `x` later. Without the unreachable, such a transformation would be illegal.
+    // This generates a `switchInt() -> [0: 0, 1: 1, otherwise: unreachable]`, which allows us or
+    // LLVM to turn it into just `x` later. Without the unreachable, such a transformation would be
+    // illegal.
     //
     // In order to preserve this information, we record reachable and unreachable targets as
     // `Assume` statements in MIR.
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index 18865c73f75..3b84755dded 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -388,10 +388,11 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
                     }
                     self.check_unwind_edge(location, unwind);
 
-                    // The code generation assumes that there are no critical call edges. The assumption
-                    // is used to simplify inserting code that should be executed along the return edge
-                    // from the call. FIXME(tmiasko): Since this is a strictly code generation concern,
-                    // the code generation should be responsible for handling it.
+                    // The code generation assumes that there are no critical call edges. The
+                    // assumption is used to simplify inserting code that should be executed along
+                    // the return edge from the call. FIXME(tmiasko): Since this is a strictly code
+                    // generation concern, the code generation should be responsible for handling
+                    // it.
                     if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Optimized)
                         && self.is_critical_call_edge(target, unwind)
                     {
@@ -404,8 +405,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
                         );
                     }
 
-                    // The call destination place and Operand::Move place used as an argument might be
-                    // passed by a reference to the callee. Consequently they cannot be packed.
+                    // The call destination place and Operand::Move place used as an argument might
+                    // be passed by a reference to the callee. Consequently they cannot be packed.
                     if is_within_packed(self.tcx, &self.body.local_decls, destination).is_some() {
                         // This is bad! The callee will expect the memory to be aligned.
                         self.fail(
@@ -953,9 +954,9 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 }
                 AggregateKind::RawPtr(pointee_ty, mutability) => {
                     if !matches!(self.mir_phase, MirPhase::Runtime(_)) {
-                        // It would probably be fine to support this in earlier phases,
-                        // but at the time of writing it's only ever introduced from intrinsic lowering,
-                        // so earlier things just `bug!` on it.
+                        // It would probably be fine to support this in earlier phases, but at the
+                        // time of writing it's only ever introduced from intrinsic lowering, so
+                        // earlier things just `bug!` on it.
                         self.fail(location, "RawPtr should be in runtime MIR only");
                     }
 
@@ -1109,10 +1110,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     }
                     UnOp::PtrMetadata => {
                         if !matches!(self.mir_phase, MirPhase::Runtime(_)) {
-                            // It would probably be fine to support this in earlier phases,
-                            // but at the time of writing it's only ever introduced from intrinsic lowering
-                            // or other runtime-phase optimization passes,
-                            // so earlier things can just `bug!` on it.
+                            // It would probably be fine to support this in earlier phases, but at
+                            // the time of writing it's only ever introduced from intrinsic
+                            // lowering or other runtime-phase optimization passes, so earlier
+                            // things can just `bug!` on it.
                             self.fail(location, "PtrMetadata should be in runtime MIR only");
                         }
 
@@ -1506,7 +1507,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 }
 
                 if let TerminatorKind::TailCall { .. } = terminator.kind {
-                    // FIXME(explicit_tail_calls): implement tail-call specific checks here (such as signature matching, forbidding closures, etc)
+                    // FIXME(explicit_tail_calls): implement tail-call specific checks here (such
+                    // as signature matching, forbidding closures, etc)
                 }
             }
             TerminatorKind::Assert { cond, .. } => {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 7572d57309c..d5240a05310 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1236,6 +1236,7 @@ symbols! {
         mir_unwind_unreachable,
         mir_variant,
         miri,
+        missing_docs,
         mmx_reg,
         modifiers,
         module,
@@ -1255,6 +1256,7 @@ symbols! {
         mut_preserve_binding_mode_2024,
         mut_ref,
         naked,
+        naked_asm,
         naked_functions,
         name,
         names,
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
index 0372105a02b..38d06f53fa6 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/region.rs
@@ -852,18 +852,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
         impl<'hir, 'tcx> hir::intravisit::Visitor<'hir> for LifetimeReplaceVisitor<'tcx, '_> {
             fn visit_lifetime(&mut self, lt: &'hir hir::Lifetime) {
                 if lt.res == self.needle {
-                    let (pos, span) = lt.suggestion_position();
-                    let new_lt = &self.new_lt;
-                    let sugg = match pos {
-                        hir::LifetimeSuggestionPosition::Normal => format!("{new_lt}"),
-                        hir::LifetimeSuggestionPosition::Ampersand => format!("{new_lt} "),
-                        hir::LifetimeSuggestionPosition::ElidedPath => format!("<{new_lt}>"),
-                        hir::LifetimeSuggestionPosition::ElidedPathArgument => {
-                            format!("{new_lt}, ")
-                        }
-                        hir::LifetimeSuggestionPosition::ObjectDefault => format!("+ {new_lt}"),
-                    };
-                    self.add_lt_suggs.push((span, sugg));
+                    self.add_lt_suggs.push(lt.suggestion(self.new_lt));
                 }
             }
 
diff --git a/compiler/rustc_type_ir/src/elaborate.rs b/compiler/rustc_type_ir/src/elaborate.rs
index 433c444e701..f30419c801f 100644
--- a/compiler/rustc_type_ir/src/elaborate.rs
+++ b/compiler/rustc_type_ir/src/elaborate.rs
@@ -237,7 +237,7 @@ pub fn supertrait_def_ids<I: Interner>(
     cx: I,
     trait_def_id: I::DefId,
 ) -> impl Iterator<Item = I::DefId> {
-    let mut set: HashSet<I::DefId> = HashSet::default();
+    let mut set = HashSet::default();
     let mut stack = vec![trait_def_id];
 
     set.insert(trait_def_id);
diff --git a/compiler/rustc_type_ir/src/interner.rs b/compiler/rustc_type_ir/src/interner.rs
index f2492ede4f5..8dec2133a45 100644
--- a/compiler/rustc_type_ir/src/interner.rs
+++ b/compiler/rustc_type_ir/src/interner.rs
@@ -137,6 +137,8 @@ pub trait Interner:
         f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R,
     ) -> R;
 
+    fn evaluation_is_concurrent(&self) -> bool;
+
     fn expand_abstract_consts<T: TypeFoldable<Self>>(self, t: T) -> T;
 
     type GenericsOf: GenericsOf<Self>;
@@ -404,4 +406,7 @@ impl<I: Interner> search_graph::Cx for I {
     ) -> R {
         I::with_global_cache(self, mode, f)
     }
+    fn evaluation_is_concurrent(&self) -> bool {
+        self.evaluation_is_concurrent()
+    }
 }
diff --git a/compiler/rustc_type_ir/src/search_graph/global_cache.rs b/compiler/rustc_type_ir/src/search_graph/global_cache.rs
index 47f7cefac6a..0ce927b58bb 100644
--- a/compiler/rustc_type_ir/src/search_graph/global_cache.rs
+++ b/compiler/rustc_type_ir/src/search_graph/global_cache.rs
@@ -44,22 +44,28 @@ impl<X: Cx> GlobalCache<X> {
         cx: X,
         input: X::Input,
 
-        result: X::Result,
+        origin_result: X::Result,
         dep_node: X::DepNodeIndex,
 
         additional_depth: usize,
         encountered_overflow: bool,
         nested_goals: NestedGoals<X>,
     ) {
-        let result = cx.mk_tracked(result, dep_node);
+        let result = cx.mk_tracked(origin_result, dep_node);
         let entry = self.map.entry(input).or_default();
         if encountered_overflow {
             let with_overflow = WithOverflow { nested_goals, result };
             let prev = entry.with_overflow.insert(additional_depth, with_overflow);
-            assert!(prev.is_none());
+            if let Some(prev) = &prev {
+                assert!(cx.evaluation_is_concurrent());
+                assert_eq!(cx.get_tracked(&prev.result), origin_result);
+            }
         } else {
             let prev = entry.success.replace(Success { additional_depth, nested_goals, result });
-            assert!(prev.is_none());
+            if let Some(prev) = &prev {
+                assert!(cx.evaluation_is_concurrent());
+                assert_eq!(cx.get_tracked(&prev.result), origin_result);
+            }
         }
     }
 
diff --git a/compiler/rustc_type_ir/src/search_graph/mod.rs b/compiler/rustc_type_ir/src/search_graph/mod.rs
index 418139c3aad..ac4d0795a92 100644
--- a/compiler/rustc_type_ir/src/search_graph/mod.rs
+++ b/compiler/rustc_type_ir/src/search_graph/mod.rs
@@ -53,6 +53,8 @@ pub trait Cx: Copy {
         mode: SolverMode,
         f: impl FnOnce(&mut GlobalCache<Self>) -> R,
     ) -> R;
+
+    fn evaluation_is_concurrent(&self) -> bool;
 }
 
 pub trait Delegate {
diff --git a/config.example.toml b/config.example.toml
index 17fe9be7d56..2b5e9ae117d 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -42,6 +42,9 @@
 # Unless you're developing for a target where Rust CI doesn't build a compiler
 # toolchain or changing LLVM locally, you probably want to leave this enabled.
 #
+# Set this to `true` to download if CI llvm available otherwise it builds
+# from `src/llvm-project`.
+#
 # Set this to `"if-unchanged"` to download only if the llvm-project has not
 # been modified. You can also use this if you are unsure whether you're on a
 # tier 1 target. All tier 1 targets are currently supported.
@@ -236,7 +239,7 @@
 # Instead of downloading the src/stage0 version of cargo-clippy specified,
 # use this cargo-clippy binary instead as the stage0 snapshot cargo-clippy.
 #
-# Note that this option should be used with the same toolchain as the `rustc` option above. 
+# Note that this option should be used with the same toolchain as the `rustc` option above.
 # Otherwise, clippy is likely to fail due to a toolchain conflict.
 #cargo-clippy = "/path/to/cargo-clippy"
 
diff --git a/library/alloc/benches/slice.rs b/library/alloc/benches/slice.rs
index b62be9d39a1..ab46603d773 100644
--- a/library/alloc/benches/slice.rs
+++ b/library/alloc/benches/slice.rs
@@ -336,10 +336,10 @@ reverse!(reverse_u32, u32, |x| x as u32);
 reverse!(reverse_u64, u64, |x| x as u64);
 reverse!(reverse_u128, u128, |x| x as u128);
 #[repr(simd)]
-struct F64x4(f64, f64, f64, f64);
+struct F64x4([f64; 4]);
 reverse!(reverse_simd_f64x4, F64x4, |x| {
     let x = x as f64;
-    F64x4(x, x, x, x)
+    F64x4([x, x, x, x])
 });
 
 macro_rules! rotate {
diff --git a/library/alloc/src/slice.rs b/library/alloc/src/slice.rs
index 9d704870326..8cdba166c9d 100644
--- a/library/alloc/src/slice.rs
+++ b/library/alloc/src/slice.rs
@@ -96,6 +96,7 @@ pub(crate) mod hack {
     // We shouldn't add inline attribute to this since this is used in
     // `vec!` macro mostly and causes perf regression. See #71204 for
     // discussion and perf results.
+    #[allow(missing_docs)]
     pub fn into_vec<T, A: Allocator>(b: Box<[T], A>) -> Vec<T, A> {
         unsafe {
             let len = b.len();
@@ -105,6 +106,7 @@ pub(crate) mod hack {
     }
 
     #[cfg(not(no_global_oom_handling))]
+    #[allow(missing_docs)]
     #[inline]
     pub fn to_vec<T: ConvertVec, A: Allocator>(s: &[T], alloc: A) -> Vec<T, A> {
         T::to_vec(s, alloc)
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index bc8b7e24bf1..05617669ed2 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -508,6 +508,7 @@ impl String {
     // NB see the slice::hack module in slice.rs for more information
     #[inline]
     #[cfg(test)]
+    #[allow(missing_docs)]
     pub fn from_str(_: &str) -> String {
         panic!("not available with cfg(test)");
     }
diff --git a/library/core/src/arch.rs b/library/core/src/arch.rs
index 31d6bc36fc8..be734d194be 100644
--- a/library/core/src/arch.rs
+++ b/library/core/src/arch.rs
@@ -17,6 +17,20 @@ pub macro asm("assembly template", $(operands,)* $(options($(option),*))?) {
     /* compiler built-in */
 }
 
+/// Inline assembly used in combination with `#[naked]` functions.
+///
+/// Refer to [Rust By Example] for a usage guide and the [reference] for
+/// detailed information about the syntax and available options.
+///
+/// [Rust By Example]: https://doc.rust-lang.org/nightly/rust-by-example/unsafe/asm.html
+/// [reference]: https://doc.rust-lang.org/nightly/reference/inline-assembly.html
+#[unstable(feature = "naked_functions", issue = "90957")]
+#[rustc_builtin_macro]
+#[cfg(not(bootstrap))]
+pub macro naked_asm("assembly template", $(operands,)* $(options($(option),*))?) {
+    /* compiler built-in */
+}
+
 /// Module-level inline assembly.
 ///
 /// Refer to [Rust By Example] for a usage guide and the [reference] for
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index 4be2e5ef1ea..0154caa7c24 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -351,6 +351,9 @@ impl<T> MaybeUninit<T> {
     /// but `MaybeUninit<&'static i32>::zeroed()` is not because references must not
     /// be null.
     ///
+    /// Note that if `T` has padding bytes, those bytes are *not* preserved when the
+    /// `MaybeUninit<T>` value is returned from this function, so those bytes will *not* be zeroed.
+    ///
     /// Note that dropping a `MaybeUninit<T>` will never call `T`'s drop code.
     /// It is your responsibility to make sure `T` gets dropped if it got initialized.
     ///
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index febb3fed963..3b45d46b31d 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -270,7 +270,7 @@ impl<T: ?Sized> *const T {
     /// }
     /// ```
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
     #[inline]
     pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> {
         // SAFETY: the caller must guarantee that `self` is valid
@@ -302,7 +302,7 @@ impl<T: ?Sized> *const T {
     /// ```
     // FIXME: mention it in the docs for `as_ref` and `as_uninit_ref` once stabilized.
     #[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
     #[inline]
     #[must_use]
     pub const unsafe fn as_ref_unchecked<'a>(self) -> &'a T {
@@ -336,7 +336,7 @@ impl<T: ?Sized> *const T {
     /// ```
     #[inline]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub const unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit<T>>
     where
         T: Sized,
@@ -1664,7 +1664,7 @@ impl<T> *const [T] {
     /// [allocated object]: crate::ptr#allocated-object
     #[inline]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> {
         if self.is_null() {
             None
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index bebc4b2f271..ddb9195d2e7 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -261,7 +261,7 @@ impl<T: ?Sized> *mut T {
     /// }
     /// ```
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
     #[inline]
     pub const unsafe fn as_ref<'a>(self) -> Option<&'a T> {
         // SAFETY: the caller must guarantee that `self` is valid for a
@@ -295,7 +295,7 @@ impl<T: ?Sized> *mut T {
     /// ```
     // FIXME: mention it in the docs for `as_ref` and `as_uninit_ref` once stabilized.
     #[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
     #[inline]
     #[must_use]
     pub const unsafe fn as_ref_unchecked<'a>(self) -> &'a T {
@@ -334,7 +334,7 @@ impl<T: ?Sized> *mut T {
     /// ```
     #[inline]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub const unsafe fn as_uninit_ref<'a>(self) -> Option<&'a MaybeUninit<T>>
     where
         T: Sized,
@@ -580,7 +580,7 @@ impl<T: ?Sized> *mut T {
     /// println!("{s:?}"); // It'll print: "[4, 2, 3]".
     /// ```
     #[stable(feature = "ptr_as_ref", since = "1.9.0")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "const_ptr_is_null", issue = "74939")]
     #[inline]
     pub const unsafe fn as_mut<'a>(self) -> Option<&'a mut T> {
         // SAFETY: the caller must guarantee that `self` is be valid for
@@ -616,7 +616,7 @@ impl<T: ?Sized> *mut T {
     /// ```
     // FIXME: mention it in the docs for `as_mut` and `as_uninit_mut` once stabilized.
     #[unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "ptr_as_ref_unchecked", issue = "122034")]
     #[inline]
     #[must_use]
     pub const unsafe fn as_mut_unchecked<'a>(self) -> &'a mut T {
@@ -639,7 +639,7 @@ impl<T: ?Sized> *mut T {
     /// the pointer is [convertible to a reference](crate::ptr#pointer-to-reference-conversion).
     #[inline]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub const unsafe fn as_uninit_mut<'a>(self) -> Option<&'a mut MaybeUninit<T>>
     where
         T: Sized,
@@ -2016,7 +2016,7 @@ impl<T> *mut [T] {
     /// [allocated object]: crate::ptr#allocated-object
     #[inline]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub const unsafe fn as_uninit_slice<'a>(self) -> Option<&'a [MaybeUninit<T>]> {
         if self.is_null() {
             None
@@ -2068,7 +2068,7 @@ impl<T> *mut [T] {
     /// [allocated object]: crate::ptr#allocated-object
     #[inline]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub const unsafe fn as_uninit_slice_mut<'a>(self) -> Option<&'a mut [MaybeUninit<T>]> {
         if self.is_null() {
             None
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index b1429fff744..673acc2972f 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -133,7 +133,7 @@ impl<T: Sized> NonNull<T> {
     #[inline]
     #[must_use]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub const unsafe fn as_uninit_ref<'a>(self) -> &'a MaybeUninit<T> {
         // SAFETY: the caller must guarantee that `self` meets all the
         // requirements for a reference.
@@ -157,7 +157,7 @@ impl<T: Sized> NonNull<T> {
     #[inline]
     #[must_use]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub const unsafe fn as_uninit_mut<'a>(self) -> &'a mut MaybeUninit<T> {
         // SAFETY: the caller must guarantee that `self` meets all the
         // requirements for a reference.
@@ -1563,7 +1563,7 @@ impl<T> NonNull<[T]> {
     #[inline]
     #[must_use]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub const unsafe fn as_uninit_slice<'a>(self) -> &'a [MaybeUninit<T>] {
         // SAFETY: the caller must uphold the safety contract for `as_uninit_slice`.
         unsafe { slice::from_raw_parts(self.cast().as_ptr(), self.len()) }
@@ -1628,7 +1628,7 @@ impl<T> NonNull<[T]> {
     #[inline]
     #[must_use]
     #[unstable(feature = "ptr_as_uninit", issue = "75402")]
-    #[rustc_const_unstable(feature = "const_ptr_as_ref", issue = "91822")]
+    #[rustc_const_unstable(feature = "ptr_as_uninit", issue = "75402")]
     pub const unsafe fn as_uninit_slice_mut<'a>(self) -> &'a mut [MaybeUninit<T>] {
         // SAFETY: the caller must uphold the safety contract for `as_uninit_slice_mut`.
         unsafe { slice::from_raw_parts_mut(self.cast().as_ptr(), self.len()) }
diff --git a/library/std/src/io/buffered/bufreader.rs b/library/std/src/io/buffered/bufreader.rs
index cf226bd28d0..035afbb8368 100644
--- a/library/std/src/io/buffered/bufreader.rs
+++ b/library/std/src/io/buffered/bufreader.rs
@@ -267,6 +267,7 @@ impl<R: ?Sized> BufReader<R> {
 // This is only used by a test which asserts that the initialization-tracking is correct.
 #[cfg(test)]
 impl<R: ?Sized> BufReader<R> {
+    #[allow(missing_docs)]
     pub fn initialized(&self) -> usize {
         self.buf.initialized()
     }
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index e8ae1d99fbf..6ecd9469c17 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -223,10 +223,10 @@ pub enum ErrorKind {
     #[stable(feature = "rust1", since = "1.0.0")]
     ConnectionReset,
     /// The remote host is not reachable.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     HostUnreachable,
     /// The network containing the remote host is not reachable.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     NetworkUnreachable,
     /// The connection was aborted (terminated) by the remote server.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -243,7 +243,7 @@ pub enum ErrorKind {
     #[stable(feature = "rust1", since = "1.0.0")]
     AddrNotAvailable,
     /// The system's networking is down.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     NetworkDown,
     /// The operation failed because a pipe was closed.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -259,18 +259,18 @@ pub enum ErrorKind {
     ///
     /// For example, a filesystem path was specified where one of the intermediate directory
     /// components was, in fact, a plain file.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     NotADirectory,
     /// The filesystem object is, unexpectedly, a directory.
     ///
     /// A directory was specified when a non-directory was expected.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     IsADirectory,
     /// A non-empty directory was specified where an empty directory was expected.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     DirectoryNotEmpty,
     /// The filesystem or storage medium is read-only, but a write operation was attempted.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     ReadOnlyFilesystem,
     /// Loop in the filesystem or IO subsystem; often, too many levels of symbolic links.
     ///
@@ -285,7 +285,7 @@ pub enum ErrorKind {
     ///
     /// With some network filesystems, notably NFS, an open file (or directory) can be invalidated
     /// by problems with the network or server.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     StaleNetworkFileHandle,
     /// A parameter was incorrect.
     #[stable(feature = "rust1", since = "1.0.0")]
@@ -319,13 +319,13 @@ pub enum ErrorKind {
     /// The underlying storage (typically, a filesystem) is full.
     ///
     /// This does not include out of quota errors.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     StorageFull,
     /// Seek on unseekable file.
     ///
     /// Seeking was attempted on an open file handle which is not suitable for seeking - for
     /// example, on Unix, a named pipe opened with `File::open`.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     NotSeekable,
     /// Filesystem quota was exceeded.
     #[unstable(feature = "io_error_more", issue = "86442")]
@@ -335,22 +335,22 @@ pub enum ErrorKind {
     /// This might arise from a hard limit of the underlying filesystem or file access API, or from
     /// an administratively imposed resource limitation.  Simple disk full, and out of quota, have
     /// their own errors.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     FileTooLarge,
     /// Resource is busy.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     ResourceBusy,
     /// Executable file is busy.
     ///
     /// An attempt was made to write to a file which is also in use as a running program.  (Not all
     /// operating systems detect this situation.)
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     ExecutableFileBusy,
     /// Deadlock (avoided).
     ///
     /// A file locking operation would result in deadlock.  This situation is typically detected, if
     /// at all, on a best-effort basis.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     Deadlock,
     /// Cross-device or cross-filesystem (hard) link or rename.
     #[unstable(feature = "io_error_more", issue = "86442")]
@@ -358,7 +358,7 @@ pub enum ErrorKind {
     /// Too many (hard) links to the same filesystem object.
     ///
     /// The filesystem does not support making so many hardlinks to the same file.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     TooManyLinks,
     /// A filename was invalid.
     ///
@@ -369,7 +369,7 @@ pub enum ErrorKind {
     ///
     /// When trying to run an external program, a system or process limit on the size of the
     /// arguments would have been exceeded.
-    #[unstable(feature = "io_error_more", issue = "86442")]
+    #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")]
     ArgumentListTooLong,
     /// This operation was interrupted.
     ///
diff --git a/library/std/src/sys/pal/unix/stack_overflow.rs b/library/std/src/sys/pal/unix/stack_overflow.rs
index 9ff44b54c41..728ce8d60f6 100644
--- a/library/std/src/sys/pal/unix/stack_overflow.rs
+++ b/library/std/src/sys/pal/unix/stack_overflow.rs
@@ -32,7 +32,8 @@ impl Drop for Handler {
     target_os = "macos",
     target_os = "netbsd",
     target_os = "openbsd",
-    target_os = "solaris"
+    target_os = "solaris",
+    target_os = "illumos",
 ))]
 mod imp {
     #[cfg(not(all(target_os = "linux", target_env = "gnu")))]
@@ -280,7 +281,7 @@ mod imp {
         libc::SIGSTKSZ
     }
 
-    #[cfg(target_os = "solaris")]
+    #[cfg(any(target_os = "solaris", target_os = "illumos"))]
     unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
         let mut current_stack: libc::stack_t = crate::mem::zeroed();
         assert_eq!(libc::stack_getbounds(&mut current_stack), 0);
@@ -486,7 +487,12 @@ mod imp {
         Some(guardaddr..guardaddr + page_size)
     }
 
-    #[cfg(any(target_os = "macos", target_os = "openbsd", target_os = "solaris"))]
+    #[cfg(any(
+        target_os = "macos",
+        target_os = "openbsd",
+        target_os = "solaris",
+        target_os = "illumos",
+    ))]
     // FIXME: I am probably not unsafe.
     unsafe fn current_guard() -> Option<Range<usize>> {
         let stackptr = get_stack_start()?;
@@ -569,7 +575,8 @@ mod imp {
     target_os = "macos",
     target_os = "netbsd",
     target_os = "openbsd",
-    target_os = "solaris"
+    target_os = "solaris",
+    target_os = "illumos",
 )))]
 mod imp {
     pub unsafe fn init() {}
diff --git a/src/bootstrap/defaults/config.compiler.toml b/src/bootstrap/defaults/config.compiler.toml
index 789586b58f7..147939d2047 100644
--- a/src/bootstrap/defaults/config.compiler.toml
+++ b/src/bootstrap/defaults/config.compiler.toml
@@ -27,4 +27,5 @@ assertions = false
 # Enable warnings during the LLVM compilation (when LLVM is changed, causing a compilation)
 enable-warnings = true
 # Will download LLVM from CI if available on your platform.
-download-ci-llvm = "if-unchanged"
+# If you intend to modify `src/llvm-project`, use `"if-unchanged"` or `false` instead.
+download-ci-llvm = true
diff --git a/src/bootstrap/download-ci-llvm-stamp b/src/bootstrap/download-ci-llvm-stamp
index 90901530501..42cecbf5df9 100644
--- a/src/bootstrap/download-ci-llvm-stamp
+++ b/src/bootstrap/download-ci-llvm-stamp
@@ -1,4 +1,4 @@
 Change this file to make users of the `download-ci-llvm` configuration download
 a new version of LLVM from CI, even if the LLVM submodule hasn’t changed.
 
-Last change is for: https://github.com/rust-lang/rust/pull/129116
+Last change is for: https://github.com/rust-lang/rust/pull/129788
diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in
index 9acd85cddde..3fa2b3c2292 100644
--- a/src/bootstrap/mk/Makefile.in
+++ b/src/bootstrap/mk/Makefile.in
@@ -54,30 +54,34 @@ check-aux:
 		src/etc/test-float-parse \
 		$(BOOTSTRAP_ARGS)
 	# Run standard library tests in Miri.
-	$(Q)BOOTSTRAP_SKIP_TARGET_SANITY=1 \
-		$(BOOTSTRAP) miri --stage 2 \
+	$(Q)$(BOOTSTRAP) miri --stage 2 \
 		library/core \
 		library/alloc \
+		$(BOOTSTRAP_ARGS) \
 		--no-doc
 	# Some doctests use file system operations to demonstrate dealing with `Result`.
 	$(Q)MIRIFLAGS="-Zmiri-disable-isolation" \
 		$(BOOTSTRAP) miri --stage 2 \
 		library/core \
 		library/alloc \
+		$(BOOTSTRAP_ARGS) \
 		--doc
 	# In `std` we cannot test everything, so we skip some modules.
 	$(Q)MIRIFLAGS="-Zmiri-disable-isolation" \
 		$(BOOTSTRAP) miri --stage 2 library/std \
+		$(BOOTSTRAP_ARGS) \
 		--no-doc -- \
 		--skip fs:: --skip net:: --skip process:: --skip sys::pal::
 	$(Q)MIRIFLAGS="-Zmiri-disable-isolation" \
 		$(BOOTSTRAP) miri --stage 2 library/std \
+		$(BOOTSTRAP_ARGS) \
 		--doc -- \
 		--skip fs:: --skip net:: --skip process:: --skip sys::pal::
 	# Also test some very target-specific modules on other targets
 	# (making sure to cover an i686 target as well).
 	$(Q)MIRIFLAGS="-Zmiri-disable-isolation" BOOTSTRAP_SKIP_TARGET_SANITY=1 \
 		$(BOOTSTRAP) miri --stage 2 library/std \
+		$(BOOTSTRAP_ARGS) \
 		--target aarch64-apple-darwin,i686-pc-windows-msvc \
 		--no-doc -- \
 		time:: sync:: thread:: env::
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index de861c42c4c..f509712730d 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -2766,7 +2766,8 @@ impl Config {
                     );
                 }
 
-                b
+                // 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)) => {
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 80ab09881fe..99bcc6e0787 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -250,4 +250,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "New option `llvm.enzyme` to control whether the llvm based autodiff tool (Enzyme) is built.",
     },
+    ChangeInfo {
+        change_id: 129473,
+        severity: ChangeSeverity::Warning,
+        summary: "`download-ci-llvm = true` now checks if CI llvm is available and has become the default for the compiler profile",
+    },
 ];
diff --git a/src/librustdoc/config.rs b/src/librustdoc/config.rs
index 9e7b69ec45f..b3c87a72508 100644
--- a/src/librustdoc/config.rs
+++ b/src/librustdoc/config.rs
@@ -53,12 +53,18 @@ impl TryFrom<&str> for OutputFormat {
     }
 }
 
+/// Either an input crate, markdown file, or nothing (--merge=finalize).
+pub(crate) enum InputMode {
+    /// The `--merge=finalize` step does not need an input crate to rustdoc.
+    NoInputMergeFinalize,
+    /// A crate or markdown file.
+    HasFile(Input),
+}
+
 /// Configuration options for rustdoc.
 #[derive(Clone)]
 pub(crate) struct Options {
     // Basic options / Options passed directly to rustc
-    /// The crate root or Markdown file to load.
-    pub(crate) input: Input,
     /// The name of the crate being documented.
     pub(crate) crate_name: Option<String>,
     /// Whether or not this is a bin crate
@@ -179,7 +185,6 @@ impl fmt::Debug for Options {
         }
 
         f.debug_struct("Options")
-            .field("input", &self.input.source_name())
             .field("crate_name", &self.crate_name)
             .field("bin_crate", &self.bin_crate)
             .field("proc_macro_crate", &self.proc_macro_crate)
@@ -289,6 +294,12 @@ pub(crate) struct RenderOptions {
     /// This field is only used for the JSON output. If it's set to true, no file will be created
     /// and content will be displayed in stdout directly.
     pub(crate) output_to_stdout: bool,
+    /// Whether we should read or write rendered cross-crate info in the doc root.
+    pub(crate) should_merge: ShouldMerge,
+    /// Path to crate-info for external crates.
+    pub(crate) include_parts_dir: Vec<PathToParts>,
+    /// Where to write crate-info
+    pub(crate) parts_out_dir: Option<PathToParts>,
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -348,7 +359,7 @@ impl Options {
         early_dcx: &mut EarlyDiagCtxt,
         matches: &getopts::Matches,
         args: Vec<String>,
-    ) -> Option<(Options, RenderOptions)> {
+    ) -> Option<(InputMode, Options, RenderOptions)> {
         // Check for unstable options.
         nightly_options::check_nightly_options(early_dcx, matches, &opts());
 
@@ -478,15 +489,17 @@ impl Options {
         let (lint_opts, describe_lints, lint_cap) = get_cmd_lint_options(early_dcx, matches);
 
         let input = if describe_lints {
-            "" // dummy, this won't be used
+            InputMode::HasFile(make_input(early_dcx, ""))
         } else {
             match matches.free.as_slice() {
+                [] if matches.opt_str("merge").as_deref() == Some("finalize") => {
+                    InputMode::NoInputMergeFinalize
+                }
                 [] => dcx.fatal("missing file operand"),
-                [input] => input,
+                [input] => InputMode::HasFile(make_input(early_dcx, input)),
                 _ => dcx.fatal("too many file operands"),
             }
         };
-        let input = make_input(early_dcx, input);
 
         let externs = parse_externs(early_dcx, matches, &unstable_opts);
         let extern_html_root_urls = match parse_extern_html_roots(matches) {
@@ -494,6 +507,16 @@ impl Options {
             Err(err) => dcx.fatal(err),
         };
 
+        let parts_out_dir =
+            match matches.opt_str("parts-out-dir").map(|p| PathToParts::from_flag(p)).transpose() {
+                Ok(parts_out_dir) => parts_out_dir,
+                Err(e) => dcx.fatal(e),
+            };
+        let include_parts_dir = match parse_include_parts_dir(matches) {
+            Ok(include_parts_dir) => include_parts_dir,
+            Err(e) => dcx.fatal(e),
+        };
+
         let default_settings: Vec<Vec<(String, String)>> = vec![
             matches
                 .opt_str("default-theme")
@@ -735,6 +758,10 @@ impl Options {
         let extern_html_root_takes_precedence =
             matches.opt_present("extern-html-root-takes-precedence");
         let html_no_source = matches.opt_present("html-no-source");
+        let should_merge = match parse_merge(matches) {
+            Ok(result) => result,
+            Err(e) => dcx.fatal(format!("--merge option error: {e}")),
+        };
 
         if generate_link_to_definition && (show_coverage || output_format != OutputFormat::Html) {
             dcx.struct_warn(
@@ -751,7 +778,6 @@ impl Options {
         let unstable_features =
             rustc_feature::UnstableFeatures::from_environment(crate_name.as_deref());
         let options = Options {
-            input,
             bin_crate,
             proc_macro_crate,
             error_format,
@@ -823,16 +849,17 @@ impl Options {
             no_emit_shared: false,
             html_no_source,
             output_to_stdout,
+            should_merge,
+            include_parts_dir,
+            parts_out_dir,
         };
-        Some((options, render_options))
+        Some((input, options, render_options))
     }
+}
 
-    /// Returns `true` if the file given as `self.input` is a Markdown file.
-    pub(crate) fn markdown_input(&self) -> Option<&Path> {
-        self.input
-            .opt_path()
-            .filter(|p| matches!(p.extension(), Some(e) if e == "md" || e == "markdown"))
-    }
+/// Returns `true` if the file given as `self.input` is a Markdown file.
+pub(crate) fn markdown_input(input: &Input) -> Option<&Path> {
+    input.opt_path().filter(|p| matches!(p.extension(), Some(e) if e == "md" || e == "markdown"))
 }
 
 fn parse_remap_path_prefix(
@@ -900,3 +927,71 @@ fn parse_extern_html_roots(
     }
     Ok(externs)
 }
+
+/// Path directly to crate-info file.
+///
+/// For example, `/home/user/project/target/doc.parts/<crate>/crate-info`.
+#[derive(Clone, Debug)]
+pub(crate) struct PathToParts(pub(crate) PathBuf);
+
+impl PathToParts {
+    fn from_flag(path: String) -> Result<PathToParts, String> {
+        let mut path = PathBuf::from(path);
+        // check here is for diagnostics
+        if path.exists() && !path.is_dir() {
+            Err(format!(
+                "--parts-out-dir and --include-parts-dir expect directories, found: {}",
+                path.display(),
+            ))
+        } else {
+            // if it doesn't exist, we'll create it. worry about that in write_shared
+            path.push("crate-info");
+            Ok(PathToParts(path))
+        }
+    }
+}
+
+/// Reports error if --include-parts-dir / crate-info is not a file
+fn parse_include_parts_dir(m: &getopts::Matches) -> Result<Vec<PathToParts>, String> {
+    let mut ret = Vec::new();
+    for p in m.opt_strs("include-parts-dir") {
+        let p = PathToParts::from_flag(p)?;
+        // this is just for diagnostic
+        if !p.0.is_file() {
+            return Err(format!("--include-parts-dir expected {} to be a file", p.0.display()));
+        }
+        ret.push(p);
+    }
+    Ok(ret)
+}
+
+/// Controls merging of cross-crate information
+#[derive(Debug, Clone)]
+pub(crate) struct ShouldMerge {
+    /// Should we append to existing cci in the doc root
+    pub(crate) read_rendered_cci: bool,
+    /// Should we write cci to the doc root
+    pub(crate) write_rendered_cci: bool,
+}
+
+/// Extracts read_rendered_cci and write_rendered_cci from command line arguments, or
+/// reports an error if an invalid option was provided
+fn parse_merge(m: &getopts::Matches) -> Result<ShouldMerge, &'static str> {
+    match m.opt_str("merge").as_deref() {
+        // default = read-write
+        None => Ok(ShouldMerge { read_rendered_cci: true, write_rendered_cci: true }),
+        Some("none") if m.opt_present("include-parts-dir") => {
+            Err("--include-parts-dir not allowed if --merge=none")
+        }
+        Some("none") => Ok(ShouldMerge { read_rendered_cci: false, write_rendered_cci: false }),
+        Some("shared") if m.opt_present("parts-out-dir") || m.opt_present("include-parts-dir") => {
+            Err("--parts-out-dir and --include-parts-dir not allowed if --merge=shared")
+        }
+        Some("shared") => Ok(ShouldMerge { read_rendered_cci: true, write_rendered_cci: true }),
+        Some("finalize") if m.opt_present("parts-out-dir") => {
+            Err("--parts-out-dir not allowed if --merge=finalize")
+        }
+        Some("finalize") => Ok(ShouldMerge { read_rendered_cci: false, write_rendered_cci: true }),
+        Some(_) => Err("argument to --merge must be `none`, `shared`, or `finalize`"),
+    }
+}
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 2cde0ac5c53..4fafef65792 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -20,7 +20,7 @@ use rustc_interface::interface;
 use rustc_lint::{late_lint_mod, MissingDoc};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
-use rustc_session::config::{self, CrateType, ErrorOutputType, ResolveDocLinks};
+use rustc_session::config::{self, CrateType, ErrorOutputType, Input, ResolveDocLinks};
 pub(crate) use rustc_session::config::{Options, UnstableOptions};
 use rustc_session::{lint, Session};
 use rustc_span::symbol::sym;
@@ -177,8 +177,8 @@ pub(crate) fn new_dcx(
 
 /// Parse, resolve, and typecheck the given crate.
 pub(crate) fn create_config(
+    input: Input,
     RustdocOptions {
-        input,
         crate_name,
         proc_macro_crate,
         error_format,
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 8b6588ea75c..05ef7289201 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -19,7 +19,7 @@ use rustc_errors::{ColorConfig, DiagCtxtHandle, ErrorGuaranteed, FatalError};
 use rustc_hir::def_id::LOCAL_CRATE;
 use rustc_hir::CRATE_HIR_ID;
 use rustc_interface::interface;
-use rustc_session::config::{self, CrateType, ErrorOutputType};
+use rustc_session::config::{self, CrateType, ErrorOutputType, Input};
 use rustc_session::lint;
 use rustc_span::edition::Edition;
 use rustc_span::symbol::sym;
@@ -88,7 +88,11 @@ fn get_doctest_dir() -> io::Result<TempDir> {
     TempFileBuilder::new().prefix("rustdoctest").tempdir()
 }
 
-pub(crate) fn run(dcx: DiagCtxtHandle<'_>, options: RustdocOptions) -> Result<(), ErrorGuaranteed> {
+pub(crate) fn run(
+    dcx: DiagCtxtHandle<'_>,
+    input: Input,
+    options: RustdocOptions,
+) -> Result<(), ErrorGuaranteed> {
     let invalid_codeblock_attributes_name = crate::lint::INVALID_CODEBLOCK_ATTRIBUTES.name;
 
     // See core::create_config for what's going on here.
@@ -135,7 +139,7 @@ pub(crate) fn run(dcx: DiagCtxtHandle<'_>, options: RustdocOptions) -> Result<()
         opts: sessopts,
         crate_cfg: cfgs,
         crate_check_cfg: options.check_cfgs.clone(),
-        input: options.input.clone(),
+        input: input.clone(),
         output_file: None,
         output_dir: None,
         file_loader: None,
diff --git a/src/librustdoc/doctest/markdown.rs b/src/librustdoc/doctest/markdown.rs
index 9a237f8684d..4f83bd5e882 100644
--- a/src/librustdoc/doctest/markdown.rs
+++ b/src/librustdoc/doctest/markdown.rs
@@ -3,6 +3,7 @@
 use std::fs::read_to_string;
 use std::sync::{Arc, Mutex};
 
+use rustc_session::config::Input;
 use rustc_span::FileName;
 use tempfile::tempdir;
 
@@ -69,9 +70,8 @@ impl DocTestVisitor for MdCollector {
 }
 
 /// Runs any tests/code examples in the markdown file `options.input`.
-pub(crate) fn test(options: Options) -> Result<(), String> {
-    use rustc_session::config::Input;
-    let input_str = match &options.input {
+pub(crate) fn test(input: &Input, options: Options) -> Result<(), String> {
+    let input_str = match input {
         Input::File(path) => {
             read_to_string(path).map_err(|err| format!("{}: {err}", path.display()))?
         }
@@ -79,7 +79,7 @@ pub(crate) fn test(options: Options) -> Result<(), String> {
     };
 
     // Obviously not a real crate name, but close enough for purposes of doctests.
-    let crate_name = options.input.filestem().to_string();
+    let crate_name = input.filestem().to_string();
     let temp_dir =
         tempdir().map_err(|error| format!("failed to create temporary directory: {error:?}"))?;
     let args_file = temp_dir.path().join("rustdoc-cfgs");
@@ -96,8 +96,7 @@ pub(crate) fn test(options: Options) -> Result<(), String> {
     let mut md_collector = MdCollector {
         tests: vec![],
         cur_path: vec![],
-        filename: options
-            .input
+        filename: input
             .opt_path()
             .map(ToOwned::to_owned)
             .map(FileName::from)
diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 58a228b74fc..a9b9377c0b9 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -16,12 +16,11 @@ use tracing::info;
 
 use super::print_item::{full_path, item_path, print_item};
 use super::sidebar::{print_sidebar, sidebar_module_like, ModuleLike, Sidebar};
-use super::write_shared::write_shared;
 use super::{collect_spans_and_sources, scrape_examples_help, AllTypes, LinkFromSrc, StylePath};
 use crate::clean::types::ExternalLocation;
 use crate::clean::utils::has_doc_flag;
 use crate::clean::{self, ExternalCrate};
-use crate::config::{ModuleSorting, RenderOptions};
+use crate::config::{ModuleSorting, RenderOptions, ShouldMerge};
 use crate::docfs::{DocFS, PathError};
 use crate::error::Error;
 use crate::formats::cache::Cache;
@@ -30,6 +29,7 @@ use crate::formats::FormatRenderer;
 use crate::html::escape::Escape;
 use crate::html::format::{join_with_double_colon, Buffer};
 use crate::html::markdown::{self, plain_text_summary, ErrorCodes, IdMap};
+use crate::html::render::write_shared::write_shared;
 use crate::html::url_parts_builder::UrlPartsBuilder;
 use crate::html::{layout, sources, static_files};
 use crate::scrape_examples::AllCallLocations;
@@ -128,8 +128,10 @@ pub(crate) struct SharedContext<'tcx> {
     pub(crate) span_correspondence_map: FxHashMap<rustc_span::Span, LinkFromSrc>,
     /// The [`Cache`] used during rendering.
     pub(crate) cache: Cache,
-
     pub(crate) call_locations: AllCallLocations,
+    /// Controls whether we read / write to cci files in the doc root. Defaults read=true,
+    /// write=true
+    should_merge: ShouldMerge,
 }
 
 impl SharedContext<'_> {
@@ -551,6 +553,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
             span_correspondence_map: matches,
             cache,
             call_locations,
+            should_merge: options.should_merge,
         };
 
         let dst = output;
@@ -640,92 +643,96 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
         );
         shared.fs.write(final_file, v)?;
 
-        // Generating settings page.
-        page.title = "Settings";
-        page.description = "Settings of Rustdoc";
-        page.root_path = "./";
-        page.rust_logo = true;
+        // if to avoid writing help, settings files to doc root unless we're on the final invocation
+        if shared.should_merge.write_rendered_cci {
+            // Generating settings page.
+            page.title = "Settings";
+            page.description = "Settings of Rustdoc";
+            page.root_path = "./";
+            page.rust_logo = true;
 
-        let sidebar = "<h2 class=\"location\">Settings</h2><div class=\"sidebar-elems\"></div>";
-        let v = layout::render(
-            &shared.layout,
-            &page,
-            sidebar,
-            |buf: &mut Buffer| {
-                write!(
-                    buf,
-                    "<div class=\"main-heading\">\
-                     <h1>Rustdoc settings</h1>\
-                     <span class=\"out-of-band\">\
-                         <a id=\"back\" href=\"javascript:void(0)\" onclick=\"history.back();\">\
-                            Back\
-                        </a>\
-                     </span>\
-                     </div>\
-                     <noscript>\
-                        <section>\
-                            You need to enable JavaScript be able to update your settings.\
-                        </section>\
-                     </noscript>\
-                     <script defer src=\"{static_root_path}{settings_js}\"></script>",
-                    static_root_path = page.get_static_root_path(),
-                    settings_js = static_files::STATIC_FILES.settings_js,
-                );
-                // Pre-load all theme CSS files, so that switching feels seamless.
-                //
-                // When loading settings.html as a popover, the equivalent HTML is
-                // generated in main.js.
-                for file in &shared.style_files {
-                    if let Ok(theme) = file.basename() {
-                        write!(
-                            buf,
-                            "<link rel=\"preload\" href=\"{root_path}{theme}{suffix}.css\" \
-                                as=\"style\">",
-                            root_path = page.static_root_path.unwrap_or(""),
-                            suffix = page.resource_suffix,
-                        );
+            let sidebar = "<h2 class=\"location\">Settings</h2><div class=\"sidebar-elems\"></div>";
+            let v = layout::render(
+                &shared.layout,
+                &page,
+                sidebar,
+                |buf: &mut Buffer| {
+                    write!(
+                        buf,
+                        "<div class=\"main-heading\">\
+                         <h1>Rustdoc settings</h1>\
+                         <span class=\"out-of-band\">\
+                             <a id=\"back\" href=\"javascript:void(0)\" onclick=\"history.back();\">\
+                                Back\
+                            </a>\
+                         </span>\
+                         </div>\
+                         <noscript>\
+                            <section>\
+                                You need to enable JavaScript be able to update your settings.\
+                            </section>\
+                         </noscript>\
+                         <script defer src=\"{static_root_path}{settings_js}\"></script>",
+                        static_root_path = page.get_static_root_path(),
+                        settings_js = static_files::STATIC_FILES.settings_js,
+                    );
+                    // Pre-load all theme CSS files, so that switching feels seamless.
+                    //
+                    // When loading settings.html as a popover, the equivalent HTML is
+                    // generated in main.js.
+                    for file in &shared.style_files {
+                        if let Ok(theme) = file.basename() {
+                            write!(
+                                buf,
+                                "<link rel=\"preload\" href=\"{root_path}{theme}{suffix}.css\" \
+                                    as=\"style\">",
+                                root_path = page.static_root_path.unwrap_or(""),
+                                suffix = page.resource_suffix,
+                            );
+                        }
                     }
-                }
-            },
-            &shared.style_files,
-        );
-        shared.fs.write(settings_file, v)?;
+                },
+                &shared.style_files,
+            );
+            shared.fs.write(settings_file, v)?;
 
-        // Generating help page.
-        page.title = "Help";
-        page.description = "Documentation for Rustdoc";
-        page.root_path = "./";
-        page.rust_logo = true;
+            // Generating help page.
+            page.title = "Help";
+            page.description = "Documentation for Rustdoc";
+            page.root_path = "./";
+            page.rust_logo = true;
 
-        let sidebar = "<h2 class=\"location\">Help</h2><div class=\"sidebar-elems\"></div>";
-        let v = layout::render(
-            &shared.layout,
-            &page,
-            sidebar,
-            |buf: &mut Buffer| {
-                write!(
-                    buf,
-                    "<div class=\"main-heading\">\
-                     <h1>Rustdoc help</h1>\
-                     <span class=\"out-of-band\">\
-                         <a id=\"back\" href=\"javascript:void(0)\" onclick=\"history.back();\">\
-                            Back\
-                        </a>\
-                     </span>\
-                     </div>\
-                     <noscript>\
-                        <section>\
-                            <p>You need to enable JavaScript to use keyboard commands or search.</p>\
-                            <p>For more information, browse the <a href=\"https://doc.rust-lang.org/rustdoc/\">rustdoc handbook</a>.</p>\
-                        </section>\
-                     </noscript>",
-                )
-            },
-            &shared.style_files,
-        );
-        shared.fs.write(help_file, v)?;
+            let sidebar = "<h2 class=\"location\">Help</h2><div class=\"sidebar-elems\"></div>";
+            let v = layout::render(
+                &shared.layout,
+                &page,
+                sidebar,
+                |buf: &mut Buffer| {
+                    write!(
+                        buf,
+                        "<div class=\"main-heading\">\
+                         <h1>Rustdoc help</h1>\
+                         <span class=\"out-of-band\">\
+                             <a id=\"back\" href=\"javascript:void(0)\" onclick=\"history.back();\">\
+                                Back\
+                            </a>\
+                         </span>\
+                         </div>\
+                         <noscript>\
+                            <section>\
+                                <p>You need to enable JavaScript to use keyboard commands or search.</p>\
+                                <p>For more information, browse the <a href=\"https://doc.rust-lang.org/rustdoc/\">rustdoc handbook</a>.</p>\
+                            </section>\
+                         </noscript>",
+                    )
+                },
+                &shared.style_files,
+            );
+            shared.fs.write(help_file, v)?;
+        }
 
-        if shared.layout.scrape_examples_extension {
+        // if to avoid writing files to doc root unless we're on the final invocation
+        if shared.layout.scrape_examples_extension && shared.should_merge.write_rendered_cci {
             page.title = "About scraped examples";
             page.description = "How the scraped examples feature works in Rustdoc";
             let v = layout::render(
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 3b8eda08372..a402d799504 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -61,6 +61,7 @@ use tracing::{debug, info};
 
 pub(crate) use self::context::*;
 pub(crate) use self::span_map::{collect_spans_and_sources, LinkFromSrc};
+pub(crate) use self::write_shared::*;
 use crate::clean::{self, ItemId, RenderedLink};
 use crate::error::Error;
 use crate::formats::cache::Cache;
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index e8d12320f82..dc1a8cca6bc 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -39,7 +39,7 @@ use serde::{Deserialize, Serialize, Serializer};
 
 use super::{collect_paths_for_type, ensure_trailing_slash, Context, RenderMode};
 use crate::clean::{Crate, Item, ItemId, ItemKind};
-use crate::config::{EmitType, RenderOptions};
+use crate::config::{EmitType, PathToParts, RenderOptions, ShouldMerge};
 use crate::docfs::PathError;
 use crate::error::Error;
 use crate::formats::cache::Cache;
@@ -50,12 +50,11 @@ use crate::html::layout;
 use crate::html::render::ordered_json::{EscapedJson, OrderedJson};
 use crate::html::render::search_index::{build_index, SerializedSearchIndex};
 use crate::html::render::sorted_template::{self, FileFormat, SortedTemplate};
-use crate::html::render::{AssocItemLink, ImplRenderingParameters};
+use crate::html::render::{AssocItemLink, ImplRenderingParameters, StylePath};
 use crate::html::static_files::{self, suffix_path};
 use crate::visit::DocVisitor;
 use crate::{try_err, try_none};
 
-/// Write cross-crate information files, static files, invocation-specific files, etc. to disk
 pub(crate) fn write_shared(
     cx: &mut Context<'_>,
     krate: &Crate,
@@ -70,13 +69,14 @@ pub(crate) fn write_shared(
 
     let SerializedSearchIndex { index, desc } =
         build_index(&krate, &mut Rc::get_mut(&mut cx.shared).unwrap().cache, tcx);
-    write_search_desc(cx, &krate, &desc)?; // does not need to be merged; written unconditionally
+    write_search_desc(cx, &krate, &desc)?; // does not need to be merged
 
     let crate_name = krate.name(cx.tcx());
     let crate_name = crate_name.as_str(); // rand
     let crate_name_json = OrderedJson::serialize(crate_name).unwrap(); // "rand"
     let external_crates = hack_get_external_crate_names(&cx.dst, &cx.shared.resource_suffix)?;
     let info = CrateInfo {
+        version: CrateInfoVersion::V1,
         src_files_js: SourcesPart::get(cx, &crate_name_json)?,
         search_index_js: SearchIndexPart::get(index, &cx.shared.resource_suffix)?,
         all_crates: AllCratesPart::get(crate_name_json.clone(), &cx.shared.resource_suffix)?,
@@ -85,47 +85,103 @@ pub(crate) fn write_shared(
         type_impl: TypeAliasPart::get(cx, krate, &crate_name_json)?,
     };
 
-    let crates = vec![info]; // we have info from just one crate. rest will found in out dir
+    if let Some(parts_out_dir) = &opt.parts_out_dir {
+        create_parents(&parts_out_dir.0)?;
+        try_err!(
+            fs::write(&parts_out_dir.0, serde_json::to_string(&info).unwrap()),
+            &parts_out_dir.0
+        );
+    }
 
-    write_static_files(cx, &opt)?;
-    let dst = &cx.dst;
-    if opt.emit.is_empty() || opt.emit.contains(&EmitType::InvocationSpecific) {
-        if cx.include_sources {
-            write_rendered_cci::<SourcesPart, _>(SourcesPart::blank, dst, &crates)?;
-        }
-        write_rendered_cci::<SearchIndexPart, _>(SearchIndexPart::blank, dst, &crates)?;
-        write_rendered_cci::<AllCratesPart, _>(AllCratesPart::blank, dst, &crates)?;
-    }
-    write_rendered_cci::<TraitAliasPart, _>(TraitAliasPart::blank, dst, &crates)?;
-    write_rendered_cci::<TypeAliasPart, _>(TypeAliasPart::blank, dst, &crates)?;
-    match &opt.index_page {
-        Some(index_page) if opt.enable_index_page => {
-            let mut md_opts = opt.clone();
-            md_opts.output = cx.dst.clone();
-            md_opts.external_html = cx.shared.layout.external_html.clone();
-            try_err!(
-                crate::markdown::render(&index_page, md_opts, cx.shared.edition()),
-                &index_page
-            );
-        }
-        None if opt.enable_index_page => {
-            write_rendered_cci::<CratesIndexPart, _>(|| CratesIndexPart::blank(cx), dst, &crates)?;
+    let mut crates = CrateInfo::read_many(&opt.include_parts_dir)?;
+    crates.push(info);
+
+    if opt.should_merge.write_rendered_cci {
+        write_not_crate_specific(
+            &crates,
+            &cx.dst,
+            opt,
+            &cx.shared.style_files,
+            cx.shared.layout.css_file_extension.as_deref(),
+            &cx.shared.resource_suffix,
+            cx.include_sources,
+        )?;
+        match &opt.index_page {
+            Some(index_page) if opt.enable_index_page => {
+                let mut md_opts = opt.clone();
+                md_opts.output = cx.dst.clone();
+                md_opts.external_html = cx.shared.layout.external_html.clone();
+                try_err!(
+                    crate::markdown::render(&index_page, md_opts, cx.shared.edition()),
+                    &index_page
+                );
+            }
+            None if opt.enable_index_page => {
+                write_rendered_cci::<CratesIndexPart, _>(
+                    || CratesIndexPart::blank(cx),
+                    &cx.dst,
+                    &crates,
+                    &opt.should_merge,
+                )?;
+            }
+            _ => {} // they don't want an index page
         }
-        _ => {} // they don't want an index page
     }
 
     Rc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(false);
     Ok(())
 }
 
-/// Writes the static files, the style files, and the css extensions
-fn write_static_files(cx: &mut Context<'_>, options: &RenderOptions) -> Result<(), Error> {
-    let static_dir = cx.dst.join("static.files");
+/// Writes files that are written directly to the `--out-dir`, without the prefix from the current
+/// crate. These are the rendered cross-crate files that encode info from multiple crates (e.g.
+/// search index), and the static files.
+pub(crate) fn write_not_crate_specific(
+    crates: &[CrateInfo],
+    dst: &Path,
+    opt: &RenderOptions,
+    style_files: &[StylePath],
+    css_file_extension: Option<&Path>,
+    resource_suffix: &str,
+    include_sources: bool,
+) -> Result<(), Error> {
+    write_rendered_cross_crate_info(crates, dst, opt, include_sources)?;
+    write_static_files(dst, opt, style_files, css_file_extension, resource_suffix)?;
+    Ok(())
+}
 
-    cx.shared.fs.create_dir_all(&static_dir).map_err(|e| PathError::new(e, "static.files"))?;
+fn write_rendered_cross_crate_info(
+    crates: &[CrateInfo],
+    dst: &Path,
+    opt: &RenderOptions,
+    include_sources: bool,
+) -> Result<(), Error> {
+    let m = &opt.should_merge;
+    if opt.emit.is_empty() || opt.emit.contains(&EmitType::InvocationSpecific) {
+        if include_sources {
+            write_rendered_cci::<SourcesPart, _>(SourcesPart::blank, dst, &crates, m)?;
+        }
+        write_rendered_cci::<SearchIndexPart, _>(SearchIndexPart::blank, dst, &crates, m)?;
+        write_rendered_cci::<AllCratesPart, _>(AllCratesPart::blank, dst, &crates, m)?;
+    }
+    write_rendered_cci::<TraitAliasPart, _>(TraitAliasPart::blank, dst, &crates, m)?;
+    write_rendered_cci::<TypeAliasPart, _>(TypeAliasPart::blank, dst, &crates, m)?;
+    Ok(())
+}
+
+/// Writes the static files, the style files, and the css extensions.
+/// Have to be careful about these, because they write to the root out dir.
+fn write_static_files(
+    dst: &Path,
+    opt: &RenderOptions,
+    style_files: &[StylePath],
+    css_file_extension: Option<&Path>,
+    resource_suffix: &str,
+) -> Result<(), Error> {
+    let static_dir = dst.join("static.files");
+    try_err!(fs::create_dir_all(&static_dir), &static_dir);
 
     // Handle added third-party themes
-    for entry in &cx.shared.style_files {
+    for entry in style_files {
         let theme = entry.basename()?;
         let extension =
             try_none!(try_none!(entry.path.extension(), &entry.path).to_str(), &entry.path);
@@ -136,22 +192,24 @@ fn write_static_files(cx: &mut Context<'_>, options: &RenderOptions) -> Result<(
         }
 
         let bytes = try_err!(fs::read(&entry.path), &entry.path);
-        let filename = format!("{theme}{suffix}.{extension}", suffix = cx.shared.resource_suffix);
-        cx.shared.fs.write(cx.dst.join(filename), bytes)?;
+        let filename = format!("{theme}{resource_suffix}.{extension}");
+        let dst_filename = dst.join(filename);
+        try_err!(fs::write(&dst_filename, bytes), &dst_filename);
     }
 
     // When the user adds their own CSS files with --extend-css, we write that as an
     // invocation-specific file (that is, with a resource suffix).
-    if let Some(ref css) = cx.shared.layout.css_file_extension {
+    if let Some(css) = css_file_extension {
         let buffer = try_err!(fs::read_to_string(css), css);
-        let path = static_files::suffix_path("theme.css", &cx.shared.resource_suffix);
-        cx.shared.fs.write(cx.dst.join(path), buffer)?;
+        let path = static_files::suffix_path("theme.css", resource_suffix);
+        let dst_path = dst.join(path);
+        try_err!(fs::write(&dst_path, buffer), &dst_path);
     }
 
-    if options.emit.is_empty() || options.emit.contains(&EmitType::Toolchain) {
+    if opt.emit.is_empty() || opt.emit.contains(&EmitType::Toolchain) {
         static_files::for_each(|f: &static_files::StaticFile| {
             let filename = static_dir.join(f.output_filename());
-            cx.shared.fs.write(filename, f.minified())
+            fs::write(&filename, f.minified()).map_err(|e| PathError::new(e, &filename))
         })?;
     }
 
@@ -186,7 +244,8 @@ fn write_search_desc(
 
 /// Contains pre-rendered contents to insert into the CCI template
 #[derive(Serialize, Deserialize, Clone, Debug)]
-struct CrateInfo {
+pub(crate) struct CrateInfo {
+    version: CrateInfoVersion,
     src_files_js: PartsAndLocations<SourcesPart>,
     search_index_js: PartsAndLocations<SearchIndexPart>,
     all_crates: PartsAndLocations<AllCratesPart>,
@@ -195,6 +254,33 @@ struct CrateInfo {
     type_impl: PartsAndLocations<TypeAliasPart>,
 }
 
+impl CrateInfo {
+    /// Read all of the crate info from its location on the filesystem
+    pub(crate) fn read_many(parts_paths: &[PathToParts]) -> Result<Vec<Self>, Error> {
+        parts_paths
+            .iter()
+            .map(|parts_path| {
+                let path = &parts_path.0;
+                let parts = try_err!(fs::read(&path), &path);
+                let parts: CrateInfo = try_err!(serde_json::from_slice(&parts), &path);
+                Ok::<_, Error>(parts)
+            })
+            .collect::<Result<Vec<CrateInfo>, Error>>()
+    }
+}
+
+/// Version for the format of the crate-info file.
+///
+/// This enum should only ever have one variant, representing the current version.
+/// Gives pretty good error message about expecting the current version on deserialize.
+///
+/// Must be incremented (V2, V3, etc.) upon any changes to the search index or CrateInfo,
+/// to provide better diagnostics about including an invalid file.
+#[derive(Serialize, Deserialize, Clone, Debug)]
+enum CrateInfoVersion {
+    V1,
+}
+
 /// Paths (relative to the doc root) and their pre-merge contents
 #[derive(Serialize, Deserialize, Debug, Clone)]
 #[serde(transparent)]
@@ -900,10 +986,14 @@ fn create_parents(path: &Path) -> Result<(), Error> {
 fn read_template_or_blank<F, T: FileFormat>(
     mut make_blank: F,
     path: &Path,
+    should_merge: &ShouldMerge,
 ) -> Result<SortedTemplate<T>, Error>
 where
     F: FnMut() -> SortedTemplate<T>,
 {
+    if !should_merge.read_rendered_cci {
+        return Ok(make_blank());
+    }
     match fs::read_to_string(&path) {
         Ok(template) => Ok(try_err!(SortedTemplate::from_str(&template), &path)),
         Err(e) if e.kind() == io::ErrorKind::NotFound => Ok(make_blank()),
@@ -916,6 +1006,7 @@ fn write_rendered_cci<T: CciPart, F>(
     mut make_blank: F,
     dst: &Path,
     crates_info: &[CrateInfo],
+    should_merge: &ShouldMerge,
 ) -> Result<(), Error>
 where
     F: FnMut() -> SortedTemplate<T::FileFormat>,
@@ -924,7 +1015,8 @@ where
     for (path, parts) in get_path_parts::<T>(dst, crates_info) {
         create_parents(&path)?;
         // read previous rendered cci from storage, append to them
-        let mut template = read_template_or_blank::<_, T::FileFormat>(&mut make_blank, &path)?;
+        let mut template =
+            read_template_or_blank::<_, T::FileFormat>(&mut make_blank, &path, should_merge)?;
         for part in parts {
             template.append(part);
         }
diff --git a/src/librustdoc/html/render/write_shared/tests.rs b/src/librustdoc/html/render/write_shared/tests.rs
index e282cd99e43..a235f1d3724 100644
--- a/src/librustdoc/html/render/write_shared/tests.rs
+++ b/src/librustdoc/html/render/write_shared/tests.rs
@@ -1,3 +1,4 @@
+use crate::config::ShouldMerge;
 use crate::html::render::ordered_json::{EscapedJson, OrderedJson};
 use crate::html::render::sorted_template::{Html, SortedTemplate};
 use crate::html::render::write_shared::*;
@@ -192,16 +193,17 @@ fn read_template_test() {
     let path = path.path().join("file.html");
     let make_blank = || SortedTemplate::<Html>::from_before_after("<div>", "</div>");
 
-    let template = read_template_or_blank(make_blank, &path).unwrap();
+    let should_merge = ShouldMerge { read_rendered_cci: true, write_rendered_cci: true };
+    let template = read_template_or_blank(make_blank, &path, &should_merge).unwrap();
     assert_eq!(but_last_line(&template.to_string()), "<div></div>");
     fs::write(&path, template.to_string()).unwrap();
-    let mut template = read_template_or_blank(make_blank, &path).unwrap();
+    let mut template = read_template_or_blank(make_blank, &path, &should_merge).unwrap();
     template.append("<img/>".to_string());
     fs::write(&path, template.to_string()).unwrap();
-    let mut template = read_template_or_blank(make_blank, &path).unwrap();
+    let mut template = read_template_or_blank(make_blank, &path, &should_merge).unwrap();
     template.append("<br/>".to_string());
     fs::write(&path, template.to_string()).unwrap();
-    let template = read_template_or_blank(make_blank, &path).unwrap();
+    let template = read_template_or_blank(make_blank, &path, &should_merge).unwrap();
 
     assert_eq!(but_last_line(&template.to_string()), "<div><br/><img/></div>");
 }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index f25acbe080a..6649e1721a4 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -603,6 +603,33 @@ fn opts() -> Vec<RustcOptGroup> {
                 "path to function call information (for displaying examples in the documentation)",
             )
         }),
+        unstable("merge", |o| {
+            o.optopt(
+                "",
+                "merge",
+                "Controls how rustdoc handles files from previously documented crates in the doc root
+                      none = Do not write cross-crate information to the --out-dir
+                      shared = Append current crate's info to files found in the --out-dir
+                      finalize = Write current crate's info and --include-parts-dir info to the --out-dir, overwriting conflicting files",
+                "none|shared|finalize",
+            )
+        }),
+        unstable("parts-out-dir", |o| {
+            o.optopt(
+                "",
+                "parts-out-dir",
+                "Writes trait implementations and other info for the current crate to provided path. Only use with --merge=none",
+                "path/to/doc.parts/<crate-name>",
+            )
+        }),
+        unstable("include-parts-dir", |o| {
+            o.optmulti(
+                "",
+                "include-parts-dir",
+                "Includes trait implementations and other crate info from provided path. Only use with --merge=finalize",
+                "path/to/doc.parts/<crate-name>",
+            )
+        }),
         // deprecated / removed options
         unstable("disable-minification", |o| o.optflagmulti("", "disable-minification", "removed")),
         stable("plugin-path", |o| {
@@ -697,6 +724,32 @@ fn run_renderer<'tcx, T: formats::FormatRenderer<'tcx>>(
     }
 }
 
+/// Renders and writes cross-crate info files, like the search index. This function exists so that
+/// we can run rustdoc without a crate root in the `--merge=finalize` mode. Cross-crate info files
+/// discovered via `--include-parts-dir` are combined and written to the doc root.
+fn run_merge_finalize(opt: config::RenderOptions) -> Result<(), error::Error> {
+    assert!(
+        opt.should_merge.write_rendered_cci,
+        "config.rs only allows us to return InputMode::NoInputMergeFinalize if --merge=finalize"
+    );
+    assert!(
+        !opt.should_merge.read_rendered_cci,
+        "config.rs only allows us to return InputMode::NoInputMergeFinalize if --merge=finalize"
+    );
+    let crates = html::render::CrateInfo::read_many(&opt.include_parts_dir)?;
+    let include_sources = !opt.html_no_source;
+    html::render::write_not_crate_specific(
+        &crates,
+        &opt.output,
+        &opt,
+        &opt.themes,
+        opt.extension_css.as_deref(),
+        &opt.resource_suffix,
+        include_sources,
+    )?;
+    Ok(())
+}
+
 fn main_args(
     early_dcx: &mut EarlyDiagCtxt,
     at_args: &[String],
@@ -727,22 +780,35 @@ fn main_args(
 
     // Note that we discard any distinction between different non-zero exit
     // codes from `from_matches` here.
-    let (options, render_options) = match config::Options::from_matches(early_dcx, &matches, args) {
-        Some(opts) => opts,
-        None => return Ok(()),
-    };
+    let (input, options, render_options) =
+        match config::Options::from_matches(early_dcx, &matches, args) {
+            Some(opts) => opts,
+            None => return Ok(()),
+        };
 
     let dcx =
         core::new_dcx(options.error_format, None, options.diagnostic_width, &options.unstable_opts);
     let dcx = dcx.handle();
 
-    match (options.should_test, options.markdown_input()) {
-        (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(options)),
-        (true, None) => return doctest::run(dcx, options),
-        (false, Some(input)) => {
-            let input = input.to_owned();
+    let input = match input {
+        config::InputMode::HasFile(input) => input,
+        config::InputMode::NoInputMergeFinalize => {
+            return wrap_return(
+                dcx,
+                run_merge_finalize(render_options)
+                    .map_err(|e| format!("could not write merged cross-crate info: {e}")),
+            );
+        }
+    };
+
+    match (options.should_test, config::markdown_input(&input)) {
+        (true, Some(_)) => return wrap_return(dcx, doctest::test_markdown(&input, options)),
+        (true, None) => return doctest::run(dcx, input, options),
+        (false, Some(md_input)) => {
+            let md_input = md_input.to_owned();
             let edition = options.edition;
-            let config = core::create_config(options, &render_options, using_internal_features);
+            let config =
+                core::create_config(input, options, &render_options, using_internal_features);
 
             // `markdown::render` can invoke `doctest::make_test`, which
             // requires session globals and a thread pool, so we use
@@ -750,7 +816,7 @@ fn main_args(
             return wrap_return(
                 dcx,
                 interface::run_compiler(config, |_compiler| {
-                    markdown::render(&input, render_options, edition)
+                    markdown::render(&md_input, render_options, edition)
                 }),
             );
         }
@@ -775,7 +841,7 @@ fn main_args(
     let scrape_examples_options = options.scrape_examples_options.clone();
     let bin_crate = options.bin_crate;
 
-    let config = core::create_config(options, &render_options, using_internal_features);
+    let config = core::create_config(input, options, &render_options, using_internal_features);
 
     interface::run_compiler(config, |compiler| {
         let sess = &compiler.sess;
diff --git a/src/librustdoc/passes/lint.rs b/src/librustdoc/passes/lint.rs
index bc804a340bf..4da5d8f0e06 100644
--- a/src/librustdoc/passes/lint.rs
+++ b/src/librustdoc/passes/lint.rs
@@ -27,12 +27,33 @@ pub(crate) fn run_lints(krate: Crate, cx: &mut DocContext<'_>) -> Crate {
 
 impl<'a, 'tcx> DocVisitor for Linter<'a, 'tcx> {
     fn visit_item(&mut self, item: &Item) {
-        bare_urls::visit_item(self.cx, item);
-        check_code_block_syntax::visit_item(self.cx, item);
-        html_tags::visit_item(self.cx, item);
-        unescaped_backticks::visit_item(self.cx, item);
-        redundant_explicit_links::visit_item(self.cx, item);
-        unportable_markdown::visit_item(self.cx, item);
+        let Some(hir_id) = DocContext::as_local_hir_id(self.cx.tcx, item.item_id) else {
+            // If non-local, no need to check anything.
+            return;
+        };
+        let dox = item.doc_value();
+        if !dox.is_empty() {
+            let may_have_link = dox.contains(&[':', '['][..]);
+            let may_have_block_comment_or_html = dox.contains(&['<', '>']);
+            // ~~~rust
+            // // This is a real, supported commonmark syntax for block code
+            // ~~~
+            let may_have_code = dox.contains(&['~', '`', '\t'][..]) || dox.contains("    ");
+            if may_have_link {
+                bare_urls::visit_item(self.cx, item, hir_id, &dox);
+                redundant_explicit_links::visit_item(self.cx, item, hir_id);
+            }
+            if may_have_code {
+                check_code_block_syntax::visit_item(self.cx, item, &dox);
+                unescaped_backticks::visit_item(self.cx, item, hir_id, &dox);
+            }
+            if may_have_block_comment_or_html {
+                html_tags::visit_item(self.cx, item, hir_id, &dox);
+                unportable_markdown::visit_item(self.cx, item, hir_id, &dox);
+            } else if may_have_link {
+                unportable_markdown::visit_item(self.cx, item, hir_id, &dox);
+            }
+        }
 
         self.visit_item_recur(item)
     }
diff --git a/src/librustdoc/passes/lint/bare_urls.rs b/src/librustdoc/passes/lint/bare_urls.rs
index 22051dd954d..bac0e07f1c1 100644
--- a/src/librustdoc/passes/lint/bare_urls.rs
+++ b/src/librustdoc/passes/lint/bare_urls.rs
@@ -8,6 +8,7 @@ use std::sync::LazyLock;
 use pulldown_cmark::{Event, Parser, Tag};
 use regex::Regex;
 use rustc_errors::Applicability;
+use rustc_hir::HirId;
 use rustc_resolve::rustdoc::source_span_for_markdown_range;
 use tracing::trace;
 
@@ -15,50 +16,43 @@ use crate::clean::*;
 use crate::core::DocContext;
 use crate::html::markdown::main_body_opts;
 
-pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item) {
-    let Some(hir_id) = DocContext::as_local_hir_id(cx.tcx, item.item_id) else {
-        // If non-local, no need to check anything.
-        return;
+pub(super) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &str) {
+    let report_diag = |cx: &DocContext<'_>, msg: &'static str, range: Range<usize>| {
+        let sp = source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs.doc_strings)
+            .unwrap_or_else(|| item.attr_span(cx.tcx));
+        cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, |lint| {
+            lint.primary_message(msg)
+                .note("bare URLs are not automatically turned into clickable links")
+                .multipart_suggestion(
+                    "use an automatic link instead",
+                    vec![
+                        (sp.shrink_to_lo(), "<".to_string()),
+                        (sp.shrink_to_hi(), ">".to_string()),
+                    ],
+                    Applicability::MachineApplicable,
+                );
+        });
     };
-    let dox = item.doc_value();
-    if !dox.is_empty() {
-        let report_diag = |cx: &DocContext<'_>, msg: &'static str, range: Range<usize>| {
-            let sp = source_span_for_markdown_range(cx.tcx, &dox, &range, &item.attrs.doc_strings)
-                .unwrap_or_else(|| item.attr_span(cx.tcx));
-            cx.tcx.node_span_lint(crate::lint::BARE_URLS, hir_id, sp, |lint| {
-                lint.primary_message(msg)
-                    .note("bare URLs are not automatically turned into clickable links")
-                    .multipart_suggestion(
-                        "use an automatic link instead",
-                        vec![
-                            (sp.shrink_to_lo(), "<".to_string()),
-                            (sp.shrink_to_hi(), ">".to_string()),
-                        ],
-                        Applicability::MachineApplicable,
-                    );
-            });
-        };
 
-        let mut p = Parser::new_ext(&dox, main_body_opts()).into_offset_iter();
+    let mut p = Parser::new_ext(&dox, main_body_opts()).into_offset_iter();
 
-        while let Some((event, range)) = p.next() {
-            match event {
-                Event::Text(s) => find_raw_urls(cx, &s, range, &report_diag),
-                // We don't want to check the text inside code blocks or links.
-                Event::Start(tag @ (Tag::CodeBlock(_) | Tag::Link { .. })) => {
-                    while let Some((event, _)) = p.next() {
-                        match event {
-                            Event::End(end)
-                                if mem::discriminant(&end) == mem::discriminant(&tag.to_end()) =>
-                            {
-                                break;
-                            }
-                            _ => {}
+    while let Some((event, range)) = p.next() {
+        match event {
+            Event::Text(s) => find_raw_urls(cx, &s, range, &report_diag),
+            // We don't want to check the text inside code blocks or links.
+            Event::Start(tag @ (Tag::CodeBlock(_) | Tag::Link { .. })) => {
+                while let Some((event, _)) = p.next() {
+                    match event {
+                        Event::End(end)
+                            if mem::discriminant(&end) == mem::discriminant(&tag.to_end()) =>
+                        {
+                            break;
                         }
+                        _ => {}
                     }
                 }
-                _ => {}
             }
+            _ => {}
         }
     }
 }
diff --git a/src/librustdoc/passes/lint/check_code_block_syntax.rs b/src/librustdoc/passes/lint/check_code_block_syntax.rs
index 977c0953336..1b2431a629b 100644
--- a/src/librustdoc/passes/lint/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/lint/check_code_block_syntax.rs
@@ -15,10 +15,8 @@ use crate::clean;
 use crate::core::DocContext;
 use crate::html::markdown::{self, RustCodeBlock};
 
-pub(crate) fn visit_item(cx: &DocContext<'_>, item: &clean::Item) {
-    if let Some(def_id) = item.item_id.as_local_def_id()
-        && let Some(dox) = &item.opt_doc_value()
-    {
+pub(crate) fn visit_item(cx: &DocContext<'_>, item: &clean::Item, dox: &str) {
+    if let Some(def_id) = item.item_id.as_local_def_id() {
         let sp = item.attr_span(cx.tcx);
         let extra = crate::html::markdown::ExtraInfo::new(cx.tcx, def_id, sp);
         for code_block in markdown::rust_code_blocks(dox, &extra) {
diff --git a/src/librustdoc/passes/lint/html_tags.rs b/src/librustdoc/passes/lint/html_tags.rs
index 6f9e9d36a5c..223174838ad 100644
--- a/src/librustdoc/passes/lint/html_tags.rs
+++ b/src/librustdoc/passes/lint/html_tags.rs
@@ -5,159 +5,149 @@ use std::ops::Range;
 use std::str::CharIndices;
 
 use pulldown_cmark::{BrokenLink, Event, LinkType, Parser, Tag, TagEnd};
+use rustc_hir::HirId;
 use rustc_resolve::rustdoc::source_span_for_markdown_range;
 
 use crate::clean::*;
 use crate::core::DocContext;
 use crate::html::markdown::main_body_opts;
 
-pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
+pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &str) {
     let tcx = cx.tcx;
-    let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id)
-    // If non-local, no need to check anything.
-    else {
-        return;
-    };
-    let dox = item.doc_value();
-    if !dox.is_empty() {
-        let report_diag = |msg: String, range: &Range<usize>, is_open_tag: bool| {
-            let sp = match source_span_for_markdown_range(tcx, &dox, range, &item.attrs.doc_strings)
-            {
-                Some(sp) => sp,
-                None => item.attr_span(tcx),
-            };
-            tcx.node_span_lint(crate::lint::INVALID_HTML_TAGS, hir_id, sp, |lint| {
-                use rustc_lint_defs::Applicability;
+    let report_diag = |msg: String, range: &Range<usize>, is_open_tag: bool| {
+        let sp = match source_span_for_markdown_range(tcx, &dox, range, &item.attrs.doc_strings) {
+            Some(sp) => sp,
+            None => item.attr_span(tcx),
+        };
+        tcx.node_span_lint(crate::lint::INVALID_HTML_TAGS, hir_id, sp, |lint| {
+            use rustc_lint_defs::Applicability;
 
-                lint.primary_message(msg);
+            lint.primary_message(msg);
 
-                // If a tag looks like `<this>`, it might actually be a generic.
-                // We don't try to detect stuff `<like, this>` because that's not valid HTML,
-                // and we don't try to detect stuff `<like this>` because that's not valid Rust.
-                let mut generics_end = range.end;
-                if let Some(Some(mut generics_start)) = (is_open_tag
-                    && dox[..generics_end].ends_with('>'))
-                .then(|| extract_path_backwards(&dox, range.start))
+            // If a tag looks like `<this>`, it might actually be a generic.
+            // We don't try to detect stuff `<like, this>` because that's not valid HTML,
+            // and we don't try to detect stuff `<like this>` because that's not valid Rust.
+            let mut generics_end = range.end;
+            if let Some(Some(mut generics_start)) = (is_open_tag
+                && dox[..generics_end].ends_with('>'))
+            .then(|| extract_path_backwards(&dox, range.start))
+            {
+                while generics_start != 0
+                    && generics_end < dox.len()
+                    && dox.as_bytes()[generics_start - 1] == b'<'
+                    && dox.as_bytes()[generics_end] == b'>'
                 {
-                    while generics_start != 0
-                        && generics_end < dox.len()
-                        && dox.as_bytes()[generics_start - 1] == b'<'
-                        && dox.as_bytes()[generics_end] == b'>'
-                    {
-                        generics_end += 1;
-                        generics_start -= 1;
-                        if let Some(new_start) = extract_path_backwards(&dox, generics_start) {
-                            generics_start = new_start;
-                        }
-                        if let Some(new_end) = extract_path_forward(&dox, generics_end) {
-                            generics_end = new_end;
-                        }
+                    generics_end += 1;
+                    generics_start -= 1;
+                    if let Some(new_start) = extract_path_backwards(&dox, generics_start) {
+                        generics_start = new_start;
                     }
                     if let Some(new_end) = extract_path_forward(&dox, generics_end) {
                         generics_end = new_end;
                     }
-                    let generics_sp = match source_span_for_markdown_range(
-                        tcx,
-                        &dox,
-                        &(generics_start..generics_end),
-                        &item.attrs.doc_strings,
-                    ) {
-                        Some(sp) => sp,
-                        None => item.attr_span(tcx),
-                    };
-                    // Sometimes, we only extract part of a path. For example, consider this:
-                    //
-                    //     <[u32] as IntoIter<u32>>::Item
-                    //                       ^^^^^ unclosed HTML tag `u32`
-                    //
-                    // We don't have any code for parsing fully-qualified trait paths.
-                    // In theory, we could add it, but doing it correctly would require
-                    // parsing the entire path grammar, which is problematic because of
-                    // overlap between the path grammar and Markdown.
-                    //
-                    // The example above shows that ambiguity. Is `[u32]` intended to be an
-                    // intra-doc link to the u32 primitive, or is it intended to be a slice?
-                    //
-                    // If the below conditional were removed, we would suggest this, which is
-                    // not what the user probably wants.
-                    //
-                    //     <[u32] as `IntoIter<u32>`>::Item
-                    //
-                    // We know that the user actually wants to wrap the whole thing in a code
-                    // block, but the only reason we know that is because `u32` does not, in
-                    // fact, implement IntoIter. If the example looks like this:
-                    //
-                    //     <[Vec<i32>] as IntoIter<i32>::Item
-                    //
-                    // The ideal fix would be significantly different.
-                    if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<')
-                        || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>')
-                    {
-                        return;
-                    }
-                    // multipart form is chosen here because ``Vec<i32>`` would be confusing.
-                    lint.multipart_suggestion(
-                        "try marking as source code",
-                        vec![
-                            (generics_sp.shrink_to_lo(), String::from("`")),
-                            (generics_sp.shrink_to_hi(), String::from("`")),
-                        ],
-                        Applicability::MaybeIncorrect,
-                    );
                 }
-            });
-        };
+                if let Some(new_end) = extract_path_forward(&dox, generics_end) {
+                    generics_end = new_end;
+                }
+                let generics_sp = match source_span_for_markdown_range(
+                    tcx,
+                    &dox,
+                    &(generics_start..generics_end),
+                    &item.attrs.doc_strings,
+                ) {
+                    Some(sp) => sp,
+                    None => item.attr_span(tcx),
+                };
+                // Sometimes, we only extract part of a path. For example, consider this:
+                //
+                //     <[u32] as IntoIter<u32>>::Item
+                //                       ^^^^^ unclosed HTML tag `u32`
+                //
+                // We don't have any code for parsing fully-qualified trait paths.
+                // In theory, we could add it, but doing it correctly would require
+                // parsing the entire path grammar, which is problematic because of
+                // overlap between the path grammar and Markdown.
+                //
+                // The example above shows that ambiguity. Is `[u32]` intended to be an
+                // intra-doc link to the u32 primitive, or is it intended to be a slice?
+                //
+                // If the below conditional were removed, we would suggest this, which is
+                // not what the user probably wants.
+                //
+                //     <[u32] as `IntoIter<u32>`>::Item
+                //
+                // We know that the user actually wants to wrap the whole thing in a code
+                // block, but the only reason we know that is because `u32` does not, in
+                // fact, implement IntoIter. If the example looks like this:
+                //
+                //     <[Vec<i32>] as IntoIter<i32>::Item
+                //
+                // The ideal fix would be significantly different.
+                if (generics_start > 0 && dox.as_bytes()[generics_start - 1] == b'<')
+                    || (generics_end < dox.len() && dox.as_bytes()[generics_end] == b'>')
+                {
+                    return;
+                }
+                // multipart form is chosen here because ``Vec<i32>`` would be confusing.
+                lint.multipart_suggestion(
+                    "try marking as source code",
+                    vec![
+                        (generics_sp.shrink_to_lo(), String::from("`")),
+                        (generics_sp.shrink_to_hi(), String::from("`")),
+                    ],
+                    Applicability::MaybeIncorrect,
+                );
+            }
+        });
+    };
 
-        let mut tags = Vec::new();
-        let mut is_in_comment = None;
-        let mut in_code_block = false;
+    let mut tags = Vec::new();
+    let mut is_in_comment = None;
+    let mut in_code_block = false;
 
-        let link_names = item.link_names(&cx.cache);
+    let link_names = item.link_names(&cx.cache);
 
-        let mut replacer = |broken_link: BrokenLink<'_>| {
-            if let Some(link) =
-                link_names.iter().find(|link| *link.original_text == *broken_link.reference)
-            {
-                Some((link.href.as_str().into(), link.new_text.to_string().into()))
-            } else if matches!(
-                &broken_link.link_type,
-                LinkType::Reference | LinkType::ReferenceUnknown
-            ) {
-                // If the link is shaped [like][this], suppress any broken HTML in the [this] part.
-                // The `broken_intra_doc_links` will report typos in there anyway.
-                Some((
-                    broken_link.reference.to_string().into(),
-                    broken_link.reference.to_string().into(),
-                ))
-            } else {
-                None
-            }
-        };
+    let mut replacer = |broken_link: BrokenLink<'_>| {
+        if let Some(link) =
+            link_names.iter().find(|link| *link.original_text == *broken_link.reference)
+        {
+            Some((link.href.as_str().into(), link.new_text.to_string().into()))
+        } else if matches!(&broken_link.link_type, LinkType::Reference | LinkType::ReferenceUnknown)
+        {
+            // If the link is shaped [like][this], suppress any broken HTML in the [this] part.
+            // The `broken_intra_doc_links` will report typos in there anyway.
+            Some((
+                broken_link.reference.to_string().into(),
+                broken_link.reference.to_string().into(),
+            ))
+        } else {
+            None
+        }
+    };
 
-        let p = Parser::new_with_broken_link_callback(&dox, main_body_opts(), Some(&mut replacer))
-            .into_offset_iter();
+    let p = Parser::new_with_broken_link_callback(&dox, main_body_opts(), Some(&mut replacer))
+        .into_offset_iter();
 
-        for (event, range) in p {
-            match event {
-                Event::Start(Tag::CodeBlock(_)) => in_code_block = true,
-                Event::Html(text) | Event::InlineHtml(text) if !in_code_block => {
-                    extract_tags(&mut tags, &text, range, &mut is_in_comment, &report_diag)
-                }
-                Event::End(TagEnd::CodeBlock) => in_code_block = false,
-                _ => {}
+    for (event, range) in p {
+        match event {
+            Event::Start(Tag::CodeBlock(_)) => in_code_block = true,
+            Event::Html(text) | Event::InlineHtml(text) if !in_code_block => {
+                extract_tags(&mut tags, &text, range, &mut is_in_comment, &report_diag)
             }
+            Event::End(TagEnd::CodeBlock) => in_code_block = false,
+            _ => {}
         }
+    }
 
-        for (tag, range) in tags.iter().filter(|(t, _)| {
-            let t = t.to_lowercase();
-            !ALLOWED_UNCLOSED.contains(&t.as_str())
-        }) {
-            report_diag(format!("unclosed HTML tag `{tag}`"), range, true);
-        }
+    for (tag, range) in tags.iter().filter(|(t, _)| {
+        let t = t.to_lowercase();
+        !ALLOWED_UNCLOSED.contains(&t.as_str())
+    }) {
+        report_diag(format!("unclosed HTML tag `{tag}`"), range, true);
+    }
 
-        if let Some(range) = is_in_comment {
-            report_diag("Unclosed HTML comment".to_string(), &range, false);
-        }
+    if let Some(range) = is_in_comment {
+        report_diag("Unclosed HTML comment".to_string(), &range, false);
     }
 }
 
diff --git a/src/librustdoc/passes/lint/redundant_explicit_links.rs b/src/librustdoc/passes/lint/redundant_explicit_links.rs
index 0a90c039dfb..9c37e11349a 100644
--- a/src/librustdoc/passes/lint/redundant_explicit_links.rs
+++ b/src/librustdoc/passes/lint/redundant_explicit_links.rs
@@ -24,12 +24,7 @@ struct LinkData {
     display_link: String,
 }
 
-pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
-    let Some(hir_id) = DocContext::as_local_hir_id(cx.tcx, item.item_id) else {
-        // If non-local, no need to check anything.
-        return;
-    };
-
+pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId) {
     let hunks = prepare_to_doc_link_resolution(&item.attrs.doc_strings);
     for (item_id, doc) in hunks {
         if let Some(item_id) = item_id.or(item.def_id())
diff --git a/src/librustdoc/passes/lint/unescaped_backticks.rs b/src/librustdoc/passes/lint/unescaped_backticks.rs
index a6c8db16f82..d79f682a580 100644
--- a/src/librustdoc/passes/lint/unescaped_backticks.rs
+++ b/src/librustdoc/passes/lint/unescaped_backticks.rs
@@ -4,6 +4,7 @@ use std::ops::Range;
 
 use pulldown_cmark::{BrokenLink, Event, Parser};
 use rustc_errors::Diag;
+use rustc_hir::HirId;
 use rustc_lint_defs::Applicability;
 use rustc_resolve::rustdoc::source_span_for_markdown_range;
 
@@ -11,17 +12,8 @@ use crate::clean::Item;
 use crate::core::DocContext;
 use crate::html::markdown::main_body_opts;
 
-pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
+pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &str) {
     let tcx = cx.tcx;
-    let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id) else {
-        // If non-local, no need to check anything.
-        return;
-    };
-
-    let dox = item.doc_value();
-    if dox.is_empty() {
-        return;
-    }
 
     let link_names = item.link_names(&cx.cache);
     let mut replacer = |broken_link: BrokenLink<'_>| {
diff --git a/src/librustdoc/passes/lint/unportable_markdown.rs b/src/librustdoc/passes/lint/unportable_markdown.rs
index 87fe0055883..f8368a866c8 100644
--- a/src/librustdoc/passes/lint/unportable_markdown.rs
+++ b/src/librustdoc/passes/lint/unportable_markdown.rs
@@ -12,6 +12,7 @@
 
 use std::collections::{BTreeMap, BTreeSet};
 
+use rustc_hir::HirId;
 use rustc_lint_defs::Applicability;
 use rustc_resolve::rustdoc::source_span_for_markdown_range;
 use {pulldown_cmark as cmarkn, pulldown_cmark_old as cmarko};
@@ -19,17 +20,8 @@ use {pulldown_cmark as cmarkn, pulldown_cmark_old as cmarko};
 use crate::clean::Item;
 use crate::core::DocContext;
 
-pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item) {
+pub(crate) fn visit_item(cx: &DocContext<'_>, item: &Item, hir_id: HirId, dox: &str) {
     let tcx = cx.tcx;
-    let Some(hir_id) = DocContext::as_local_hir_id(tcx, item.item_id) else {
-        // If non-local, no need to check anything.
-        return;
-    };
-
-    let dox = item.doc_value();
-    if dox.is_empty() {
-        return;
-    }
 
     // P1: unintended strikethrough was fixed by requiring single-tildes to flank
     // the same way underscores do, so nothing is done here
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-div-by-zero.rs b/src/tools/miri/tests/fail/intrinsics/simd-div-by-zero.rs
index ba474332b81..57a9b66d8ec 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-div-by-zero.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-div-by-zero.rs
@@ -4,12 +4,12 @@ use std::intrinsics::simd::simd_div;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
-struct i32x2(i32, i32);
+struct i32x2([i32; 2]);
 
 fn main() {
     unsafe {
-        let x = i32x2(1, 1);
-        let y = i32x2(1, 0);
+        let x = i32x2([1, 1]);
+        let y = i32x2([1, 0]);
         simd_div(x, y); //~ERROR: Undefined Behavior: dividing by zero
     }
 }
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-div-overflow.rs b/src/tools/miri/tests/fail/intrinsics/simd-div-overflow.rs
index d01e41de0e4..8ffc2669828 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-div-overflow.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-div-overflow.rs
@@ -4,12 +4,12 @@ use std::intrinsics::simd::simd_div;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
-struct i32x2(i32, i32);
+struct i32x2([i32; 2]);
 
 fn main() {
     unsafe {
-        let x = i32x2(1, i32::MIN);
-        let y = i32x2(1, -1);
+        let x = i32x2([1, i32::MIN]);
+        let y = i32x2([1, -1]);
         simd_div(x, y); //~ERROR: Undefined Behavior: overflow in signed division
     }
 }
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-reduce-invalid-bool.rs b/src/tools/miri/tests/fail/intrinsics/simd-reduce-invalid-bool.rs
index a194f0dd18a..ea0f908d996 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-reduce-invalid-bool.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-reduce-invalid-bool.rs
@@ -4,11 +4,11 @@ use std::intrinsics::simd::simd_reduce_any;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
-struct i32x2(i32, i32);
+struct i32x2([i32; 2]);
 
 fn main() {
     unsafe {
-        let x = i32x2(0, 1);
+        let x = i32x2([0, 1]);
         simd_reduce_any(x); //~ERROR: must be all-0-bits or all-1-bits
     }
 }
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-rem-by-zero.rs b/src/tools/miri/tests/fail/intrinsics/simd-rem-by-zero.rs
index cd1e4b8162b..21c9520efc4 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-rem-by-zero.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-rem-by-zero.rs
@@ -4,12 +4,12 @@ use std::intrinsics::simd::simd_rem;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
-struct i32x2(i32, i32);
+struct i32x2([i32; 2]);
 
 fn main() {
     unsafe {
-        let x = i32x2(1, 1);
-        let y = i32x2(1, 0);
+        let x = i32x2([1, 1]);
+        let y = i32x2([1, 0]);
         simd_rem(x, y); //~ERROR: Undefined Behavior: calculating the remainder with a divisor of zero
     }
 }
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-select-bitmask-invalid.rs b/src/tools/miri/tests/fail/intrinsics/simd-select-bitmask-invalid.rs
index 96802fae49c..409098ac3b5 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-select-bitmask-invalid.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-select-bitmask-invalid.rs
@@ -5,11 +5,11 @@ use std::intrinsics::simd::simd_select_bitmask;
 #[repr(simd)]
 #[allow(non_camel_case_types)]
 #[derive(Copy, Clone)]
-struct i32x2(i32, i32);
+struct i32x2([i32; 2]);
 
 fn main() {
     unsafe {
-        let x = i32x2(0, 1);
+        let x = i32x2([0, 1]);
         simd_select_bitmask(0b11111111u8, x, x); //~ERROR: bitmask less than 8 bits long must be filled with 0s for the remaining bits
     }
 }
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-select-invalid-bool.rs b/src/tools/miri/tests/fail/intrinsics/simd-select-invalid-bool.rs
index 388fb2e2a84..a81ce95ada6 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-select-invalid-bool.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-select-invalid-bool.rs
@@ -5,11 +5,11 @@ use std::intrinsics::simd::simd_select;
 #[repr(simd)]
 #[allow(non_camel_case_types)]
 #[derive(Copy, Clone)]
-struct i32x2(i32, i32);
+struct i32x2([i32; 2]);
 
 fn main() {
     unsafe {
-        let x = i32x2(0, 1);
+        let x = i32x2([0, 1]);
         simd_select(x, x, x); //~ERROR: must be all-0-bits or all-1-bits
     }
 }
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-shl-too-far.rs b/src/tools/miri/tests/fail/intrinsics/simd-shl-too-far.rs
index 12aa7c10af4..ed317254ee6 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-shl-too-far.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-shl-too-far.rs
@@ -4,12 +4,12 @@ use std::intrinsics::simd::simd_shl;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
-struct i32x2(i32, i32);
+struct i32x2([i32; 2]);
 
 fn main() {
     unsafe {
-        let x = i32x2(1, 1);
-        let y = i32x2(100, 0);
+        let x = i32x2([1, 1]);
+        let y = i32x2([100, 0]);
         simd_shl(x, y); //~ERROR: overflowing shift by 100 in `simd_shl` in lane 0
     }
 }
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-shr-too-far.rs b/src/tools/miri/tests/fail/intrinsics/simd-shr-too-far.rs
index ada7cf408c4..5d2ff1b82ed 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-shr-too-far.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-shr-too-far.rs
@@ -4,12 +4,12 @@ use std::intrinsics::simd::simd_shr;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
-struct i32x2(i32, i32);
+struct i32x2([i32; 2]);
 
 fn main() {
     unsafe {
-        let x = i32x2(1, 1);
-        let y = i32x2(20, 40);
+        let x = i32x2([1, 1]);
+        let y = i32x2([20, 40]);
         simd_shr(x, y); //~ERROR: overflowing shift by 40 in `simd_shr` in lane 1
     }
 }
diff --git a/src/tools/miri/tests/pass/simd-intrinsic-generic-elements.rs b/src/tools/miri/tests/pass/simd-intrinsic-generic-elements.rs
index 4a87f8c3ca7..9cf0c2ddef3 100644
--- a/src/tools/miri/tests/pass/simd-intrinsic-generic-elements.rs
+++ b/src/tools/miri/tests/pass/simd-intrinsic-generic-elements.rs
@@ -3,22 +3,22 @@
 #[repr(simd)]
 #[derive(Copy, Clone, Debug, PartialEq)]
 #[allow(non_camel_case_types)]
-struct i32x2(i32, i32);
+struct i32x2([i32; 2]);
 #[repr(simd)]
 #[derive(Copy, Clone, Debug, PartialEq)]
 #[allow(non_camel_case_types)]
-struct i32x4(i32, i32, i32, i32);
+struct i32x4([i32; 4]);
 #[repr(simd)]
 #[derive(Copy, Clone, Debug, PartialEq)]
 #[allow(non_camel_case_types)]
-struct i32x8(i32, i32, i32, i32, i32, i32, i32, i32);
+struct i32x8([i32; 8]);
 
 fn main() {
-    let _x2 = i32x2(20, 21);
-    let _x4 = i32x4(40, 41, 42, 43);
-    let _x8 = i32x8(80, 81, 82, 83, 84, 85, 86, 87);
+    let _x2 = i32x2([20, 21]);
+    let _x4 = i32x4([40, 41, 42, 43]);
+    let _x8 = i32x8([80, 81, 82, 83, 84, 85, 86, 87]);
 
-    let _y2 = i32x2(120, 121);
-    let _y4 = i32x4(140, 141, 142, 143);
-    let _y8 = i32x8(180, 181, 182, 183, 184, 185, 186, 187);
+    let _y2 = i32x2([120, 121]);
+    let _y4 = i32x4([140, 141, 142, 143]);
+    let _y8 = i32x8([180, 181, 182, 183, 184, 185, 186, 187]);
 }
diff --git a/src/tools/run-make-support/src/external_deps/cargo.rs b/src/tools/run-make-support/src/external_deps/cargo.rs
new file mode 100644
index 00000000000..b0e045dc80b
--- /dev/null
+++ b/src/tools/run-make-support/src/external_deps/cargo.rs
@@ -0,0 +1,7 @@
+use crate::command::Command;
+use crate::env_var;
+
+/// Returns a command that can be used to invoke Cargo.
+pub fn cargo() -> Command {
+    Command::new(env_var("BOOTSTRAP_CARGO"))
+}
diff --git a/src/tools/run-make-support/src/external_deps/mod.rs b/src/tools/run-make-support/src/external_deps/mod.rs
index f7c84724d0e..80c34a9070f 100644
--- a/src/tools/run-make-support/src/external_deps/mod.rs
+++ b/src/tools/run-make-support/src/external_deps/mod.rs
@@ -2,6 +2,7 @@
 //! such as `cc` or `python`.
 
 pub mod c_build;
+pub mod cargo;
 pub mod cc;
 pub mod clang;
 pub mod htmldocck;
diff --git a/src/tools/run-make-support/src/external_deps/rustc.rs b/src/tools/run-make-support/src/external_deps/rustc.rs
index f60ea972839..35d983dc607 100644
--- a/src/tools/run-make-support/src/external_deps/rustc.rs
+++ b/src/tools/run-make-support/src/external_deps/rustc.rs
@@ -36,10 +36,13 @@ pub struct Rustc {
 
 crate::macros::impl_common_helpers!(Rustc);
 
+pub fn rustc_path() -> String {
+    env_var("RUSTC")
+}
+
 #[track_caller]
 fn setup_common() -> Command {
-    let rustc = env_var("RUSTC");
-    let mut cmd = Command::new(rustc);
+    let mut cmd = Command::new(rustc_path());
     set_host_rpath(&mut cmd);
     cmd
 }
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 980bd37dca8..15d813ccf53 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -50,6 +50,7 @@ pub use external_deps::{c_build, cc, clang, htmldocck, llvm, python, rustc, rust
 // These rely on external dependencies.
 pub use cc::{cc, cxx, extra_c_flags, extra_cxx_flags, Cc};
 pub use c_build::{build_native_dynamic_lib, build_native_static_lib, build_native_static_lib_optimized, build_native_static_lib_cxx};
+pub use cargo::cargo;
 pub use clang::{clang, Clang};
 pub use htmldocck::htmldocck;
 pub use llvm::{
@@ -58,7 +59,7 @@ pub use llvm::{
     LlvmProfdata, LlvmReadobj,
 };
 pub use python::python_command;
-pub use rustc::{aux_build, bare_rustc, rustc, Rustc};
+pub use rustc::{aux_build, bare_rustc, rustc, rustc_path, Rustc};
 pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
 
 /// [`diff`][mod@diff] is implemented in terms of the [similar] library.
@@ -98,3 +99,4 @@ pub use assertion_helpers::{
 pub use string::{
     count_regex_matches_in_files_with_extension, invalid_utf8_contains, invalid_utf8_not_contains,
 };
+use crate::external_deps::cargo;
diff --git a/tests/assembly/asm/aarch64-types.rs b/tests/assembly/asm/aarch64-types.rs
index cf1882ba1a2..1173ba8a4eb 100644
--- a/tests/assembly/asm/aarch64-types.rs
+++ b/tests/assembly/asm/aarch64-types.rs
@@ -31,36 +31,39 @@ trait Sized {}
 #[lang = "copy"]
 trait Copy {}
 
+// Do we really need to use no_core for this?!?
+impl<T: Copy, const N: usize> Copy for [T; N] {}
+
 type ptr = *mut u8;
 
 #[repr(simd)]
-pub struct i8x8(i8, i8, i8, i8, i8, i8, i8, i8);
+pub struct i8x8([i8; 8]);
 #[repr(simd)]
-pub struct i16x4(i16, i16, i16, i16);
+pub struct i16x4([i16; 4]);
 #[repr(simd)]
-pub struct i32x2(i32, i32);
+pub struct i32x2([i32; 2]);
 #[repr(simd)]
-pub struct i64x1(i64);
+pub struct i64x1([i64; 1]);
 #[repr(simd)]
-pub struct f16x4(f16, f16, f16, f16);
+pub struct f16x4([f16; 4]);
 #[repr(simd)]
-pub struct f32x2(f32, f32);
+pub struct f32x2([f32; 2]);
 #[repr(simd)]
-pub struct f64x1(f64);
+pub struct f64x1([f64; 1]);
 #[repr(simd)]
-pub struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8);
+pub struct i8x16([i8; 16]);
 #[repr(simd)]
-pub struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16);
+pub struct i16x8([i16; 8]);
 #[repr(simd)]
-pub struct i32x4(i32, i32, i32, i32);
+pub struct i32x4([i32; 4]);
 #[repr(simd)]
-pub struct i64x2(i64, i64);
+pub struct i64x2([i64; 2]);
 #[repr(simd)]
-pub struct f16x8(f16, f16, f16, f16, f16, f16, f16, f16);
+pub struct f16x8([f16; 8]);
 #[repr(simd)]
-pub struct f32x4(f32, f32, f32, f32);
+pub struct f32x4([f32; 4]);
 #[repr(simd)]
-pub struct f64x2(f64, f64);
+pub struct f64x2([f64; 2]);
 
 impl Copy for i8 {}
 impl Copy for i16 {}
diff --git a/tests/assembly/asm/arm-modifiers.rs b/tests/assembly/asm/arm-modifiers.rs
index d421e0e6954..7d8d7e83870 100644
--- a/tests/assembly/asm/arm-modifiers.rs
+++ b/tests/assembly/asm/arm-modifiers.rs
@@ -28,8 +28,11 @@ trait Sized {}
 #[lang = "copy"]
 trait Copy {}
 
+// Do we really need to use no_core for this?!?
+impl<T: Copy, const N: usize> Copy for [T; N] {}
+
 #[repr(simd)]
-pub struct f32x4(f32, f32, f32, f32);
+pub struct f32x4([f32; 4]);
 
 impl Copy for i32 {}
 impl Copy for f32 {}
diff --git a/tests/assembly/asm/arm-types.rs b/tests/assembly/asm/arm-types.rs
index 448b92aa839..9cebb588aaf 100644
--- a/tests/assembly/asm/arm-types.rs
+++ b/tests/assembly/asm/arm-types.rs
@@ -31,32 +31,35 @@ trait Sized {}
 #[lang = "copy"]
 trait Copy {}
 
+// Do we really need to use no_core for this?!?
+impl<T: Copy, const N: usize> Copy for [T; N] {}
+
 type ptr = *mut u8;
 
 #[repr(simd)]
-pub struct i8x8(i8, i8, i8, i8, i8, i8, i8, i8);
+pub struct i8x8([i8; 8]);
 #[repr(simd)]
-pub struct i16x4(i16, i16, i16, i16);
+pub struct i16x4([i16; 4]);
 #[repr(simd)]
-pub struct i32x2(i32, i32);
+pub struct i32x2([i32; 2]);
 #[repr(simd)]
-pub struct i64x1(i64);
+pub struct i64x1([i64; 1]);
 #[repr(simd)]
-pub struct f16x4(f16, f16, f16, f16);
+pub struct f16x4([f16; 4]);
 #[repr(simd)]
-pub struct f32x2(f32, f32);
+pub struct f32x2([f32; 2]);
 #[repr(simd)]
-pub struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8);
+pub struct i8x16([i8; 16]);
 #[repr(simd)]
-pub struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16);
+pub struct i16x8([i16; 8]);
 #[repr(simd)]
-pub struct i32x4(i32, i32, i32, i32);
+pub struct i32x4([i32; 4]);
 #[repr(simd)]
-pub struct i64x2(i64, i64);
+pub struct i64x2([i64; 2]);
 #[repr(simd)]
-pub struct f16x8(f16, f16, f16, f16, f16, f16, f16, f16);
+pub struct f16x8([f16; 8]);
 #[repr(simd)]
-pub struct f32x4(f32, f32, f32, f32);
+pub struct f32x4([f32; 4]);
 
 impl Copy for i8 {}
 impl Copy for i16 {}
diff --git a/tests/assembly/asm/x86-types.rs b/tests/assembly/asm/x86-types.rs
index a40bc10d991..567dc7a8245 100644
--- a/tests/assembly/asm/x86-types.rs
+++ b/tests/assembly/asm/x86-types.rs
@@ -31,216 +31,55 @@ trait Sized {}
 #[lang = "copy"]
 trait Copy {}
 
+// Do we really need to use no_core for this?!?
+impl<T: Copy, const N: usize> Copy for [T; N] {}
+
 type ptr = *mut u8;
 
 #[repr(simd)]
-pub struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8);
+pub struct i8x16([i8; 16]);
 #[repr(simd)]
-pub struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16);
+pub struct i16x8([i16; 8]);
 #[repr(simd)]
-pub struct i32x4(i32, i32, i32, i32);
+pub struct i32x4([i32; 4]);
 #[repr(simd)]
-pub struct i64x2(i64, i64);
+pub struct i64x2([i64; 2]);
 #[repr(simd)]
-pub struct f16x8(f16, f16, f16, f16, f16, f16, f16, f16);
+pub struct f16x8([f16; 8]);
 #[repr(simd)]
-pub struct f32x4(f32, f32, f32, f32);
+pub struct f32x4([f32; 4]);
 #[repr(simd)]
-pub struct f64x2(f64, f64);
+pub struct f64x2([f64; 2]);
 
 #[repr(simd)]
-pub struct i8x32(
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-);
+pub struct i8x32([i8; 32]);
 #[repr(simd)]
-pub struct i16x16(i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16);
+pub struct i16x16([i16; 16]);
 #[repr(simd)]
-pub struct i32x8(i32, i32, i32, i32, i32, i32, i32, i32);
+pub struct i32x8([i32; 8]);
 #[repr(simd)]
-pub struct i64x4(i64, i64, i64, i64);
+pub struct i64x4([i64; 4]);
 #[repr(simd)]
-pub struct f16x16(f16, f16, f16, f16, f16, f16, f16, f16, f16, f16, f16, f16, f16, f16, f16, f16);
+pub struct f16x16([f16; 16]);
 #[repr(simd)]
-pub struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32);
+pub struct f32x8([f32; 8]);
 #[repr(simd)]
-pub struct f64x4(f64, f64, f64, f64);
+pub struct f64x4([f64; 4]);
 
 #[repr(simd)]
-pub struct i8x64(
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-    i8,
-);
+pub struct i8x64([i8; 64]);
 #[repr(simd)]
-pub struct i16x32(
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-    i16,
-);
+pub struct i16x32([i16; 32]);
 #[repr(simd)]
-pub struct i32x16(i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32);
+pub struct i32x16([i32; 16]);
 #[repr(simd)]
-pub struct i64x8(i64, i64, i64, i64, i64, i64, i64, i64);
+pub struct i64x8([i64; 8]);
 #[repr(simd)]
-pub struct f16x32(
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-    f16,
-);
+pub struct f16x32([f16; 32]);
 #[repr(simd)]
-pub struct f32x16(f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32, f32);
+pub struct f32x16([f32; 16]);
 #[repr(simd)]
-pub struct f64x8(f64, f64, f64, f64, f64, f64, f64, f64);
+pub struct f64x8([f64; 8]);
 
 macro_rules! impl_copy {
     ($($ty:ident)*) => {
diff --git a/tests/codegen/align-byval-vector.rs b/tests/codegen/align-byval-vector.rs
index 02b7d6b0c5e..60d49f93081 100644
--- a/tests/codegen/align-byval-vector.rs
+++ b/tests/codegen/align-byval-vector.rs
@@ -21,7 +21,7 @@ trait Freeze {}
 trait Copy {}
 
 #[repr(simd)]
-pub struct i32x4(i32, i32, i32, i32);
+pub struct i32x4([i32; 4]);
 
 #[repr(C)]
 pub struct Foo {
@@ -47,12 +47,12 @@ extern "C" {
 }
 
 pub fn main() {
-    unsafe { f(Foo { a: i32x4(1, 2, 3, 4), b: 0 }) }
+    unsafe { f(Foo { a: i32x4([1, 2, 3, 4]), b: 0 }) }
 
     unsafe {
         g(DoubleFoo {
-            one: Foo { a: i32x4(1, 2, 3, 4), b: 0 },
-            two: Foo { a: i32x4(1, 2, 3, 4), b: 0 },
+            one: Foo { a: i32x4([1, 2, 3, 4]), b: 0 },
+            two: Foo { a: i32x4([1, 2, 3, 4]), b: 0 },
         })
     }
 }
diff --git a/tests/codegen/const-vector.rs b/tests/codegen/const-vector.rs
index d368838201e..8343594e5d2 100644
--- a/tests/codegen/const-vector.rs
+++ b/tests/codegen/const-vector.rs
@@ -13,19 +13,11 @@
 // Setting up structs that can be used as const vectors
 #[repr(simd)]
 #[derive(Clone)]
-pub struct i8x2(i8, i8);
+pub struct i8x2([i8; 2]);
 
 #[repr(simd)]
 #[derive(Clone)]
-pub struct i8x2_arr([i8; 2]);
-
-#[repr(simd)]
-#[derive(Clone)]
-pub struct f32x2(f32, f32);
-
-#[repr(simd)]
-#[derive(Clone)]
-pub struct f32x2_arr([f32; 2]);
+pub struct f32x2([f32; 2]);
 
 #[repr(simd, packed)]
 #[derive(Copy, Clone)]
@@ -35,42 +27,34 @@ pub struct Simd<T, const N: usize>([T; N]);
 // that they are called with a const vector
 
 extern "unadjusted" {
-    #[no_mangle]
     fn test_i8x2(a: i8x2);
 }
 
 extern "unadjusted" {
-    #[no_mangle]
     fn test_i8x2_two_args(a: i8x2, b: i8x2);
 }
 
 extern "unadjusted" {
-    #[no_mangle]
     fn test_i8x2_mixed_args(a: i8x2, c: i32, b: i8x2);
 }
 
 extern "unadjusted" {
-    #[no_mangle]
-    fn test_i8x2_arr(a: i8x2_arr);
+    fn test_i8x2_arr(a: i8x2);
 }
 
 extern "unadjusted" {
-    #[no_mangle]
     fn test_f32x2(a: f32x2);
 }
 
 extern "unadjusted" {
-    #[no_mangle]
-    fn test_f32x2_arr(a: f32x2_arr);
+    fn test_f32x2_arr(a: f32x2);
 }
 
 extern "unadjusted" {
-    #[no_mangle]
     fn test_simd(a: Simd<i32, 4>);
 }
 
 extern "unadjusted" {
-    #[no_mangle]
     fn test_simd_unaligned(a: Simd<i32, 3>);
 }
 
@@ -81,22 +65,22 @@ extern "unadjusted" {
 pub fn do_call() {
     unsafe {
         // CHECK: call void @test_i8x2(<2 x i8> <i8 32, i8 64>
-        test_i8x2(const { i8x2(32, 64) });
+        test_i8x2(const { i8x2([32, 64]) });
 
         // CHECK: call void @test_i8x2_two_args(<2 x i8> <i8 32, i8 64>, <2 x i8> <i8 8, i8 16>
-        test_i8x2_two_args(const { i8x2(32, 64) }, const { i8x2(8, 16) });
+        test_i8x2_two_args(const { i8x2([32, 64]) }, const { i8x2([8, 16]) });
 
         // CHECK: call void @test_i8x2_mixed_args(<2 x i8> <i8 32, i8 64>, i32 43, <2 x i8> <i8 8, i8 16>
-        test_i8x2_mixed_args(const { i8x2(32, 64) }, 43, const { i8x2(8, 16) });
+        test_i8x2_mixed_args(const { i8x2([32, 64]) }, 43, const { i8x2([8, 16]) });
 
         // CHECK: call void @test_i8x2_arr(<2 x i8> <i8 32, i8 64>
-        test_i8x2_arr(const { i8x2_arr([32, 64]) });
+        test_i8x2_arr(const { i8x2([32, 64]) });
 
         // CHECK: call void @test_f32x2(<2 x float> <float 0x3FD47AE140000000, float 0x3FE47AE140000000>
-        test_f32x2(const { f32x2(0.32, 0.64) });
+        test_f32x2(const { f32x2([0.32, 0.64]) });
 
         // CHECK: void @test_f32x2_arr(<2 x float> <float 0x3FD47AE140000000, float 0x3FE47AE140000000>
-        test_f32x2_arr(const { f32x2_arr([0.32, 0.64]) });
+        test_f32x2_arr(const { f32x2([0.32, 0.64]) });
 
         // CHECK: call void @test_simd(<4 x i32> <i32 2, i32 4, i32 6, i32 8>
         test_simd(const { Simd::<i32, 4>([2, 4, 6, 8]) });
diff --git a/tests/codegen/naked-asan.rs b/tests/codegen/naked-asan.rs
index a45b95780f7..ac36018eed3 100644
--- a/tests/codegen/naked-asan.rs
+++ b/tests/codegen/naked-asan.rs
@@ -20,3 +20,4 @@ pub extern "x86-interrupt" fn page_fault_handler(_: u64, _: u64) {
 
 // CHECK: #[[ATTRS]] =
 // CHECK-NOT: sanitize_address
+// CHECK: !llvm.module.flags
diff --git a/tests/codegen/repr/transparent.rs b/tests/codegen/repr/transparent.rs
index 9140b8542ec..adcd3aacd2a 100644
--- a/tests/codegen/repr/transparent.rs
+++ b/tests/codegen/repr/transparent.rs
@@ -132,7 +132,7 @@ pub extern "C" fn test_Nested2(_: Nested2) -> Nested2 {
 }
 
 #[repr(simd)]
-struct f32x4(f32, f32, f32, f32);
+struct f32x4([f32; 4]);
 
 #[repr(transparent)]
 pub struct Vector(f32x4);
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs
index f8efb678f76..4a5a6391c05 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs
@@ -7,23 +7,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x2(pub f32, pub f32);
+pub struct f32x2(pub [f32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(pub f32, pub f32, pub f32, pub f32,
-                 pub f32, pub f32, pub f32, pub f32);
+pub struct f32x8(pub [f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32);
+pub struct f32x16(pub [f32; 16]);
 
 extern "rust-intrinsic" {
     fn simd_fabs<T>(x: T) -> T;
@@ -59,16 +55,15 @@ pub unsafe fn fabs_32x16(a: f32x16) -> f32x16 {
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x2(pub f64, pub f64);
+pub struct f64x2(pub [f64; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x4(pub f64, pub f64, pub f64, pub f64);
+pub struct f64x4(pub [f64; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x8(pub f64, pub f64, pub f64, pub f64,
-                 pub f64, pub f64, pub f64, pub f64);
+pub struct f64x8(pub [f64; 8]);
 
 // CHECK-LABEL: @fabs_64x4
 #[no_mangle]
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs
index a3ebec174b6..89e54f579ff 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs
@@ -7,23 +7,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x2(pub f32, pub f32);
+pub struct f32x2(pub [f32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(pub f32, pub f32, pub f32, pub f32,
-                 pub f32, pub f32, pub f32, pub f32);
+pub struct f32x8(pub [f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32);
+pub struct f32x16(pub [f32; 16]);
 
 extern "rust-intrinsic" {
     fn simd_ceil<T>(x: T) -> T;
@@ -59,16 +55,15 @@ pub unsafe fn ceil_32x16(a: f32x16) -> f32x16 {
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x2(pub f64, pub f64);
+pub struct f64x2(pub [f64; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x4(pub f64, pub f64, pub f64, pub f64);
+pub struct f64x4(pub [f64; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x8(pub f64, pub f64, pub f64, pub f64,
-                 pub f64, pub f64, pub f64, pub f64);
+pub struct f64x8(pub [f64; 8]);
 
 // CHECK-LABEL: @ceil_64x4
 #[no_mangle]
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs
index 00f97eef6f0..b40fd5365de 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs
@@ -7,23 +7,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x2(pub f32, pub f32);
+pub struct f32x2(pub [f32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(pub f32, pub f32, pub f32, pub f32,
-                 pub f32, pub f32, pub f32, pub f32);
+pub struct f32x8(pub [f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32);
+pub struct f32x16(pub [f32; 16]);
 
 extern "rust-intrinsic" {
     fn simd_fcos<T>(x: T) -> T;
@@ -59,16 +55,15 @@ pub unsafe fn fcos_32x16(a: f32x16) -> f32x16 {
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x2(pub f64, pub f64);
+pub struct f64x2(pub [f64; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x4(pub f64, pub f64, pub f64, pub f64);
+pub struct f64x4(pub [f64; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x8(pub f64, pub f64, pub f64, pub f64,
-                 pub f64, pub f64, pub f64, pub f64);
+pub struct f64x8(pub [f64; 8]);
 
 // CHECK-LABEL: @fcos_64x4
 #[no_mangle]
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs
index 48c1a8ec489..fef003dde5b 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs
@@ -7,23 +7,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x2(pub f32, pub f32);
+pub struct f32x2(pub [f32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(pub f32, pub f32, pub f32, pub f32,
-                 pub f32, pub f32, pub f32, pub f32);
+pub struct f32x8(pub [f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32);
+pub struct f32x16(pub [f32; 16]);
 
 extern "rust-intrinsic" {
     fn simd_fexp<T>(x: T) -> T;
@@ -59,16 +55,15 @@ pub unsafe fn exp_32x16(a: f32x16) -> f32x16 {
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x2(pub f64, pub f64);
+pub struct f64x2(pub [f64; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x4(pub f64, pub f64, pub f64, pub f64);
+pub struct f64x4(pub [f64; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x8(pub f64, pub f64, pub f64, pub f64,
-                 pub f64, pub f64, pub f64, pub f64);
+pub struct f64x8(pub [f64; 8]);
 
 // CHECK-LABEL: @exp_64x4
 #[no_mangle]
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs
index 23c38d81621..779c0fc403a 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs
@@ -7,23 +7,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x2(pub f32, pub f32);
+pub struct f32x2(pub [f32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(pub f32, pub f32, pub f32, pub f32,
-                 pub f32, pub f32, pub f32, pub f32);
+pub struct f32x8(pub [f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32);
+pub struct f32x16(pub [f32; 16]);
 
 extern "rust-intrinsic" {
     fn simd_fexp2<T>(x: T) -> T;
@@ -59,16 +55,15 @@ pub unsafe fn exp2_32x16(a: f32x16) -> f32x16 {
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x2(pub f64, pub f64);
+pub struct f64x2(pub [f64; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x4(pub f64, pub f64, pub f64, pub f64);
+pub struct f64x4(pub [f64; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x8(pub f64, pub f64, pub f64, pub f64,
-                 pub f64, pub f64, pub f64, pub f64);
+pub struct f64x8(pub [f64; 8]);
 
 // CHECK-LABEL: @exp2_64x4
 #[no_mangle]
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs
index 978f263031a..b2bd27a5b75 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs
@@ -7,23 +7,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x2(pub f32, pub f32);
+pub struct f32x2(pub [f32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(pub f32, pub f32, pub f32, pub f32,
-                 pub f32, pub f32, pub f32, pub f32);
+pub struct f32x8(pub [f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32);
+pub struct f32x16(pub [f32; 16]);
 
 extern "rust-intrinsic" {
     fn simd_floor<T>(x: T) -> T;
@@ -59,16 +55,15 @@ pub unsafe fn floor_32x16(a: f32x16) -> f32x16 {
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x2(pub f64, pub f64);
+pub struct f64x2(pub [f64; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x4(pub f64, pub f64, pub f64, pub f64);
+pub struct f64x4(pub [f64; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x8(pub f64, pub f64, pub f64, pub f64,
-                 pub f64, pub f64, pub f64, pub f64);
+pub struct f64x8(pub [f64; 8]);
 
 // CHECK-LABEL: @floor_64x4
 #[no_mangle]
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs
index 200d6718026..37f4782626a 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs
@@ -7,23 +7,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x2(pub f32, pub f32);
+pub struct f32x2(pub [f32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(pub f32, pub f32, pub f32, pub f32,
-                 pub f32, pub f32, pub f32, pub f32);
+pub struct f32x8(pub [f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32);
+pub struct f32x16(pub [f32; 16]);
 
 extern "rust-intrinsic" {
     fn simd_fma<T>(x: T, b: T, c: T) -> T;
@@ -59,16 +55,15 @@ pub unsafe fn fma_32x16(a: f32x16, b: f32x16, c: f32x16) -> f32x16 {
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x2(pub f64, pub f64);
+pub struct f64x2(pub [f64; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x4(pub f64, pub f64, pub f64, pub f64);
+pub struct f64x4(pub [f64; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x8(pub f64, pub f64, pub f64, pub f64,
-                 pub f64, pub f64, pub f64, pub f64);
+pub struct f64x8(pub [f64; 8]);
 
 // CHECK-LABEL: @fma_64x4
 #[no_mangle]
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs
index f70de3e2753..336adf6db73 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs
@@ -7,23 +7,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x2(pub f32, pub f32);
+pub struct f32x2(pub [f32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(pub f32, pub f32, pub f32, pub f32,
-                 pub f32, pub f32, pub f32, pub f32);
+pub struct f32x8(pub [f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32);
+pub struct f32x16(pub [f32; 16]);
 
 extern "rust-intrinsic" {
     fn simd_fsqrt<T>(x: T) -> T;
@@ -59,16 +55,15 @@ pub unsafe fn fsqrt_32x16(a: f32x16) -> f32x16 {
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x2(pub f64, pub f64);
+pub struct f64x2(pub [f64; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x4(pub f64, pub f64, pub f64, pub f64);
+pub struct f64x4(pub [f64; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x8(pub f64, pub f64, pub f64, pub f64,
-                 pub f64, pub f64, pub f64, pub f64);
+pub struct f64x8(pub [f64; 8]);
 
 // CHECK-LABEL: @fsqrt_64x4
 #[no_mangle]
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs
index c0edd3ea48f..8e97abc3a66 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs
@@ -7,23 +7,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x2(pub f32, pub f32);
+pub struct f32x2(pub [f32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(pub f32, pub f32, pub f32, pub f32,
-                 pub f32, pub f32, pub f32, pub f32);
+pub struct f32x8(pub [f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32);
+pub struct f32x16(pub [f32; 16]);
 
 extern "rust-intrinsic" {
     fn simd_flog<T>(x: T) -> T;
@@ -59,16 +55,15 @@ pub unsafe fn log_32x16(a: f32x16) -> f32x16 {
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x2(pub f64, pub f64);
+pub struct f64x2(pub [f64; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x4(pub f64, pub f64, pub f64, pub f64);
+pub struct f64x4(pub [f64; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x8(pub f64, pub f64, pub f64, pub f64,
-                 pub f64, pub f64, pub f64, pub f64);
+pub struct f64x8(pub [f64; 8]);
 
 // CHECK-LABEL: @log_64x4
 #[no_mangle]
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs
index 766307f47ed..1d4d4dc24e9 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs
@@ -7,23 +7,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x2(pub f32, pub f32);
+pub struct f32x2(pub [f32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(pub f32, pub f32, pub f32, pub f32,
-                 pub f32, pub f32, pub f32, pub f32);
+pub struct f32x8(pub [f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32);
+pub struct f32x16(pub [f32; 16]);
 
 extern "rust-intrinsic" {
     fn simd_flog10<T>(x: T) -> T;
@@ -59,16 +55,15 @@ pub unsafe fn log10_32x16(a: f32x16) -> f32x16 {
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x2(pub f64, pub f64);
+pub struct f64x2(pub [f64; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x4(pub f64, pub f64, pub f64, pub f64);
+pub struct f64x4(pub [f64; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x8(pub f64, pub f64, pub f64, pub f64,
-                 pub f64, pub f64, pub f64, pub f64);
+pub struct f64x8(pub [f64; 8]);
 
 // CHECK-LABEL: @log10_64x4
 #[no_mangle]
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs
index 90c5918c33e..28f2f151617 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs
@@ -7,23 +7,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x2(pub f32, pub f32);
+pub struct f32x2(pub [f32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(pub f32, pub f32, pub f32, pub f32,
-                 pub f32, pub f32, pub f32, pub f32);
+pub struct f32x8(pub [f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32);
+pub struct f32x16(pub [f32; 16]);
 
 extern "rust-intrinsic" {
     fn simd_flog2<T>(x: T) -> T;
@@ -59,16 +55,15 @@ pub unsafe fn log2_32x16(a: f32x16) -> f32x16 {
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x2(pub f64, pub f64);
+pub struct f64x2(pub [f64; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x4(pub f64, pub f64, pub f64, pub f64);
+pub struct f64x4(pub [f64; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x8(pub f64, pub f64, pub f64, pub f64,
-                 pub f64, pub f64, pub f64, pub f64);
+pub struct f64x8(pub [f64; 8]);
 
 // CHECK-LABEL: @log2_64x4
 #[no_mangle]
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs
index d949112bae7..50c51bebe37 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs
@@ -7,7 +7,7 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 extern "rust-intrinsic" {
     fn simd_fmin<T>(x: T, y: T) -> T;
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs
index 21641c80d31..3527f71c00b 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs
@@ -7,23 +7,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x2(pub f32, pub f32);
+pub struct f32x2(pub [f32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(pub f32, pub f32, pub f32, pub f32,
-                 pub f32, pub f32, pub f32, pub f32);
+pub struct f32x8(pub [f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32);
+pub struct f32x16(pub [f32; 16]);
 
 extern "rust-intrinsic" {
     fn simd_fpow<T>(x: T, b: T) -> T;
@@ -59,16 +55,15 @@ pub unsafe fn fpow_32x16(a: f32x16, b: f32x16) -> f32x16 {
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x2(pub f64, pub f64);
+pub struct f64x2(pub [f64; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x4(pub f64, pub f64, pub f64, pub f64);
+pub struct f64x4(pub [f64; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x8(pub f64, pub f64, pub f64, pub f64,
-                 pub f64, pub f64, pub f64, pub f64);
+pub struct f64x8(pub [f64; 8]);
 
 // CHECK-LABEL: @fpow_64x4
 #[no_mangle]
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs
index 3985bdd50df..4f0b5e4e01a 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs
@@ -7,23 +7,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x2(pub f32, pub f32);
+pub struct f32x2(pub [f32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(pub f32, pub f32, pub f32, pub f32,
-                 pub f32, pub f32, pub f32, pub f32);
+pub struct f32x8(pub [f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32);
+pub struct f32x16(pub [f32; 16]);
 
 extern "rust-intrinsic" {
     fn simd_fpowi<T>(x: T, b: i32) -> T;
@@ -59,16 +55,15 @@ pub unsafe fn fpowi_32x16(a: f32x16, b: i32) -> f32x16 {
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x2(pub f64, pub f64);
+pub struct f64x2(pub [f64; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x4(pub f64, pub f64, pub f64, pub f64);
+pub struct f64x4(pub [f64; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x8(pub f64, pub f64, pub f64, pub f64,
-                 pub f64, pub f64, pub f64, pub f64);
+pub struct f64x8(pub [f64; 8]);
 
 // CHECK-LABEL: @fpowi_64x4
 #[no_mangle]
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs
index f6978e32df7..4173809e3a9 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs
@@ -7,23 +7,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x2(pub f32, pub f32);
+pub struct f32x2(pub [f32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(pub f32, pub f32, pub f32, pub f32,
-                 pub f32, pub f32, pub f32, pub f32);
+pub struct f32x8(pub [f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32,
-                  pub f32, pub f32, pub f32, pub f32);
+pub struct f32x16(pub [f32; 16]);
 
 extern "rust-intrinsic" {
     fn simd_fsin<T>(x: T) -> T;
@@ -59,16 +55,15 @@ pub unsafe fn fsin_32x16(a: f32x16) -> f32x16 {
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x2(pub f64, pub f64);
+pub struct f64x2(pub [f64; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x4(pub f64, pub f64, pub f64, pub f64);
+pub struct f64x4(pub [f64; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f64x8(pub f64, pub f64, pub f64, pub f64,
-                 pub f64, pub f64, pub f64, pub f64);
+pub struct f64x8(pub [f64; 8]);
 
 // CHECK-LABEL: @fsin_64x4
 #[no_mangle]
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs
index 809f9a32226..a5afa27876a 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs
@@ -9,107 +9,57 @@
 
 // signed integer types
 
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x2(i8, i8);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x4(i8, i8, i8, i8);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x8(
-    i8, i8, i8, i8, i8, i8, i8, i8,
-);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x16(
-    i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8,
-);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x32(
-    i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8,
-    i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8,
-);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x64(
-    i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8,
-    i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8,
-    i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8,
-    i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8,
-);
-
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x2(i16, i16);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x4(i16, i16, i16, i16);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x8(
-    i16, i16, i16, i16, i16, i16, i16, i16,
-);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x16(
-    i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16,
-);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x32(
-    i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16,
-    i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16, i16,
-);
-
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i32x2(i32, i32);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i32x4(i32, i32, i32, i32);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i32x8(
-    i32, i32, i32, i32, i32, i32, i32, i32,
-);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i32x16(
-    i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32,
-);
-
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i64x2(i64, i64);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i64x4(i64, i64, i64, i64);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i64x8(
-    i64, i64, i64, i64, i64, i64, i64, i64,
-);
-
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i128x2(i128, i128);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct i128x4(i128, i128, i128, i128);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x2([i8; 2]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x4([i8; 4]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x8([i8; 8]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x16([i8; 16]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x32([i8; 32]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i8x64([i8; 64]);
+
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x2([i16; 2]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x4([i16; 4]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x8([i16; 8]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x16([i16; 16]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i16x32([i16; 32]);
+
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i32x2([i32; 2]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i32x4([i32; 4]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i32x8([i32; 8]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i32x16([i32; 16]);
+
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i64x2([i64; 2]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i64x4([i64; 4]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i64x8([i64; 8]);
+
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i128x2([i128; 2]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct i128x4([i128; 4]);
 
 // unsigned integer types
 
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x2(u8, u8);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x4(u8, u8, u8, u8);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x8(
-    u8, u8, u8, u8, u8, u8, u8, u8,
-);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x16(
-    u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8,
-);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x32(
-    u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8,
-    u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8,
-);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x64(
-    u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8,
-    u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8,
-    u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8,
-    u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8,
-);
-
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x2(u16, u16);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x4(u16, u16, u16, u16);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x8(
-    u16, u16, u16, u16, u16, u16, u16, u16,
-);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x16(
-    u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16,
-);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x32(
-    u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16,
-    u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16, u16,
-);
-
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u32x2(u32, u32);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u32x4(u32, u32, u32, u32);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u32x8(
-    u32, u32, u32, u32, u32, u32, u32, u32,
-);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u32x16(
-    u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32, u32,
-);
-
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u64x2(u64, u64);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u64x4(u64, u64, u64, u64);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u64x8(
-    u64, u64, u64, u64, u64, u64, u64, u64,
-);
-
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u128x2(u128, u128);
-#[repr(simd)] #[derive(Copy, Clone)] pub struct u128x4(u128, u128, u128, u128);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x2([u8; 2]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x4([u8; 4]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x8([u8; 8]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x16([u8; 16]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x32([u8; 32]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u8x64([u8; 64]);
+
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x2([u16; 2]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x4([u16; 4]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x8([u16; 8]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x16([u16; 16]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u16x32([u16; 32]);
+
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u32x2([u32; 2]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u32x4([u32; 4]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u32x8([u32; 8]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u32x16([u32; 16]);
+
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u64x2([u64; 2]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u64x4([u64; 4]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u64x8([u64; 8]);
+
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u128x2([u128; 2]);
+#[repr(simd)] #[derive(Copy, Clone)] pub struct u128x4([u128; 4]);
 
 extern "rust-intrinsic" {
     fn simd_saturating_add<T>(x: T, y: T) -> T;
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs
index 44a4c52d64a..81ac90269b7 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs
@@ -8,19 +8,15 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-pub struct u32x2(u32, u32);
+pub struct u32x2([u32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-pub struct i32x2(i32, i32);
+pub struct i32x2([i32; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-pub struct i8x16(
-    i8, i8, i8, i8, i8, i8, i8, i8,
-    i8, i8, i8, i8, i8, i8, i8, i8,
-);
-
+pub struct i8x16([i8; 16]);
 
 extern "rust-intrinsic" {
     fn simd_bitmask<T, U>(x: T) -> U;
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs
index 863a9606c7e..10ceeecf900 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs
@@ -9,11 +9,11 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct Vec2<T>(pub T, pub T);
+pub struct Vec2<T>(pub [T; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct Vec4<T>(pub T, pub T, pub T, pub T);
+pub struct Vec4<T>(pub [T; 4]);
 
 extern "rust-intrinsic" {
     fn simd_gather<T, P, M>(value: T, pointers: P, mask: M) -> T;
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs
index b41c42810aa..073dc0ac94d 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs
@@ -7,11 +7,11 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct Vec2<T>(pub T, pub T);
+pub struct Vec2<T>(pub [T; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct Vec4<T>(pub T, pub T, pub T, pub T);
+pub struct Vec4<T>(pub [T; 4]);
 
 extern "rust-intrinsic" {
     fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs
index 066392bcde6..7c3393e6f2e 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs
@@ -7,11 +7,11 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct Vec2<T>(pub T, pub T);
+pub struct Vec2<T>(pub [T; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct Vec4<T>(pub T, pub T, pub T, pub T);
+pub struct Vec4<T>(pub [T; 4]);
 
 extern "rust-intrinsic" {
     fn simd_masked_store<M, P, T>(mask: M, pointer: P, values: T) -> ();
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs
index e85bd61c7f8..3c75ef5be40 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs
@@ -9,11 +9,11 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct Vec2<T>(pub T, pub T);
+pub struct Vec2<T>(pub [T; 2]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct Vec4<T>(pub T, pub T, pub T, pub T);
+pub struct Vec4<T>(pub [T; 4]);
 
 extern "rust-intrinsic" {
     fn simd_scatter<T, P, M>(value: T, pointers: P, mask: M);
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs
index 05d2bf627ef..c12fefa413b 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs
@@ -7,15 +7,15 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32);
+pub struct f32x8([f32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-pub struct b8x4(pub i8, pub i8, pub i8, pub i8);
+pub struct b8x4(pub [i8; 4]);
 
 extern "rust-intrinsic" {
     fn simd_select<T, U>(x: T, a: U, b: U) -> U;
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs
index c416f4d28bb..75f989d6e12 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs
@@ -13,10 +13,6 @@ pub struct S<const N: usize>([f32; N]);
 #[derive(Copy, Clone)]
 pub struct T([f32; 4]);
 
-#[repr(simd)]
-#[derive(Copy, Clone)]
-pub struct U(f32, f32, f32, f32);
-
 // CHECK-LABEL: @array_align(
 #[no_mangle]
 pub fn array_align() -> usize {
@@ -28,7 +24,7 @@ pub fn array_align() -> usize {
 #[no_mangle]
 pub fn vector_align() -> usize {
     // CHECK: ret [[USIZE]] [[VECTOR_ALIGN:[0-9]+]]
-    const { std::mem::align_of::<U>() }
+    const { std::mem::align_of::<T>() }
 }
 
 // CHECK-LABEL: @build_array_s
@@ -60,22 +56,3 @@ pub fn build_array_transmute_t(x: [f32; 4]) -> T {
     // CHECK: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]]
     unsafe { std::mem::transmute(x) }
 }
-
-// CHECK-LABEL: @build_array_u
-#[no_mangle]
-pub fn build_array_u(x: [f32; 4]) -> U {
-    // CHECK: store float %a, {{.+}}, align [[VECTOR_ALIGN]]
-    // CHECK: store float %b, {{.+}}, align [[ARRAY_ALIGN]]
-    // CHECK: store float %c, {{.+}}, align
-    // CHECK: store float %d, {{.+}}, align [[ARRAY_ALIGN]]
-    let [a, b, c, d] = x;
-    U(a, b, c, d)
-}
-
-// CHECK-LABEL: @build_array_transmute_u
-#[no_mangle]
-pub fn build_array_transmute_u(x: [f32; 4]) -> U {
-    // CHECK: %[[VAL:.+]] = load <4 x float>, ptr %x, align [[ARRAY_ALIGN]]
-    // CHECK: store <4 x float> %[[VAL:.+]], ptr %_0, align [[VECTOR_ALIGN]]
-    unsafe { std::mem::transmute(x) }
-}
diff --git a/tests/codegen/simd/unpadded-simd.rs b/tests/codegen/simd/unpadded-simd.rs
index 66d9298c006..ef067a15702 100644
--- a/tests/codegen/simd/unpadded-simd.rs
+++ b/tests/codegen/simd/unpadded-simd.rs
@@ -7,7 +7,7 @@
 
 #[derive(Copy, Clone)]
 #[repr(simd)]
-pub struct int16x4_t(pub i16, pub i16, pub i16, pub i16);
+pub struct int16x4_t(pub [i16; 4]);
 
 #[derive(Copy, Clone)]
 pub struct int16x4x2_t(pub int16x4_t, pub int16x4_t);
diff --git a/tests/codegen/union-abi.rs b/tests/codegen/union-abi.rs
index 08015014456..a1c081d7d61 100644
--- a/tests/codegen/union-abi.rs
+++ b/tests/codegen/union-abi.rs
@@ -16,7 +16,7 @@ pub enum Unhab {}
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-pub struct i64x4(i64, i64, i64, i64);
+pub struct i64x4([i64; 4]);
 
 #[derive(Copy, Clone)]
 pub union UnionI64x4 {
diff --git a/tests/codegen/zst-offset.rs b/tests/codegen/zst-offset.rs
index 14e97fd26dd..475394a8815 100644
--- a/tests/codegen/zst-offset.rs
+++ b/tests/codegen/zst-offset.rs
@@ -27,7 +27,7 @@ pub fn scalarpair_layout(s: &(u64, u32, ())) {
 }
 
 #[repr(simd)]
-pub struct U64x4(u64, u64, u64, u64);
+pub struct U64x4([u64; 4]);
 
 // Check that we correctly generate a GEP for a ZST that is not included in Vector layout
 // CHECK-LABEL: @vector_layout
diff --git a/tests/debuginfo/simd.rs b/tests/debuginfo/simd.rs
index e4fe262235b..12675a71a57 100644
--- a/tests/debuginfo/simd.rs
+++ b/tests/debuginfo/simd.rs
@@ -10,27 +10,27 @@
 // gdb-command:run
 
 // gdb-command:print vi8x16
-// gdb-check:$1 = simd::i8x16 (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15)
+// gdb-check:$1 = simd::i8x16 ([0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15])
 // gdb-command:print vi16x8
-// gdb-check:$2 = simd::i16x8 (16, 17, 18, 19, 20, 21, 22, 23)
+// gdb-check:$2 = simd::i16x8 ([16, 17, 18, 19, 20, 21, 22, 23])
 // gdb-command:print vi32x4
-// gdb-check:$3 = simd::i32x4 (24, 25, 26, 27)
+// gdb-check:$3 = simd::i32x4 ([24, 25, 26, 27])
 // gdb-command:print vi64x2
-// gdb-check:$4 = simd::i64x2 (28, 29)
+// gdb-check:$4 = simd::i64x2 ([28, 29])
 
 // gdb-command:print vu8x16
-// gdb-check:$5 = simd::u8x16 (30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45)
+// gdb-check:$5 = simd::u8x16 ([30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45])
 // gdb-command:print vu16x8
-// gdb-check:$6 = simd::u16x8 (46, 47, 48, 49, 50, 51, 52, 53)
+// gdb-check:$6 = simd::u16x8 ([46, 47, 48, 49, 50, 51, 52, 53])
 // gdb-command:print vu32x4
-// gdb-check:$7 = simd::u32x4 (54, 55, 56, 57)
+// gdb-check:$7 = simd::u32x4 ([54, 55, 56, 57])
 // gdb-command:print vu64x2
-// gdb-check:$8 = simd::u64x2 (58, 59)
+// gdb-check:$8 = simd::u64x2 ([58, 59])
 
 // gdb-command:print vf32x4
-// gdb-check:$9 = simd::f32x4 (60.5, 61.5, 62.5, 63.5)
+// gdb-check:$9 = simd::f32x4 ([60.5, 61.5, 62.5, 63.5])
 // gdb-command:print vf64x2
-// gdb-check:$10 = simd::f64x2 (64.5, 65.5)
+// gdb-check:$10 = simd::f64x2 ([64.5, 65.5])
 
 // gdb-command:continue
 
@@ -40,43 +40,43 @@
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct i8x16(i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8);
+struct i8x16([i8; 16]);
 #[repr(simd)]
-struct i16x8(i16, i16, i16, i16, i16, i16, i16, i16);
+struct i16x8([i16; 8]);
 #[repr(simd)]
-struct i32x4(i32, i32, i32, i32);
+struct i32x4([i32; 4]);
 #[repr(simd)]
-struct i64x2(i64, i64);
+struct i64x2([i64; 2]);
 #[repr(simd)]
-struct u8x16(u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8, u8);
+struct u8x16([u8; 16]);
 #[repr(simd)]
-struct u16x8(u16, u16, u16, u16, u16, u16, u16, u16);
+struct u16x8([u16; 8]);
 #[repr(simd)]
-struct u32x4(u32, u32, u32, u32);
+struct u32x4([u32; 4]);
 #[repr(simd)]
-struct u64x2(u64, u64);
+struct u64x2([u64; 2]);
 #[repr(simd)]
-struct f32x4(f32, f32, f32, f32);
+struct f32x4([f32; 4]);
 #[repr(simd)]
-struct f64x2(f64, f64);
+struct f64x2([f64; 2]);
 
 fn main() {
 
-    let vi8x16 = i8x16(0, 1, 2, 3, 4, 5, 6, 7,
-                      8, 9, 10, 11, 12, 13, 14, 15);
+    let vi8x16 = i8x16([0, 1, 2, 3, 4, 5, 6, 7,
+                      8, 9, 10, 11, 12, 13, 14, 15]);
 
-    let vi16x8 = i16x8(16, 17, 18, 19, 20, 21, 22, 23);
-    let vi32x4 = i32x4(24, 25, 26, 27);
-    let vi64x2 = i64x2(28, 29);
+    let vi16x8 = i16x8([16, 17, 18, 19, 20, 21, 22, 23]);
+    let vi32x4 = i32x4([24, 25, 26, 27]);
+    let vi64x2 = i64x2([28, 29]);
 
-    let vu8x16 = u8x16(30, 31, 32, 33, 34, 35, 36, 37,
-                      38, 39, 40, 41, 42, 43, 44, 45);
-    let vu16x8 = u16x8(46, 47, 48, 49, 50, 51, 52, 53);
-    let vu32x4 = u32x4(54, 55, 56, 57);
-    let vu64x2 = u64x2(58, 59);
+    let vu8x16 = u8x16([30, 31, 32, 33, 34, 35, 36, 37,
+                      38, 39, 40, 41, 42, 43, 44, 45]);
+    let vu16x8 = u16x8([46, 47, 48, 49, 50, 51, 52, 53]);
+    let vu32x4 = u32x4([54, 55, 56, 57]);
+    let vu64x2 = u64x2([58, 59]);
 
-    let vf32x4 = f32x4(60.5f32, 61.5f32, 62.5f32, 63.5f32);
-    let vf64x2 = f64x2(64.5f64, 65.5f64);
+    let vf32x4 = f32x4([60.5f32, 61.5f32, 62.5f32, 63.5f32]);
+    let vf64x2 = f64x2([64.5f64, 65.5f64]);
 
     zzz(); // #break
 }
diff --git a/tests/incremental/issue-61530.rs b/tests/incremental/issue-61530.rs
index e4ee8ccbc4b..b4914dda11a 100644
--- a/tests/incremental/issue-61530.rs
+++ b/tests/incremental/issue-61530.rs
@@ -3,7 +3,7 @@
 //@ revisions:rpass1 rpass2
 
 #[repr(simd)]
-struct I32x2(i32, i32);
+struct I32x2([i32; 2]);
 
 extern "rust-intrinsic" {
     fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
@@ -12,7 +12,7 @@ extern "rust-intrinsic" {
 fn main() {
     unsafe {
         const IDX: [u32; 2] = [0, 0];
-        let _: I32x2 = simd_shuffle(I32x2(1, 2), I32x2(3, 4), IDX);
-        let _: I32x2 = simd_shuffle(I32x2(1, 2), I32x2(3, 4), IDX);
+        let _: I32x2 = simd_shuffle(I32x2([1, 2]), I32x2([3, 4]), IDX);
+        let _: I32x2 = simd_shuffle(I32x2([1, 2]), I32x2([3, 4]), IDX);
     }
 }
diff --git a/tests/pretty/tests-are-sorted.pp b/tests/pretty/tests-are-sorted.pp
index 816cd5a5c07..a4b15dde453 100644
--- a/tests/pretty/tests-are-sorted.pp
+++ b/tests/pretty/tests-are-sorted.pp
@@ -83,6 +83,7 @@ pub const a_test: test::TestDescAndFn =
 fn a_test() {}
 #[rustc_main]
 #[coverage(off)]
+#[allow(missing_docs)]
 pub fn main() -> () {
     extern crate test;
     test::test_main_static(&[&a_test, &m_test, &z_test])
diff --git a/tests/run-make/rustc-crates-on-stable/rmake.rs b/tests/run-make/rustc-crates-on-stable/rmake.rs
new file mode 100644
index 00000000000..81cc775c919
--- /dev/null
+++ b/tests/run-make/rustc-crates-on-stable/rmake.rs
@@ -0,0 +1,36 @@
+//! Checks if selected rustc crates can be compiled on the stable channel (or a "simulation" of it).
+//! These crates are designed to be used by downstream users.
+
+use run_make_support::{cargo, rustc_path, source_root};
+
+fn main() {
+    // Use the stage0 beta cargo for the compilation (it shouldn't really matter which cargo we use)
+    cargo()
+        // Ensure `proc-macro2`'s nightly detection is disabled
+        .env("RUSTC_STAGE", "0")
+        .env("RUSTC", rustc_path())
+        // We want to disallow all nightly features to simulate a stable build
+        .env("RUSTFLAGS", "-Zallow-features=")
+        .arg("build")
+        .arg("--manifest-path")
+        .arg(source_root().join("Cargo.toml"))
+        .args(&[
+            // Avoid depending on transitive rustc crates
+            "--no-default-features",
+            // Emit artifacts in this temporary directory, not in the source_root's `target` folder
+            "--target-dir",
+            "target",
+        ])
+        // Check that these crates can be compiled on "stable"
+        .args(&[
+            "-p",
+            "rustc_type_ir",
+            "-p",
+            "rustc_next_trait_solver",
+            "-p",
+            "rustc_pattern_analysis",
+            "-p",
+            "rustc_lexer",
+        ])
+        .run();
+}
diff --git a/tests/run-make/rustdoc-default-output/output-default.stdout b/tests/run-make/rustdoc-default-output/output-default.stdout
index bc38d9e9dc6..125443ce619 100644
--- a/tests/run-make/rustdoc-default-output/output-default.stdout
+++ b/tests/run-make/rustdoc-default-output/output-default.stdout
@@ -172,6 +172,23 @@ Options:
         --scrape-tests  Include test code when scraping examples
         --with-examples path to function call information (for displaying examples in the documentation)
                         
+        --merge none|shared|finalize
+                        Controls how rustdoc handles files from previously
+                        documented crates in the doc root
+                        none = Do not write cross-crate information to the
+                        --out-dir
+                        shared = Append current crate's info to files found in
+                        the --out-dir
+                        finalize = Write current crate's info and
+                        --include-parts-dir info to the --out-dir, overwriting
+                        conflicting files
+        --parts-out-dir path/to/doc.parts/<crate-name>
+                        Writes trait implementations and other info for the
+                        current crate to provided path. Only use with
+                        --merge=none
+        --include-parts-dir path/to/doc.parts/<crate-name>
+                        Includes trait implementations and other crate info
+                        from provided path. Only use with --merge=finalize
         --disable-minification 
                         removed
         --plugin-path DIR
diff --git a/tests/run-make/simd-ffi/simd.rs b/tests/run-make/simd-ffi/simd.rs
index d11cfd77c5b..b72078faafa 100644
--- a/tests/run-make/simd-ffi/simd.rs
+++ b/tests/run-make/simd-ffi/simd.rs
@@ -8,7 +8,7 @@
 
 #[derive(Copy)]
 #[repr(simd)]
-pub struct f32x4(f32, f32, f32, f32);
+pub struct f32x4([f32; 4]);
 
 extern "C" {
     #[link_name = "llvm.sqrt.v4f32"]
@@ -21,7 +21,7 @@ pub fn foo(x: f32x4) -> f32x4 {
 
 #[derive(Copy)]
 #[repr(simd)]
-pub struct i32x4(i32, i32, i32, i32);
+pub struct i32x4([i32; 4]);
 
 extern "C" {
     // _mm_sll_epi32
@@ -62,6 +62,8 @@ pub trait Copy {}
 
 impl Copy for f32 {}
 impl Copy for i32 {}
+impl Copy for [f32; 4] {}
+impl Copy for [i32; 4] {}
 
 pub mod marker {
     pub use Copy;
diff --git a/tests/rustdoc-ui/projection-as-union-type-error.rs b/tests/rustdoc-ui/projection-as-union-type-error.rs
new file mode 100644
index 00000000000..d1d2e72249d
--- /dev/null
+++ b/tests/rustdoc-ui/projection-as-union-type-error.rs
@@ -0,0 +1,14 @@
+// Test to ensure that there is no ICE when normalizing a projection.
+// See also <https://github.com/rust-lang/rust/pull/106938>.
+// issue: rust-lang/rust#107872
+
+pub trait Identity {
+    type Identity;
+}
+
+pub type Foo = u8;
+
+pub union Bar {
+    a:  <Foo as Identity>::Identity, //~ ERROR the trait bound `u8: Identity` is not satisfied
+    b: u8,
+}
diff --git a/tests/rustdoc-ui/projection-as-union-type-error.stderr b/tests/rustdoc-ui/projection-as-union-type-error.stderr
new file mode 100644
index 00000000000..32598015864
--- /dev/null
+++ b/tests/rustdoc-ui/projection-as-union-type-error.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `u8: Identity` is not satisfied
+  --> $DIR/projection-as-union-type-error.rs:12:9
+   |
+LL |     a:  <Foo as Identity>::Identity,
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Identity` is not implemented for `u8`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/projection-as-union-type-error.rs:5:1
+   |
+LL | pub trait Identity {
+   | ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/rustdoc-ui/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs b/tests/rustdoc-ui/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs
new file mode 100644
index 00000000000..9f8053d5538
--- /dev/null
+++ b/tests/rustdoc-ui/recursive-type-alias-impl-trait-declaration-too-subtle-2.rs
@@ -0,0 +1,23 @@
+// issue: rust-lang/rust#98250
+//@ check-pass
+
+#![feature(type_alias_impl_trait)]
+
+mod foo {
+    pub type Foo = impl PartialEq<(Foo, i32)>;
+
+    fn foo() -> Foo {
+        super::Bar
+    }
+}
+use foo::Foo;
+
+struct Bar;
+
+impl PartialEq<(Foo, i32)> for Bar {
+    fn eq(&self, _other: &(Foo, i32)) -> bool {
+        true
+    }
+}
+
+fn main() {}
diff --git a/tests/rustdoc/inline_cross/auxiliary/repr.rs b/tests/rustdoc/inline_cross/auxiliary/repr.rs
index 35f08c11b7b..0211e1a8658 100644
--- a/tests/rustdoc/inline_cross/auxiliary/repr.rs
+++ b/tests/rustdoc/inline_cross/auxiliary/repr.rs
@@ -6,7 +6,7 @@ pub struct ReprC {
 }
 #[repr(simd, packed(2))]
 pub struct ReprSimd {
-    field: u8,
+    field: [u8; 1],
 }
 #[repr(transparent)]
 pub struct ReprTransparent {
diff --git a/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs
new file mode 100644
index 00000000000..fdafb3b7ac3
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/quebec.rs
@@ -0,0 +1,5 @@
+//@ doc-flags:--merge=shared
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs
new file mode 100644
index 00000000000..ff12fe98d82
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/auxiliary/tango.rs
@@ -0,0 +1,8 @@
+//@ aux-build:quebec.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=shared
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+extern crate quebec;
+pub trait Tango {}
diff --git a/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs b/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs
new file mode 100644
index 00000000000..665f9567ba2
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/cargo-transitive-read-write/sierra.rs
@@ -0,0 +1,25 @@
+//@ aux-build:tango.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=shared
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ has index.html
+//@ has index.html '//h1' 'List of all crates'
+//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec'
+//@ has index.html '//ul[@class="all-items"]//a[@href="sierra/index.html"]' 'sierra'
+//@ has index.html '//ul[@class="all-items"]//a[@href="tango/index.html"]' 'tango'
+//@ has quebec/struct.Quebec.html
+//@ has sierra/struct.Sierra.html
+//@ has tango/trait.Tango.html
+//@ hasraw sierra/struct.Sierra.html 'Tango'
+//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html'
+//@ hasraw search-index.js 'Tango'
+//@ hasraw search-index.js 'Sierra'
+//@ hasraw search-index.js 'Quebec'
+
+// similar to cargo-workflow-transitive, but we use --merge=read-write,
+// which is the default.
+extern crate tango;
+pub struct Sierra;
+impl tango::Tango for Sierra {}
diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs
new file mode 100644
index 00000000000..d10bc0316cc
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/quebec.rs
@@ -0,0 +1,7 @@
+//@ unique-doc-out-dir
+//@ doc-flags:--merge=none
+//@ doc-flags:--parts-out-dir=info/doc.parts/quebec
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs
new file mode 100644
index 00000000000..6d0c8651db5
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/romeo.rs
@@ -0,0 +1,10 @@
+//@ aux-build:sierra.rs
+//@ build-aux-docs
+//@ unique-doc-out-dir
+//@ doc-flags:--merge=none
+//@ doc-flags:--parts-out-dir=info/doc.parts/romeo
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+extern crate sierra;
+pub type Romeo = sierra::Sierra;
diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs
new file mode 100644
index 00000000000..10898f38864
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/sierra.rs
@@ -0,0 +1,11 @@
+//@ aux-build:tango.rs
+//@ build-aux-docs
+//@ unique-doc-out-dir
+//@ doc-flags:--merge=none
+//@ doc-flags:--parts-out-dir=info/doc.parts/sierra
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+extern crate tango;
+pub struct Sierra;
+impl tango::Tango for Sierra {}
diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs
new file mode 100644
index 00000000000..3c3721ee6eb
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/auxiliary/tango.rs
@@ -0,0 +1,10 @@
+//@ aux-build:quebec.rs
+//@ build-aux-docs
+//@ unique-doc-out-dir
+//@ doc-flags:--merge=none
+//@ doc-flags:--parts-out-dir=info/doc.parts/tango
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+extern crate quebec;
+pub trait Tango {}
diff --git a/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs
new file mode 100644
index 00000000000..f03f6bd6026
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/kitchen-sink-separate-dirs/indigo.rs
@@ -0,0 +1,35 @@
+//@ aux-build:tango.rs
+//@ aux-build:romeo.rs
+//@ aux-build:quebec.rs
+//@ aux-build:sierra.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=finalize
+//@ doc-flags:--include-parts-dir=info/doc.parts/tango
+//@ doc-flags:--include-parts-dir=info/doc.parts/romeo
+//@ doc-flags:--include-parts-dir=info/doc.parts/quebec
+//@ doc-flags:--include-parts-dir=info/doc.parts/sierra
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ has index.html '//h1' 'List of all crates'
+//@ has index.html
+//@ has index.html '//ul[@class="all-items"]//a[@href="indigo/index.html"]' 'indigo'
+//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec'
+//@ has index.html '//ul[@class="all-items"]//a[@href="romeo/index.html"]' 'romeo'
+//@ has index.html '//ul[@class="all-items"]//a[@href="sierra/index.html"]' 'sierra'
+//@ has index.html '//ul[@class="all-items"]//a[@href="tango/index.html"]' 'tango'
+//@ !has quebec/struct.Quebec.html
+//@ !has romeo/type.Romeo.html
+//@ !has sierra/struct.Sierra.html
+//@ !has tango/trait.Tango.html
+//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html'
+//@ hasraw search-index.js 'Quebec'
+//@ hasraw search-index.js 'Romeo'
+//@ hasraw search-index.js 'Sierra'
+//@ hasraw search-index.js 'Tango'
+//@ has type.impl/sierra/struct.Sierra.js
+//@ hasraw type.impl/sierra/struct.Sierra.js 'Tango'
+//@ hasraw type.impl/sierra/struct.Sierra.js 'Romeo'
+
+// document everything in the default mode, there are separate out
+// directories that are linked together
diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs
new file mode 100644
index 00000000000..61210529fa6
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/quebec.rs
@@ -0,0 +1,6 @@
+//@ unique-doc-out-dir
+//@ doc-flags:--merge=none
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs
new file mode 100644
index 00000000000..70d8a4b91f5
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/no-merge-separate/auxiliary/tango.rs
@@ -0,0 +1,9 @@
+//@ aux-build:quebec.rs
+//@ build-aux-docs
+//@ unique-doc-out-dir
+//@ doc-flags:--merge=none
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+extern crate quebec;
+pub trait Tango {}
diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-separate/sierra.rs b/tests/rustdoc/merge-cross-crate-info/no-merge-separate/sierra.rs
new file mode 100644
index 00000000000..7eac207e518
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/no-merge-separate/sierra.rs
@@ -0,0 +1,17 @@
+//@ aux-build:tango.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=none
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ !has index.html
+//@ has sierra/struct.Sierra.html
+//@ hasraw sierra/struct.Sierra.html 'Tango'
+//@ !has trait.impl/tango/trait.Tango.js
+//@ !has search-index.js
+
+// we don't generate any cross-crate info if --merge=none, even if we
+// document crates separately
+extern crate tango;
+pub struct Sierra;
+impl tango::Tango for Sierra {}
diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs
new file mode 100644
index 00000000000..6ab921533b0
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/quebec.rs
@@ -0,0 +1,6 @@
+//@ doc-flags:--merge=none
+//@ doc-flags:--parts-out-dir=info/doc.parts/quebec
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs
new file mode 100644
index 00000000000..9fa99d3be8a
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/auxiliary/tango.rs
@@ -0,0 +1,9 @@
+//@ aux-build:quebec.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=none
+//@ doc-flags:--parts-out-dir=info/doc.parts/tango
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+extern crate quebec;
+pub trait Tango {}
diff --git a/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/sierra.rs b/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/sierra.rs
new file mode 100644
index 00000000000..f3340a80c84
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/no-merge-write-anyway/sierra.rs
@@ -0,0 +1,18 @@
+//@ aux-build:tango.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=none
+//@ doc-flags:--parts-out-dir=info/doc.parts/sierra
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ !has index.html
+//@ has sierra/struct.Sierra.html
+//@ has tango/trait.Tango.html
+//@ hasraw sierra/struct.Sierra.html 'Tango'
+//@ !has trait.impl/tango/trait.Tango.js
+//@ !has search-index.js
+
+// we --merge=none, so --parts-out-dir doesn't do anything
+extern crate tango;
+pub struct Sierra;
+impl tango::Tango for Sierra {}
diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs
new file mode 100644
index 00000000000..6ab921533b0
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/quebec.rs
@@ -0,0 +1,6 @@
+//@ doc-flags:--merge=none
+//@ doc-flags:--parts-out-dir=info/doc.parts/quebec
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs
new file mode 100644
index 00000000000..9fa99d3be8a
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/auxiliary/tango.rs
@@ -0,0 +1,9 @@
+//@ aux-build:quebec.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=none
+//@ doc-flags:--parts-out-dir=info/doc.parts/tango
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+extern crate quebec;
+pub trait Tango {}
diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/sierra.rs b/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/sierra.rs
new file mode 100644
index 00000000000..8eb0f1d0498
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/overwrite-but-include/sierra.rs
@@ -0,0 +1,22 @@
+//@ aux-build:tango.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=finalize
+//@ doc-flags:--include-parts-dir=info/doc.parts/tango
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ has quebec/struct.Quebec.html
+//@ has sierra/struct.Sierra.html
+//@ has tango/trait.Tango.html
+//@ hasraw sierra/struct.Sierra.html 'Tango'
+//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html'
+//@ hasraw search-index.js 'Tango'
+//@ hasraw search-index.js 'Sierra'
+//@ !hasraw search-index.js 'Quebec'
+
+// we overwrite quebec and tango's cross-crate information, but we
+// include the info from tango meaning that it should appear in the out
+// dir
+extern crate tango;
+pub struct Sierra;
+impl tango::Tango for Sierra {}
diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs
new file mode 100644
index 00000000000..d10bc0316cc
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/quebec.rs
@@ -0,0 +1,7 @@
+//@ unique-doc-out-dir
+//@ doc-flags:--merge=none
+//@ doc-flags:--parts-out-dir=info/doc.parts/quebec
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs
new file mode 100644
index 00000000000..3c3721ee6eb
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/auxiliary/tango.rs
@@ -0,0 +1,10 @@
+//@ aux-build:quebec.rs
+//@ build-aux-docs
+//@ unique-doc-out-dir
+//@ doc-flags:--merge=none
+//@ doc-flags:--parts-out-dir=info/doc.parts/tango
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+extern crate quebec;
+pub trait Tango {}
diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/sierra.rs b/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/sierra.rs
new file mode 100644
index 00000000000..4ee036238b4
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/overwrite-but-separate/sierra.rs
@@ -0,0 +1,25 @@
+//@ aux-build:tango.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=finalize
+//@ doc-flags:--include-parts-dir=info/doc.parts/tango
+//@ doc-flags:--include-parts-dir=info/doc.parts/quebec
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ has index.html
+//@ has index.html '//h1' 'List of all crates'
+//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec'
+//@ has index.html '//ul[@class="all-items"]//a[@href="sierra/index.html"]' 'sierra'
+//@ has index.html '//ul[@class="all-items"]//a[@href="tango/index.html"]' 'tango'
+//@ has sierra/struct.Sierra.html
+//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html'
+//@ hasraw search-index.js 'Tango'
+//@ hasraw search-index.js 'Sierra'
+//@ hasraw search-index.js 'Quebec'
+
+// If these were documeted into the same directory, the info would be
+// overwritten. However, since they are merged, we can still recover all
+// of the cross-crate information
+extern crate tango;
+pub struct Sierra;
+impl tango::Tango for Sierra {}
diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/quebec.rs
new file mode 100644
index 00000000000..0e28d8e6466
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/quebec.rs
@@ -0,0 +1,5 @@
+//@ doc-flags:--merge=none
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/tango.rs
new file mode 100644
index 00000000000..363b2d5508e
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/overwrite/auxiliary/tango.rs
@@ -0,0 +1,8 @@
+//@ aux-build:quebec.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=finalize
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+extern crate quebec;
+pub trait Tango {}
diff --git a/tests/rustdoc/merge-cross-crate-info/overwrite/sierra.rs b/tests/rustdoc/merge-cross-crate-info/overwrite/sierra.rs
new file mode 100644
index 00000000000..11e61dd2744
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/overwrite/sierra.rs
@@ -0,0 +1,20 @@
+//@ aux-build:tango.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=shared
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ has quebec/struct.Quebec.html
+//@ has sierra/struct.Sierra.html
+//@ has tango/trait.Tango.html
+//@ hasraw sierra/struct.Sierra.html 'Tango'
+//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html'
+//@ hasraw search-index.js 'Tango'
+//@ hasraw search-index.js 'Sierra'
+//@ !hasraw search-index.js 'Quebec'
+
+// since tango is documented with --merge=finalize, we overwrite q's
+// cross-crate information
+extern crate tango;
+pub struct Sierra;
+impl tango::Tango for Sierra {}
diff --git a/tests/rustdoc/merge-cross-crate-info/single-crate-finalize/quebec.rs b/tests/rustdoc/merge-cross-crate-info/single-crate-finalize/quebec.rs
new file mode 100644
index 00000000000..09bb78c06f1
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/single-crate-finalize/quebec.rs
@@ -0,0 +1,13 @@
+//@ doc-flags:--merge=finalize
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ has index.html
+//@ has index.html '//h1' 'List of all crates'
+//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec'
+//@ has quebec/struct.Quebec.html
+//@ hasraw search-index.js 'Quebec'
+
+// there is nothing to read from the output directory if we use a single
+// crate
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/single-crate-read-write/quebec.rs b/tests/rustdoc/merge-cross-crate-info/single-crate-read-write/quebec.rs
new file mode 100644
index 00000000000..72475426f6e
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/single-crate-read-write/quebec.rs
@@ -0,0 +1,12 @@
+//@ doc-flags:--merge=shared
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ has index.html
+//@ has index.html '//h1' 'List of all crates'
+//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec'
+//@ has quebec/struct.Quebec.html
+//@ hasraw search-index.js 'Quebec'
+
+// read-write is the default and this does the same as `single-crate`
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/single-crate-write-anyway/quebec.rs b/tests/rustdoc/merge-cross-crate-info/single-crate-write-anyway/quebec.rs
new file mode 100644
index 00000000000..b20e173a830
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/single-crate-write-anyway/quebec.rs
@@ -0,0 +1,13 @@
+//@ doc-flags:--parts-out-dir=info/doc.parts/quebec
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ has index.html
+//@ has index.html '//h1' 'List of all crates'
+//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec'
+//@ has quebec/struct.Quebec.html
+//@ hasraw search-index.js 'Quebec'
+
+// we can --parts-out-dir, but that doesn't do anything other than create
+// the file
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs b/tests/rustdoc/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs
new file mode 100644
index 00000000000..e888a43c460
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/single-merge-none-useless-write/quebec.rs
@@ -0,0 +1,11 @@
+//@ doc-flags:--merge=none
+//@ doc-flags:--parts-out-dir=info/doc.parts/quebec
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ !has index.html
+//@ has quebec/struct.Quebec.html
+//@ !has search-index.js
+
+// --merge=none doesn't write anything, despite --parts-out-dir
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs
new file mode 100644
index 00000000000..1beca543f81
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/quebec.rs
@@ -0,0 +1,5 @@
+//@ doc-flags:--merge=finalize
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs
new file mode 100644
index 00000000000..363b2d5508e
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/transitive-finalize/auxiliary/tango.rs
@@ -0,0 +1,8 @@
+//@ aux-build:quebec.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=finalize
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+extern crate quebec;
+pub trait Tango {}
diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-finalize/sierra.rs b/tests/rustdoc/merge-cross-crate-info/transitive-finalize/sierra.rs
new file mode 100644
index 00000000000..68fc4b13fa8
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/transitive-finalize/sierra.rs
@@ -0,0 +1,20 @@
+//@ aux-build:tango.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=finalize
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ has index.html
+//@ has index.html '//h1' 'List of all crates'
+//@ has index.html '//ul[@class="all-items"]//a[@href="sierra/index.html"]' 'sierra'
+//@ has index.html '//ul[@class="all-items"]//a[@href="tango/index.html"]' 'tango'
+//@ has sierra/struct.Sierra.html
+//@ has tango/trait.Tango.html
+//@ hasraw sierra/struct.Sierra.html 'Tango'
+//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html'
+//@ hasraw search-index.js 'Sierra'
+
+// write only overwrites stuff in the output directory
+extern crate tango;
+pub struct Sierra;
+impl tango::Tango for Sierra {}
diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs
new file mode 100644
index 00000000000..6ab921533b0
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/quebec.rs
@@ -0,0 +1,6 @@
+//@ doc-flags:--merge=none
+//@ doc-flags:--parts-out-dir=info/doc.parts/quebec
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs
new file mode 100644
index 00000000000..9fa99d3be8a
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/auxiliary/tango.rs
@@ -0,0 +1,9 @@
+//@ aux-build:quebec.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=none
+//@ doc-flags:--parts-out-dir=info/doc.parts/tango
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+extern crate quebec;
+pub trait Tango {}
diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/sierra.rs b/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/sierra.rs
new file mode 100644
index 00000000000..b407228085e
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/transitive-merge-none/sierra.rs
@@ -0,0 +1,27 @@
+//@ aux-build:tango.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=finalize
+//@ doc-flags:--include-parts-dir=info/doc.parts/tango
+//@ doc-flags:--include-parts-dir=info/doc.parts/quebec
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ has index.html
+//@ has index.html '//h1' 'List of all crates'
+//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec'
+//@ has index.html '//ul[@class="all-items"]//a[@href="sierra/index.html"]' 'sierra'
+//@ has index.html '//ul[@class="all-items"]//a[@href="tango/index.html"]' 'tango'
+//@ has quebec/struct.Quebec.html
+//@ has sierra/struct.Sierra.html
+//@ has tango/trait.Tango.html
+//@ hasraw sierra/struct.Sierra.html 'Tango'
+//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html'
+//@ hasraw search-index.js 'Tango'
+//@ hasraw search-index.js 'Sierra'
+//@ hasraw search-index.js 'Quebec'
+
+// We avoid writing any cross-crate information, preferring to include it
+// with --include-parts-dir.
+extern crate tango;
+pub struct Sierra;
+impl tango::Tango for Sierra {}
diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs
new file mode 100644
index 00000000000..1beca543f81
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/quebec.rs
@@ -0,0 +1,5 @@
+//@ doc-flags:--merge=finalize
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs
new file mode 100644
index 00000000000..ff12fe98d82
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/auxiliary/tango.rs
@@ -0,0 +1,8 @@
+//@ aux-build:quebec.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=shared
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+extern crate quebec;
+pub trait Tango {}
diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/sierra.rs b/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/sierra.rs
new file mode 100644
index 00000000000..15e32d5941f
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/transitive-merge-read-write/sierra.rs
@@ -0,0 +1,25 @@
+//@ aux-build:tango.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=shared
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ has index.html
+//@ has index.html '//h1' 'List of all crates'
+//@ has index.html '//ul[@class="all-items"]//a[@href="quebec/index.html"]' 'quebec'
+//@ has index.html '//ul[@class="all-items"]//a[@href="sierra/index.html"]' 'sierra'
+//@ has index.html '//ul[@class="all-items"]//a[@href="tango/index.html"]' 'tango'
+//@ has quebec/struct.Quebec.html
+//@ has sierra/struct.Sierra.html
+//@ has tango/trait.Tango.html
+//@ hasraw sierra/struct.Sierra.html 'Tango'
+//@ hasraw trait.impl/tango/trait.Tango.js 'struct.Sierra.html'
+//@ hasraw search-index.js 'Tango'
+//@ hasraw search-index.js 'Sierra'
+//@ hasraw search-index.js 'Quebec'
+
+// We can use read-write to emulate the default behavior of rustdoc, when
+// --merge is left out.
+extern crate tango;
+pub struct Sierra;
+impl tango::Tango for Sierra {}
diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs b/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs
new file mode 100644
index 00000000000..0e28d8e6466
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/quebec.rs
@@ -0,0 +1,5 @@
+//@ doc-flags:--merge=none
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+pub struct Quebec;
diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs b/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs
new file mode 100644
index 00000000000..3827119f696
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/transitive-no-info/auxiliary/tango.rs
@@ -0,0 +1,8 @@
+//@ aux-build:quebec.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=none
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+extern crate quebec;
+pub trait Tango {}
diff --git a/tests/rustdoc/merge-cross-crate-info/transitive-no-info/sierra.rs b/tests/rustdoc/merge-cross-crate-info/transitive-no-info/sierra.rs
new file mode 100644
index 00000000000..3eb2cebd743
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/transitive-no-info/sierra.rs
@@ -0,0 +1,17 @@
+//@ aux-build:tango.rs
+//@ build-aux-docs
+//@ doc-flags:--merge=none
+//@ doc-flags:--enable-index-page
+//@ doc-flags:-Zunstable-options
+
+//@ !has index.html
+//@ has sierra/struct.Sierra.html
+//@ has tango/trait.Tango.html
+//@ hasraw sierra/struct.Sierra.html 'Tango'
+//@ !has trait.impl/tango/trait.Tango.js
+//@ !has search-index.js
+
+// --merge=none on all crates does not generate any cross-crate info
+extern crate tango;
+pub struct Sierra;
+impl tango::Tango for Sierra {}
diff --git a/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs b/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs
new file mode 100644
index 00000000000..e492b700dbc
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/auxiliary/foxtrot.rs
@@ -0,0 +1,5 @@
+//@ unique-doc-out-dir
+//@ doc-flags:--parts-out-dir=info/doc.parts/foxtrot
+//@ doc-flags:-Zunstable-options
+
+pub trait Foxtrot {}
diff --git a/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/echo.rs b/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/echo.rs
new file mode 100644
index 00000000000..ee2b646e43c
--- /dev/null
+++ b/tests/rustdoc/merge-cross-crate-info/two-separate-out-dir/echo.rs
@@ -0,0 +1,16 @@
+//@ aux-build:foxtrot.rs
+//@ build-aux-docs
+//@ doc-flags:--include-parts-dir=info/doc.parts/foxtrot
+//@ doc-flags:-Zunstable-options
+
+//@ has echo/enum.Echo.html
+//@ hasraw echo/enum.Echo.html 'Foxtrot'
+//@ hasraw trait.impl/foxtrot/trait.Foxtrot.js 'enum.Echo.html'
+//@ hasraw search-index.js 'Foxtrot'
+//@ hasraw search-index.js 'Echo'
+
+// document two crates in different places, and merge their docs after
+// they are generated
+extern crate foxtrot;
+pub enum Echo {}
+impl foxtrot::Foxtrot for Echo {}
diff --git a/tests/ui/abi/arm-unadjusted-intrinsic.rs b/tests/ui/abi/arm-unadjusted-intrinsic.rs
index 7a728d4b241..533cd40b30a 100644
--- a/tests/ui/abi/arm-unadjusted-intrinsic.rs
+++ b/tests/ui/abi/arm-unadjusted-intrinsic.rs
@@ -25,16 +25,13 @@ impl Copy for i8 {}
 impl<T: ?Sized> Copy for *const T {}
 impl<T: ?Sized> Copy for *mut T {}
 
+// I hate no_core tests!
+impl<T: Copy, const N: usize> Copy for [T; N] {}
 
 // Regression test for https://github.com/rust-lang/rust/issues/118124.
 
 #[repr(simd)]
-pub struct int8x16_t(
-    pub(crate) i8, pub(crate) i8, pub(crate) i8, pub(crate) i8,
-    pub(crate) i8, pub(crate) i8, pub(crate) i8, pub(crate) i8,
-    pub(crate) i8, pub(crate) i8, pub(crate) i8, pub(crate) i8,
-    pub(crate) i8, pub(crate) i8, pub(crate) i8, pub(crate) i8,
-);
+pub struct int8x16_t(pub(crate) [i8; 16]);
 impl Copy for int8x16_t {}
 
 #[repr(C)]
diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs
index d37e793d989..9600c8dff67 100644
--- a/tests/ui/abi/compatibility.rs
+++ b/tests/ui/abi/compatibility.rs
@@ -189,7 +189,7 @@ mod prelude {
 #[cfg(not(host))]
 use prelude::*;
 
-macro_rules! assert_abi_compatible {
+macro_rules! test_abi_compatible {
     ($name:ident, $t1:ty, $t2:ty) => {
         mod $name {
             use super::*;
@@ -213,16 +213,6 @@ impl Clone for Zst {
 }
 
 #[repr(C)]
-struct ReprC1<T: ?Sized>(T);
-#[repr(C)]
-struct ReprC2Int<T>(i32, T);
-#[repr(C)]
-struct ReprC2Float<T>(f32, T);
-#[repr(C)]
-struct ReprC4<T>(T, Vec<i32>, Zst, T);
-#[repr(C)]
-struct ReprC4Mixed<T>(T, f32, i32, T);
-#[repr(C)]
 enum ReprCEnum<T> {
     Variant1,
     Variant2(T),
@@ -233,23 +223,6 @@ union ReprCUnion<T> {
     something: ManuallyDrop<T>,
 }
 
-macro_rules! test_abi_compatible {
-    ($name:ident, $t1:ty, $t2:ty) => {
-        mod $name {
-            use super::*;
-            assert_abi_compatible!(plain, $t1, $t2);
-            // We also do some tests with differences in fields of `repr(C)` types.
-            assert_abi_compatible!(repr_c_1, ReprC1<$t1>, ReprC1<$t2>);
-            assert_abi_compatible!(repr_c_2_int, ReprC2Int<$t1>, ReprC2Int<$t2>);
-            assert_abi_compatible!(repr_c_2_float, ReprC2Float<$t1>, ReprC2Float<$t2>);
-            assert_abi_compatible!(repr_c_4, ReprC4<$t1>, ReprC4<$t2>);
-            assert_abi_compatible!(repr_c_4mixed, ReprC4Mixed<$t1>, ReprC4Mixed<$t2>);
-            assert_abi_compatible!(repr_c_enum, ReprCEnum<$t1>, ReprCEnum<$t2>);
-            assert_abi_compatible!(repr_c_union, ReprCUnion<$t1>, ReprCUnion<$t2>);
-        }
-    };
-}
-
 // Compatibility of pointers.
 test_abi_compatible!(ptr_mut, *const i32, *mut i32);
 test_abi_compatible!(ptr_pointee, *const i32, *const Vec<i32>);
@@ -268,7 +241,6 @@ test_abi_compatible!(isize_int, isize, i64);
 
 // Compatibility of 1-ZST.
 test_abi_compatible!(zst_unit, Zst, ());
-#[cfg(not(any(target_arch = "sparc64")))]
 test_abi_compatible!(zst_array, Zst, [u8; 0]);
 test_abi_compatible!(nonzero_int, NonZero<i32>, i32);
 
@@ -285,13 +257,13 @@ test_abi_compatible!(arc, Arc<i32>, *mut i32);
 
 // `repr(transparent)` compatibility.
 #[repr(transparent)]
-struct Wrapper1<T: ?Sized>(T);
+struct TransparentWrapper1<T: ?Sized>(T);
 #[repr(transparent)]
-struct Wrapper2<T: ?Sized>((), Zst, T);
+struct TransparentWrapper2<T: ?Sized>((), Zst, T);
 #[repr(transparent)]
-struct Wrapper3<T>(T, [u8; 0], PhantomData<u64>);
+struct TransparentWrapper3<T>(T, [u8; 0], PhantomData<u64>);
 #[repr(transparent)]
-union WrapperUnion<T> {
+union TransparentWrapperUnion<T> {
     nothing: (),
     something: ManuallyDrop<T>,
 }
@@ -300,10 +272,10 @@ macro_rules! test_transparent {
     ($name:ident, $t:ty) => {
         mod $name {
             use super::*;
-            test_abi_compatible!(wrap1, $t, Wrapper1<$t>);
-            test_abi_compatible!(wrap2, $t, Wrapper2<$t>);
-            test_abi_compatible!(wrap3, $t, Wrapper3<$t>);
-            test_abi_compatible!(wrap4, $t, WrapperUnion<$t>);
+            test_abi_compatible!(wrap1, $t, TransparentWrapper1<$t>);
+            test_abi_compatible!(wrap2, $t, TransparentWrapper2<$t>);
+            test_abi_compatible!(wrap3, $t, TransparentWrapper3<$t>);
+            test_abi_compatible!(wrap4, $t, TransparentWrapperUnion<$t>);
         }
     };
 }
@@ -342,10 +314,8 @@ macro_rules! test_transparent_unsized {
     ($name:ident, $t:ty) => {
         mod $name {
             use super::*;
-            assert_abi_compatible!(wrap1, $t, Wrapper1<$t>);
-            assert_abi_compatible!(wrap1_reprc, ReprC1<$t>, ReprC1<Wrapper1<$t>>);
-            assert_abi_compatible!(wrap2, $t, Wrapper2<$t>);
-            assert_abi_compatible!(wrap2_reprc, ReprC1<$t>, ReprC1<Wrapper2<$t>>);
+            test_abi_compatible!(wrap1, $t, TransparentWrapper1<$t>);
+            test_abi_compatible!(wrap2, $t, TransparentWrapper2<$t>);
         }
     };
 }
diff --git a/tests/ui/abi/homogenous-floats-target-feature-mixup.rs b/tests/ui/abi/homogenous-floats-target-feature-mixup.rs
index 3a8540a825c..4afb710b193 100644
--- a/tests/ui/abi/homogenous-floats-target-feature-mixup.rs
+++ b/tests/ui/abi/homogenous-floats-target-feature-mixup.rs
@@ -65,13 +65,13 @@ fn is_sigill(status: ExitStatus) -> bool {
 #[allow(nonstandard_style)]
 mod test {
     #[derive(PartialEq, Debug, Clone, Copy)]
-    struct f32x2(f32, f32);
+    struct f32x2([f32; 2]);
 
     #[derive(PartialEq, Debug, Clone, Copy)]
-    struct f32x4(f32, f32, f32, f32);
+    struct f32x4([f32; 4]);
 
     #[derive(PartialEq, Debug, Clone, Copy)]
-    struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32);
+    struct f32x8([f32; 8]);
 
     pub fn main(level: &str) {
         unsafe {
@@ -97,9 +97,9 @@ mod test {
         )*) => ($(
             $(#[$attr])*
             unsafe fn $main(level: &str) {
-                let m128 = f32x2(1., 2.);
-                let m256 = f32x4(3., 4., 5., 6.);
-                let m512 = f32x8(7., 8., 9., 10., 11., 12., 13., 14.);
+                let m128 = f32x2([1., 2.]);
+                let m256 = f32x4([3., 4., 5., 6.]);
+                let m512 = f32x8([7., 8., 9., 10., 11., 12., 13., 14.]);
                 assert_eq!(id_sse_128(m128), m128);
                 assert_eq!(id_sse_256(m256), m256);
                 assert_eq!(id_sse_512(m512), m512);
@@ -133,55 +133,55 @@ mod test {
 
     #[target_feature(enable = "sse2")]
     unsafe fn id_sse_128(a: f32x2) -> f32x2 {
-        assert_eq!(a, f32x2(1., 2.));
+        assert_eq!(a, f32x2([1., 2.]));
         a.clone()
     }
 
     #[target_feature(enable = "sse2")]
     unsafe fn id_sse_256(a: f32x4) -> f32x4 {
-        assert_eq!(a, f32x4(3., 4., 5., 6.));
+        assert_eq!(a, f32x4([3., 4., 5., 6.]));
         a.clone()
     }
 
     #[target_feature(enable = "sse2")]
     unsafe fn id_sse_512(a: f32x8) -> f32x8 {
-        assert_eq!(a, f32x8(7., 8., 9., 10., 11., 12., 13., 14.));
+        assert_eq!(a, f32x8([7., 8., 9., 10., 11., 12., 13., 14.]));
         a.clone()
     }
 
     #[target_feature(enable = "avx")]
     unsafe fn id_avx_128(a: f32x2) -> f32x2 {
-        assert_eq!(a, f32x2(1., 2.));
+        assert_eq!(a, f32x2([1., 2.]));
         a.clone()
     }
 
     #[target_feature(enable = "avx")]
     unsafe fn id_avx_256(a: f32x4) -> f32x4 {
-        assert_eq!(a, f32x4(3., 4., 5., 6.));
+        assert_eq!(a, f32x4([3., 4., 5., 6.]));
         a.clone()
     }
 
     #[target_feature(enable = "avx")]
     unsafe fn id_avx_512(a: f32x8) -> f32x8 {
-        assert_eq!(a, f32x8(7., 8., 9., 10., 11., 12., 13., 14.));
+        assert_eq!(a, f32x8([7., 8., 9., 10., 11., 12., 13., 14.]));
         a.clone()
     }
 
     #[target_feature(enable = "avx512bw")]
     unsafe fn id_avx512_128(a: f32x2) -> f32x2 {
-        assert_eq!(a, f32x2(1., 2.));
+        assert_eq!(a, f32x2([1., 2.]));
         a.clone()
     }
 
     #[target_feature(enable = "avx512bw")]
     unsafe fn id_avx512_256(a: f32x4) -> f32x4 {
-        assert_eq!(a, f32x4(3., 4., 5., 6.));
+        assert_eq!(a, f32x4([3., 4., 5., 6.]));
         a.clone()
     }
 
     #[target_feature(enable = "avx512bw")]
     unsafe fn id_avx512_512(a: f32x8) -> f32x8 {
-        assert_eq!(a, f32x8(7., 8., 9., 10., 11., 12., 13., 14.));
+        assert_eq!(a, f32x8([7., 8., 9., 10., 11., 12., 13., 14.]));
         a.clone()
     }
 }
diff --git a/tests/ui/asm/aarch64/type-check-2-2.rs b/tests/ui/asm/aarch64/type-check-2-2.rs
index f442ce81476..4b8ee1d9229 100644
--- a/tests/ui/asm/aarch64/type-check-2-2.rs
+++ b/tests/ui/asm/aarch64/type-check-2-2.rs
@@ -6,10 +6,10 @@ use std::arch::{asm, global_asm};
 
 #[repr(simd)]
 #[derive(Clone, Copy)]
-struct SimdType(f32, f32, f32, f32);
+struct SimdType([f32; 4]);
 
 #[repr(simd)]
-struct SimdNonCopy(f32, f32, f32, f32);
+struct SimdNonCopy([f32; 4]);
 
 fn main() {
     unsafe {
diff --git a/tests/ui/asm/aarch64/type-check-2.rs b/tests/ui/asm/aarch64/type-check-2.rs
index 46667ae3a65..ad223b799b7 100644
--- a/tests/ui/asm/aarch64/type-check-2.rs
+++ b/tests/ui/asm/aarch64/type-check-2.rs
@@ -6,10 +6,10 @@ use std::arch::{asm, global_asm};
 
 #[repr(simd)]
 #[derive(Clone, Copy)]
-struct SimdType(f32, f32, f32, f32);
+struct SimdType([f32; 4]);
 
 #[repr(simd)]
-struct SimdNonCopy(f32, f32, f32, f32);
+struct SimdNonCopy([f32; 4]);
 
 fn main() {
     unsafe {
@@ -17,7 +17,7 @@ fn main() {
 
         // Register operands must be Copy
 
-        asm!("{:v}", in(vreg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
+        asm!("{:v}", in(vreg) SimdNonCopy([0.0, 0.0, 0.0, 0.0]));
         //~^ ERROR arguments for inline assembly must be copyable
 
         // Register operands must be integers, floats, SIMD vectors, pointers or
@@ -25,7 +25,7 @@ fn main() {
 
         asm!("{}", in(reg) 0i64);
         asm!("{}", in(reg) 0f64);
-        asm!("{:v}", in(vreg) SimdType(0.0, 0.0, 0.0, 0.0));
+        asm!("{:v}", in(vreg) SimdType([0.0, 0.0, 0.0, 0.0]));
         asm!("{}", in(reg) 0 as *const u8);
         asm!("{}", in(reg) 0 as *mut u8);
         asm!("{}", in(reg) main as fn());
diff --git a/tests/ui/asm/aarch64/type-check-2.stderr b/tests/ui/asm/aarch64/type-check-2.stderr
index b7723fc74d4..84bc5f08b4e 100644
--- a/tests/ui/asm/aarch64/type-check-2.stderr
+++ b/tests/ui/asm/aarch64/type-check-2.stderr
@@ -1,8 +1,8 @@
 error: arguments for inline assembly must be copyable
   --> $DIR/type-check-2.rs:20:31
    |
-LL |         asm!("{:v}", in(vreg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         asm!("{:v}", in(vreg) SimdNonCopy([0.0, 0.0, 0.0, 0.0]));
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `SimdNonCopy` does not implement the Copy trait
 
diff --git a/tests/ui/asm/aarch64/type-check-3.rs b/tests/ui/asm/aarch64/type-check-3.rs
index b64473f98c0..2f8439d0a0f 100644
--- a/tests/ui/asm/aarch64/type-check-3.rs
+++ b/tests/ui/asm/aarch64/type-check-3.rs
@@ -8,11 +8,11 @@ use std::arch::{asm, global_asm};
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct Simd256bit(f64, f64, f64, f64);
+struct Simd256bit([f64; 4]);
 
 fn main() {
     let f64x2: float64x2_t = unsafe { std::mem::transmute(0i128) };
-    let f64x4 = Simd256bit(0.0, 0.0, 0.0, 0.0);
+    let f64x4 = Simd256bit([0.0, 0.0, 0.0, 0.0]);
 
     unsafe {
         // Types must be listed in the register class.
diff --git a/tests/ui/asm/aarch64/type-check-4.rs b/tests/ui/asm/aarch64/type-check-4.rs
index 41eb9de5669..1169c3dcfa8 100644
--- a/tests/ui/asm/aarch64/type-check-4.rs
+++ b/tests/ui/asm/aarch64/type-check-4.rs
@@ -8,7 +8,7 @@ use std::arch::{asm, global_asm};
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct Simd256bit(f64, f64, f64, f64);
+struct Simd256bit([f64; 4]);
 
 fn main() {}
 
diff --git a/tests/ui/asm/naked-functions-inline.rs b/tests/ui/asm/naked-functions-inline.rs
index cfb38f2e738..74049e8ecbc 100644
--- a/tests/ui/asm/naked-functions-inline.rs
+++ b/tests/ui/asm/naked-functions-inline.rs
@@ -2,37 +2,37 @@
 #![feature(naked_functions)]
 #![crate_type = "lib"]
 
-use std::arch::asm;
+use std::arch::naked_asm;
 
 #[naked]
 pub unsafe extern "C" fn inline_none() {
-    asm!("", options(noreturn));
+    naked_asm!("");
 }
 
 #[naked]
 #[inline]
 //~^ ERROR [E0736]
 pub unsafe extern "C" fn inline_hint() {
-    asm!("", options(noreturn));
+    naked_asm!("");
 }
 
 #[naked]
 #[inline(always)]
 //~^ ERROR [E0736]
 pub unsafe extern "C" fn inline_always() {
-    asm!("", options(noreturn));
+    naked_asm!("");
 }
 
 #[naked]
 #[inline(never)]
 //~^ ERROR [E0736]
 pub unsafe extern "C" fn inline_never() {
-    asm!("", options(noreturn));
+    naked_asm!("");
 }
 
 #[naked]
 #[cfg_attr(all(), inline(never))]
 //~^ ERROR [E0736]
 pub unsafe extern "C" fn conditional_inline_never() {
-    asm!("", options(noreturn));
+    naked_asm!("");
 }
diff --git a/tests/ui/asm/x86_64/type-check-2.rs b/tests/ui/asm/x86_64/type-check-2.rs
index ff811961462..1650c595fae 100644
--- a/tests/ui/asm/x86_64/type-check-2.rs
+++ b/tests/ui/asm/x86_64/type-check-2.rs
@@ -5,7 +5,7 @@
 use std::arch::{asm, global_asm};
 
 #[repr(simd)]
-struct SimdNonCopy(f32, f32, f32, f32);
+struct SimdNonCopy([f32; 4]);
 
 fn main() {
     unsafe {
@@ -29,7 +29,7 @@ fn main() {
 
         // Register operands must be Copy
 
-        asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
+        asm!("{}", in(xmm_reg) SimdNonCopy([0.0, 0.0, 0.0, 0.0]));
         //~^ ERROR arguments for inline assembly must be copyable
 
         // Register operands must be integers, floats, SIMD vectors, pointers or
diff --git a/tests/ui/asm/x86_64/type-check-2.stderr b/tests/ui/asm/x86_64/type-check-2.stderr
index c72e695aefb..8b1bfa85fa2 100644
--- a/tests/ui/asm/x86_64/type-check-2.stderr
+++ b/tests/ui/asm/x86_64/type-check-2.stderr
@@ -1,8 +1,8 @@
 error: arguments for inline assembly must be copyable
   --> $DIR/type-check-2.rs:32:32
    |
-LL |         asm!("{}", in(xmm_reg) SimdNonCopy(0.0, 0.0, 0.0, 0.0));
-   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |         asm!("{}", in(xmm_reg) SimdNonCopy([0.0, 0.0, 0.0, 0.0]));
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `SimdNonCopy` does not implement the Copy trait
 
diff --git a/tests/ui/asm/x86_64/type-check-5.rs b/tests/ui/asm/x86_64/type-check-5.rs
index b5b51f61168..81e096a7230 100644
--- a/tests/ui/asm/x86_64/type-check-5.rs
+++ b/tests/ui/asm/x86_64/type-check-5.rs
@@ -1,12 +1,9 @@
 //@ only-x86_64
 
-#![feature(repr_simd, never_type)]
+#![feature(never_type)]
 
 use std::arch::asm;
 
-#[repr(simd)]
-struct SimdNonCopy(f32, f32, f32, f32);
-
 fn main() {
     unsafe {
         // Inputs must be initialized
diff --git a/tests/ui/asm/x86_64/type-check-5.stderr b/tests/ui/asm/x86_64/type-check-5.stderr
index 4fb75993463..377e1d19f6c 100644
--- a/tests/ui/asm/x86_64/type-check-5.stderr
+++ b/tests/ui/asm/x86_64/type-check-5.stderr
@@ -1,5 +1,5 @@
 error[E0381]: used binding `x` isn't initialized
-  --> $DIR/type-check-5.rs:15:28
+  --> $DIR/type-check-5.rs:12:28
    |
 LL |         let x: u64;
    |             - binding declared here but left uninitialized
@@ -12,7 +12,7 @@ LL |         let x: u64 = 42;
    |                    ++++
 
 error[E0381]: used binding `y` isn't initialized
-  --> $DIR/type-check-5.rs:18:9
+  --> $DIR/type-check-5.rs:15:9
    |
 LL |         let mut y: u64;
    |             ----- binding declared here but left uninitialized
@@ -25,7 +25,7 @@ LL |         let mut y: u64 = 42;
    |                        ++++
 
 error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable
-  --> $DIR/type-check-5.rs:24:13
+  --> $DIR/type-check-5.rs:21:13
    |
 LL |         let v: Vec<u64> = vec![0, 1, 2];
    |             ^ not mutable
diff --git a/tests/ui/consts/const-eval/simd/insert_extract.rs b/tests/ui/consts/const-eval/simd/insert_extract.rs
index fc7dbd5a41c..f4f25327aaf 100644
--- a/tests/ui/consts/const-eval/simd/insert_extract.rs
+++ b/tests/ui/consts/const-eval/simd/insert_extract.rs
@@ -5,10 +5,9 @@
 #![stable(feature = "foo", since = "1.3.37")]
 #![allow(non_camel_case_types)]
 
-#[repr(simd)] struct i8x1(i8);
-#[repr(simd)] struct u16x2(u16, u16);
-// Make some of them array types to ensure those also work.
-#[repr(simd)] struct i8x1_arr([i8; 1]);
+// repr(simd) now only supports array types
+#[repr(simd)] struct i8x1([i8; 1]);
+#[repr(simd)] struct u16x2([u16; 2]);
 #[repr(simd)] struct f32x4([f32; 4]);
 
 extern "rust-intrinsic" {
@@ -20,26 +19,18 @@ extern "rust-intrinsic" {
 
 fn main() {
     {
-        const U: i8x1 = i8x1(13);
+        const U: i8x1 = i8x1([13]);
         const V: i8x1 = unsafe { simd_insert(U, 0_u32, 42_i8) };
-        const X0: i8 = V.0;
-        const Y0: i8 = unsafe { simd_extract(V, 0) };
-        assert_eq!(X0, 42);
-        assert_eq!(Y0, 42);
-    }
-    {
-        const U: i8x1_arr = i8x1_arr([13]);
-        const V: i8x1_arr = unsafe { simd_insert(U, 0_u32, 42_i8) };
         const X0: i8 = V.0[0];
         const Y0: i8 = unsafe { simd_extract(V, 0) };
         assert_eq!(X0, 42);
         assert_eq!(Y0, 42);
     }
     {
-        const U: u16x2 = u16x2(13, 14);
+        const U: u16x2 = u16x2([13, 14]);
         const V: u16x2 = unsafe { simd_insert(U, 1_u32, 42_u16) };
-        const X0: u16 = V.0;
-        const X1: u16 = V.1;
+        const X0: u16 = V.0[0];
+        const X1: u16 = V.0[1];
         const Y0: u16 = unsafe { simd_extract(V, 0) };
         const Y1: u16 = unsafe { simd_extract(V, 1) };
         assert_eq!(X0, 13);
diff --git a/tests/ui/error-codes/E0075.rs b/tests/ui/error-codes/E0075.rs
index 7feab0a8bd7..2c610d9186b 100644
--- a/tests/ui/error-codes/E0075.rs
+++ b/tests/ui/error-codes/E0075.rs
@@ -3,5 +3,8 @@
 #[repr(simd)]
 struct Bad; //~ ERROR E0075
 
+#[repr(simd)]
+struct AlsoBad([i32; 1], [i32; 1]); //~ ERROR E0075
+
 fn main() {
 }
diff --git a/tests/ui/error-codes/E0075.stderr b/tests/ui/error-codes/E0075.stderr
index 43e9971e309..0a44a2eadeb 100644
--- a/tests/ui/error-codes/E0075.stderr
+++ b/tests/ui/error-codes/E0075.stderr
@@ -4,6 +4,12 @@ error[E0075]: SIMD vector cannot be empty
 LL | struct Bad;
    | ^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error[E0075]: SIMD vector cannot have multiple fields
+  --> $DIR/E0075.rs:7:1
+   |
+LL | struct AlsoBad([i32; 1], [i32; 1]);
+   | ^^^^^^^^^^^^^^           -------- excess field
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0075`.
diff --git a/tests/ui/error-codes/E0076.rs b/tests/ui/error-codes/E0076.rs
index a27072eb71e..2c0376fe7e0 100644
--- a/tests/ui/error-codes/E0076.rs
+++ b/tests/ui/error-codes/E0076.rs
@@ -1,7 +1,7 @@
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Bad(u16, u32, u32);
+struct Bad(u32);
 //~^ ERROR E0076
 
 fn main() {
diff --git a/tests/ui/error-codes/E0076.stderr b/tests/ui/error-codes/E0076.stderr
index ea3bbf09497..8bf46cf38e3 100644
--- a/tests/ui/error-codes/E0076.stderr
+++ b/tests/ui/error-codes/E0076.stderr
@@ -1,8 +1,8 @@
-error[E0076]: SIMD vector should be homogeneous
+error[E0076]: SIMD vector's only field must be an array
   --> $DIR/E0076.rs:4:1
    |
-LL | struct Bad(u16, u32, u32);
-   | ^^^^^^^^^^ SIMD elements must have the same type
+LL | struct Bad(u32);
+   | ^^^^^^^^^^ --- not an array
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/error-codes/E0077.rs b/tests/ui/error-codes/E0077.rs
index fa2d5e24fa3..2704bbeb4ea 100644
--- a/tests/ui/error-codes/E0077.rs
+++ b/tests/ui/error-codes/E0077.rs
@@ -1,7 +1,7 @@
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct Bad(String); //~ ERROR E0077
+struct Bad([String; 2]); //~ ERROR E0077
 
 fn main() {
 }
diff --git a/tests/ui/error-codes/E0077.stderr b/tests/ui/error-codes/E0077.stderr
index aae4b3f2c29..063b40a147c 100644
--- a/tests/ui/error-codes/E0077.stderr
+++ b/tests/ui/error-codes/E0077.stderr
@@ -1,7 +1,7 @@
 error[E0077]: SIMD vector element type should be a primitive scalar (integer/float/pointer) type
   --> $DIR/E0077.rs:4:1
    |
-LL | struct Bad(String);
+LL | struct Bad([String; 2]);
    | ^^^^^^^^^^
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/feature-gates/feature-gate-repr-simd.rs b/tests/ui/feature-gates/feature-gate-repr-simd.rs
index c527404f572..65ade97c7e1 100644
--- a/tests/ui/feature-gates/feature-gate-repr-simd.rs
+++ b/tests/ui/feature-gates/feature-gate-repr-simd.rs
@@ -1,9 +1,9 @@
 #[repr(simd)] //~ error: SIMD types are experimental
-struct Foo(u64, u64);
+struct Foo([u64; 2]);
 
 #[repr(C)] //~ ERROR conflicting representation hints
 //~^ WARN this was previously accepted
 #[repr(simd)] //~ error: SIMD types are experimental
-struct Bar(u64, u64);
+struct Bar([u64; 2]);
 
 fn main() {}
diff --git a/tests/ui/feature-gates/feature-gate-simd-ffi.rs b/tests/ui/feature-gates/feature-gate-simd-ffi.rs
index abffa4a1001..2ee935e07ff 100644
--- a/tests/ui/feature-gates/feature-gate-simd-ffi.rs
+++ b/tests/ui/feature-gates/feature-gate-simd-ffi.rs
@@ -3,7 +3,7 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct LocalSimd(u8, u8);
+struct LocalSimd([u8; 2]);
 
 extern "C" {
     fn baz() -> LocalSimd; //~ ERROR use of SIMD type
diff --git a/tests/ui/feature-gates/feature-gate-simd.rs b/tests/ui/feature-gates/feature-gate-simd.rs
index de5f645e6fd..e7aef5a97f2 100644
--- a/tests/ui/feature-gates/feature-gate-simd.rs
+++ b/tests/ui/feature-gates/feature-gate-simd.rs
@@ -2,10 +2,7 @@
 
 #[repr(simd)] //~ ERROR SIMD types are experimental
 struct RGBA {
-    r: f32,
-    g: f32,
-    b: f32,
-    a: f32
+    rgba: [f32; 4],
 }
 
 pub fn main() {}
diff --git a/tests/ui/layout/debug.rs b/tests/ui/layout/debug.rs
index aeacbc78446..91e96d78ff5 100644
--- a/tests/ui/layout/debug.rs
+++ b/tests/ui/layout/debug.rs
@@ -49,7 +49,7 @@ union P2 { x: (u32, u32) } //~ ERROR: layout_of
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct F32x4(f32, f32, f32, f32);
+struct F32x4([f32; 4]);
 
 #[rustc_layout(debug)]
 #[repr(packed(1))]
diff --git a/tests/ui/lint/lint-missing-doc-crate.rs b/tests/ui/lint/lint-missing-doc-crate.rs
new file mode 100644
index 00000000000..afda73cbc60
--- /dev/null
+++ b/tests/ui/lint/lint-missing-doc-crate.rs
@@ -0,0 +1,4 @@
+// This test checks that we lint on the crate when it's missing a documentation.
+//
+//@ compile-flags: -Dmissing-docs --crate-type=lib
+//~ ERROR missing documentation for the crate
diff --git a/tests/ui/lint/lint-missing-doc-crate.stderr b/tests/ui/lint/lint-missing-doc-crate.stderr
new file mode 100644
index 00000000000..8efd3a17263
--- /dev/null
+++ b/tests/ui/lint/lint-missing-doc-crate.stderr
@@ -0,0 +1,10 @@
+error: missing documentation for the crate
+  --> $DIR/lint-missing-doc-crate.rs:4:47
+   |
+LL |
+   |                                              ^
+   |
+   = note: requested on the command line with `-D missing-docs`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/lint/lint-missing-doc-expect.rs b/tests/ui/lint/lint-missing-doc-expect.rs
new file mode 100644
index 00000000000..991f65003dc
--- /dev/null
+++ b/tests/ui/lint/lint-missing-doc-expect.rs
@@ -0,0 +1,13 @@
+// Make sure that `#[expect(missing_docs)]` is always correctly fulfilled.
+
+//@ check-pass
+//@ revisions: lib bin test
+//@ [lib]compile-flags: --crate-type lib
+//@ [bin]compile-flags: --crate-type bin
+//@ [test]compile-flags: --test
+
+#[expect(missing_docs)]
+pub fn foo() {}
+
+#[cfg(bin)]
+fn main() {}
diff --git a/tests/ui/lint/lint-missing-doc-test.rs b/tests/ui/lint/lint-missing-doc-test.rs
new file mode 100644
index 00000000000..93d4e4a44e9
--- /dev/null
+++ b/tests/ui/lint/lint-missing-doc-test.rs
@@ -0,0 +1,5 @@
+//! This test checks that denying the missing_docs lint does not trigger
+//! on the generated test harness.
+
+//@ check-pass
+//@ compile-flags: --test -Dmissing_docs
diff --git a/tests/ui/repr/attr-usage-repr.rs b/tests/ui/repr/attr-usage-repr.rs
index 8965decc379..dc0d4f5be2e 100644
--- a/tests/ui/repr/attr-usage-repr.rs
+++ b/tests/ui/repr/attr-usage-repr.rs
@@ -10,7 +10,7 @@ struct SExtern(f64, f64);
 struct SPacked(f64, f64);
 
 #[repr(simd)]
-struct SSimd(f64, f64);
+struct SSimd([f64; 2]);
 
 #[repr(i8)] //~ ERROR: attribute should be applied to an enum
 struct SInt(f64, f64);
diff --git a/tests/ui/repr/explicit-rust-repr-conflicts.rs b/tests/ui/repr/explicit-rust-repr-conflicts.rs
index 22dd12d316a..5278f5e6ae0 100644
--- a/tests/ui/repr/explicit-rust-repr-conflicts.rs
+++ b/tests/ui/repr/explicit-rust-repr-conflicts.rs
@@ -18,6 +18,6 @@ enum U {
 #[repr(Rust, simd)]
 //~^ ERROR conflicting representation hints
 //~| ERROR SIMD types are experimental and possibly buggy
-struct F32x4(f32, f32, f32, f32);
+struct F32x4([f32; 4]);
 
 fn main() {}
diff --git a/tests/ui/simd/const-err-trumps-simd-err.rs b/tests/ui/simd/const-err-trumps-simd-err.rs
index fda04434451..fb87fe1cbca 100644
--- a/tests/ui/simd/const-err-trumps-simd-err.rs
+++ b/tests/ui/simd/const-err-trumps-simd-err.rs
@@ -10,7 +10,7 @@ use std::intrinsics::simd::*;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
-struct int8x4_t(u8,u8,u8,u8);
+struct int8x4_t([u8; 4]);
 
 fn get_elem<const LANE: u32>(a: int8x4_t) -> u8 {
     const { assert!(LANE < 4); } // the error should be here...
@@ -20,5 +20,5 @@ fn get_elem<const LANE: u32>(a: int8x4_t) -> u8 {
 }
 
 fn main() {
-    get_elem::<4>(int8x4_t(0,0,0,0));
+    get_elem::<4>(int8x4_t([0, 0, 0, 0]));
 }
diff --git a/tests/ui/simd/const-err-trumps-simd-err.stderr b/tests/ui/simd/const-err-trumps-simd-err.stderr
index 1e46667cf4e..11cbcad227f 100644
--- a/tests/ui/simd/const-err-trumps-simd-err.stderr
+++ b/tests/ui/simd/const-err-trumps-simd-err.stderr
@@ -15,8 +15,8 @@ LL |     const { assert!(LANE < 4); } // the error should be here...
 note: the above error was encountered while instantiating `fn get_elem::<4>`
   --> $DIR/const-err-trumps-simd-err.rs:23:5
    |
-LL |     get_elem::<4>(int8x4_t(0,0,0,0));
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     get_elem::<4>(int8x4_t([0, 0, 0, 0]));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/simd/generics.rs b/tests/ui/simd/generics.rs
index bd048b19ca8..f96a7cd75e9 100644
--- a/tests/ui/simd/generics.rs
+++ b/tests/ui/simd/generics.rs
@@ -6,7 +6,7 @@ use std::ops;
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct f32x4(f32, f32, f32, f32);
+struct f32x4([f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
@@ -67,8 +67,8 @@ pub fn main() {
     let y = [2.0f32, 4.0f32, 6.0f32, 8.0f32];
 
     // lame-o
-    let a = f32x4(1.0f32, 2.0f32, 3.0f32, 4.0f32);
-    let f32x4(a0, a1, a2, a3) = add(a, a);
+    let a = f32x4([1.0f32, 2.0f32, 3.0f32, 4.0f32]);
+    let f32x4([a0, a1, a2, a3]) = add(a, a);
     assert_eq!(a0, 2.0f32);
     assert_eq!(a1, 4.0f32);
     assert_eq!(a2, 6.0f32);
diff --git a/tests/ui/simd/intrinsic/float-math-pass.rs b/tests/ui/simd/intrinsic/float-math-pass.rs
index ea31e2a7c57..9b14d410acb 100644
--- a/tests/ui/simd/intrinsic/float-math-pass.rs
+++ b/tests/ui/simd/intrinsic/float-math-pass.rs
@@ -13,7 +13,7 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-struct f32x4(pub f32, pub f32, pub f32, pub f32);
+struct f32x4(pub [f32; 4]);
 
 extern "rust-intrinsic" {
     fn simd_fsqrt<T>(x: T) -> T;
@@ -47,19 +47,19 @@ macro_rules! assert_approx_eq {
     ($a:expr, $b:expr) => ({
         let a = $a;
         let b = $b;
-        assert_approx_eq_f32!(a.0, b.0);
-        assert_approx_eq_f32!(a.1, b.1);
-        assert_approx_eq_f32!(a.2, b.2);
-        assert_approx_eq_f32!(a.3, b.3);
+        assert_approx_eq_f32!(a.0[0], b.0[0]);
+        assert_approx_eq_f32!(a.0[1], b.0[1]);
+        assert_approx_eq_f32!(a.0[2], b.0[2]);
+        assert_approx_eq_f32!(a.0[3], b.0[3]);
     })
 }
 
 fn main() {
-    let x = f32x4(1.0, 1.0, 1.0, 1.0);
-    let y = f32x4(-1.0, -1.0, -1.0, -1.0);
-    let z = f32x4(0.0, 0.0, 0.0, 0.0);
+    let x = f32x4([1.0, 1.0, 1.0, 1.0]);
+    let y = f32x4([-1.0, -1.0, -1.0, -1.0]);
+    let z = f32x4([0.0, 0.0, 0.0, 0.0]);
 
-    let h = f32x4(0.5, 0.5, 0.5, 0.5);
+    let h = f32x4([0.5, 0.5, 0.5, 0.5]);
 
     unsafe {
         let r = simd_fabs(y);
diff --git a/tests/ui/simd/intrinsic/float-minmax-pass.rs b/tests/ui/simd/intrinsic/float-minmax-pass.rs
index d6cbcd4e05a..00c0d8cea3f 100644
--- a/tests/ui/simd/intrinsic/float-minmax-pass.rs
+++ b/tests/ui/simd/intrinsic/float-minmax-pass.rs
@@ -8,13 +8,13 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-struct f32x4(pub f32, pub f32, pub f32, pub f32);
+struct f32x4(pub [f32; 4]);
 
 use std::intrinsics::simd::*;
 
 fn main() {
-    let x = f32x4(1.0, 2.0, 3.0, 4.0);
-    let y = f32x4(2.0, 1.0, 4.0, 3.0);
+    let x = f32x4([1.0, 2.0, 3.0, 4.0]);
+    let y = f32x4([2.0, 1.0, 4.0, 3.0]);
 
     #[cfg(not(any(target_arch = "mips", target_arch = "mips64")))]
     let nan = f32::NAN;
@@ -23,13 +23,13 @@ fn main() {
     #[cfg(any(target_arch = "mips", target_arch = "mips64"))]
     let nan = f32::from_bits(f32::NAN.to_bits() - 1);
 
-    let n = f32x4(nan, nan, nan, nan);
+    let n = f32x4([nan, nan, nan, nan]);
 
     unsafe {
         let min0 = simd_fmin(x, y);
         let min1 = simd_fmin(y, x);
         assert_eq!(min0, min1);
-        let e = f32x4(1.0, 1.0, 3.0, 3.0);
+        let e = f32x4([1.0, 1.0, 3.0, 3.0]);
         assert_eq!(min0, e);
         let minn = simd_fmin(x, n);
         assert_eq!(minn, x);
@@ -39,7 +39,7 @@ fn main() {
         let max0 = simd_fmax(x, y);
         let max1 = simd_fmax(y, x);
         assert_eq!(max0, max1);
-        let e = f32x4(2.0, 2.0, 4.0, 4.0);
+        let e = f32x4([2.0, 2.0, 4.0, 4.0]);
         assert_eq!(max0, e);
         let maxn = simd_fmax(x, n);
         assert_eq!(maxn, x);
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-2.rs b/tests/ui/simd/intrinsic/generic-arithmetic-2.rs
index fc3087cbf75..663bcdf1981 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-2.rs
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-2.rs
@@ -4,15 +4,15 @@
 #![allow(non_camel_case_types)]
 #[repr(simd)]
 #[derive(Copy, Clone)]
-pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
+pub struct i32x4(pub [i32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
+pub struct u32x4(pub [u32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 extern "rust-intrinsic" {
     fn simd_add<T>(x: T, y: T) -> T;
@@ -35,9 +35,9 @@ extern "rust-intrinsic" {
 }
 
 fn main() {
-    let x = i32x4(0, 0, 0, 0);
-    let y = u32x4(0, 0, 0, 0);
-    let z = f32x4(0.0, 0.0, 0.0, 0.0);
+    let x = i32x4([0, 0, 0, 0]);
+    let y = u32x4([0, 0, 0, 0]);
+    let z = f32x4([0.0, 0.0, 0.0, 0.0]);
 
     unsafe {
         simd_add(x, x);
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs b/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
index 60dfa627414..e4eb2a9da27 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
@@ -5,7 +5,7 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct i32x4(pub i32, pub i32, pub i32, pub i32);
+struct i32x4(pub [i32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
@@ -13,20 +13,12 @@ struct U32<const N: usize>([u32; N]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct f32x4(pub f32, pub f32, pub f32, pub f32);
+struct f32x4(pub [f32; 4]);
 
 macro_rules! all_eq {
     ($a: expr, $b: expr) => {{
         let a = $a;
         let b = $b;
-        assert!(a.0 == b.0 && a.1 == b.1 && a.2 == b.2 && a.3 == b.3);
-    }};
-}
-
-macro_rules! all_eq_ {
-    ($a: expr, $b: expr) => {{
-        let a = $a;
-        let b = $b;
         assert!(a.0 == b.0);
     }};
 }
@@ -52,112 +44,112 @@ extern "rust-intrinsic" {
 }
 
 fn main() {
-    let x1 = i32x4(1, 2, 3, 4);
+    let x1 = i32x4([1, 2, 3, 4]);
     let y1 = U32::<4>([1, 2, 3, 4]);
-    let z1 = f32x4(1.0, 2.0, 3.0, 4.0);
-    let x2 = i32x4(2, 3, 4, 5);
+    let z1 = f32x4([1.0, 2.0, 3.0, 4.0]);
+    let x2 = i32x4([2, 3, 4, 5]);
     let y2 = U32::<4>([2, 3, 4, 5]);
-    let z2 = f32x4(2.0, 3.0, 4.0, 5.0);
-    let x3 = i32x4(0, i32::MAX, i32::MIN, -1_i32);
+    let z2 = f32x4([2.0, 3.0, 4.0, 5.0]);
+    let x3 = i32x4([0, i32::MAX, i32::MIN, -1_i32]);
     let y3 = U32::<4>([0, i32::MAX as _, i32::MIN as _, -1_i32 as _]);
 
     unsafe {
-        all_eq!(simd_add(x1, x2), i32x4(3, 5, 7, 9));
-        all_eq!(simd_add(x2, x1), i32x4(3, 5, 7, 9));
-        all_eq_!(simd_add(y1, y2), U32::<4>([3, 5, 7, 9]));
-        all_eq_!(simd_add(y2, y1), U32::<4>([3, 5, 7, 9]));
-        all_eq!(simd_add(z1, z2), f32x4(3.0, 5.0, 7.0, 9.0));
-        all_eq!(simd_add(z2, z1), f32x4(3.0, 5.0, 7.0, 9.0));
-
-        all_eq!(simd_mul(x1, x2), i32x4(2, 6, 12, 20));
-        all_eq!(simd_mul(x2, x1), i32x4(2, 6, 12, 20));
-        all_eq_!(simd_mul(y1, y2), U32::<4>([2, 6, 12, 20]));
-        all_eq_!(simd_mul(y2, y1), U32::<4>([2, 6, 12, 20]));
-        all_eq!(simd_mul(z1, z2), f32x4(2.0, 6.0, 12.0, 20.0));
-        all_eq!(simd_mul(z2, z1), f32x4(2.0, 6.0, 12.0, 20.0));
-
-        all_eq!(simd_sub(x2, x1), i32x4(1, 1, 1, 1));
-        all_eq!(simd_sub(x1, x2), i32x4(-1, -1, -1, -1));
-        all_eq_!(simd_sub(y2, y1), U32::<4>([1, 1, 1, 1]));
-        all_eq_!(simd_sub(y1, y2), U32::<4>([!0, !0, !0, !0]));
-        all_eq!(simd_sub(z2, z1), f32x4(1.0, 1.0, 1.0, 1.0));
-        all_eq!(simd_sub(z1, z2), f32x4(-1.0, -1.0, -1.0, -1.0));
-
-        all_eq!(simd_div(x1, x1), i32x4(1, 1, 1, 1));
-        all_eq!(simd_div(i32x4(2, 4, 6, 8), i32x4(2, 2, 2, 2)), x1);
-        all_eq_!(simd_div(y1, y1), U32::<4>([1, 1, 1, 1]));
-        all_eq_!(simd_div(U32::<4>([2, 4, 6, 8]), U32::<4>([2, 2, 2, 2])), y1);
-        all_eq!(simd_div(z1, z1), f32x4(1.0, 1.0, 1.0, 1.0));
-        all_eq!(simd_div(z1, z2), f32x4(1.0 / 2.0, 2.0 / 3.0, 3.0 / 4.0, 4.0 / 5.0));
-        all_eq!(simd_div(z2, z1), f32x4(2.0 / 1.0, 3.0 / 2.0, 4.0 / 3.0, 5.0 / 4.0));
-
-        all_eq!(simd_rem(x1, x1), i32x4(0, 0, 0, 0));
-        all_eq!(simd_rem(x2, x1), i32x4(0, 1, 1, 1));
-        all_eq_!(simd_rem(y1, y1), U32::<4>([0, 0, 0, 0]));
-        all_eq_!(simd_rem(y2, y1), U32::<4>([0, 1, 1, 1]));
-        all_eq!(simd_rem(z1, z1), f32x4(0.0, 0.0, 0.0, 0.0));
+        all_eq!(simd_add(x1, x2), i32x4([3, 5, 7, 9]));
+        all_eq!(simd_add(x2, x1), i32x4([3, 5, 7, 9]));
+        all_eq!(simd_add(y1, y2), U32::<4>([3, 5, 7, 9]));
+        all_eq!(simd_add(y2, y1), U32::<4>([3, 5, 7, 9]));
+        all_eq!(simd_add(z1, z2), f32x4([3.0, 5.0, 7.0, 9.0]));
+        all_eq!(simd_add(z2, z1), f32x4([3.0, 5.0, 7.0, 9.0]));
+
+        all_eq!(simd_mul(x1, x2), i32x4([2, 6, 12, 20]));
+        all_eq!(simd_mul(x2, x1), i32x4([2, 6, 12, 20]));
+        all_eq!(simd_mul(y1, y2), U32::<4>([2, 6, 12, 20]));
+        all_eq!(simd_mul(y2, y1), U32::<4>([2, 6, 12, 20]));
+        all_eq!(simd_mul(z1, z2), f32x4([2.0, 6.0, 12.0, 20.0]));
+        all_eq!(simd_mul(z2, z1), f32x4([2.0, 6.0, 12.0, 20.0]));
+
+        all_eq!(simd_sub(x2, x1), i32x4([1, 1, 1, 1]));
+        all_eq!(simd_sub(x1, x2), i32x4([-1, -1, -1, -1]));
+        all_eq!(simd_sub(y2, y1), U32::<4>([1, 1, 1, 1]));
+        all_eq!(simd_sub(y1, y2), U32::<4>([!0, !0, !0, !0]));
+        all_eq!(simd_sub(z2, z1), f32x4([1.0, 1.0, 1.0, 1.0]));
+        all_eq!(simd_sub(z1, z2), f32x4([-1.0, -1.0, -1.0, -1.0]));
+
+        all_eq!(simd_div(x1, x1), i32x4([1, 1, 1, 1]));
+        all_eq!(simd_div(i32x4([2, 4, 6, 8]), i32x4([2, 2, 2, 2])), x1);
+        all_eq!(simd_div(y1, y1), U32::<4>([1, 1, 1, 1]));
+        all_eq!(simd_div(U32::<4>([2, 4, 6, 8]), U32::<4>([2, 2, 2, 2])), y1);
+        all_eq!(simd_div(z1, z1), f32x4([1.0, 1.0, 1.0, 1.0]));
+        all_eq!(simd_div(z1, z2), f32x4([1.0 / 2.0, 2.0 / 3.0, 3.0 / 4.0, 4.0 / 5.0]));
+        all_eq!(simd_div(z2, z1), f32x4([2.0 / 1.0, 3.0 / 2.0, 4.0 / 3.0, 5.0 / 4.0]));
+
+        all_eq!(simd_rem(x1, x1), i32x4([0, 0, 0, 0]));
+        all_eq!(simd_rem(x2, x1), i32x4([0, 1, 1, 1]));
+        all_eq!(simd_rem(y1, y1), U32::<4>([0, 0, 0, 0]));
+        all_eq!(simd_rem(y2, y1), U32::<4>([0, 1, 1, 1]));
+        all_eq!(simd_rem(z1, z1), f32x4([0.0, 0.0, 0.0, 0.0]));
         all_eq!(simd_rem(z1, z2), z1);
-        all_eq!(simd_rem(z2, z1), f32x4(0.0, 1.0, 1.0, 1.0));
+        all_eq!(simd_rem(z2, z1), f32x4([0.0, 1.0, 1.0, 1.0]));
 
-        all_eq!(simd_shl(x1, x2), i32x4(1 << 2, 2 << 3, 3 << 4, 4 << 5));
-        all_eq!(simd_shl(x2, x1), i32x4(2 << 1, 3 << 2, 4 << 3, 5 << 4));
-        all_eq_!(simd_shl(y1, y2), U32::<4>([1 << 2, 2 << 3, 3 << 4, 4 << 5]));
-        all_eq_!(simd_shl(y2, y1), U32::<4>([2 << 1, 3 << 2, 4 << 3, 5 << 4]));
+        all_eq!(simd_shl(x1, x2), i32x4([1 << 2, 2 << 3, 3 << 4, 4 << 5]));
+        all_eq!(simd_shl(x2, x1), i32x4([2 << 1, 3 << 2, 4 << 3, 5 << 4]));
+        all_eq!(simd_shl(y1, y2), U32::<4>([1 << 2, 2 << 3, 3 << 4, 4 << 5]));
+        all_eq!(simd_shl(y2, y1), U32::<4>([2 << 1, 3 << 2, 4 << 3, 5 << 4]));
 
         // test right-shift by assuming left-shift is correct
         all_eq!(simd_shr(simd_shl(x1, x2), x2), x1);
         all_eq!(simd_shr(simd_shl(x2, x1), x1), x2);
-        all_eq_!(simd_shr(simd_shl(y1, y2), y2), y1);
-        all_eq_!(simd_shr(simd_shl(y2, y1), y1), y2);
+        all_eq!(simd_shr(simd_shl(y1, y2), y2), y1);
+        all_eq!(simd_shr(simd_shl(y2, y1), y1), y2);
 
         // ensure we get logical vs. arithmetic shifts correct
         let (a, b, c, d) = (-12, -123, -1234, -12345);
-        all_eq!(simd_shr(i32x4(a, b, c, d), x1), i32x4(a >> 1, b >> 2, c >> 3, d >> 4));
-        all_eq_!(
+        all_eq!(simd_shr(i32x4([a, b, c, d]), x1), i32x4([a >> 1, b >> 2, c >> 3, d >> 4]));
+        all_eq!(
             simd_shr(U32::<4>([a as u32, b as u32, c as u32, d as u32]), y1),
             U32::<4>([(a as u32) >> 1, (b as u32) >> 2, (c as u32) >> 3, (d as u32) >> 4])
         );
 
-        all_eq!(simd_and(x1, x2), i32x4(0, 2, 0, 4));
-        all_eq!(simd_and(x2, x1), i32x4(0, 2, 0, 4));
-        all_eq_!(simd_and(y1, y2), U32::<4>([0, 2, 0, 4]));
-        all_eq_!(simd_and(y2, y1), U32::<4>([0, 2, 0, 4]));
+        all_eq!(simd_and(x1, x2), i32x4([0, 2, 0, 4]));
+        all_eq!(simd_and(x2, x1), i32x4([0, 2, 0, 4]));
+        all_eq!(simd_and(y1, y2), U32::<4>([0, 2, 0, 4]));
+        all_eq!(simd_and(y2, y1), U32::<4>([0, 2, 0, 4]));
 
-        all_eq!(simd_or(x1, x2), i32x4(3, 3, 7, 5));
-        all_eq!(simd_or(x2, x1), i32x4(3, 3, 7, 5));
-        all_eq_!(simd_or(y1, y2), U32::<4>([3, 3, 7, 5]));
-        all_eq_!(simd_or(y2, y1), U32::<4>([3, 3, 7, 5]));
+        all_eq!(simd_or(x1, x2), i32x4([3, 3, 7, 5]));
+        all_eq!(simd_or(x2, x1), i32x4([3, 3, 7, 5]));
+        all_eq!(simd_or(y1, y2), U32::<4>([3, 3, 7, 5]));
+        all_eq!(simd_or(y2, y1), U32::<4>([3, 3, 7, 5]));
 
-        all_eq!(simd_xor(x1, x2), i32x4(3, 1, 7, 1));
-        all_eq!(simd_xor(x2, x1), i32x4(3, 1, 7, 1));
-        all_eq_!(simd_xor(y1, y2), U32::<4>([3, 1, 7, 1]));
-        all_eq_!(simd_xor(y2, y1), U32::<4>([3, 1, 7, 1]));
+        all_eq!(simd_xor(x1, x2), i32x4([3, 1, 7, 1]));
+        all_eq!(simd_xor(x2, x1), i32x4([3, 1, 7, 1]));
+        all_eq!(simd_xor(y1, y2), U32::<4>([3, 1, 7, 1]));
+        all_eq!(simd_xor(y2, y1), U32::<4>([3, 1, 7, 1]));
 
-        all_eq!(simd_neg(x1), i32x4(-1, -2, -3, -4));
-        all_eq!(simd_neg(x2), i32x4(-2, -3, -4, -5));
-        all_eq!(simd_neg(z1), f32x4(-1.0, -2.0, -3.0, -4.0));
-        all_eq!(simd_neg(z2), f32x4(-2.0, -3.0, -4.0, -5.0));
+        all_eq!(simd_neg(x1), i32x4([-1, -2, -3, -4]));
+        all_eq!(simd_neg(x2), i32x4([-2, -3, -4, -5]));
+        all_eq!(simd_neg(z1), f32x4([-1.0, -2.0, -3.0, -4.0]));
+        all_eq!(simd_neg(z2), f32x4([-2.0, -3.0, -4.0, -5.0]));
 
-        all_eq!(simd_bswap(x1), i32x4(0x01000000, 0x02000000, 0x03000000, 0x04000000));
-        all_eq_!(simd_bswap(y1), U32::<4>([0x01000000, 0x02000000, 0x03000000, 0x04000000]));
+        all_eq!(simd_bswap(x1), i32x4([0x01000000, 0x02000000, 0x03000000, 0x04000000]));
+        all_eq!(simd_bswap(y1), U32::<4>([0x01000000, 0x02000000, 0x03000000, 0x04000000]));
 
         all_eq!(
             simd_bitreverse(x1),
-            i32x4(0x80000000u32 as i32, 0x40000000, 0xc0000000u32 as i32, 0x20000000)
+            i32x4([0x80000000u32 as i32, 0x40000000, 0xc0000000u32 as i32, 0x20000000])
         );
-        all_eq_!(simd_bitreverse(y1), U32::<4>([0x80000000, 0x40000000, 0xc0000000, 0x20000000]));
+        all_eq!(simd_bitreverse(y1), U32::<4>([0x80000000, 0x40000000, 0xc0000000, 0x20000000]));
 
-        all_eq!(simd_ctlz(x1), i32x4(31, 30, 30, 29));
-        all_eq_!(simd_ctlz(y1), U32::<4>([31, 30, 30, 29]));
+        all_eq!(simd_ctlz(x1), i32x4([31, 30, 30, 29]));
+        all_eq!(simd_ctlz(y1), U32::<4>([31, 30, 30, 29]));
 
-        all_eq!(simd_ctpop(x1), i32x4(1, 1, 2, 1));
-        all_eq_!(simd_ctpop(y1), U32::<4>([1, 1, 2, 1]));
-        all_eq!(simd_ctpop(x2), i32x4(1, 2, 1, 2));
-        all_eq_!(simd_ctpop(y2), U32::<4>([1, 2, 1, 2]));
-        all_eq!(simd_ctpop(x3), i32x4(0, 31, 1, 32));
-        all_eq_!(simd_ctpop(y3), U32::<4>([0, 31, 1, 32]));
+        all_eq!(simd_ctpop(x1), i32x4([1, 1, 2, 1]));
+        all_eq!(simd_ctpop(y1), U32::<4>([1, 1, 2, 1]));
+        all_eq!(simd_ctpop(x2), i32x4([1, 2, 1, 2]));
+        all_eq!(simd_ctpop(y2), U32::<4>([1, 2, 1, 2]));
+        all_eq!(simd_ctpop(x3), i32x4([0, 31, 1, 32]));
+        all_eq!(simd_ctpop(y3), U32::<4>([0, 31, 1, 32]));
 
-        all_eq!(simd_cttz(x1), i32x4(0, 1, 0, 2));
-        all_eq_!(simd_cttz(y1), U32::<4>([0, 1, 0, 2]));
+        all_eq!(simd_cttz(x1), i32x4([0, 1, 0, 2]));
+        all_eq!(simd_cttz(y1), U32::<4>([0, 1, 0, 2]));
     }
 }
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs
index 36be8cc62a8..ec6ac78df1a 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs
@@ -4,15 +4,15 @@
 #![allow(non_camel_case_types)]
 #[repr(simd)]
 #[derive(Copy, Clone)]
-pub struct i32x4(pub i32, pub i32, pub i32, pub i32);
+pub struct i32x4(pub [i32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-pub struct x4<T>(pub T, pub T, pub T, pub T);
+pub struct x4<T>(pub [T; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 extern "rust-intrinsic" {
     fn simd_saturating_add<T>(x: T, y: T) -> T;
@@ -20,9 +20,9 @@ extern "rust-intrinsic" {
 }
 
 fn main() {
-    let x = i32x4(0, 0, 0, 0);
-    let y = x4(0_usize, 0, 0, 0);
-    let z = f32x4(0.0, 0.0, 0.0, 0.0);
+    let x = i32x4([0, 0, 0, 0]);
+    let y = x4([0_usize, 0, 0, 0]);
+    let z = f32x4([0.0, 0.0, 0.0, 0.0]);
 
     unsafe {
         simd_saturating_add(x, x);
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
index deee9c2ac41..57bda5c2d62 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
@@ -6,7 +6,7 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-struct u32x4(pub u32, pub u32, pub u32, pub u32);
+struct u32x4(pub [u32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
@@ -22,11 +22,11 @@ fn main() {
     {
         const M: u32 = u32::MAX;
 
-        let a = u32x4(1, 2, 3, 4);
-        let b = u32x4(2, 4, 6, 8);
-        let m = u32x4(M, M, M, M);
-        let m1 = u32x4(M - 1, M - 1, M - 1, M - 1);
-        let z = u32x4(0, 0, 0, 0);
+        let a = u32x4([1, 2, 3, 4]);
+        let b = u32x4([2, 4, 6, 8]);
+        let m = u32x4([M, M, M, M]);
+        let m1 = u32x4([M - 1, M - 1, M - 1, M - 1]);
+        let z = u32x4([0, 0, 0, 0]);
 
         unsafe {
             assert_eq!(simd_saturating_add(z, z), z);
diff --git a/tests/ui/simd/intrinsic/generic-bitmask-pass.rs b/tests/ui/simd/intrinsic/generic-bitmask-pass.rs
index 5c6a07876e3..db10020bd46 100644
--- a/tests/ui/simd/intrinsic/generic-bitmask-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-bitmask-pass.rs
@@ -11,36 +11,36 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-struct u32x4(pub u32, pub u32, pub u32, pub u32);
+struct u32x4(pub [u32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-struct u8x4(pub u8, pub u8, pub u8, pub u8);
+struct u8x4(pub [u8; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-struct Tx4<T>(pub T, pub T, pub T, pub T);
+struct Tx4<T>(pub [T; 4]);
 
 extern "rust-intrinsic" {
     fn simd_bitmask<T, U>(x: T) -> U;
 }
 
 fn main() {
-    let z = u32x4(0, 0, 0, 0);
+    let z = u32x4([0, 0, 0, 0]);
     let ez = 0_u8;
 
-    let o = u32x4(!0, !0, !0, !0);
+    let o = u32x4([!0, !0, !0, !0]);
     let eo = 0b_1111_u8;
 
-    let m0 = u32x4(!0, 0, !0, 0);
+    let m0 = u32x4([!0, 0, !0, 0]);
     let e0 = 0b_0000_0101_u8;
 
     // Check that the MSB is extracted:
-    let m = u8x4(0b_1000_0000, 0b_0100_0001, 0b_1100_0001, 0b_1111_1111);
+    let m = u8x4([0b_1000_0000, 0b_0100_0001, 0b_1100_0001, 0b_1111_1111]);
     let e = 0b_1101;
 
     // Check usize / isize
-    let msize: Tx4<usize> = Tx4(usize::MAX, 0, usize::MAX, usize::MAX);
+    let msize: Tx4<usize> = Tx4([usize::MAX, 0, usize::MAX, usize::MAX]);
 
     unsafe {
         let r: u8 = simd_bitmask(z);
diff --git a/tests/ui/simd/intrinsic/generic-cast.rs b/tests/ui/simd/intrinsic/generic-cast.rs
index f3fdbe3403f..33978a2f739 100644
--- a/tests/ui/simd/intrinsic/generic-cast.rs
+++ b/tests/ui/simd/intrinsic/generic-cast.rs
@@ -5,22 +5,20 @@
 #[repr(simd)]
 #[derive(Copy, Clone)]
 #[allow(non_camel_case_types)]
-struct i32x4(i32, i32, i32, i32);
+struct i32x4([i32; 4]);
 #[repr(simd)]
 #[derive(Copy, Clone)]
 #[allow(non_camel_case_types)]
-struct i32x8(i32, i32, i32, i32,
-             i32, i32, i32, i32);
+struct i32x8([i32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
 #[allow(non_camel_case_types)]
-struct f32x4(f32, f32, f32, f32);
+struct f32x4([f32; 4]);
 #[repr(simd)]
 #[derive(Copy, Clone)]
 #[allow(non_camel_case_types)]
-struct f32x8(f32, f32, f32, f32,
-             f32, f32, f32, f32);
+struct f32x8([f32; 8]);
 
 
 extern "rust-intrinsic" {
@@ -28,7 +26,7 @@ extern "rust-intrinsic" {
 }
 
 fn main() {
-    let x = i32x4(0, 0, 0, 0);
+    let x = i32x4([0, 0, 0, 0]);
 
     unsafe {
         simd_cast::<i32, i32>(0);
diff --git a/tests/ui/simd/intrinsic/generic-cast.stderr b/tests/ui/simd/intrinsic/generic-cast.stderr
index 2226bbbe1bd..2f9d44037af 100644
--- a/tests/ui/simd/intrinsic/generic-cast.stderr
+++ b/tests/ui/simd/intrinsic/generic-cast.stderr
@@ -1,23 +1,23 @@
 error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-cast.rs:34:9
+  --> $DIR/generic-cast.rs:32:9
    |
 LL |         simd_cast::<i32, i32>(0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-cast.rs:36:9
+  --> $DIR/generic-cast.rs:34:9
    |
 LL |         simd_cast::<i32, i32x4>(0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/generic-cast.rs:38:9
+  --> $DIR/generic-cast.rs:36:9
    |
 LL |         simd_cast::<i32x4, i32>(x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_cast` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i32x8` with length 8
-  --> $DIR/generic-cast.rs:40:9
+  --> $DIR/generic-cast.rs:38:9
    |
 LL |         simd_cast::<_, i32x8>(x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/simd/intrinsic/generic-comparison-pass.rs b/tests/ui/simd/intrinsic/generic-comparison-pass.rs
index a4df836b6f8..a4d84a4c534 100644
--- a/tests/ui/simd/intrinsic/generic-comparison-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-comparison-pass.rs
@@ -6,13 +6,13 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct i32x4(i32, i32, i32, i32);
+struct i32x4([i32; 4]);
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct u32x4(pub u32, pub u32, pub u32, pub u32);
+struct u32x4(pub [u32; 4]);
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct f32x4(pub f32, pub f32, pub f32, pub f32);
+struct f32x4(pub [f32; 4]);
 
 extern "rust-intrinsic" {
     fn simd_eq<T, U>(x: T, y: T) -> U;
@@ -29,10 +29,10 @@ macro_rules! cmp {
         let rhs = $rhs;
         let e: u32x4 = concat_idents!(simd_, $method)($lhs, $rhs);
         // assume the scalar version is correct/the behaviour we want.
-        assert!((e.0 != 0) == lhs.0 .$method(&rhs.0));
-        assert!((e.1 != 0) == lhs.1 .$method(&rhs.1));
-        assert!((e.2 != 0) == lhs.2 .$method(&rhs.2));
-        assert!((e.3 != 0) == lhs.3 .$method(&rhs.3));
+        assert!((e.0[0] != 0) == lhs.0[0] .$method(&rhs.0[0]));
+        assert!((e.0[1] != 0) == lhs.0[1] .$method(&rhs.0[1]));
+        assert!((e.0[2] != 0) == lhs.0[2] .$method(&rhs.0[2]));
+        assert!((e.0[3] != 0) == lhs.0[3] .$method(&rhs.0[3]));
     }}
 }
 macro_rules! tests {
@@ -61,17 +61,17 @@ macro_rules! tests {
 fn main() {
     // 13 vs. -100 tests that we get signed vs. unsigned comparisons
     // correct (i32: 13 > -100, u32: 13 < -100).    let i1 = i32x4(10, -11, 12, 13);
-    let i1 = i32x4(10, -11, 12, 13);
-    let i2 = i32x4(5, -5, 20, -100);
-    let i3 = i32x4(10, -11, 20, -100);
+    let i1 = i32x4([10, -11, 12, 13]);
+    let i2 = i32x4([5, -5, 20, -100]);
+    let i3 = i32x4([10, -11, 20, -100]);
 
-    let u1 = u32x4(10, !11+1, 12, 13);
-    let u2 = u32x4(5, !5+1, 20, !100+1);
-    let u3 = u32x4(10, !11+1, 20, !100+1);
+    let u1 = u32x4([10, !11+1, 12, 13]);
+    let u2 = u32x4([5, !5+1, 20, !100+1]);
+    let u3 = u32x4([10, !11+1, 20, !100+1]);
 
-    let f1 = f32x4(10.0, -11.0, 12.0, 13.0);
-    let f2 = f32x4(5.0, -5.0, 20.0, -100.0);
-    let f3 = f32x4(10.0, -11.0, 20.0, -100.0);
+    let f1 = f32x4([10.0, -11.0, 12.0, 13.0]);
+    let f2 = f32x4([5.0, -5.0, 20.0, -100.0]);
+    let f3 = f32x4([10.0, -11.0, 20.0, -100.0]);
 
     unsafe {
         tests! {
@@ -92,7 +92,7 @@ fn main() {
     // NAN comparisons are special:
     // -11 (*)    13
     // -5        -100 (*)
-    let f4 = f32x4(f32::NAN, f1.1, f32::NAN, f2.3);
+    let f4 = f32x4([f32::NAN, f1.0[1], f32::NAN, f2.0[3]]);
 
     unsafe {
         tests! {
diff --git a/tests/ui/simd/intrinsic/generic-comparison.rs b/tests/ui/simd/intrinsic/generic-comparison.rs
index bb2720f615f..f7f0655f3d2 100644
--- a/tests/ui/simd/intrinsic/generic-comparison.rs
+++ b/tests/ui/simd/intrinsic/generic-comparison.rs
@@ -5,12 +5,11 @@
 #[repr(simd)]
 #[derive(Copy, Clone)]
 #[allow(non_camel_case_types)]
-struct i32x4(i32, i32, i32, i32);
+struct i32x4([i32; 4]);
 #[repr(simd)]
 #[derive(Copy, Clone)]
 #[allow(non_camel_case_types)]
-struct i16x8(i16, i16, i16, i16,
-             i16, i16, i16, i16);
+struct i16x8([i16; 8]);
 
 extern "rust-intrinsic" {
     fn simd_eq<T, U>(x: T, y: T) -> U;
@@ -22,7 +21,7 @@ extern "rust-intrinsic" {
 }
 
 fn main() {
-    let x = i32x4(0, 0, 0, 0);
+    let x = i32x4([0, 0, 0, 0]);
 
     unsafe {
         simd_eq::<i32, i32>(0, 0);
diff --git a/tests/ui/simd/intrinsic/generic-comparison.stderr b/tests/ui/simd/intrinsic/generic-comparison.stderr
index 0eae2688bce..ac4d4918827 100644
--- a/tests/ui/simd/intrinsic/generic-comparison.stderr
+++ b/tests/ui/simd/intrinsic/generic-comparison.stderr
@@ -1,107 +1,107 @@
 error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:28:9
+  --> $DIR/generic-comparison.rs:27:9
    |
 LL |         simd_eq::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:30:9
+  --> $DIR/generic-comparison.rs:29:9
    |
 LL |         simd_ne::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:32:9
+  --> $DIR/generic-comparison.rs:31:9
    |
 LL |         simd_lt::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:34:9
+  --> $DIR/generic-comparison.rs:33:9
    |
 LL |         simd_le::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:36:9
+  --> $DIR/generic-comparison.rs:35:9
    |
 LL |         simd_gt::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:38:9
+  --> $DIR/generic-comparison.rs:37:9
    |
 LL |         simd_ge::<i32, i32>(0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:41:9
+  --> $DIR/generic-comparison.rs:40:9
    |
 LL |         simd_eq::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:43:9
+  --> $DIR/generic-comparison.rs:42:9
    |
 LL |         simd_ne::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:45:9
+  --> $DIR/generic-comparison.rs:44:9
    |
 LL |         simd_lt::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:47:9
+  --> $DIR/generic-comparison.rs:46:9
    |
 LL |         simd_le::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:49:9
+  --> $DIR/generic-comparison.rs:48:9
    |
 LL |         simd_gt::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected SIMD return type, found non-SIMD `i32`
-  --> $DIR/generic-comparison.rs:51:9
+  --> $DIR/generic-comparison.rs:50:9
    |
 LL |         simd_ge::<_, i32>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_eq` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/generic-comparison.rs:54:9
+  --> $DIR/generic-comparison.rs:53:9
    |
 LL |         simd_eq::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ne` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/generic-comparison.rs:56:9
+  --> $DIR/generic-comparison.rs:55:9
    |
 LL |         simd_ne::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_lt` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/generic-comparison.rs:58:9
+  --> $DIR/generic-comparison.rs:57:9
    |
 LL |         simd_lt::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_le` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/generic-comparison.rs:60:9
+  --> $DIR/generic-comparison.rs:59:9
    |
 LL |         simd_le::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_gt` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/generic-comparison.rs:62:9
+  --> $DIR/generic-comparison.rs:61:9
    |
 LL |         simd_gt::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_ge` intrinsic: expected return type with length 4 (same as input type `i32x4`), found `i16x8` with length 8
-  --> $DIR/generic-comparison.rs:64:9
+  --> $DIR/generic-comparison.rs:63:9
    |
 LL |         simd_ge::<_, i16x8>(x, x);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/simd/intrinsic/generic-elements-pass.rs b/tests/ui/simd/intrinsic/generic-elements-pass.rs
index a81d8ebdf50..b159387ab62 100644
--- a/tests/ui/simd/intrinsic/generic-elements-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-elements-pass.rs
@@ -6,16 +6,15 @@
 #[repr(simd)]
 #[derive(Copy, Clone, Debug, PartialEq)]
 #[allow(non_camel_case_types)]
-struct i32x2(i32, i32);
+struct i32x2([i32; 2]);
 #[repr(simd)]
 #[derive(Copy, Clone, Debug, PartialEq)]
 #[allow(non_camel_case_types)]
-struct i32x4(i32, i32, i32, i32);
+struct i32x4([i32; 4]);
 #[repr(simd)]
 #[derive(Copy, Clone, Debug, PartialEq)]
 #[allow(non_camel_case_types)]
-struct i32x8(i32, i32, i32, i32,
-             i32, i32, i32, i32);
+struct i32x8([i32; 8]);
 
 extern "rust-intrinsic" {
     fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
@@ -37,26 +36,26 @@ macro_rules! all_eq {
 }
 
 fn main() {
-    let x2 = i32x2(20, 21);
-    let x4 = i32x4(40, 41, 42, 43);
-    let x8 = i32x8(80, 81, 82, 83, 84, 85, 86, 87);
+    let x2 = i32x2([20, 21]);
+    let x4 = i32x4([40, 41, 42, 43]);
+    let x8 = i32x8([80, 81, 82, 83, 84, 85, 86, 87]);
     unsafe {
-        all_eq!(simd_insert(x2, 0, 100), i32x2(100, 21));
-        all_eq!(simd_insert(x2, 1, 100), i32x2(20, 100));
+        all_eq!(simd_insert(x2, 0, 100), i32x2([100, 21]));
+        all_eq!(simd_insert(x2, 1, 100), i32x2([20, 100]));
 
-        all_eq!(simd_insert(x4, 0, 100), i32x4(100, 41, 42, 43));
-        all_eq!(simd_insert(x4, 1, 100), i32x4(40, 100, 42, 43));
-        all_eq!(simd_insert(x4, 2, 100), i32x4(40, 41, 100, 43));
-        all_eq!(simd_insert(x4, 3, 100), i32x4(40, 41, 42, 100));
+        all_eq!(simd_insert(x4, 0, 100), i32x4([100, 41, 42, 43]));
+        all_eq!(simd_insert(x4, 1, 100), i32x4([40, 100, 42, 43]));
+        all_eq!(simd_insert(x4, 2, 100), i32x4([40, 41, 100, 43]));
+        all_eq!(simd_insert(x4, 3, 100), i32x4([40, 41, 42, 100]));
 
-        all_eq!(simd_insert(x8, 0, 100), i32x8(100, 81, 82, 83, 84, 85, 86, 87));
-        all_eq!(simd_insert(x8, 1, 100), i32x8(80, 100, 82, 83, 84, 85, 86, 87));
-        all_eq!(simd_insert(x8, 2, 100), i32x8(80, 81, 100, 83, 84, 85, 86, 87));
-        all_eq!(simd_insert(x8, 3, 100), i32x8(80, 81, 82, 100, 84, 85, 86, 87));
-        all_eq!(simd_insert(x8, 4, 100), i32x8(80, 81, 82, 83, 100, 85, 86, 87));
-        all_eq!(simd_insert(x8, 5, 100), i32x8(80, 81, 82, 83, 84, 100, 86, 87));
-        all_eq!(simd_insert(x8, 6, 100), i32x8(80, 81, 82, 83, 84, 85, 100, 87));
-        all_eq!(simd_insert(x8, 7, 100), i32x8(80, 81, 82, 83, 84, 85, 86, 100));
+        all_eq!(simd_insert(x8, 0, 100), i32x8([100, 81, 82, 83, 84, 85, 86, 87]));
+        all_eq!(simd_insert(x8, 1, 100), i32x8([80, 100, 82, 83, 84, 85, 86, 87]));
+        all_eq!(simd_insert(x8, 2, 100), i32x8([80, 81, 100, 83, 84, 85, 86, 87]));
+        all_eq!(simd_insert(x8, 3, 100), i32x8([80, 81, 82, 100, 84, 85, 86, 87]));
+        all_eq!(simd_insert(x8, 4, 100), i32x8([80, 81, 82, 83, 100, 85, 86, 87]));
+        all_eq!(simd_insert(x8, 5, 100), i32x8([80, 81, 82, 83, 84, 100, 86, 87]));
+        all_eq!(simd_insert(x8, 6, 100), i32x8([80, 81, 82, 83, 84, 85, 100, 87]));
+        all_eq!(simd_insert(x8, 7, 100), i32x8([80, 81, 82, 83, 84, 85, 86, 100]));
 
         all_eq!(simd_extract(x2, 0), 20);
         all_eq!(simd_extract(x2, 1), 21);
@@ -76,24 +75,24 @@ fn main() {
         all_eq!(simd_extract(x8, 7), 87);
     }
 
-    let y2 = i32x2(120, 121);
-    let y4 = i32x4(140, 141, 142, 143);
-    let y8 = i32x8(180, 181, 182, 183, 184, 185, 186, 187);
+    let y2 = i32x2([120, 121]);
+    let y4 = i32x4([140, 141, 142, 143]);
+    let y8 = i32x8([180, 181, 182, 183, 184, 185, 186, 187]);
     unsafe {
-        all_eq!(simd_shuffle(x2, y2, const { [3u32, 0] }), i32x2(121, 20));
-        all_eq!(simd_shuffle(x2, y2, const { [3u32, 0, 1, 2] }), i32x4(121, 20, 21, 120));
+        all_eq!(simd_shuffle(x2, y2, const { [3u32, 0] }), i32x2([121, 20]));
+        all_eq!(simd_shuffle(x2, y2, const { [3u32, 0, 1, 2] }), i32x4([121, 20, 21, 120]));
         all_eq!(simd_shuffle(x2, y2, const { [3u32, 0, 1, 2, 1, 2, 3, 0] }),
-                i32x8(121, 20, 21, 120, 21, 120, 121, 20));
+                i32x8([121, 20, 21, 120, 21, 120, 121, 20]));
 
-        all_eq!(simd_shuffle(x4, y4, const { [7u32, 2] }), i32x2(143, 42));
-        all_eq!(simd_shuffle(x4, y4, const { [7u32, 2, 5, 0] }), i32x4(143, 42, 141, 40));
+        all_eq!(simd_shuffle(x4, y4, const { [7u32, 2] }), i32x2([143, 42]));
+        all_eq!(simd_shuffle(x4, y4, const { [7u32, 2, 5, 0] }), i32x4([143, 42, 141, 40]));
         all_eq!(simd_shuffle(x4, y4, const { [7u32, 2, 5, 0, 3, 6, 4, 1] }),
-                i32x8(143, 42, 141, 40, 43, 142, 140, 41));
+                i32x8([143, 42, 141, 40, 43, 142, 140, 41]));
 
-        all_eq!(simd_shuffle(x8, y8, const { [11u32, 5] }), i32x2(183, 85));
-        all_eq!(simd_shuffle(x8, y8, const { [11u32, 5, 15, 0] }), i32x4(183, 85, 187, 80));
+        all_eq!(simd_shuffle(x8, y8, const { [11u32, 5] }), i32x2([183, 85]));
+        all_eq!(simd_shuffle(x8, y8, const { [11u32, 5, 15, 0] }), i32x4([183, 85, 187, 80]));
         all_eq!(simd_shuffle(x8, y8, const { [11u32, 5, 15, 0, 3, 8, 12, 1] }),
-                i32x8(183, 85, 187, 80, 83, 180, 184, 81));
+                i32x8([183, 85, 187, 80, 83, 180, 184, 81]));
     }
 
 }
diff --git a/tests/ui/simd/intrinsic/generic-elements.rs b/tests/ui/simd/intrinsic/generic-elements.rs
index aec75a67306..4848fd1b803 100644
--- a/tests/ui/simd/intrinsic/generic-elements.rs
+++ b/tests/ui/simd/intrinsic/generic-elements.rs
@@ -6,28 +6,28 @@
 #[repr(simd)]
 #[derive(Copy, Clone)]
 #[allow(non_camel_case_types)]
-struct i32x2(i32, i32);
+struct i32x2([i32; 2]);
 #[repr(simd)]
 #[derive(Copy, Clone)]
 #[allow(non_camel_case_types)]
-struct i32x4(i32, i32, i32, i32);
+struct i32x4([i32; 4]);
 #[repr(simd)]
 #[derive(Copy, Clone)]
 #[allow(non_camel_case_types)]
-struct i32x8(i32, i32, i32, i32, i32, i32, i32, i32);
+struct i32x8([i32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
 #[allow(non_camel_case_types)]
-struct f32x2(f32, f32);
+struct f32x2([f32; 2]);
 #[repr(simd)]
 #[derive(Copy, Clone)]
 #[allow(non_camel_case_types)]
-struct f32x4(f32, f32, f32, f32);
+struct f32x4([f32; 4]);
 #[repr(simd)]
 #[derive(Copy, Clone)]
 #[allow(non_camel_case_types)]
-struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32);
+struct f32x8([f32; 8]);
 
 extern "rust-intrinsic" {
     fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
@@ -38,7 +38,7 @@ extern "rust-intrinsic" {
 }
 
 fn main() {
-    let x = i32x4(0, 0, 0, 0);
+    let x = i32x4([0, 0, 0, 0]);
 
     unsafe {
         simd_insert(0, 0, 0);
diff --git a/tests/ui/simd/intrinsic/generic-gather-pass.rs b/tests/ui/simd/intrinsic/generic-gather-pass.rs
index a00bc67e73b..3315d1cdaa2 100644
--- a/tests/ui/simd/intrinsic/generic-gather-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-gather-pass.rs
@@ -8,7 +8,7 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-struct x4<T>(pub T, pub T, pub T, pub T);
+struct x4<T>(pub [T; 4]);
 
 extern "rust-intrinsic" {
     fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
@@ -18,19 +18,19 @@ extern "rust-intrinsic" {
 fn main() {
     let mut x = [0_f32, 1., 2., 3., 4., 5., 6., 7.];
 
-    let default = x4(-3_f32, -3., -3., -3.);
-    let s_strided = x4(0_f32, 2., -3., 6.);
-    let mask = x4(-1_i32, -1, 0, -1);
+    let default = x4([-3_f32, -3., -3., -3.]);
+    let s_strided = x4([0_f32, 2., -3., 6.]);
+    let mask = x4([-1_i32, -1, 0, -1]);
 
     // reading from *const
     unsafe {
         let pointer = x.as_ptr();
-        let pointers =  x4(
+        let pointers =  x4([
             pointer.offset(0),
             pointer.offset(2),
             pointer.offset(4),
             pointer.offset(6)
-        );
+        ]);
 
         let r_strided = simd_gather(default, pointers, mask);
 
@@ -40,12 +40,12 @@ fn main() {
     // reading from *mut
     unsafe {
         let pointer = x.as_mut_ptr();
-        let pointers = x4(
+        let pointers = x4([
             pointer.offset(0),
             pointer.offset(2),
             pointer.offset(4),
             pointer.offset(6)
-        );
+        ]);
 
         let r_strided = simd_gather(default, pointers, mask);
 
@@ -55,14 +55,14 @@ fn main() {
     // writing to *mut
     unsafe {
         let pointer = x.as_mut_ptr();
-        let pointers = x4(
+        let pointers = x4([
             pointer.offset(0),
             pointer.offset(2),
             pointer.offset(4),
             pointer.offset(6)
-        );
+        ]);
 
-        let values = x4(42_f32, 43_f32, 44_f32, 45_f32);
+        let values = x4([42_f32, 43_f32, 44_f32, 45_f32]);
         simd_scatter(values, pointers, mask);
 
         assert_eq!(x, [42., 1., 43., 3., 4., 5., 45., 7.]);
@@ -80,18 +80,18 @@ fn main() {
         &x[7] as *const f32
     ];
 
-    let default = x4(y[0], y[0], y[0], y[0]);
-    let s_strided = x4(y[0], y[2], y[0], y[6]);
+    let default = x4([y[0], y[0], y[0], y[0]]);
+    let s_strided = x4([y[0], y[2], y[0], y[6]]);
 
     // reading from *const
     unsafe {
         let pointer = y.as_ptr();
-        let pointers = x4(
+        let pointers = x4([
             pointer.offset(0),
             pointer.offset(2),
             pointer.offset(4),
             pointer.offset(6)
-        );
+        ]);
 
         let r_strided = simd_gather(default, pointers, mask);
 
@@ -101,12 +101,12 @@ fn main() {
     // reading from *mut
     unsafe {
         let pointer = y.as_mut_ptr();
-        let pointers = x4(
+        let pointers = x4([
             pointer.offset(0),
             pointer.offset(2),
             pointer.offset(4),
             pointer.offset(6)
-        );
+        ]);
 
         let r_strided = simd_gather(default, pointers, mask);
 
@@ -116,14 +116,14 @@ fn main() {
     // writing to *mut
     unsafe {
         let pointer = y.as_mut_ptr();
-        let pointers = x4(
+        let pointers = x4([
             pointer.offset(0),
             pointer.offset(2),
             pointer.offset(4),
             pointer.offset(6)
-        );
+        ]);
 
-        let values = x4(y[7], y[6], y[5], y[1]);
+        let values = x4([y[7], y[6], y[5], y[1]]);
         simd_scatter(values, pointers, mask);
 
         let s = [
diff --git a/tests/ui/simd/intrinsic/generic-reduction-pass.rs b/tests/ui/simd/intrinsic/generic-reduction-pass.rs
index 64902788709..699fb396259 100644
--- a/tests/ui/simd/intrinsic/generic-reduction-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-reduction-pass.rs
@@ -10,19 +10,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct i32x4(pub i32, pub i32, pub i32, pub i32);
+struct i32x4(pub [i32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct u32x4(pub u32, pub u32, pub u32, pub u32);
+struct u32x4(pub [u32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct f32x4(pub f32, pub f32, pub f32, pub f32);
+struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-struct b8x4(pub i8, pub i8, pub i8, pub i8);
+struct b8x4(pub [i8; 4]);
 
 extern "rust-intrinsic" {
     fn simd_reduce_add_unordered<T, U>(x: T) -> U;
@@ -40,7 +40,7 @@ extern "rust-intrinsic" {
 
 fn main() {
     unsafe {
-        let x = i32x4(1, -2, 3, 4);
+        let x = i32x4([1, -2, 3, 4]);
         let r: i32 = simd_reduce_add_unordered(x);
         assert_eq!(r, 6_i32);
         let r: i32 = simd_reduce_mul_unordered(x);
@@ -55,7 +55,7 @@ fn main() {
         let r: i32 = simd_reduce_max(x);
         assert_eq!(r, 4_i32);
 
-        let x = i32x4(-1, -1, -1, -1);
+        let x = i32x4([-1, -1, -1, -1]);
         let r: i32 = simd_reduce_and(x);
         assert_eq!(r, -1_i32);
         let r: i32 = simd_reduce_or(x);
@@ -63,7 +63,7 @@ fn main() {
         let r: i32 = simd_reduce_xor(x);
         assert_eq!(r, 0_i32);
 
-        let x = i32x4(-1, -1, 0, -1);
+        let x = i32x4([-1, -1, 0, -1]);
         let r: i32 = simd_reduce_and(x);
         assert_eq!(r, 0_i32);
         let r: i32 = simd_reduce_or(x);
@@ -73,7 +73,7 @@ fn main() {
     }
 
     unsafe {
-        let x = u32x4(1, 2, 3, 4);
+        let x = u32x4([1, 2, 3, 4]);
         let r: u32 = simd_reduce_add_unordered(x);
         assert_eq!(r, 10_u32);
         let r: u32 = simd_reduce_mul_unordered(x);
@@ -89,7 +89,7 @@ fn main() {
         assert_eq!(r, 4_u32);
 
         let t = u32::MAX;
-        let x = u32x4(t, t, t, t);
+        let x = u32x4([t, t, t, t]);
         let r: u32 = simd_reduce_and(x);
         assert_eq!(r, t);
         let r: u32 = simd_reduce_or(x);
@@ -97,7 +97,7 @@ fn main() {
         let r: u32 = simd_reduce_xor(x);
         assert_eq!(r, 0_u32);
 
-        let x = u32x4(t, t, 0, t);
+        let x = u32x4([t, t, 0, t]);
         let r: u32 = simd_reduce_and(x);
         assert_eq!(r, 0_u32);
         let r: u32 = simd_reduce_or(x);
@@ -107,7 +107,7 @@ fn main() {
     }
 
     unsafe {
-        let x = f32x4(1., -2., 3., 4.);
+        let x = f32x4([1., -2., 3., 4.]);
         let r: f32 = simd_reduce_add_unordered(x);
         assert_eq!(r, 6_f32);
         let r: f32 = simd_reduce_mul_unordered(x);
@@ -128,19 +128,19 @@ fn main() {
     }
 
     unsafe {
-        let x = b8x4(!0, !0, !0, !0);
+        let x = b8x4([!0, !0, !0, !0]);
         let r: bool = simd_reduce_all(x);
         assert_eq!(r, true);
         let r: bool = simd_reduce_any(x);
         assert_eq!(r, true);
 
-        let x = b8x4(!0, !0, 0, !0);
+        let x = b8x4([!0, !0, 0, !0]);
         let r: bool = simd_reduce_all(x);
         assert_eq!(r, false);
         let r: bool = simd_reduce_any(x);
         assert_eq!(r, true);
 
-        let x = b8x4(0, 0, 0, 0);
+        let x = b8x4([0, 0, 0, 0]);
         let r: bool = simd_reduce_all(x);
         assert_eq!(r, false);
         let r: bool = simd_reduce_any(x);
diff --git a/tests/ui/simd/intrinsic/generic-reduction.rs b/tests/ui/simd/intrinsic/generic-reduction.rs
index 96df7359169..1986deafb6a 100644
--- a/tests/ui/simd/intrinsic/generic-reduction.rs
+++ b/tests/ui/simd/intrinsic/generic-reduction.rs
@@ -9,11 +9,11 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
+pub struct u32x4(pub [u32; 4]);
 
 
 extern "rust-intrinsic" {
@@ -27,8 +27,8 @@ extern "rust-intrinsic" {
 }
 
 fn main() {
-    let x = u32x4(0, 0, 0, 0);
-    let z = f32x4(0.0, 0.0, 0.0, 0.0);
+    let x = u32x4([0, 0, 0, 0]);
+    let z = f32x4([0.0, 0.0, 0.0, 0.0]);
 
     unsafe {
         simd_reduce_add_ordered(z, 0);
diff --git a/tests/ui/simd/intrinsic/generic-select-pass.rs b/tests/ui/simd/intrinsic/generic-select-pass.rs
index 98e1534e6e6..5690bad5048 100644
--- a/tests/ui/simd/intrinsic/generic-select-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-select-pass.rs
@@ -11,23 +11,23 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-struct i32x4(pub i32, pub i32, pub i32, pub i32);
+struct i32x4(pub [i32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-struct u32x4(pub u32, pub u32, pub u32, pub u32);
+struct u32x4(pub [u32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-struct u32x8(u32, u32, u32, u32, u32, u32, u32, u32);
+struct u32x8([u32; 8]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-struct f32x4(pub f32, pub f32, pub f32, pub f32);
+struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-struct b8x4(pub i8, pub i8, pub i8, pub i8);
+struct b8x4(pub [i8; 4]);
 
 extern "rust-intrinsic" {
     fn simd_select<T, U>(x: T, a: U, b: U) -> U;
@@ -35,15 +35,15 @@ extern "rust-intrinsic" {
 }
 
 fn main() {
-    let m0 = b8x4(!0, !0, !0, !0);
-    let m1 = b8x4(0, 0, 0, 0);
-    let m2 = b8x4(!0, !0, 0, 0);
-    let m3 = b8x4(0, 0, !0, !0);
-    let m4 = b8x4(!0, 0, !0, 0);
+    let m0 = b8x4([!0, !0, !0, !0]);
+    let m1 = b8x4([0, 0, 0, 0]);
+    let m2 = b8x4([!0, !0, 0, 0]);
+    let m3 = b8x4([0, 0, !0, !0]);
+    let m4 = b8x4([!0, 0, !0, 0]);
 
     unsafe {
-        let a = i32x4(1, -2, 3, 4);
-        let b = i32x4(5, 6, -7, 8);
+        let a = i32x4([1, -2, 3, 4]);
+        let b = i32x4([5, 6, -7, 8]);
 
         let r: i32x4 = simd_select(m0, a, b);
         let e = a;
@@ -54,21 +54,21 @@ fn main() {
         assert_eq!(r, e);
 
         let r: i32x4 = simd_select(m2, a, b);
-        let e = i32x4(1, -2, -7, 8);
+        let e = i32x4([1, -2, -7, 8]);
         assert_eq!(r, e);
 
         let r: i32x4 = simd_select(m3, a, b);
-        let e = i32x4(5, 6, 3, 4);
+        let e = i32x4([5, 6, 3, 4]);
         assert_eq!(r, e);
 
         let r: i32x4 = simd_select(m4, a, b);
-        let e = i32x4(1, 6, 3, 8);
+        let e = i32x4([1, 6, 3, 8]);
         assert_eq!(r, e);
     }
 
     unsafe {
-        let a = u32x4(1, 2, 3, 4);
-        let b = u32x4(5, 6, 7, 8);
+        let a = u32x4([1, 2, 3, 4]);
+        let b = u32x4([5, 6, 7, 8]);
 
         let r: u32x4 = simd_select(m0, a, b);
         let e = a;
@@ -79,21 +79,21 @@ fn main() {
         assert_eq!(r, e);
 
         let r: u32x4 = simd_select(m2, a, b);
-        let e = u32x4(1, 2, 7, 8);
+        let e = u32x4([1, 2, 7, 8]);
         assert_eq!(r, e);
 
         let r: u32x4 = simd_select(m3, a, b);
-        let e = u32x4(5, 6, 3, 4);
+        let e = u32x4([5, 6, 3, 4]);
         assert_eq!(r, e);
 
         let r: u32x4 = simd_select(m4, a, b);
-        let e = u32x4(1, 6, 3, 8);
+        let e = u32x4([1, 6, 3, 8]);
         assert_eq!(r, e);
     }
 
     unsafe {
-        let a = f32x4(1., 2., 3., 4.);
-        let b = f32x4(5., 6., 7., 8.);
+        let a = f32x4([1., 2., 3., 4.]);
+        let b = f32x4([5., 6., 7., 8.]);
 
         let r: f32x4 = simd_select(m0, a, b);
         let e = a;
@@ -104,23 +104,23 @@ fn main() {
         assert_eq!(r, e);
 
         let r: f32x4 = simd_select(m2, a, b);
-        let e = f32x4(1., 2., 7., 8.);
+        let e = f32x4([1., 2., 7., 8.]);
         assert_eq!(r, e);
 
         let r: f32x4 = simd_select(m3, a, b);
-        let e = f32x4(5., 6., 3., 4.);
+        let e = f32x4([5., 6., 3., 4.]);
         assert_eq!(r, e);
 
         let r: f32x4 = simd_select(m4, a, b);
-        let e = f32x4(1., 6., 3., 8.);
+        let e = f32x4([1., 6., 3., 8.]);
         assert_eq!(r, e);
     }
 
     unsafe {
         let t = !0 as i8;
         let f = 0 as i8;
-        let a = b8x4(t, f, t, f);
-        let b = b8x4(f, f, f, t);
+        let a = b8x4([t, f, t, f]);
+        let b = b8x4([f, f, f, t]);
 
         let r: b8x4 = simd_select(m0, a, b);
         let e = a;
@@ -131,21 +131,21 @@ fn main() {
         assert_eq!(r, e);
 
         let r: b8x4 = simd_select(m2, a, b);
-        let e = b8x4(t, f, f, t);
+        let e = b8x4([t, f, f, t]);
         assert_eq!(r, e);
 
         let r: b8x4 = simd_select(m3, a, b);
-        let e = b8x4(f, f, t, f);
+        let e = b8x4([f, f, t, f]);
         assert_eq!(r, e);
 
         let r: b8x4 = simd_select(m4, a, b);
-        let e = b8x4(t, f, t, t);
+        let e = b8x4([t, f, t, t]);
         assert_eq!(r, e);
     }
 
     unsafe {
-        let a = u32x8(0, 1, 2, 3, 4, 5, 6, 7);
-        let b = u32x8(8, 9, 10, 11, 12, 13, 14, 15);
+        let a = u32x8([0, 1, 2, 3, 4, 5, 6, 7]);
+        let b = u32x8([8, 9, 10, 11, 12, 13, 14, 15]);
 
         let r: u32x8 = simd_select_bitmask(0u8, a, b);
         let e = b;
@@ -156,21 +156,21 @@ fn main() {
         assert_eq!(r, e);
 
         let r: u32x8 = simd_select_bitmask(0b01010101u8, a, b);
-        let e = u32x8(0, 9, 2, 11, 4, 13, 6, 15);
+        let e = u32x8([0, 9, 2, 11, 4, 13, 6, 15]);
         assert_eq!(r, e);
 
         let r: u32x8 = simd_select_bitmask(0b10101010u8, a, b);
-        let e = u32x8(8, 1, 10, 3, 12, 5, 14, 7);
+        let e = u32x8([8, 1, 10, 3, 12, 5, 14, 7]);
         assert_eq!(r, e);
 
         let r: u32x8 = simd_select_bitmask(0b11110000u8, a, b);
-        let e = u32x8(8, 9, 10, 11, 4, 5, 6, 7);
+        let e = u32x8([8, 9, 10, 11, 4, 5, 6, 7]);
         assert_eq!(r, e);
     }
 
     unsafe {
-        let a = u32x4(0, 1, 2, 3);
-        let b = u32x4(4, 5, 6, 7);
+        let a = u32x4([0, 1, 2, 3]);
+        let b = u32x4([4, 5, 6, 7]);
 
         let r: u32x4 = simd_select_bitmask(0u8, a, b);
         let e = b;
@@ -181,15 +181,15 @@ fn main() {
         assert_eq!(r, e);
 
         let r: u32x4 = simd_select_bitmask(0b0101u8, a, b);
-        let e = u32x4(0, 5, 2, 7);
+        let e = u32x4([0, 5, 2, 7]);
         assert_eq!(r, e);
 
         let r: u32x4 = simd_select_bitmask(0b1010u8, a, b);
-        let e = u32x4(4, 1, 6, 3);
+        let e = u32x4([4, 1, 6, 3]);
         assert_eq!(r, e);
 
         let r: u32x4 = simd_select_bitmask(0b1100u8, a, b);
-        let e = u32x4(4, 5, 2, 3);
+        let e = u32x4([4, 5, 2, 3]);
         assert_eq!(r, e);
     }
 }
diff --git a/tests/ui/simd/intrinsic/generic-select.rs b/tests/ui/simd/intrinsic/generic-select.rs
index 215ae405c37..52e02649590 100644
--- a/tests/ui/simd/intrinsic/generic-select.rs
+++ b/tests/ui/simd/intrinsic/generic-select.rs
@@ -8,19 +8,19 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
+pub struct f32x4(pub [f32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
-pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
+pub struct u32x4(pub [u32; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq)]
-struct b8x4(pub i8, pub i8, pub i8, pub i8);
+struct b8x4(pub [i8; 4]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq)]
-struct b8x8(pub i8, pub i8, pub i8, pub i8, pub i8, pub i8, pub i8, pub i8);
+struct b8x8(pub [i8; 8]);
 
 extern "rust-intrinsic" {
     fn simd_select<T, U>(x: T, a: U, b: U) -> U;
@@ -28,10 +28,10 @@ extern "rust-intrinsic" {
 }
 
 fn main() {
-    let m4 = b8x4(0, 0, 0, 0);
-    let m8 = b8x8(0, 0, 0, 0, 0, 0, 0, 0);
-    let x = u32x4(0, 0, 0, 0);
-    let z = f32x4(0.0, 0.0, 0.0, 0.0);
+    let m4 = b8x4([0, 0, 0, 0]);
+    let m8 = b8x8([0, 0, 0, 0, 0, 0, 0, 0]);
+    let x = u32x4([0, 0, 0, 0]);
+    let z = f32x4([0.0, 0.0, 0.0, 0.0]);
 
     unsafe {
         simd_select(m4, x, x);
diff --git a/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs b/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs
index 928d3824703..a64a7c0b48a 100644
--- a/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs
+++ b/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs
@@ -11,7 +11,7 @@ extern "rust-intrinsic" {
 
 #[repr(simd)]
 #[derive(Debug, PartialEq)]
-struct Simd2(u8, u8);
+struct Simd2([u8; 2]);
 
 fn main() {
     unsafe {
@@ -22,5 +22,5 @@ fn main() {
 #[inline(always)]
 unsafe fn inline_me() -> Simd2 {
     const IDX: [u32; 2] = [0, 3];
-    simd_shuffle(Simd2(10, 11), Simd2(12, 13), IDX)
+    simd_shuffle(Simd2([10, 11]), Simd2([12, 13]), IDX)
 }
diff --git a/tests/ui/simd/intrinsic/inlining-issue67557.rs b/tests/ui/simd/intrinsic/inlining-issue67557.rs
index b8b8dbba547..cb80d65d468 100644
--- a/tests/ui/simd/intrinsic/inlining-issue67557.rs
+++ b/tests/ui/simd/intrinsic/inlining-issue67557.rs
@@ -11,12 +11,12 @@ extern "rust-intrinsic" {
 
 #[repr(simd)]
 #[derive(Debug, PartialEq)]
-struct Simd2(u8, u8);
+struct Simd2([u8; 2]);
 
 fn main() {
     unsafe {
         const IDX: [u32; 2] = [0, 1];
-        let p_res: Simd2 = simd_shuffle(Simd2(10, 11), Simd2(12, 13), IDX);
+        let p_res: Simd2 = simd_shuffle(Simd2([10, 11]), Simd2([12, 13]), IDX);
         let a_res: Simd2 = inline_me();
 
         assert_10_11(p_res);
@@ -26,17 +26,17 @@ fn main() {
 
 #[inline(never)]
 fn assert_10_11(x: Simd2) {
-    assert_eq!(x, Simd2(10, 11));
+    assert_eq!(x, Simd2([10, 11]));
 }
 
 #[inline(never)]
 fn assert_10_13(x: Simd2) {
-    assert_eq!(x, Simd2(10, 13));
+    assert_eq!(x, Simd2([10, 13]));
 }
 
 
 #[inline(always)]
 unsafe fn inline_me() -> Simd2 {
     const IDX: [u32; 2] = [0, 3];
-    simd_shuffle(Simd2(10, 11), Simd2(12, 13), IDX)
+    simd_shuffle(Simd2([10, 11]), Simd2([12, 13]), IDX)
 }
diff --git a/tests/ui/simd/issue-17170.rs b/tests/ui/simd/issue-17170.rs
index abfc1c25ffb..2d13962843c 100644
--- a/tests/ui/simd/issue-17170.rs
+++ b/tests/ui/simd/issue-17170.rs
@@ -2,9 +2,9 @@
 #![feature(repr_simd)]
 
 #[repr(simd)]
-struct T(f64, f64, f64);
+struct T([f64; 3]);
 
-static X: T = T(0.0, 0.0, 0.0);
+static X: T = T([0.0, 0.0, 0.0]);
 
 fn main() {
     let _ = X;
diff --git a/tests/ui/simd/issue-32947.rs b/tests/ui/simd/issue-32947.rs
index bccca25c52b..dc5e7a4ec91 100644
--- a/tests/ui/simd/issue-32947.rs
+++ b/tests/ui/simd/issue-32947.rs
@@ -6,7 +6,7 @@
 extern crate test;
 
 #[repr(simd)]
-pub struct Mu64(pub u64, pub u64, pub u64, pub u64);
+pub struct Mu64(pub [u64; 4]);
 
 fn main() {
     // This ensures an unaligned pointer even in optimized builds, though LLVM
@@ -18,7 +18,7 @@ fn main() {
         let misaligned_ptr: &mut [u8; 32] = {
             std::mem::transmute(memory.offset(1))
         };
-        *misaligned_ptr = std::mem::transmute(Mu64(1, 1, 1, 1));
+        *misaligned_ptr = std::mem::transmute(Mu64([1, 1, 1, 1]));
         test::black_box(memory);
     }
 }
diff --git a/tests/ui/simd/issue-39720.rs b/tests/ui/simd/issue-39720.rs
index 4610b1d5004..2b51c0224c6 100644
--- a/tests/ui/simd/issue-39720.rs
+++ b/tests/ui/simd/issue-39720.rs
@@ -5,18 +5,18 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, Debug)]
-pub struct Char3(pub i8, pub i8, pub i8);
+pub struct Char3(pub [i8; 3]);
 
 #[repr(simd)]
 #[derive(Copy, Clone, Debug)]
-pub struct Short3(pub i16, pub i16, pub i16);
+pub struct Short3(pub [i16; 3]);
 
 extern "rust-intrinsic" {
     fn simd_cast<T, U>(x: T) -> U;
 }
 
 fn main() {
-    let cast: Short3 = unsafe { simd_cast(Char3(10, -3, -9)) };
+    let cast: Short3 = unsafe { simd_cast(Char3([10, -3, -9])) };
 
     println!("{:?}", cast);
 }
diff --git a/tests/ui/simd/issue-89193.rs b/tests/ui/simd/issue-89193.rs
index a4ed9be9962..9530124a7cc 100644
--- a/tests/ui/simd/issue-89193.rs
+++ b/tests/ui/simd/issue-89193.rs
@@ -8,7 +8,7 @@
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
-struct x4<T>(pub T, pub T, pub T, pub T);
+struct x4<T>(pub [T; 4]);
 
 extern "rust-intrinsic" {
     fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
@@ -16,36 +16,36 @@ extern "rust-intrinsic" {
 
 fn main() {
     let x: [usize; 4] = [10, 11, 12, 13];
-    let default = x4(0_usize, 1, 2, 3);
+    let default = x4([0_usize, 1, 2, 3]);
     let all_set = u8::MAX as i8; // aka -1
-    let mask = x4(all_set, all_set, all_set, all_set);
-    let expected = x4(10_usize, 11, 12, 13);
+    let mask = x4([all_set, all_set, all_set, all_set]);
+    let expected = x4([10_usize, 11, 12, 13]);
 
     unsafe {
         let pointer = x.as_ptr();
-        let pointers =  x4(
+        let pointers =  x4([
             pointer.offset(0),
             pointer.offset(1),
             pointer.offset(2),
             pointer.offset(3)
-        );
+        ]);
         let result = simd_gather(default, pointers, mask);
         assert_eq!(result, expected);
     }
 
     // and again for isize
     let x: [isize; 4] = [10, 11, 12, 13];
-    let default = x4(0_isize, 1, 2, 3);
-    let expected = x4(10_isize, 11, 12, 13);
+    let default = x4([0_isize, 1, 2, 3]);
+    let expected = x4([10_isize, 11, 12, 13]);
 
     unsafe {
         let pointer = x.as_ptr();
-        let pointers =  x4(
+        let pointers =  x4([
             pointer.offset(0),
             pointer.offset(1),
             pointer.offset(2),
             pointer.offset(3)
-        );
+        ]);
         let result = simd_gather(default, pointers, mask);
         assert_eq!(result, expected);
     }
diff --git a/tests/ui/simd/monomorphize-heterogeneous.rs b/tests/ui/simd/monomorphize-heterogeneous.rs
index 42e380dbb77..326e52acc34 100644
--- a/tests/ui/simd/monomorphize-heterogeneous.rs
+++ b/tests/ui/simd/monomorphize-heterogeneous.rs
@@ -2,7 +2,11 @@
 
 #[repr(simd)]
 struct I64F64(i64, f64);
-//~^ ERROR SIMD vector should be homogeneous
+//~^ ERROR SIMD vector's only field must be an array
+
+#[repr(simd)]
+struct I64x4F64x0([i64; 4], [f64; 0]);
+//~^ ERROR SIMD vector cannot have multiple fields
 
 static X: I64F64 = I64F64(1, 2.0);
 
diff --git a/tests/ui/simd/monomorphize-heterogeneous.stderr b/tests/ui/simd/monomorphize-heterogeneous.stderr
index 58e2b7c8347..610a1a49038 100644
--- a/tests/ui/simd/monomorphize-heterogeneous.stderr
+++ b/tests/ui/simd/monomorphize-heterogeneous.stderr
@@ -1,9 +1,16 @@
-error[E0076]: SIMD vector should be homogeneous
+error[E0076]: SIMD vector's only field must be an array
   --> $DIR/monomorphize-heterogeneous.rs:4:1
    |
 LL | struct I64F64(i64, f64);
-   | ^^^^^^^^^^^^^ SIMD elements must have the same type
+   | ^^^^^^^^^^^^^ --- not an array
 
-error: aborting due to 1 previous error
+error[E0075]: SIMD vector cannot have multiple fields
+  --> $DIR/monomorphize-heterogeneous.rs:8:1
+   |
+LL | struct I64x4F64x0([i64; 4], [f64; 0]);
+   | ^^^^^^^^^^^^^^^^^           -------- excess field
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0076`.
+Some errors have detailed explanations: E0075, E0076.
+For more information about an error, try `rustc --explain E0075`.
diff --git a/tests/ui/simd/monomorphize-too-long.rs b/tests/ui/simd/monomorphize-too-long.rs
new file mode 100644
index 00000000000..4bcde782292
--- /dev/null
+++ b/tests/ui/simd/monomorphize-too-long.rs
@@ -0,0 +1,11 @@
+//@ build-fail
+//@ error-pattern: monomorphising SIMD type `Simd<u16, 54321>` of length greater than 32768
+
+#![feature(repr_simd)]
+
+#[repr(simd)]
+struct Simd<T, const N: usize>([T; N]);
+
+fn main() {
+    let _too_big = Simd([1_u16; 54321]);
+}
diff --git a/tests/ui/simd/monomorphize-too-long.stderr b/tests/ui/simd/monomorphize-too-long.stderr
new file mode 100644
index 00000000000..978eef307ab
--- /dev/null
+++ b/tests/ui/simd/monomorphize-too-long.stderr
@@ -0,0 +1,4 @@
+error: monomorphising SIMD type `Simd<u16, 54321>` of length greater than 32768
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/simd/monomorphize-zero-length.rs b/tests/ui/simd/monomorphize-zero-length.rs
new file mode 100644
index 00000000000..44b4cfc0bcf
--- /dev/null
+++ b/tests/ui/simd/monomorphize-zero-length.rs
@@ -0,0 +1,11 @@
+//@ build-fail
+//@ error-pattern: monomorphising SIMD type `Simd<f64, 0>` of zero length
+
+#![feature(repr_simd)]
+
+#[repr(simd)]
+struct Simd<T, const N: usize>([T; N]);
+
+fn main() {
+    let _empty = Simd([1.0; 0]);
+}
diff --git a/tests/ui/simd/monomorphize-zero-length.stderr b/tests/ui/simd/monomorphize-zero-length.stderr
new file mode 100644
index 00000000000..738c20fe51a
--- /dev/null
+++ b/tests/ui/simd/monomorphize-zero-length.stderr
@@ -0,0 +1,4 @@
+error: monomorphising SIMD type `Simd<f64, 0>` of zero length
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/simd/target-feature-mixup.rs b/tests/ui/simd/target-feature-mixup.rs
index 034cb867c95..62d87c3a6dc 100644
--- a/tests/ui/simd/target-feature-mixup.rs
+++ b/tests/ui/simd/target-feature-mixup.rs
@@ -54,17 +54,17 @@ mod test {
     // An SSE type
     #[repr(simd)]
     #[derive(PartialEq, Debug, Clone, Copy)]
-    struct __m128i(u64, u64);
+    struct __m128i([u64; 2]);
 
     // An AVX type
     #[repr(simd)]
     #[derive(PartialEq, Debug, Clone, Copy)]
-    struct __m256i(u64, u64, u64, u64);
+    struct __m256i([u64; 4]);
 
     // An AVX-512 type
     #[repr(simd)]
     #[derive(PartialEq, Debug, Clone, Copy)]
-    struct __m512i(u64, u64, u64, u64, u64, u64, u64, u64);
+    struct __m512i([u64; 8]);
 
     pub fn main(level: &str) {
         unsafe {
@@ -90,9 +90,9 @@ mod test {
         )*) => ($(
             $(#[$attr])*
             unsafe fn $main(level: &str) {
-                let m128 = __m128i(1, 2);
-                let m256 = __m256i(3, 4, 5, 6);
-                let m512 = __m512i(7, 8, 9, 10, 11, 12, 13, 14);
+                let m128 = __m128i([1, 2]);
+                let m256 = __m256i([3, 4, 5, 6]);
+                let m512 = __m512i([7, 8, 9, 10, 11, 12, 13, 14]);
                 assert_eq!(id_sse_128(m128), m128);
                 assert_eq!(id_sse_256(m256), m256);
                 assert_eq!(id_sse_512(m512), m512);
@@ -127,55 +127,55 @@ mod test {
 
     #[target_feature(enable = "sse2")]
     unsafe fn id_sse_128(a: __m128i) -> __m128i {
-        assert_eq!(a, __m128i(1, 2));
+        assert_eq!(a, __m128i([1, 2]));
         a.clone()
     }
 
     #[target_feature(enable = "sse2")]
     unsafe fn id_sse_256(a: __m256i) -> __m256i {
-        assert_eq!(a, __m256i(3, 4, 5, 6));
+        assert_eq!(a, __m256i([3, 4, 5, 6]));
         a.clone()
     }
 
     #[target_feature(enable = "sse2")]
     unsafe fn id_sse_512(a: __m512i) -> __m512i {
-        assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14));
+        assert_eq!(a, __m512i([7, 8, 9, 10, 11, 12, 13, 14]));
         a.clone()
     }
 
     #[target_feature(enable = "avx")]
     unsafe fn id_avx_128(a: __m128i) -> __m128i {
-        assert_eq!(a, __m128i(1, 2));
+        assert_eq!(a, __m128i([1, 2]));
         a.clone()
     }
 
     #[target_feature(enable = "avx")]
     unsafe fn id_avx_256(a: __m256i) -> __m256i {
-        assert_eq!(a, __m256i(3, 4, 5, 6));
+        assert_eq!(a, __m256i([3, 4, 5, 6]));
         a.clone()
     }
 
     #[target_feature(enable = "avx")]
     unsafe fn id_avx_512(a: __m512i) -> __m512i {
-        assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14));
+        assert_eq!(a, __m512i([7, 8, 9, 10, 11, 12, 13, 14]));
         a.clone()
     }
 
     #[target_feature(enable = "avx512bw")]
     unsafe fn id_avx512_128(a: __m128i) -> __m128i {
-        assert_eq!(a, __m128i(1, 2));
+        assert_eq!(a, __m128i([1, 2]));
         a.clone()
     }
 
     #[target_feature(enable = "avx512bw")]
     unsafe fn id_avx512_256(a: __m256i) -> __m256i {
-        assert_eq!(a, __m256i(3, 4, 5, 6));
+        assert_eq!(a, __m256i([3, 4, 5, 6]));
         a.clone()
     }
 
     #[target_feature(enable = "avx512bw")]
     unsafe fn id_avx512_512(a: __m512i) -> __m512i {
-        assert_eq!(a, __m512i(7, 8, 9, 10, 11, 12, 13, 14));
+        assert_eq!(a, __m512i([7, 8, 9, 10, 11, 12, 13, 14]));
         a.clone()
     }
 }
diff --git a/tests/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs b/tests/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs
index dbe2d9ddd54..a969295c9f9 100644
--- a/tests/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs
+++ b/tests/ui/simd/type-generic-monomorphisation-extern-nonnull-ptr.rs
@@ -11,7 +11,7 @@ extern {
 }
 
 #[repr(simd)]
-struct S<T>(T);
+struct S<T>([T; 4]);
 
 #[inline(never)]
 fn identity<T>(v: T) -> T {
@@ -19,5 +19,5 @@ fn identity<T>(v: T) -> T {
 }
 
 fn main() {
-    let _v: S<[Option<NonNull<Extern>>; 4]> = identity(S([None; 4]));
+    let _v: S<Option<NonNull<Extern>>> = identity(S([None; 4]));
 }
diff --git a/tests/ui/simd/type-generic-monomorphisation-wide-ptr.rs b/tests/ui/simd/type-generic-monomorphisation-wide-ptr.rs
index 564118e9b13..18fc0753430 100644
--- a/tests/ui/simd/type-generic-monomorphisation-wide-ptr.rs
+++ b/tests/ui/simd/type-generic-monomorphisation-wide-ptr.rs
@@ -2,11 +2,11 @@
 
 #![feature(repr_simd)]
 
-//@ error-pattern:monomorphising SIMD type `S<[*mut [u8]; 4]>` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
+//@ error-pattern:monomorphising SIMD type `S<*mut [u8]>` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
 
 #[repr(simd)]
-struct S<T>(T);
+struct S<T>([T; 4]);
 
 fn main() {
-    let _v: Option<S<[*mut [u8]; 4]>> = None;
+    let _v: Option<S<*mut [u8]>> = None;
 }
diff --git a/tests/ui/simd/type-generic-monomorphisation-wide-ptr.stderr b/tests/ui/simd/type-generic-monomorphisation-wide-ptr.stderr
index 7ac8d715360..13b8b0315ba 100644
--- a/tests/ui/simd/type-generic-monomorphisation-wide-ptr.stderr
+++ b/tests/ui/simd/type-generic-monomorphisation-wide-ptr.stderr
@@ -1,4 +1,4 @@
-error: monomorphising SIMD type `S<[*mut [u8]; 4]>` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
+error: monomorphising SIMD type `S<*mut [u8]>` with a non-primitive-scalar (integer/float/pointer) element type `*mut [u8]`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/simd/type-generic-monomorphisation.rs b/tests/ui/simd/type-generic-monomorphisation.rs
index 2eeba55ef91..8b8d645a264 100644
--- a/tests/ui/simd/type-generic-monomorphisation.rs
+++ b/tests/ui/simd/type-generic-monomorphisation.rs
@@ -7,8 +7,8 @@
 
 struct X(Vec<i32>);
 #[repr(simd)]
-struct Simd2<T>(T, T);
+struct Simd2<T>([T; 2]);
 
 fn main() {
-    let _ = Simd2(X(vec![]), X(vec![]));
+    let _ = Simd2([X(vec![]), X(vec![])]);
 }
diff --git a/tests/ui/simd/type-len.rs b/tests/ui/simd/type-len.rs
index d82c70b8d82..a971177e154 100644
--- a/tests/ui/simd/type-len.rs
+++ b/tests/ui/simd/type-len.rs
@@ -1,7 +1,6 @@
 #![feature(repr_simd)]
 #![allow(non_camel_case_types)]
 
-
 #[repr(simd)]
 struct empty; //~ ERROR SIMD vector cannot be empty
 
@@ -12,12 +11,12 @@ struct empty2([f32; 0]); //~ ERROR SIMD vector cannot be empty
 struct pow2([f32; 7]);
 
 #[repr(simd)]
-struct i64f64(i64, f64); //~ ERROR SIMD vector should be homogeneous
+struct i64f64(i64, f64); //~ ERROR SIMD vector's only field must be an array
 
 struct Foo;
 
 #[repr(simd)]
-struct FooV(Foo, Foo); //~ ERROR SIMD vector element type should be a primitive scalar (integer/float/pointer) type
+struct FooV(Foo, Foo); //~ ERROR SIMD vector's only field must be an array
 
 #[repr(simd)]
 struct FooV2([Foo; 2]); //~ ERROR SIMD vector element type should be a primitive scalar (integer/float/pointer) type
@@ -29,11 +28,11 @@ struct TooBig([f32; 65536]); //~ ERROR SIMD vector cannot have more than 32768 e
 struct JustRight([u128; 32768]);
 
 #[repr(simd)]
-struct RGBA {
+struct RGBA { //~ ERROR SIMD vector's only field must be an array
     r: f32,
     g: f32,
     b: f32,
-    a: f32
+    a: f32,
 }
 
 fn main() {}
diff --git a/tests/ui/simd/type-len.stderr b/tests/ui/simd/type-len.stderr
index 2a6bd1b0fd5..04c4ca7677c 100644
--- a/tests/ui/simd/type-len.stderr
+++ b/tests/ui/simd/type-len.stderr
@@ -1,40 +1,48 @@
 error[E0075]: SIMD vector cannot be empty
-  --> $DIR/type-len.rs:6:1
+  --> $DIR/type-len.rs:5:1
    |
 LL | struct empty;
    | ^^^^^^^^^^^^
 
 error[E0075]: SIMD vector cannot be empty
-  --> $DIR/type-len.rs:9:1
+  --> $DIR/type-len.rs:8:1
    |
 LL | struct empty2([f32; 0]);
    | ^^^^^^^^^^^^^
 
-error[E0076]: SIMD vector should be homogeneous
-  --> $DIR/type-len.rs:15:1
+error[E0076]: SIMD vector's only field must be an array
+  --> $DIR/type-len.rs:14:1
    |
 LL | struct i64f64(i64, f64);
-   | ^^^^^^^^^^^^^ SIMD elements must have the same type
+   | ^^^^^^^^^^^^^ --- not an array
 
-error[E0077]: SIMD vector element type should be a primitive scalar (integer/float/pointer) type
-  --> $DIR/type-len.rs:20:1
+error[E0076]: SIMD vector's only field must be an array
+  --> $DIR/type-len.rs:19:1
    |
 LL | struct FooV(Foo, Foo);
-   | ^^^^^^^^^^^
+   | ^^^^^^^^^^^ --- not an array
 
 error[E0077]: SIMD vector element type should be a primitive scalar (integer/float/pointer) type
-  --> $DIR/type-len.rs:23:1
+  --> $DIR/type-len.rs:22:1
    |
 LL | struct FooV2([Foo; 2]);
    | ^^^^^^^^^^^^
 
 error[E0075]: SIMD vector cannot have more than 32768 elements
-  --> $DIR/type-len.rs:26:1
+  --> $DIR/type-len.rs:25:1
    |
 LL | struct TooBig([f32; 65536]);
    | ^^^^^^^^^^^^^
 
-error: aborting due to 6 previous errors
+error[E0076]: SIMD vector's only field must be an array
+  --> $DIR/type-len.rs:31:1
+   |
+LL | struct RGBA {
+   | ^^^^^^^^^^^
+LL |     r: f32,
+   |     ------ not an array
+
+error: aborting due to 7 previous errors
 
 Some errors have detailed explanations: E0075, E0076, E0077.
 For more information about an error, try `rustc --explain E0075`.
diff --git a/tests/ui/span/gated-features-attr-spans.rs b/tests/ui/span/gated-features-attr-spans.rs
index 69511ab8e1f..55527fa8add 100644
--- a/tests/ui/span/gated-features-attr-spans.rs
+++ b/tests/ui/span/gated-features-attr-spans.rs
@@ -1,7 +1,6 @@
 #[repr(simd)] //~ ERROR are experimental
 struct Coord {
-    x: u32,
-    y: u32,
+    v: [u32; 2],
 }
 
 fn main() {}
diff --git a/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.rs b/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.rs
new file mode 100644
index 00000000000..2b4f7ba9fa2
--- /dev/null
+++ b/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.rs
@@ -0,0 +1,27 @@
+//@ compile-flags: -Zthreads=16
+
+// original issue: https://github.com/rust-lang/rust/issues/129112
+// Previously, the "next" solver asserted that each successful solution is only obtained once.
+// This test exhibits a repro that, with next-solver + -Zthreads, triggered that old assert.
+// In the presence of multithreaded solving, it's possible to concurrently evaluate things twice,
+// which leads to replacing already-solved solutions in the global solution cache!
+// We assume this is fine if we check to make sure they are solved the same way each time.
+
+// This test only nondeterministically fails but that's okay, as it will be rerun by CI many times,
+// so it should almost always fail before anything is merged. As other thread tests already exist,
+// we already face this difficulty, probably. If we need to fix this by reducing the error margin,
+// we should improve compiletest.
+
+#[derive(Clone, Eq)] //~ ERROR [E0277]
+pub struct Struct<T>(T);
+
+impl<T: Clone, U> PartialEq<U> for Struct<T>
+where
+    U: Into<Struct<T>> + Clone
+{
+    fn eq(&self, _other: &U) -> bool {
+        todo!()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.stderr b/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.stderr
new file mode 100644
index 00000000000..65e7dd2ab34
--- /dev/null
+++ b/tests/ui/traits/next-solver/global-cache-and-parallel-frontend.stderr
@@ -0,0 +1,24 @@
+error[E0277]: the trait bound `T: Clone` is not satisfied
+  --> $DIR/global-cache-and-parallel-frontend.rs:15:17
+   |
+LL | #[derive(Clone, Eq)]
+   |                 ^^ the trait `Clone` is not implemented for `T`, which is required by `Struct<T>: PartialEq`
+   |
+note: required for `Struct<T>` to implement `PartialEq`
+  --> $DIR/global-cache-and-parallel-frontend.rs:18:19
+   |
+LL | impl<T: Clone, U> PartialEq<U> for Struct<T>
+   |         -----     ^^^^^^^^^^^^     ^^^^^^^^^
+   |         |
+   |         unsatisfied trait bound introduced here
+note: required by a bound in `Eq`
+  --> $SRC_DIR/core/src/cmp.rs:LL:COL
+   = note: this error originates in the derive macro `Eq` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider restricting type parameter `T`
+   |
+LL | pub struct Struct<T: std::clone::Clone>(T);
+   |                    +++++++++++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.