about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/ast.rs3
-rw-r--r--compiler/rustc_ast/src/ptr.rs16
-rw-r--r--compiler/rustc_ast/src/util/parser.rs7
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs8
-rw-r--r--compiler/rustc_borrowck/src/borrow_set.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/vtable.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs120
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs32
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/cast.rs6
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs2
-rw-r--r--compiler/rustc_data_structures/src/graph/dominators/mod.rs8
-rw-r--r--compiler/rustc_errors/src/lib.rs33
-rw-r--r--compiler/rustc_hir/src/hir.rs5
-rw-r--r--compiler/rustc_hir/src/hir_id.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs44
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl2
-rw-r--r--compiler/rustc_hir_typeck/src/check.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs311
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs5
-rw-r--r--compiler/rustc_index_macros/src/newtype.rs3
-rw-r--r--compiler/rustc_interface/src/passes.rs3
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs6
-rw-r--r--compiler/rustc_llvm/build.rs6
-rw-r--r--compiler/rustc_middle/src/arena.rs1
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs5
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs8
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs2
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs4
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs15
-rw-r--r--compiler/rustc_middle/src/mir/query.rs63
-rw-r--r--compiler/rustc_middle/src/mir/statement.rs2
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs4
-rw-r--r--compiler/rustc_middle/src/query/mod.rs6
-rw-r--r--compiler/rustc_middle/src/thir.rs6
-rw-r--r--compiler/rustc_middle/src/ty/cast.rs2
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs1
-rw-r--r--compiler/rustc_middle/src/ty/context.rs115
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs2
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs34
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/block.rs45
-rw-r--r--compiler/rustc_mir_build/src/build/custom/mod.rs5
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs17
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs52
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs20
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs5
-rw-r--r--compiler/rustc_mir_build/src/errors.rs23
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs3
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs57
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs10
-rw-r--r--compiler/rustc_mir_transform/messages.ftl49
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs615
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs10
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs149
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_box_derefs.rs12
-rw-r--r--compiler/rustc_mir_transform/src/errors.rs171
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs2
-rw-r--r--compiler/rustc_mir_transform/src/inline/cycle.rs18
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs12
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs14
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs2
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs2
-rw-r--r--compiler/rustc_mir_transform/src/simplify.rs8
-rw-r--r--compiler/rustc_mir_transform/src/unreachable_enum_branching.rs (renamed from compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs)57
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs1
-rw-r--r--compiler/rustc_pattern_analysis/src/constructor.rs29
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs2
-rw-r--r--compiler/rustc_pattern_analysis/src/usefulness.rs49
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs2
-rw-r--r--compiler/rustc_resolve/src/imports.rs6
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs2
-rw-r--r--compiler/rustc_span/src/def_id.rs2
-rw-r--r--compiler/rustc_span/src/hygiene.rs4
-rw-r--r--compiler/rustc_span/src/source_map/tests.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs2
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs25
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs42
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs2
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs3
-rw-r--r--compiler/rustc_type_ir/src/lib.rs2
-rw-r--r--compiler/stable_mir/src/mir/body.rs1
-rw-r--r--library/core/src/clone.rs5
-rw-r--r--library/core/src/cmp.rs10
-rw-r--r--library/core/src/fmt/mod.rs4
-rw-r--r--library/core/src/intrinsics/simd.rs6
-rw-r--r--library/core/src/lib.rs4
-rw-r--r--library/core/src/marker.rs8
-rw-r--r--library/core/src/ptr/const_ptr.rs10
-rw-r--r--library/core/src/ptr/mod.rs14
-rw-r--r--library/core/src/ptr/mut_ptr.rs11
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs10
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs10
-rw-r--r--library/portable-simd/crates/core_simd/tests/pointers.rs6
-rw-r--r--library/std/src/fs.rs4
-rw-r--r--library/std/src/sys/pal/hermit/thread.rs2
-rw-r--r--library/std/src/sys/pal/itron/thread.rs2
-rw-r--r--library/std/src/sys/pal/mod.rs6
-rw-r--r--library/std/src/sys/pal/wasip2/cabi_realloc.rs65
-rw-r--r--library/std/src/sys/pal/wasip2/mod.rs8
-rw-r--r--src/bootstrap/src/core/builder.rs13
-rw-r--r--src/bootstrap/src/core/builder/tests.rs2
-rw-r--r--src/bootstrap/src/core/config/flags.rs3
-rwxr-xr-xsrc/ci/scripts/upload-artifacts.sh14
-rw-r--r--src/doc/rustc/src/platform-support/netbsd.md8
-rw-r--r--src/doc/unstable-book/src/compiler-flags/external-clangrt.md6
-rw-r--r--src/doc/unstable-book/src/compiler-flags/sanitizer.md15
-rw-r--r--src/etc/completions/x.py.fish2
-rw-r--r--src/etc/completions/x.py.ps12
-rw-r--r--src/etc/completions/x.py.sh10
-rw-r--r--src/etc/completions/x.py.zsh2
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs4
-rw-r--r--src/tools/miri/src/shims/intrinsics/simd.rs6
-rw-r--r--src/tools/miri/tests/fail/provenance/ptr_invalid.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs2
-rw-r--r--src/tools/miri/tests/pass/async-closure-captures.rs91
-rw-r--r--src/tools/miri/tests/pass/async-closure-captures.stdout10
-rw-r--r--src/tools/miri/tests/pass/portable-simd-ptrs.rs2
-rw-r--r--src/tools/miri/tests/pass/ptr_int_from_exposed.rs10
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs4
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs2
-rw-r--r--src/tools/tidy/src/issues.txt18
-rw-r--r--src/tools/tidy/src/ui_tests.rs2
-rw-r--r--tests/auxiliary/rust_test_helpers.c24
-rw-r--r--tests/codegen/cast-target-abi.rs280
-rw-r--r--tests/codegen/cffi/ffi-out-of-bounds-loads.rs28
-rw-r--r--tests/codegen/enum/uninhabited_enum_default_branch.rs24
-rw-r--r--tests/codegen/enum/unreachable_enum_default_branch.rs43
-rw-r--r--tests/incremental/hashes/function_interfaces.rs6
-rw-r--r--tests/incremental/hashes/inherent_impls.rs8
-rw-r--r--tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir2
-rw-r--r--tests/mir-opt/box_expr.main.ElaborateDrops.diff2
-rw-r--r--tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir8
-rw-r--r--tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir6
-rw-r--r--tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir6
-rw-r--r--tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff2
-rw-r--r--tests/mir-opt/const_prop/address_of_pair.fn0.GVN.diff2
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff6
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff6
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff6
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff6
-rw-r--r--tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff2
-rw-r--r--tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff2
-rw-r--r--tests/mir-opt/const_prop/indirect_mutation.bar.GVN.diff2
-rw-r--r--tests/mir-opt/const_prop/invalid_constant.main.GVN.diff12
-rw-r--r--tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff12
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_no_prop.main.GVN.diff2
-rw-r--r--tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-abort.diff (renamed from tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-abort.diff)2
-rw-r--r--tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-unwind.diff (renamed from tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-unwind.diff)2
-rw-r--r--tests/mir-opt/const_prop/pointer_expose_provenance.rs (renamed from tests/mir-opt/const_prop/pointer_expose_address.rs)4
-rw-r--r--tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff2
-rw-r--r--tests/mir-opt/const_prop/reify_fn_ptr.rs2
-rw-r--r--tests/mir-opt/const_prop/transmute.from_char.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.from_char.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.invalid_bool.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.invalid_bool.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.invalid_char.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.invalid_char.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.less_as_i8.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.less_as_i8.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.valid_char.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.valid_char.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-abort.diff4
-rw-r--r--tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff4
-rw-r--r--tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-abort.diff4
-rw-r--r--tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff4
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-abort.diff8
-rw-r--r--tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff8
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff4
-rw-r--r--tests/mir-opt/dead-store-elimination/provenance_soundness.rs4
-rw-r--r--tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff6
-rw-r--r--tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff6
-rw-r--r--tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff10
-rw-r--r--tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff10
-rw-r--r--tests/mir-opt/gvn.slices.GVN.panic-abort.diff6
-rw-r--r--tests/mir-opt/gvn.slices.GVN.panic-unwind.diff6
-rw-r--r--tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff12
-rw-r--r--tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff12
-rw-r--r--tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-abort.diff6
-rw-r--r--tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-unwind.diff6
-rw-r--r--tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff4
-rw-r--r--tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff4
-rw-r--r--tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff8
-rw-r--r--tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff8
-rw-r--r--tests/mir-opt/inline/inline_instruction_set.default.Inline.diff2
-rw-r--r--tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff20
-rw-r--r--tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff12
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff14
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff14
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir10
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir10
-rw-r--r--tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff24
-rw-r--r--tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff24
-rw-r--r--tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify.diff28
-rw-r--r--tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir8
-rw-r--r--tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir8
-rw-r--r--tests/mir-opt/issue_72181.main.built.after.mir2
-rw-r--r--tests/mir-opt/issue_72181_1.main.built.after.mir2
-rw-r--r--tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff6
-rw-r--r--tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff2
-rw-r--r--tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.mir10
-rw-r--r--tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir6
-rw-r--r--tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir4
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir20
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir20
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir4
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir4
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir4
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir4
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir48
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir48
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir44
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir44
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir4
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir4
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir50
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir50
-rw-r--r--tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff2
-rw-r--r--tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff258
-rw-r--r--tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff232
-rw-r--r--tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff4
-rw-r--r--tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir10
-rw-r--r--tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir10
-rw-r--r--tests/mir-opt/simplify_dead_blocks.assert_nonzero_nonmax.SimplifyCfg-after-unreachable-enum-branching.diff33
-rw-r--r--tests/mir-opt/simplify_dead_blocks.rs52
-rw-r--r--tests/mir-opt/simplify_duplicate_unreachable_blocks.assert_nonzero_nonmax.SimplifyCfg-after-uninhabited-enum-branching.diff25
-rw-r--r--tests/mir-opt/simplify_duplicate_unreachable_blocks.rs31
-rw-r--r--tests/mir-opt/simplify_locals.expose_provenance.SimplifyLocals-before-const-prop.diff (renamed from tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff)8
-rw-r--r--tests/mir-opt/simplify_locals.rs6
-rw-r--r--tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff2
-rw-r--r--tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff2
-rw-r--r--tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff2
-rw-r--r--tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff2
-rw-r--r--tests/mir-opt/sroa/structs.unions.ScalarReplacementOfAggregates.diff2
-rw-r--r--tests/mir-opt/tls_access.main.PreCodegen.after.mir6
-rw-r--r--tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir2
-rw-r--r--tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir2
-rw-r--r--tests/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UnreachableEnumBranching.diff (renamed from tests/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff)4
-rw-r--r--tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UnreachableEnumBranching.diff (renamed from tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff)4
-rw-r--r--tests/mir-opt/uninhabited_fallthrough_elimination.rs4
-rw-r--r--tests/mir-opt/unnamed-fields/field_access.bar.SimplifyCfg-initial.after.mir2
-rw-r--r--tests/mir-opt/unreachable_enum_branching.byref.UnreachableEnumBranching.panic-abort.diff (renamed from tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-abort.diff)4
-rw-r--r--tests/mir-opt/unreachable_enum_branching.byref.UnreachableEnumBranching.panic-unwind.diff (renamed from tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-unwind.diff)4
-rw-r--r--tests/mir-opt/unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.panic-abort.diff (renamed from tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-abort.diff)4
-rw-r--r--tests/mir-opt/unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.panic-unwind.diff (renamed from tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-unwind.diff)4
-rw-r--r--tests/mir-opt/unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.panic-abort.diff (renamed from tests/mir-opt/uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.panic-abort.diff)4
-rw-r--r--tests/mir-opt/unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.panic-unwind.diff (renamed from tests/mir-opt/uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.panic-unwind.diff)4
-rw-r--r--tests/mir-opt/unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.panic-abort.diff (renamed from tests/mir-opt/uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.panic-abort.diff)4
-rw-r--r--tests/mir-opt/unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.panic-unwind.diff (renamed from tests/mir-opt/uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.panic-unwind.diff)4
-rw-r--r--tests/mir-opt/unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.panic-abort.diff (renamed from tests/mir-opt/uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.panic-abort.diff)4
-rw-r--r--tests/mir-opt/unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.panic-unwind.diff (renamed from tests/mir-opt/uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.panic-unwind.diff)4
-rw-r--r--tests/mir-opt/unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.panic-abort.diff (renamed from tests/mir-opt/uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.panic-abort.diff)4
-rw-r--r--tests/mir-opt/unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.panic-unwind.diff (renamed from tests/mir-opt/uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.panic-unwind.diff)4
-rw-r--r--tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.panic-abort.diff (renamed from tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.panic-abort.diff)6
-rw-r--r--tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.panic-unwind.diff (renamed from tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.panic-unwind.diff)6
-rw-r--r--tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.panic-abort.diff (renamed from tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.panic-abort.diff)6
-rw-r--r--tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.panic-unwind.diff (renamed from tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.panic-unwind.diff)6
-rw-r--r--tests/mir-opt/unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.panic-abort.diff (renamed from tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.panic-abort.diff)6
-rw-r--r--tests/mir-opt/unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.panic-unwind.diff (renamed from tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.panic-unwind.diff)6
-rw-r--r--tests/mir-opt/unreachable_enum_branching.rs (renamed from tests/mir-opt/uninhabited_enum_branching.rs)40
-rw-r--r--tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff (renamed from tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-abort.diff)4
-rw-r--r--tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff (renamed from tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-unwind.diff)4
-rw-r--r--tests/ui/abi/extern/extern-pass-FiveU16s.rs30
-rw-r--r--tests/ui/abi/extern/extern-return-FiveU16s.rs26
-rw-r--r--tests/ui/asm/x86_64/goto.mirunsafeck.stderr23
-rw-r--r--tests/ui/asm/x86_64/goto.rs2
-rw-r--r--tests/ui/asm/x86_64/goto.stderr (renamed from tests/ui/asm/x86_64/goto.thirunsafeck.stderr)4
-rw-r--r--tests/ui/async-await/async-closures/captures.rs82
-rw-r--r--tests/ui/async-await/async-closures/captures.run.stdout10
-rw-r--r--tests/ui/async-await/coroutine-desc.stderr28
-rw-r--r--tests/ui/closures/issue-1460.rs (renamed from tests/ui/issues/issue-1460.rs)0
-rw-r--r--tests/ui/closures/issue-1460.stderr (renamed from tests/ui/issues/issue-1460.stderr)0
-rw-r--r--tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr10
-rw-r--r--tests/ui/fn/fn-item-type.stderr50
-rw-r--r--tests/ui/fn/issue-1451.rs (renamed from tests/ui/issues/issue-1451.rs)0
-rw-r--r--tests/ui/fn/issue-1900.rs (renamed from tests/ui/issues/issue-1900.rs)0
-rw-r--r--tests/ui/fn/issue-1900.stderr (renamed from tests/ui/issues/issue-1900.stderr)0
-rw-r--r--tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs1
-rw-r--r--tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr19
-rw-r--r--tests/ui/issues/issue-1476.rs3
-rw-r--r--tests/ui/issues/issue-1476.stderr9
-rw-r--r--tests/ui/issues/issue-1696.rs8
-rw-r--r--tests/ui/lint/lint-strict-provenance-lossy-casts.stderr8
-rw-r--r--tests/ui/loops/issue-1962.fixed (renamed from tests/ui/issues/issue-1962.fixed)0
-rw-r--r--tests/ui/loops/issue-1962.rs (renamed from tests/ui/issues/issue-1962.rs)0
-rw-r--r--tests/ui/loops/issue-1962.stderr (renamed from tests/ui/issues/issue-1962.stderr)0
-rw-r--r--tests/ui/loops/issue-1974.rs (renamed from tests/ui/issues/issue-1974.rs)0
-rw-r--r--tests/ui/match/postfix-match/match-after-as.rs7
-rw-r--r--tests/ui/match/postfix-match/match-after-as.stderr28
-rw-r--r--tests/ui/mir/const_eval_select_cycle.rs18
-rw-r--r--tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.rs14
-rw-r--r--tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr97
-rw-r--r--tests/ui/mismatched_types/issue-1362.rs (renamed from tests/ui/issues/issue-1362.rs)0
-rw-r--r--tests/ui/mismatched_types/issue-1362.stderr (renamed from tests/ui/issues/issue-1362.stderr)0
-rw-r--r--tests/ui/mismatched_types/issue-1448-2.rs (renamed from tests/ui/issues/issue-1448-2.rs)0
-rw-r--r--tests/ui/mismatched_types/issue-1448-2.stderr (renamed from tests/ui/issues/issue-1448-2.stderr)0
-rw-r--r--tests/ui/pattern/usefulness/unions.rs35
-rw-r--r--tests/ui/pattern/usefulness/unions.stderr34
-rw-r--r--tests/ui/simd/intrinsic/ptr-cast.rs4
-rw-r--r--tests/ui/static/issue-1660.rs (renamed from tests/ui/issues/issue-1660.rs)0
401 files changed, 2989 insertions, 3002 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 4ba298902a9..c10a6258d39 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1276,7 +1276,8 @@ impl Expr {
             ExprKind::While(..) => ExprPrecedence::While,
             ExprKind::ForLoop { .. } => ExprPrecedence::ForLoop,
             ExprKind::Loop(..) => ExprPrecedence::Loop,
-            ExprKind::Match(..) => ExprPrecedence::Match,
+            ExprKind::Match(_, _, MatchKind::Prefix) => ExprPrecedence::Match,
+            ExprKind::Match(_, _, MatchKind::Postfix) => ExprPrecedence::PostfixMatch,
             ExprKind::Closure(..) => ExprPrecedence::Closure,
             ExprKind::Block(..) => ExprPrecedence::Block,
             ExprKind::TryBlock(..) => ExprPrecedence::TryBlock,
diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs
index 0140fb752bf..e22a523dbc3 100644
--- a/compiler/rustc_ast/src/ptr.rs
+++ b/compiler/rustc_ast/src/ptr.rs
@@ -1,6 +1,6 @@
 //! The AST pointer.
 //!
-//! Provides `P<T>`, a frozen owned smart pointer.
+//! Provides [`P<T>`][struct@P], an owned smart pointer.
 //!
 //! # Motivations and benefits
 //!
@@ -8,18 +8,14 @@
 //!   passes (e.g., one may be able to bypass the borrow checker with a shared
 //!   `ExprKind::AddrOf` node taking a mutable borrow).
 //!
-//! * **Immutability**: `P<T>` disallows mutating its inner `T`, unlike `Box<T>`
-//!   (unless it contains an `Unsafe` interior, but that may be denied later).
-//!   This mainly prevents mistakes, but also enforces a kind of "purity".
-//!
 //! * **Efficiency**: folding can reuse allocation space for `P<T>` and `Vec<T>`,
 //!   the latter even when the input and output types differ (as it would be the
 //!   case with arenas or a GADT AST using type parameters to toggle features).
 //!
-//! * **Maintainability**: `P<T>` provides a fixed interface - `Deref`,
-//!   `and_then` and `map` - which can remain fully functional even if the
-//!   implementation changes (using a special thread-local heap, for example).
-//!   Moreover, a switch to, e.g., `P<'a, T>` would be easy and mostly automated.
+//! * **Maintainability**: `P<T>` provides an interface, which can remain fully
+//!   functional even if the implementation changes (using a special thread-local
+//!   heap, for example). Moreover, a switch to, e.g., `P<'a, T>` would be easy
+//!   and mostly automated.
 
 use std::fmt::{self, Debug, Display};
 use std::ops::{Deref, DerefMut};
@@ -29,6 +25,8 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 /// An owned smart pointer.
+///
+/// See the [module level documentation][crate::ptr] for details.
 pub struct P<T: ?Sized> {
     ptr: Box<T>,
 }
diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs
index 13768c12017..373c0ebcc5c 100644
--- a/compiler/rustc_ast/src/util/parser.rs
+++ b/compiler/rustc_ast/src/util/parser.rs
@@ -281,6 +281,7 @@ pub enum ExprPrecedence {
     ForLoop,
     Loop,
     Match,
+    PostfixMatch,
     ConstBlock,
     Block,
     TryBlock,
@@ -334,7 +335,8 @@ impl ExprPrecedence {
             | ExprPrecedence::InlineAsm
             | ExprPrecedence::Mac
             | ExprPrecedence::FormatArgs
-            | ExprPrecedence::OffsetOf => PREC_POSTFIX,
+            | ExprPrecedence::OffsetOf
+            | ExprPrecedence::PostfixMatch => PREC_POSTFIX,
 
             // Never need parens
             ExprPrecedence::Array
@@ -390,7 +392,8 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
         | ast::ExprKind::Cast(x, _)
         | ast::ExprKind::Type(x, _)
         | ast::ExprKind::Field(x, _)
-        | ast::ExprKind::Index(x, _, _) => {
+        | ast::ExprKind::Index(x, _, _)
+        | ast::ExprKind::Match(x, _, ast::MatchKind::Postfix) => {
             // &X { y: 1 }, X { y: 1 }.y
             contains_exterior_struct_lit(x)
         }
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index a1164008d0d..402044c7af9 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -3,7 +3,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{LocalDefId, LocalDefIdMap};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::*;
-use rustc_index::{Idx, IndexVec};
+use rustc_index::IndexVec;
 use rustc_middle::span_bug;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::{Span, DUMMY_SP};
@@ -31,7 +31,7 @@ pub(super) fn index_hir<'hir>(
     bodies: &SortedMap<ItemLocalId, &'hir Body<'hir>>,
     num_nodes: usize,
 ) -> (IndexVec<ItemLocalId, ParentedNode<'hir>>, LocalDefIdMap<ItemLocalId>) {
-    let zero_id = ItemLocalId::new(0);
+    let zero_id = ItemLocalId::ZERO;
     let err_node = ParentedNode { parent: zero_id, node: Node::Err(item.span()) };
     let mut nodes = IndexVec::from_elem_n(err_node, num_nodes);
     // This node's parent should never be accessed: the owner's parent is computed by the
@@ -112,7 +112,9 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
     }
 
     fn insert_nested(&mut self, item: LocalDefId) {
-        self.parenting.insert(item, self.parent_node);
+        if self.parent_node.as_u32() != 0 {
+            self.parenting.insert(item, self.parent_node);
+        }
     }
 }
 
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index c9786328565..abfea6078f2 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -11,7 +11,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
 use rustc_hir::PredicateOrigin;
-use rustc_index::{Idx, IndexSlice, IndexVec};
+use rustc_index::{IndexSlice, IndexVec};
 use rustc_middle::span_bug;
 use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
 use rustc_span::edit_distance::find_best_match_for_name;
@@ -563,7 +563,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         let kind =
                             this.lower_use_tree(use_tree, &prefix, id, vis_span, &mut ident, attrs);
                         if let Some(attrs) = attrs {
-                            this.attrs.insert(hir::ItemLocalId::new(0), attrs);
+                            this.attrs.insert(hir::ItemLocalId::ZERO, attrs);
                         }
 
                         let item = hir::Item {
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 833b0e9b567..8cf347bfa96 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -157,7 +157,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             attrs: SortedMap::default(),
             children: Vec::default(),
             current_hir_id_owner: hir::CRATE_OWNER_ID,
-            item_local_id_counter: hir::ItemLocalId::new(0),
+            item_local_id_counter: hir::ItemLocalId::ZERO,
             node_id_to_local_id: Default::default(),
             trait_map: Default::default(),
 
@@ -583,7 +583,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         // and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s.
 
         // Always allocate the first `HirId` for the owner itself.
-        let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::new(0));
+        let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::ZERO);
         debug_assert_eq!(_old, None);
 
         let item = f(self);
@@ -677,7 +677,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 v.insert(local_id);
                 self.item_local_id_counter.increment_by(1);
 
-                assert_ne!(local_id, hir::ItemLocalId::new(0));
+                assert_ne!(local_id, hir::ItemLocalId::ZERO);
                 if let Some(def_id) = self.opt_local_def_id(ast_node_id) {
                     self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
                 }
@@ -696,7 +696,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn next_id(&mut self) -> hir::HirId {
         let owner = self.current_hir_id_owner;
         let local_id = self.item_local_id_counter;
-        assert_ne!(local_id, hir::ItemLocalId::new(0));
+        assert_ne!(local_id, hir::ItemLocalId::ZERO);
         self.item_local_id_counter.increment_by(1);
         hir::HirId { owner, local_id }
     }
diff --git a/compiler/rustc_borrowck/src/borrow_set.rs b/compiler/rustc_borrowck/src/borrow_set.rs
index 6a683d129de..a38dd286be5 100644
--- a/compiler/rustc_borrowck/src/borrow_set.rs
+++ b/compiler/rustc_borrowck/src/borrow_set.rs
@@ -159,7 +159,7 @@ impl<'tcx> BorrowSet<'tcx> {
     }
 
     pub(crate) fn indices(&self) -> impl Iterator<Item = BorrowIndex> {
-        BorrowIndex::from_usize(0)..BorrowIndex::from_usize(self.len())
+        BorrowIndex::ZERO..BorrowIndex::from_usize(self.len())
     }
 
     pub(crate) fn iter_enumerated(&self) -> impl Iterator<Item = (BorrowIndex, &BorrowData<'tcx>)> {
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 6405364c30c..71b54a761a2 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2261,7 +2261,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         }
                     }
 
-                    CastKind::PointerExposeAddress => {
+                    CastKind::PointerExposeProvenance => {
                         let ty_from = op.ty(body, tcx);
                         let cast_ty_from = CastTy::from_ty(ty_from);
                         let cast_ty_to = CastTy::from_ty(*ty);
@@ -2271,7 +2271,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                                 span_mirbug!(
                                     self,
                                     rvalue,
-                                    "Invalid PointerExposeAddress cast {:?} -> {:?}",
+                                    "Invalid PointerExposeProvenance cast {:?} -> {:?}",
                                     ty_from,
                                     ty
                                 )
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 249c16898ce..0aa2bae8f78 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -649,7 +649,7 @@ fn codegen_stmt<'tcx>(
                     | CastKind::IntToFloat
                     | CastKind::FnPtrToPtr
                     | CastKind::PtrToPtr
-                    | CastKind::PointerExposeAddress
+                    | CastKind::PointerExposeProvenance
                     | CastKind::PointerWithExposedProvenance,
                     ref operand,
                     to_ty,
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
index 1615dc5de69..8df83c706a1 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
@@ -1393,7 +1393,7 @@ fn llvm_add_sub<'tcx>(
 
     // c + carry -> c + first intermediate carry or borrow respectively
     let int0 = crate::num::codegen_checked_int_binop(fx, bin_op, a, b);
-    let c = int0.value_field(fx, FieldIdx::new(0));
+    let c = int0.value_field(fx, FieldIdx::ZERO);
     let cb0 = int0.value_field(fx, FieldIdx::new(1)).load_scalar(fx);
 
     // c + carry -> c + second intermediate carry or borrow respectively
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index 783ad5d1dd1..67f9d831062 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -965,7 +965,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
             });
         }
 
-        sym::simd_expose_addr | sym::simd_with_exposed_provenance | sym::simd_cast_ptr => {
+        sym::simd_expose_provenance | sym::simd_with_exposed_provenance | sym::simd_cast_ptr => {
             intrinsic_args!(fx, args => (arg); intrinsic);
             ret.write_cvalue_transmute(fx, arg);
         }
diff --git a/compiler/rustc_codegen_cranelift/src/vtable.rs b/compiler/rustc_codegen_cranelift/src/vtable.rs
index 86ebf37d105..04e24320f91 100644
--- a/compiler/rustc_codegen_cranelift/src/vtable.rs
+++ b/compiler/rustc_codegen_cranelift/src/vtable.rs
@@ -61,7 +61,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
             if ty.is_dyn_star() {
                 let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap().ty);
                 let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout);
-                let ptr = dyn_star.place_field(fx, FieldIdx::new(0)).to_ptr();
+                let ptr = dyn_star.place_field(fx, FieldIdx::ZERO).to_ptr();
                 let vtable =
                     dyn_star.place_field(fx, FieldIdx::new(1)).to_cvalue(fx).load_scalar(fx);
                 break 'block (ptr, vtable);
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index e5f5146fac8..d2828669d43 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -16,13 +16,15 @@ pub use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
 use rustc_middle::ty::Ty;
 use rustc_session::config;
 pub use rustc_target::abi::call::*;
-use rustc_target::abi::{self, HasDataLayout, Int};
+use rustc_target::abi::{self, HasDataLayout, Int, Size};
 pub use rustc_target::spec::abi::Abi;
 use rustc_target::spec::SanitizerSet;
 
 use libc::c_uint;
 use smallvec::SmallVec;
 
+use std::cmp;
+
 pub trait ArgAttributesExt {
     fn apply_attrs_to_llfn(&self, idx: AttributePlace, cx: &CodegenCx<'_, '_>, llfn: &Value);
     fn apply_attrs_to_callsite(
@@ -130,42 +132,36 @@ impl LlvmType for Reg {
 impl LlvmType for CastTarget {
     fn llvm_type<'ll>(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type {
         let rest_ll_unit = self.rest.unit.llvm_type(cx);
-        let (rest_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 {
-            (0, 0)
+        let rest_count = if self.rest.total == Size::ZERO {
+            0
         } else {
-            (
-                self.rest.total.bytes() / self.rest.unit.size.bytes(),
-                self.rest.total.bytes() % self.rest.unit.size.bytes(),
-            )
+            assert_ne!(
+                self.rest.unit.size,
+                Size::ZERO,
+                "total size {:?} cannot be divided into units of zero size",
+                self.rest.total
+            );
+            if self.rest.total.bytes() % self.rest.unit.size.bytes() != 0 {
+                assert_eq!(self.rest.unit.kind, RegKind::Integer, "only int regs can be split");
+            }
+            self.rest.total.bytes().div_ceil(self.rest.unit.size.bytes())
         };
 
+        // Simplify to a single unit or an array if there's no prefix.
+        // This produces the same layout, but using a simpler type.
         if self.prefix.iter().all(|x| x.is_none()) {
-            // Simplify to a single unit when there is no prefix and size <= unit size
-            if self.rest.total <= self.rest.unit.size {
+            if rest_count == 1 {
                 return rest_ll_unit;
             }
 
-            // Simplify to array when all chunks are the same size and type
-            if rem_bytes == 0 {
-                return cx.type_array(rest_ll_unit, rest_count);
-            }
-        }
-
-        // Create list of fields in the main structure
-        let mut args: Vec<_> = self
-            .prefix
-            .iter()
-            .flat_map(|option_reg| option_reg.map(|reg| reg.llvm_type(cx)))
-            .chain((0..rest_count).map(|_| rest_ll_unit))
-            .collect();
-
-        // Append final integer
-        if rem_bytes != 0 {
-            // Only integers can be really split further.
-            assert_eq!(self.rest.unit.kind, RegKind::Integer);
-            args.push(cx.type_ix(rem_bytes * 8));
+            return cx.type_array(rest_ll_unit, rest_count);
         }
 
+        // Generate a struct type with the prefix and the "rest" arguments.
+        let prefix_args =
+            self.prefix.iter().flat_map(|option_reg| option_reg.map(|reg| reg.llvm_type(cx)));
+        let rest_args = (0..rest_count).map(|_| rest_ll_unit);
+        let args: Vec<_> = prefix_args.chain(rest_args).collect();
         cx.type_struct(&args, false)
     }
 }
@@ -215,47 +211,33 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
                 bug!("unsized `ArgAbi` must be handled through `store_fn_arg`");
             }
             PassMode::Cast { cast, pad_i32: _ } => {
-                // FIXME(eddyb): Figure out when the simpler Store is safe, clang
-                // uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.
-                let can_store_through_cast_ptr = false;
-                if can_store_through_cast_ptr {
-                    bx.store(val, dst.llval, self.layout.align.abi);
-                } else {
-                    // The actual return type is a struct, but the ABI
-                    // adaptation code has cast it into some scalar type. The
-                    // code that follows is the only reliable way I have
-                    // found to do a transform like i64 -> {i32,i32}.
-                    // Basically we dump the data onto the stack then memcpy it.
-                    //
-                    // Other approaches I tried:
-                    // - Casting rust ret pointer to the foreign type and using Store
-                    //   is (a) unsafe if size of foreign type > size of rust type and
-                    //   (b) runs afoul of strict aliasing rules, yielding invalid
-                    //   assembly under -O (specifically, the store gets removed).
-                    // - Truncating foreign type to correct integral type and then
-                    //   bitcasting to the struct type yields invalid cast errors.
-
-                    // We instead thus allocate some scratch space...
-                    let scratch_size = cast.size(bx);
-                    let scratch_align = cast.align(bx);
-                    let llscratch = bx.alloca(cast.llvm_type(bx), scratch_align);
-                    bx.lifetime_start(llscratch, scratch_size);
-
-                    // ... where we first store the value...
-                    bx.store(val, llscratch, scratch_align);
-
-                    // ... and then memcpy it to the intended destination.
-                    bx.memcpy(
-                        dst.llval,
-                        self.layout.align.abi,
-                        llscratch,
-                        scratch_align,
-                        bx.const_usize(self.layout.size.bytes()),
-                        MemFlags::empty(),
-                    );
-
-                    bx.lifetime_end(llscratch, scratch_size);
-                }
+                // The ABI mandates that the value is passed as a different struct representation.
+                // Spill and reload it from the stack to convert from the ABI representation to
+                // the Rust representation.
+                let scratch_size = cast.size(bx);
+                let scratch_align = cast.align(bx);
+                // Note that the ABI type may be either larger or smaller than the Rust type,
+                // due to the presence or absence of trailing padding. For example:
+                // - On some ABIs, the Rust layout { f64, f32, <f32 padding> } may omit padding
+                //   when passed by value, making it smaller.
+                // - On some ABIs, the Rust layout { u16, u16, u16 } may be padded up to 8 bytes
+                //   when passed by value, making it larger.
+                let copy_bytes = cmp::min(scratch_size.bytes(), self.layout.size.bytes());
+                // Allocate some scratch space...
+                let llscratch = bx.alloca(cast.llvm_type(bx), scratch_align);
+                bx.lifetime_start(llscratch, scratch_size);
+                // ...store the value...
+                bx.store(val, llscratch, scratch_align);
+                // ... and then memcpy it to the intended destination.
+                bx.memcpy(
+                    dst.llval,
+                    self.layout.align.abi,
+                    llscratch,
+                    scratch_align,
+                    bx.const_usize(copy_bytes),
+                    MemFlags::empty(),
+                );
+                bx.lifetime_end(llscratch, scratch_size);
             }
             _ => {
                 OperandRef::from_immediate_or_packed_pair(bx, val, self.layout).val.store(bx, dst);
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index e4ec7974e90..dc52dd156b7 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -2111,7 +2111,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         return Ok(args[0].immediate());
     }
 
-    if name == sym::simd_expose_addr {
+    if name == sym::simd_expose_provenance {
         let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
         require!(
             in_len == out_len,
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index d4123329f44..1aa52a985ef 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -1505,9 +1505,35 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         if by_ref && !arg.is_indirect() {
             // Have to load the argument, maybe while casting it.
-            if let PassMode::Cast { cast: ty, .. } = &arg.mode {
-                let llty = bx.cast_backend_type(ty);
-                llval = bx.load(llty, llval, align.min(arg.layout.align.abi));
+            if let PassMode::Cast { cast, pad_i32: _ } = &arg.mode {
+                // The ABI mandates that the value is passed as a different struct representation.
+                // Spill and reload it from the stack to convert from the Rust representation to
+                // the ABI representation.
+                let scratch_size = cast.size(bx);
+                let scratch_align = cast.align(bx);
+                // Note that the ABI type may be either larger or smaller than the Rust type,
+                // due to the presence or absence of trailing padding. For example:
+                // - On some ABIs, the Rust layout { f64, f32, <f32 padding> } may omit padding
+                //   when passed by value, making it smaller.
+                // - On some ABIs, the Rust layout { u16, u16, u16 } may be padded up to 8 bytes
+                //   when passed by value, making it larger.
+                let copy_bytes = cmp::min(scratch_size.bytes(), arg.layout.size.bytes());
+                // Allocate some scratch space...
+                let llscratch = bx.alloca(bx.cast_backend_type(cast), scratch_align);
+                bx.lifetime_start(llscratch, scratch_size);
+                // ...memcpy the value...
+                bx.memcpy(
+                    llscratch,
+                    scratch_align,
+                    llval,
+                    align,
+                    bx.const_usize(copy_bytes),
+                    MemFlags::empty(),
+                );
+                // ...and then load it with the ABI type.
+                let cast_ty = bx.cast_backend_type(cast);
+                llval = bx.load(cast_ty, llscratch, scratch_align);
+                bx.lifetime_end(llscratch, scratch_size);
             } else {
                 // We can't use `PlaceRef::load` here because the argument
                 // may have a type we don't treat as immediate, but the ABI
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 6f7b98a262d..4d746c89f1f 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -405,7 +405,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 let cast = bx.cx().layout_of(self.monomorphize(mir_cast_ty));
 
                 let val = match *kind {
-                    mir::CastKind::PointerExposeAddress => {
+                    mir::CastKind::PointerExposeProvenance => {
                         assert!(bx.cx().is_backend_immediate(cast));
                         let llptr = operand.immediate();
                         let llcast_ty = bx.cx().immediate_backend_type(cast);
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index e0d45f1fe11..9447d18fe8c 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -34,9 +34,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.unsize_into(src, cast_layout, dest)?;
             }
 
-            CastKind::PointerExposeAddress => {
+            CastKind::PointerExposeProvenance => {
                 let src = self.read_immediate(src)?;
-                let res = self.pointer_expose_address_cast(&src, cast_layout)?;
+                let res = self.pointer_expose_provenance_cast(&src, cast_layout)?;
                 self.write_immediate(*res, dest)?;
             }
 
@@ -225,7 +225,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         }
     }
 
-    pub fn pointer_expose_address_cast(
+    pub fn pointer_expose_provenance_cast(
         &mut self,
         src: &ImmTy<'tcx, M::Provenance>,
         cast_to: TyAndLayout<'tcx>,
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index b6dcc334147..543996c86ba 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -544,7 +544,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                 // Unsizing is implemented for CTFE.
             }
 
-            Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => {
+            Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
                 self.check_op(ops::RawPtrToIntCast);
             }
             Rvalue::Cast(CastKind::PointerWithExposedProvenance, _, _) => {
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index e1e98ebc1e9..a499e4b980f 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -1077,7 +1077,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     }
                     // FIXME: Add Checks for these
                     CastKind::PointerWithExposedProvenance
-                    | CastKind::PointerExposeAddress
+                    | CastKind::PointerExposeProvenance
                     | CastKind::PointerCoercion(_) => {}
                     CastKind::IntToInt | CastKind::IntToFloat => {
                         let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool();
diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
index a45f1dd72a1..30e240cf85b 100644
--- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
@@ -72,7 +72,7 @@ fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {
         IndexVec::with_capacity(graph.num_nodes());
 
     let mut stack = vec![PreOrderFrame {
-        pre_order_idx: PreorderIndex::new(0),
+        pre_order_idx: PreorderIndex::ZERO,
         iter: graph.successors(graph.start_node()),
     }];
     let mut pre_order_to_real: IndexVec<PreorderIndex, G::Node> =
@@ -80,8 +80,8 @@ fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {
     let mut real_to_pre_order: IndexVec<G::Node, Option<PreorderIndex>> =
         IndexVec::from_elem_n(None, graph.num_nodes());
     pre_order_to_real.push(graph.start_node());
-    parent.push(PreorderIndex::new(0)); // the parent of the root node is the root for now.
-    real_to_pre_order[graph.start_node()] = Some(PreorderIndex::new(0));
+    parent.push(PreorderIndex::ZERO); // the parent of the root node is the root for now.
+    real_to_pre_order[graph.start_node()] = Some(PreorderIndex::ZERO);
     let mut post_order_idx = 0;
 
     // Traverse the graph, collecting a number of things:
@@ -111,7 +111,7 @@ fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {
 
     let reachable_vertices = pre_order_to_real.len();
 
-    let mut idom = IndexVec::from_elem_n(PreorderIndex::new(0), reachable_vertices);
+    let mut idom = IndexVec::from_elem_n(PreorderIndex::ZERO, reachable_vertices);
     let mut semi = IndexVec::from_fn_n(std::convert::identity, reachable_vertices);
     let mut label = semi.clone();
     let mut bucket = IndexVec::from_elem_n(vec![], reachable_vertices);
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index c47abf5e988..b4107bd4a2b 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -1951,6 +1951,39 @@ pub fn report_ambiguity_error<'a, G: EmissionGuarantee>(
     }
 }
 
+/// Grammatical tool for displaying messages to end users in a nice form.
+///
+/// Returns "an" if the given string starts with a vowel, and "a" otherwise.
+pub fn a_or_an(s: &str) -> &'static str {
+    let mut chars = s.chars();
+    let Some(mut first_alpha_char) = chars.next() else {
+        return "a";
+    };
+    if first_alpha_char == '`' {
+        let Some(next) = chars.next() else {
+            return "a";
+        };
+        first_alpha_char = next;
+    }
+    if ["a", "e", "i", "o", "u", "&"].contains(&&first_alpha_char.to_lowercase().to_string()[..]) {
+        "an"
+    } else {
+        "a"
+    }
+}
+
+/// Grammatical tool for displaying messages to end users in a nice form.
+///
+/// Take a list ["a", "b", "c"] and output a display friendly version "a, b and c"
+pub fn display_list_with_comma_and<T: std::fmt::Display>(v: &[T]) -> String {
+    match v.len() {
+        0 => "".to_string(),
+        1 => v[0].to_string(),
+        2 => format!("{} and {}", v[0], v[1]),
+        _ => format!("{}, {}", v[0], display_list_with_comma_and(&v[1..])),
+    }
+}
+
 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
 pub enum TerminalUrl {
     No,
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index f6d63a293ba..f21cd653f96 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -846,9 +846,8 @@ pub struct OwnerNodes<'tcx> {
 
 impl<'tcx> OwnerNodes<'tcx> {
     pub fn node(&self) -> OwnerNode<'tcx> {
-        use rustc_index::Idx;
         // Indexing must ensure it is an OwnerNode.
-        self.nodes[ItemLocalId::new(0)].node.as_owner().unwrap()
+        self.nodes[ItemLocalId::ZERO].node.as_owner().unwrap()
     }
 }
 
@@ -856,7 +855,7 @@ impl fmt::Debug for OwnerNodes<'_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("OwnerNodes")
             // Do not print all the pointers to all the nodes, as it would be unreadable.
-            .field("node", &self.nodes[ItemLocalId::from_u32(0)])
+            .field("node", &self.nodes[ItemLocalId::ZERO])
             .field(
                 "parents",
                 &self
diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs
index d339075c171..0341a482fa8 100644
--- a/compiler/rustc_hir/src/hir_id.rs
+++ b/compiler/rustc_hir/src/hir_id.rs
@@ -17,7 +17,7 @@ impl Debug for OwnerId {
 
 impl From<OwnerId> for HirId {
     fn from(owner: OwnerId) -> HirId {
-        HirId { owner, local_id: ItemLocalId::from_u32(0) }
+        HirId { owner, local_id: ItemLocalId::ZERO }
     }
 }
 
@@ -110,7 +110,7 @@ impl HirId {
 
     #[inline]
     pub fn make_owner(owner: LocalDefId) -> Self {
-        Self { owner: OwnerId { def_id: owner }, local_id: ItemLocalId::from_u32(0) }
+        Self { owner: OwnerId { def_id: owner }, local_id: ItemLocalId::ZERO }
     }
 
     pub fn index(self) -> (usize, usize) {
@@ -172,6 +172,6 @@ unsafe impl StableOrd for ItemLocalId {
 
 /// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_ID`.
 pub const CRATE_HIR_ID: HirId =
-    HirId { owner: OwnerId { def_id: CRATE_DEF_ID }, local_id: ItemLocalId::from_u32(0) };
+    HirId { owner: OwnerId { def_id: CRATE_DEF_ID }, local_id: ItemLocalId::ZERO };
 
 pub const CRATE_OWNER_ID: OwnerId = OwnerId { def_id: CRATE_DEF_ID };
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index a880445a27c..739a7086992 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -899,7 +899,7 @@ pub 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::from_u32(0)].ty(tcx, args);
+        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")
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 00a0fca4907..bd64621f077 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -183,7 +183,7 @@ pub fn check_intrinsic_type(
             let region = ty::Region::new_bound(
                 tcx,
                 ty::INNERMOST,
-                ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon },
+                ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BrAnon },
             );
             let env_region = ty::Region::new_bound(
                 tcx,
@@ -495,7 +495,7 @@ pub fn check_intrinsic_type(
                 );
                 let discriminant_def_id = assoc_items[0];
 
-                let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon };
+                let br = ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BrAnon };
                 (
                     1,
                     0,
@@ -555,7 +555,7 @@ pub fn check_intrinsic_type(
             }
 
             sym::raw_eq => {
-                let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon };
+                let br = ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BrAnon };
                 let param_ty_lhs =
                     Ty::new_imm_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), param(0));
                 let br = ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrAnon };
@@ -627,7 +627,7 @@ pub fn check_intrinsic_type(
             sym::simd_cast
             | sym::simd_as
             | sym::simd_cast_ptr
-            | sym::simd_expose_addr
+            | sym::simd_expose_provenance
             | sym::simd_with_exposed_provenance => (2, 0, vec![param(0)], param(1)),
             sym::simd_bitmask => (2, 0, vec![param(0)], param(1)),
             sym::simd_select | sym::simd_select_bitmask => {
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index df4db3ec3fb..1958a80d47c 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -67,7 +67,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
             ty::RawPtr(ty, _) if self.is_thin_ptr_ty(ty) => Some(asm_ty_isize),
             ty::Adt(adt, args) if adt.repr().simd() => {
                 let fields = &adt.non_enum_variant().fields;
-                let elem_ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, args);
+                let elem_ty = fields[FieldIdx::ZERO].ty(self.tcx, args);
 
                 let (size, ty) = match elem_ty.kind() {
                     ty::Array(ty, len) => {
@@ -146,7 +146,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                     "expected first field of `MaybeUnit` to be `ManuallyDrop`"
                 );
                 let fields = &ty.non_enum_variant().fields;
-                let ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, args);
+                let ty = fields[FieldIdx::ZERO].ty(self.tcx, args);
                 self.get_asm_ty(ty)
             }
             _ => self.get_asm_ty(ty),
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 722def2563c..9d7deebac48 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -474,9 +474,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
             VariantData::Unit(..) | VariantData::Struct { .. } => {
                 tcx.type_of(tcx.hir().get_parent_item(hir_id)).instantiate_identity()
             }
-            VariantData::Tuple(..) => {
+            VariantData::Tuple(_, _, ctor) => {
                 let args = ty::GenericArgs::identity_for_item(tcx, def_id);
-                Ty::new_fn_def(tcx, def_id.to_def_id(), args)
+                Ty::new_fn_def(tcx, ctor.to_def_id(), args)
             }
         },
 
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 7a0890e50da..70f09dd6175 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -628,7 +628,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     let projection_ty = pred.skip_binder().projection_ty;
 
                     let args_with_infer_self = tcx.mk_args_from_iter(
-                        std::iter::once(Ty::new_var(tcx, ty::TyVid::from_u32(0)).into())
+                        std::iter::once(Ty::new_var(tcx, ty::TyVid::ZERO).into())
                             .chain(projection_ty.args.iter().skip(1)),
                     );
 
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
index d3ca35ba481..97ba946b7e0 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
@@ -6,9 +6,10 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::fold::BottomUpFolder;
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_middle::ty::{DynKind, ToPredicate};
-use rustc_span::Span;
+use rustc_span::{ErrorGuaranteed, Span};
 use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
 use rustc_trait_selection::traits::{self, hir_ty_lowering_object_safety_violations};
 
@@ -228,12 +229,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         if arg == dummy_self.into() {
                             let param = &generics.params[index];
                             missing_type_params.push(param.name);
-                            return Ty::new_misc_error(tcx).into();
+                            Ty::new_misc_error(tcx).into()
                         } else if arg.walk().any(|arg| arg == dummy_self.into()) {
                             references_self = true;
-                            return Ty::new_misc_error(tcx).into();
+                            let guar = tcx.dcx().span_delayed_bug(
+                                span,
+                                "trait object trait bounds reference `Self`",
+                            );
+                            replace_dummy_self_with_error(tcx, arg, guar)
+                        } else {
+                            arg
                         }
-                        arg
                     })
                     .collect();
                 let args = tcx.mk_args(&args);
@@ -288,18 +294,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     let guar = tcx
                         .dcx()
                         .span_delayed_bug(span, "trait object projection bounds reference `Self`");
-                    let args: Vec<_> = b
-                        .projection_ty
-                        .args
-                        .iter()
-                        .map(|arg| {
-                            if arg.walk().any(|arg| arg == dummy_self.into()) {
-                                return Ty::new_error(tcx, guar).into();
-                            }
-                            arg
-                        })
-                        .collect();
-                    b.projection_ty.args = tcx.mk_args(&args);
+                    b.projection_ty = replace_dummy_self_with_error(tcx, b.projection_ty, guar);
                 }
 
                 ty::ExistentialProjection::erase_self_ty(tcx, b)
@@ -357,3 +352,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         Ty::new_dynamic(tcx, existential_predicates, region_bound, representation)
     }
 }
+
+fn replace_dummy_self_with_error<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
+    tcx: TyCtxt<'tcx>,
+    t: T,
+    guar: ErrorGuaranteed,
+) -> T {
+    t.fold_with(&mut BottomUpFolder {
+        tcx,
+        ty_op: |ty| {
+            if ty == tcx.types.trait_object_dummy_self { Ty::new_error(tcx, guar) } else { ty }
+        },
+        lt_op: |lt| lt,
+        ct_op: |ct| ct,
+    })
+}
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index fbdc3d1adb8..1d51101c940 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -91,7 +91,7 @@ hir_typeck_lossy_provenance_int2ptr =
 hir_typeck_lossy_provenance_ptr2int =
     under strict provenance it is considered bad style to cast pointer `{$expr_ty}` to integer `{$cast_ty}`
     .suggestion = use `.addr()` to obtain the address of a pointer
-    .help = if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
+    .help = if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
 
 hir_typeck_method_call_on_unknown_raw_pointee =
     cannot call a method on a raw pointer with an unknown pointee type
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index 5841392dbcf..59a043d1d69 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -182,7 +182,7 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
         ty::Region::new_bound(
             tcx,
             ty::INNERMOST,
-            ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon },
+            ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BrAnon },
         ),
         panic_info_ty,
     );
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 5f5ff40fb9f..f1feffcc82c 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -17,7 +17,8 @@ use itertools::Itertools;
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::{
-    codes::*, pluralize, Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey,
+    a_or_an, codes::*, display_list_with_comma_and, pluralize, Applicability, Diag,
+    ErrorGuaranteed, MultiSpan, StashKey,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
@@ -818,6 +819,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         call_expr,
                         None,
                         Some(mismatch_idx),
+                        &matched_inputs,
+                        &formal_and_expected_inputs,
                         is_method,
                     );
                     suggest_confusable(&mut err);
@@ -904,6 +907,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
             err.span_label(full_call_span, format!("arguments to this {call_name} are incorrect"));
 
+            self.label_generic_mismatches(
+                &mut err,
+                fn_def_id,
+                &matched_inputs,
+                &provided_arg_tys,
+                &formal_and_expected_inputs,
+                is_method,
+            );
+
             if let hir::ExprKind::MethodCall(_, rcvr, _, _) = call_expr.kind
                 && provided_idx.as_usize() == expected_idx.as_usize()
             {
@@ -932,6 +944,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 call_expr,
                 Some(expected_ty),
                 Some(expected_idx.as_usize()),
+                &matched_inputs,
+                &formal_and_expected_inputs,
                 is_method,
             );
             suggest_confusable(&mut err);
@@ -1270,6 +1284,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
+        self.label_generic_mismatches(
+            &mut err,
+            fn_def_id,
+            &matched_inputs,
+            &provided_arg_tys,
+            &formal_and_expected_inputs,
+            is_method,
+        );
+
         // Incorporate the argument changes in the removal suggestion.
         // When a type is *missing*, and the rest are additional, we want to suggest these with a
         // multipart suggestion, but in order to do so we need to figure out *where* the arg that
@@ -1317,7 +1340,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         // Call out where the function is defined
-        self.label_fn_like(&mut err, fn_def_id, callee_ty, call_expr, None, None, is_method);
+        self.label_fn_like(
+            &mut err,
+            fn_def_id,
+            callee_ty,
+            call_expr,
+            None,
+            None,
+            &matched_inputs,
+            &formal_and_expected_inputs,
+            is_method,
+        );
 
         // And add a suggestion block for all of the parameters
         let suggestion_text = match suggestion_text {
@@ -2094,6 +2127,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected_ty: Option<Ty<'tcx>>,
         // A specific argument should be labeled, instead of all of them
         expected_idx: Option<usize>,
+        matched_inputs: &IndexVec<ExpectedIdx, Option<ProvidedIdx>>,
+        formal_and_expected_inputs: &IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
         is_method: bool,
     ) {
         let Some(mut def_id) = callable_def_id else {
@@ -2185,21 +2220,164 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         {
             let mut spans: MultiSpan = def_span.into();
 
-            let params = self
+            let params_with_generics = self.get_hir_params_with_generics(def_id, is_method);
+            let mut generics_with_unmatched_params = Vec::new();
+
+            let check_for_matched_generics = || {
+                if matched_inputs.iter().any(|x| x.is_some())
+                    && params_with_generics.iter().any(|x| x.0.is_some())
+                {
+                    for (idx, (generic, _)) in params_with_generics.iter().enumerate() {
+                        // Param has to have a generic and be matched to be relevant
+                        if matched_inputs[idx.into()].is_none() {
+                            continue;
+                        }
+
+                        let Some(generic) = generic else {
+                            continue;
+                        };
+
+                        for unmatching_idx in idx + 1..params_with_generics.len() {
+                            if matched_inputs[unmatching_idx.into()].is_none()
+                                && let Some(unmatched_idx_param_generic) =
+                                    params_with_generics[unmatching_idx].0
+                                && unmatched_idx_param_generic.name.ident() == generic.name.ident()
+                            {
+                                // We found a parameter that didn't match that needed to
+                                return true;
+                            }
+                        }
+                    }
+                }
+                false
+            };
+
+            let check_for_matched_generics = check_for_matched_generics();
+
+            for (idx, (generic_param, param)) in
+                params_with_generics.iter().enumerate().filter(|(idx, _)| {
+                    check_for_matched_generics
+                        || expected_idx.map_or(true, |expected_idx| expected_idx == *idx)
+                })
+            {
+                let Some(generic_param) = generic_param else {
+                    spans.push_span_label(param.span, "");
+                    continue;
+                };
+
+                let other_params_matched: Vec<(usize, &hir::Param<'_>)> = params_with_generics
+                    .iter()
+                    .enumerate()
+                    .filter(|(other_idx, (other_generic_param, _))| {
+                        if *other_idx == idx {
+                            return false;
+                        }
+                        let Some(other_generic_param) = other_generic_param else {
+                            return false;
+                        };
+                        if matched_inputs[idx.into()].is_none()
+                            && matched_inputs[(*other_idx).into()].is_none()
+                        {
+                            return false;
+                        }
+                        if matched_inputs[idx.into()].is_some()
+                            && matched_inputs[(*other_idx).into()].is_some()
+                        {
+                            return false;
+                        }
+                        other_generic_param.name.ident() == generic_param.name.ident()
+                    })
+                    .map(|(other_idx, (_, other_param))| (other_idx, *other_param))
+                    .collect();
+
+                if !other_params_matched.is_empty() {
+                    let other_param_matched_names: Vec<String> = other_params_matched
+                        .iter()
+                        .map(|(_, other_param)| {
+                            if let hir::PatKind::Binding(_, _, ident, _) = other_param.pat.kind {
+                                format!("`{ident}`")
+                            } else {
+                                "{unknown}".to_string()
+                            }
+                        })
+                        .collect();
+
+                    let matched_ty = self
+                        .resolve_vars_if_possible(formal_and_expected_inputs[idx.into()].1)
+                        .sort_string(self.tcx);
+
+                    if matched_inputs[idx.into()].is_some() {
+                        spans.push_span_label(
+                            param.span,
+                            format!(
+                                "{} {} to match the {} type of this parameter",
+                                display_list_with_comma_and(&other_param_matched_names),
+                                format!(
+                                    "need{}",
+                                    pluralize!(if other_param_matched_names.len() == 1 {
+                                        0
+                                    } else {
+                                        1
+                                    })
+                                ),
+                                matched_ty,
+                            ),
+                        );
+                    } else {
+                        spans.push_span_label(
+                            param.span,
+                            format!(
+                                "this parameter needs to match the {} type of {}",
+                                matched_ty,
+                                display_list_with_comma_and(&other_param_matched_names),
+                            ),
+                        );
+                    }
+                    generics_with_unmatched_params.push(generic_param);
+                } else {
+                    spans.push_span_label(param.span, "");
+                }
+            }
+
+            for generic_param in self
                 .tcx
                 .hir()
                 .get_if_local(def_id)
-                .and_then(|node| node.body_id())
-                .into_iter()
-                .flat_map(|id| self.tcx.hir().body(id).params)
-                .skip(if is_method { 1 } else { 0 });
-
-            for (_, param) in params
+                .and_then(|node| node.generics())
                 .into_iter()
-                .enumerate()
-                .filter(|(idx, _)| expected_idx.map_or(true, |expected_idx| expected_idx == *idx))
+                .flat_map(|x| x.params)
+                .filter(|x| {
+                    generics_with_unmatched_params.iter().any(|y| x.name.ident() == y.name.ident())
+                })
             {
-                spans.push_span_label(param.span, "");
+                let param_idents_matching: Vec<String> = params_with_generics
+                    .iter()
+                    .filter(|(generic, _)| {
+                        if let Some(generic) = generic {
+                            generic.name.ident() == generic_param.name.ident()
+                        } else {
+                            false
+                        }
+                    })
+                    .map(|(_, param)| {
+                        if let hir::PatKind::Binding(_, _, ident, _) = param.pat.kind {
+                            format!("`{ident}`")
+                        } else {
+                            "{unknown}".to_string()
+                        }
+                    })
+                    .collect();
+
+                if !param_idents_matching.is_empty() {
+                    spans.push_span_label(
+                        generic_param.span,
+                        format!(
+                            "{} all reference this parameter {}",
+                            display_list_with_comma_and(&param_idents_matching),
+                            generic_param.name.ident().name,
+                        ),
+                    );
+                }
             }
 
             err.span_note(spans, format!("{} defined here", self.tcx.def_descr(def_id)));
@@ -2260,6 +2438,115 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
         }
     }
+
+    fn label_generic_mismatches(
+        &self,
+        err: &mut Diag<'_>,
+        callable_def_id: Option<DefId>,
+        matched_inputs: &IndexVec<ExpectedIdx, Option<ProvidedIdx>>,
+        provided_arg_tys: &IndexVec<ProvidedIdx, (Ty<'tcx>, Span)>,
+        formal_and_expected_inputs: &IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
+        is_method: bool,
+    ) {
+        let Some(def_id) = callable_def_id else {
+            return;
+        };
+
+        let params_with_generics = self.get_hir_params_with_generics(def_id, is_method);
+
+        for (idx, (generic_param, _)) in params_with_generics.iter().enumerate() {
+            if matched_inputs[idx.into()].is_none() {
+                continue;
+            }
+
+            let Some((_, matched_arg_span)) = provided_arg_tys.get(idx.into()) else {
+                continue;
+            };
+
+            let Some(generic_param) = generic_param else {
+                continue;
+            };
+
+            let mut idxs_matched: Vec<usize> = vec![];
+            for (other_idx, (_, _)) in params_with_generics.iter().enumerate().filter(
+                |(other_idx, (other_generic_param, _))| {
+                    if *other_idx == idx {
+                        return false;
+                    }
+                    let Some(other_generic_param) = other_generic_param else {
+                        return false;
+                    };
+                    if matched_inputs[(*other_idx).into()].is_some() {
+                        return false;
+                    }
+                    other_generic_param.name.ident() == generic_param.name.ident()
+                },
+            ) {
+                idxs_matched.push(other_idx.into());
+            }
+
+            if idxs_matched.is_empty() {
+                continue;
+            }
+
+            let expected_display_type = self
+                .resolve_vars_if_possible(formal_and_expected_inputs[idx.into()].1)
+                .sort_string(self.tcx);
+            let label = if idxs_matched.len() == params_with_generics.len() - 1 {
+                format!(
+                    "expected all arguments to be this {} type because they need to match the type of this parameter",
+                    expected_display_type
+                )
+            } else {
+                format!(
+                    "expected some other arguments to be {} {} type to match the type of this parameter",
+                    a_or_an(&expected_display_type),
+                    expected_display_type,
+                )
+            };
+
+            err.span_label(*matched_arg_span, label);
+        }
+    }
+
+    fn get_hir_params_with_generics(
+        &self,
+        def_id: DefId,
+        is_method: bool,
+    ) -> Vec<(Option<&hir::GenericParam<'_>>, &hir::Param<'_>)> {
+        let fn_node = self.tcx.hir().get_if_local(def_id);
+
+        let generic_params: Vec<Option<&hir::GenericParam<'_>>> = fn_node
+            .and_then(|node| node.fn_decl())
+            .into_iter()
+            .flat_map(|decl| decl.inputs)
+            .skip(if is_method { 1 } else { 0 })
+            .map(|param| {
+                if let hir::TyKind::Path(QPath::Resolved(
+                    _,
+                    hir::Path { res: Res::Def(_, res_def_id), .. },
+                )) = param.kind
+                {
+                    fn_node
+                        .and_then(|node| node.generics())
+                        .into_iter()
+                        .flat_map(|generics| generics.params)
+                        .find(|gen| &gen.def_id.to_def_id() == res_def_id)
+                } else {
+                    None
+                }
+            })
+            .collect();
+
+        let params: Vec<&hir::Param<'_>> = fn_node
+            .and_then(|node| node.body_id())
+            .into_iter()
+            .flat_map(|id| self.tcx.hir().body(id).params)
+            .skip(if is_method { 1 } else { 0 })
+            .collect();
+
+        generic_params.into_iter().zip(params).collect()
+    }
 }
 
 struct FindClosureArg<'tcx> {
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index 9e3867e630d..62711e40049 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -17,7 +17,7 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
         let data_idx;
 
         let one = VariantIdx::new(1);
-        let zero = VariantIdx::new(0);
+        let zero = VariantIdx::ZERO;
 
         if def.variant(zero).fields.is_empty() {
             data_idx = one;
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 12f522d1adc..a199f57aad9 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -774,7 +774,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         let projection_ty = pred.skip_binder().projection_ty;
 
                         let args_with_infer_self = tcx.mk_args_from_iter(
-                            iter::once(Ty::new_var(tcx, ty::TyVid::from_u32(0)).into())
+                            iter::once(Ty::new_var(tcx, ty::TyVid::ZERO).into())
                                 .chain(projection_ty.args.iter().skip(1)),
                         );
 
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 54344adaabd..72e5b1ed95b 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -343,10 +343,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let closure_env_region: ty::Region<'_> = ty::Region::new_bound(
                 self.tcx,
                 ty::INNERMOST,
-                ty::BoundRegion {
-                    var: ty::BoundVar::from_usize(0),
-                    kind: ty::BoundRegionKind::BrEnv,
-                },
+                ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::BrEnv },
             );
             let tupled_upvars_ty_for_borrow = Ty::new_tup_from_iter(
                 self.tcx,
diff --git a/compiler/rustc_index_macros/src/newtype.rs b/compiler/rustc_index_macros/src/newtype.rs
index e5c2ba42483..fe9a048734f 100644
--- a/compiler/rustc_index_macros/src/newtype.rs
+++ b/compiler/rustc_index_macros/src/newtype.rs
@@ -174,6 +174,9 @@ impl Parse for Newtype {
                 /// Maximum value the index can take.
                 #vis const MAX: Self = Self::from_u32(#max);
 
+                /// Zero value of the index.
+                #vis const ZERO: Self = Self::from_u32(0);
+
                 /// Creates a new index from a given `usize`.
                 ///
                 /// # Panics
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index d763a12f816..1f92cc4d763 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -748,9 +748,6 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
 
     sess.time("MIR_effect_checking", || {
         for def_id in tcx.hir().body_owners() {
-            if !tcx.sess.opts.unstable_opts.thir_unsafeck {
-                rustc_mir_transform::check_unsafety::check_unsafety(tcx, def_id);
-            }
             tcx.ensure().has_ffi_unwind_calls(def_id);
 
             // If we need to codegen, ensure that we emit all errors from
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 3b78e6a43ab..b9025917d13 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -840,7 +840,6 @@ fn test_unstable_options_tracking_hash() {
     tracked!(stack_protector, StackProtector::All);
     tracked!(teach, true);
     tracked!(thinlto, Some(true));
-    tracked!(thir_unsafeck, false);
     tracked!(tiny_const_eval_limit, true);
     tracked!(tls_model, Some(TlsModel::GeneralDynamic));
     tracked!(translate_remapped_path_to_local_path, false);
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 7e9d35ca6c1..30522628f46 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -2797,17 +2797,17 @@ declare_lint! {
     /// Since this cast is lossy, it is considered good style to use the
     /// [`ptr::addr`] method instead, which has a similar effect, but doesn't
     /// "expose" the pointer provenance. This improves optimisation potential.
-    /// See the docs of [`ptr::addr`] and [`ptr::expose_addr`] for more information
+    /// See the docs of [`ptr::addr`] and [`ptr::expose_provenance`] for more information
     /// about exposing pointer provenance.
     ///
     /// If your code can't comply with strict provenance and needs to expose
-    /// the provenance, then there is [`ptr::expose_addr`] as an escape hatch,
+    /// the provenance, then there is [`ptr::expose_provenance`] as an escape hatch,
     /// which preserves the behaviour of `as usize` casts while being explicit
     /// about the semantics.
     ///
     /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
     /// [`ptr::addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.addr
-    /// [`ptr::expose_addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.expose_addr
+    /// [`ptr::expose_provenance`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.expose_provenance
     pub LOSSY_PROVENANCE_CASTS,
     Allow,
     "a lossy pointer to integer cast is used",
diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index 4b0c1229da1..e2c0ec90c7c 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
@@ -391,6 +391,12 @@ fn main() {
         }
     }
 
+    // libc++abi and libunwind have to be specified explicitly on AIX.
+    if target.contains("aix") {
+        println!("cargo:rustc-link-lib=c++abi");
+        println!("cargo:rustc-link-lib=unwind");
+    }
+
     // Libstdc++ depends on pthread which Rust doesn't link on MinGW
     // since nothing else requires it.
     if target.ends_with("windows-gnu") {
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index c90427256b8..bd11b3eb04c 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -35,7 +35,6 @@ macro_rules! arena_types {
             )>,
             [] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>,
             [] resolutions: rustc_middle::ty::ResolverGlobalCtxt,
-            [decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult,
             [decode] code_region: rustc_middle::mir::coverage::CodeRegion,
             [] const_allocs: rustc_middle::mir::interpret::Allocation,
             [] region_scope_tree: rustc_middle::middle::region::ScopeTree,
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 53cb05198cd..72f849b534a 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -13,7 +13,6 @@ use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::*;
-use rustc_index::Idx;
 use rustc_middle::hir::nested_filter;
 use rustc_span::def_id::StableCrateId;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -69,7 +68,7 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> {
 
     fn next(&mut self) -> Option<Self::Item> {
         if self.current_id.local_id.index() != 0 {
-            self.current_id.local_id = ItemLocalId::new(0);
+            self.current_id.local_id = ItemLocalId::ZERO;
             let node = self.map.tcx.hir_owner_node(self.current_id.owner);
             return Some((self.current_id.owner, node));
         }
@@ -133,7 +132,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`].
     pub fn parent_hir_id(self, hir_id: HirId) -> HirId {
         let HirId { owner, local_id } = hir_id;
-        if local_id == ItemLocalId::from_u32(0) {
+        if local_id == ItemLocalId::ZERO {
             self.hir_owner_parent(owner)
         } else {
             let parent_local_id = self.hir_owner_nodes(owner).nodes[local_id].parent;
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index 28f7574f66f..42a06c968c7 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -174,8 +174,12 @@ pub fn provide(providers: &mut Providers) {
             let parent_owner_id = tcx.local_def_id_to_hir_id(parent_def_id).owner;
             HirId {
                 owner: parent_owner_id,
-                local_id: tcx.hir_crate(()).owners[parent_owner_id.def_id].unwrap().parenting
-                    [&owner_id.def_id],
+                local_id: tcx.hir_crate(()).owners[parent_owner_id.def_id]
+                    .unwrap()
+                    .parenting
+                    .get(&owner_id.def_id)
+                    .copied()
+                    .unwrap_or(ItemLocalId::from_u32(0)),
             }
         })
     };
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index 7b65c11bc3c..acea89e4aab 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -82,7 +82,7 @@ impl CanonicalVarValues<'_> {
     }
 
     pub fn is_identity_modulo_regions(&self) -> bool {
-        let mut var = ty::BoundVar::from_u32(0);
+        let mut var = ty::BoundVar::ZERO;
         for arg in self.var_values {
             match arg.unpack() {
                 ty::GenericArgKind::Lifetime(r) => {
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index 588aa1f40d7..0c91dc6d3c6 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -34,7 +34,7 @@ rustc_index::newtype_index! {
 }
 
 impl CounterId {
-    pub const START: Self = Self::from_u32(0);
+    pub const START: Self = Self::ZERO;
 }
 
 rustc_index::newtype_index! {
@@ -56,7 +56,7 @@ rustc_index::newtype_index! {
 }
 
 impl ExpressionId {
-    pub const START: Self = Self::from_u32(0);
+    pub const START: Self = Self::ZERO;
 }
 
 /// Enum that can hold a constant zero value, the ID of an physical coverage
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index e046f076389..ad166620bcc 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -845,17 +845,6 @@ impl<'tcx> Body<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)]
-pub enum Safety {
-    Safe,
-    /// Unsafe because of compiler-generated unsafe code, like `await` desugaring
-    BuiltinUnsafe,
-    /// Unsafe because of an unsafe fn
-    FnUnsafe,
-    /// Unsafe because of an `unsafe` block
-    ExplicitUnsafe(hir::HirId),
-}
-
 impl<'tcx> Index<BasicBlock> for Body<'tcx> {
     type Output = BasicBlockData<'tcx>;
 
@@ -1611,8 +1600,6 @@ pub struct SourceScopeData<'tcx> {
 pub struct SourceScopeLocalData {
     /// An `HirId` with lint levels equivalent to this scope's lint levels.
     pub lint_root: hir::HirId,
-    /// The unsafe block that contains this node.
-    pub safety: Safety,
 }
 
 /// A collection of projections into user types.
@@ -1888,7 +1875,7 @@ mod size_asserts {
     // tidy-alphabetical-start
     static_assert_size!(BasicBlockData<'_>, 144);
     static_assert_size!(LocalDecl<'_>, 40);
-    static_assert_size!(SourceScopeData<'_>, 72);
+    static_assert_size!(SourceScopeData<'_>, 64);
     static_assert_size!(Statement<'_>, 32);
     static_assert_size!(StatementKind<'_>, 16);
     static_assert_size!(Terminator<'_>, 112);
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index 0a567e2781d..0f622127430 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -3,9 +3,7 @@
 use crate::mir;
 use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
 use rustc_data_structures::fx::FxIndexMap;
-use rustc_data_structures::unord::UnordSet;
 use rustc_errors::ErrorGuaranteed;
-use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_index::bit_set::BitMatrix;
 use rustc_index::{Idx, IndexVec};
@@ -18,67 +16,6 @@ use std::fmt::{self, Debug};
 
 use super::{ConstValue, SourceInfo};
 
-#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
-pub enum UnsafetyViolationKind {
-    /// Unsafe operation outside `unsafe`.
-    General,
-    /// Unsafe operation in an `unsafe fn` but outside an `unsafe` block.
-    /// Has to be handled as a lint for backwards compatibility.
-    UnsafeFn,
-}
-
-#[derive(Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
-pub enum UnsafetyViolationDetails {
-    CallToUnsafeFunction,
-    UseOfInlineAssembly,
-    InitializingTypeWith,
-    CastOfPointerToInt,
-    UseOfMutableStatic,
-    UseOfExternStatic,
-    DerefOfRawPointer,
-    AccessToUnionField,
-    MutationOfLayoutConstrainedField,
-    BorrowOfLayoutConstrainedField,
-    CallToFunctionWith {
-        /// Target features enabled in callee's `#[target_feature]` but missing in
-        /// caller's `#[target_feature]`.
-        missing: Vec<Symbol>,
-        /// Target features in `missing` that are enabled at compile time
-        /// (e.g., with `-C target-feature`).
-        build_enabled: Vec<Symbol>,
-    },
-}
-
-#[derive(Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
-pub struct UnsafetyViolation {
-    pub source_info: SourceInfo,
-    pub lint_root: hir::HirId,
-    pub kind: UnsafetyViolationKind,
-    pub details: UnsafetyViolationDetails,
-}
-
-#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
-pub enum UnusedUnsafe {
-    /// `unsafe` block contains no unsafe operations
-    /// > ``unnecessary `unsafe` block``
-    Unused,
-    /// `unsafe` block nested under another (used) `unsafe` block
-    /// > ``… because it's nested under this `unsafe` block``
-    InUnsafeBlock(hir::HirId),
-}
-
-#[derive(TyEncodable, TyDecodable, HashStable, Debug)]
-pub struct UnsafetyCheckResult {
-    /// Violations that are propagated *upwards* from this function.
-    pub violations: Vec<UnsafetyViolation>,
-
-    /// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint.
-    pub used_unsafe_blocks: UnordSet<hir::HirId>,
-
-    /// This is `Some` iff the item is not a closure.
-    pub unused_unsafes: Option<Vec<(hir::HirId, UnusedUnsafe)>>,
-}
-
 rustc_index::newtype_index! {
     #[derive(HashStable)]
     #[encodable]
diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs
index 947764307e4..069c8019cb2 100644
--- a/compiler/rustc_middle/src/mir/statement.rs
+++ b/compiler/rustc_middle/src/mir/statement.rs
@@ -409,7 +409,7 @@ impl<'tcx> Rvalue<'tcx> {
             // Pointer to int casts may be side-effects due to exposing the provenance.
             // While the model is undecided, we should be conservative. See
             // <https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html>
-            Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => false,
+            Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => false,
 
             Rvalue::Use(_)
             | Rvalue::CopyForDeref(_)
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index eae6ef8c396..c78c225b0cd 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1309,8 +1309,8 @@ pub enum Rvalue<'tcx> {
 pub enum CastKind {
     /// An exposing pointer to address cast. A cast between a pointer and an integer type, or
     /// between a function pointer and an integer type.
-    /// See the docs on `expose_addr` for more details.
-    PointerExposeAddress,
+    /// See the docs on `expose_provenance` for more details.
+    PointerExposeProvenance,
     /// An address-to-pointer cast that picks up an exposed provenance.
     /// See the docs on `with_exposed_provenance` for more details.
     PointerWithExposedProvenance,
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 5e4454db3e2..62a60a650ec 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -877,12 +877,6 @@ rustc_queries! {
         desc { |tcx| "collecting all inherent impls for `{:?}`", key }
     }
 
-    /// The result of unsafety-checking this `LocalDefId` with the old checker.
-    query mir_unsafety_check_result(key: LocalDefId) -> &'tcx mir::UnsafetyCheckResult {
-        desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) }
-        cache_on_disk_if { true }
-    }
-
     /// Unsafety-check this `LocalDefId`.
     query check_unsafety(key: LocalDefId) {
         desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) }
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 9bb38a893eb..f10b204cd47 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -12,7 +12,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_errors::{DiagArgValue, IntoDiagArg};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
-use rustc_hir::{BindingAnnotation, ByRef, RangeEnd};
+use rustc_hir::{BindingAnnotation, ByRef, MatchSource, RangeEnd};
 use rustc_index::newtype_index;
 use rustc_index::IndexVec;
 use rustc_middle::middle::region;
@@ -358,6 +358,7 @@ pub enum ExprKind<'tcx> {
         scrutinee: ExprId,
         scrutinee_hir_id: hir::HirId,
         arms: Box<[ArmId]>,
+        match_source: MatchSource,
     },
     /// A block.
     Block {
@@ -1120,7 +1121,8 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
                             printed += 1;
                         }
 
-                        if printed < variant.fields.len() {
+                        let is_union = self.ty.ty_adt_def().is_some_and(|adt| adt.is_union());
+                        if printed < variant.fields.len() && (!is_union || printed == 0) {
                             write!(f, "{}..", start_or_comma())?;
                         }
 
diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs
index 9bdc679d4e5..c9fd20bc112 100644
--- a/compiler/rustc_middle/src/ty/cast.rs
+++ b/compiler/rustc_middle/src/ty/cast.rs
@@ -83,7 +83,7 @@ pub fn mir_cast_kind<'tcx>(from_ty: Ty<'tcx>, cast_ty: Ty<'tcx>) -> mir::CastKin
     let cast = CastTy::from_ty(cast_ty);
     let cast_kind = match (from, cast) {
         (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => {
-            mir::CastKind::PointerExposeAddress
+            mir::CastKind::PointerExposeProvenance
         }
         (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance,
         (_, Some(CastTy::DynStar)) => mir::CastKind::DynStar,
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index ddbc0bffaed..e7a1679b151 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -458,7 +458,6 @@ impl_decodable_via_ref! {
     &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
     &'tcx traits::ImplSource<'tcx, ()>,
     &'tcx mir::Body<'tcx>,
-    &'tcx mir::UnsafetyCheckResult,
     &'tcx mir::BorrowCheckResult<'tcx>,
     &'tcx mir::coverage::CodeRegion,
     &'tcx ty::List<ty::BoundVariableKind>,
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 23881c4b124..b8d68c1b8be 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1961,33 +1961,104 @@ impl<'tcx> TyCtxt<'tcx> {
         if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
     }
 
-    #[inline(always)]
-    pub(crate) fn check_and_mk_args(
+    pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
+        self.check_args_compatible_inner(def_id, args, false)
+    }
+
+    fn check_args_compatible_inner(
         self,
-        _def_id: DefId,
-        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
-    ) -> GenericArgsRef<'tcx> {
-        let args = args.into_iter().map(Into::into);
-        #[cfg(debug_assertions)]
+        def_id: DefId,
+        args: &'tcx [ty::GenericArg<'tcx>],
+        nested: bool,
+    ) -> bool {
+        let generics = self.generics_of(def_id);
+
+        // IATs themselves have a weird arg setup (self + own args), but nested items *in* IATs
+        // (namely: opaques, i.e. ATPITs) do not.
+        let own_args = if !nested
+            && let DefKind::AssocTy = self.def_kind(def_id)
+            && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
         {
-            let generics = self.generics_of(_def_id);
+            if generics.params.len() + 1 != args.len() {
+                return false;
+            }
 
-            let n = if let DefKind::AssocTy = self.def_kind(_def_id)
-                && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(_def_id))
+            if !matches!(args[0].unpack(), ty::GenericArgKind::Type(_)) {
+                return false;
+            }
+
+            &args[1..]
+        } else {
+            if generics.count() != args.len() {
+                return false;
+            }
+
+            let (parent_args, own_args) = args.split_at(generics.parent_count);
+
+            if let Some(parent) = generics.parent
+                && !self.check_args_compatible_inner(parent, parent_args, true)
             {
-                // If this is an inherent projection.
-                generics.params.len() + 1
-            } else {
-                generics.count()
-            };
-            assert_eq!(
-                (n, Some(n)),
-                args.size_hint(),
-                "wrong number of generic parameters for {_def_id:?}: {:?}",
-                args.collect::<Vec<_>>(),
-            );
+                return false;
+            }
+
+            own_args
+        };
+
+        for (param, arg) in std::iter::zip(&generics.params, own_args) {
+            match (&param.kind, arg.unpack()) {
+                (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
+                | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
+                | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
+                _ => return false,
+            }
         }
-        self.mk_args_from_iter(args)
+
+        true
+    }
+
+    /// With `cfg(debug_assertions)`, assert that args are compatible with their generics,
+    /// and print out the args if not.
+    pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
+        if cfg!(debug_assertions) {
+            if !self.check_args_compatible(def_id, args) {
+                if let DefKind::AssocTy = self.def_kind(def_id)
+                    && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
+                {
+                    bug!(
+                        "args not compatible with generics for {}: args={:#?}, generics={:#?}",
+                        self.def_path_str(def_id),
+                        args,
+                        // Make `[Self, GAT_ARGS...]` (this could be simplified)
+                        self.mk_args_from_iter(
+                            [self.types.self_param.into()].into_iter().chain(
+                                self.generics_of(def_id)
+                                    .own_args(ty::GenericArgs::identity_for_item(self, def_id))
+                                    .iter()
+                                    .copied()
+                            )
+                        )
+                    );
+                } else {
+                    bug!(
+                        "args not compatible with generics for {}: args={:#?}, generics={:#?}",
+                        self.def_path_str(def_id),
+                        args,
+                        ty::GenericArgs::identity_for_item(self, def_id)
+                    );
+                }
+            }
+        }
+    }
+
+    #[inline(always)]
+    pub(crate) fn check_and_mk_args(
+        self,
+        def_id: DefId,
+        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
+    ) -> GenericArgsRef<'tcx> {
+        let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
+        self.debug_assert_args_compatible(def_id, args);
+        args
     }
 
     #[inline]
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 191cdafacb6..62bfa0ff928 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -1324,7 +1324,7 @@ impl VariantDef {
     pub fn single_field(&self) -> &FieldDef {
         assert!(self.fields.len() == 1);
 
-        &self.fields[FieldIdx::from_u32(0)]
+        &self.fields[FieldIdx::ZERO]
     }
 
     /// Returns the last field in this variant, if present.
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 5ff98dc8c87..2a898430ce9 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2589,7 +2589,7 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
                     ty::BrAnon | ty::BrEnv => r,
                     _ => {
                         // Index doesn't matter, since this is just for naming and these never get bound
-                        let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind };
+                        let br = ty::BoundRegion { var: ty::BoundVar::ZERO, kind };
                         *self
                             .region_map
                             .entry(br)
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index fb511f2275f..2ab63f01e7c 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -11,7 +11,7 @@ use crate::ty::{
 };
 use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
 use crate::ty::{List, ParamEnv};
-use hir::def::DefKind;
+use hir::def::{CtorKind, DefKind};
 use rustc_data_structures::captures::Captures;
 use rustc_errors::{DiagArgValue, ErrorGuaranteed, IntoDiagArg, MultiSpan};
 use rustc_hir as hir;
@@ -1624,13 +1624,7 @@ impl<'tcx> Ty<'tcx> {
 
     #[inline]
     pub fn new_adt(tcx: TyCtxt<'tcx>, def: AdtDef<'tcx>, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
-        debug_assert_eq!(
-            tcx.generics_of(def.did()).count(),
-            args.len(),
-            "wrong number of args for ADT: {:#?} vs {:#?}",
-            tcx.generics_of(def.did()).params,
-            args
-        );
+        tcx.debug_assert_args_compatible(def.did(), args);
         Ty::new(tcx, Adt(def, args))
     }
 
@@ -1677,6 +1671,10 @@ impl<'tcx> Ty<'tcx> {
         def_id: DefId,
         args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
     ) -> Ty<'tcx> {
+        debug_assert_matches!(
+            tcx.def_kind(def_id),
+            DefKind::AssocFn | DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn)
+        );
         let args = tcx.check_and_mk_args(def_id, args);
         Ty::new(tcx, FnDef(def_id, args))
     }
@@ -1711,11 +1709,7 @@ impl<'tcx> Ty<'tcx> {
         def_id: DefId,
         closure_args: GenericArgsRef<'tcx>,
     ) -> Ty<'tcx> {
-        debug_assert_eq!(
-            closure_args.len(),
-            tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 3,
-            "closure constructed with incorrect generic parameters"
-        );
+        tcx.debug_assert_args_compatible(def_id, closure_args);
         Ty::new(tcx, Closure(def_id, closure_args))
     }
 
@@ -1725,11 +1719,7 @@ impl<'tcx> Ty<'tcx> {
         def_id: DefId,
         closure_args: GenericArgsRef<'tcx>,
     ) -> Ty<'tcx> {
-        debug_assert_eq!(
-            closure_args.len(),
-            tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 5,
-            "closure constructed with incorrect generic parameters"
-        );
+        tcx.debug_assert_args_compatible(def_id, closure_args);
         Ty::new(tcx, CoroutineClosure(def_id, closure_args))
     }
 
@@ -1739,11 +1729,7 @@ impl<'tcx> Ty<'tcx> {
         def_id: DefId,
         coroutine_args: GenericArgsRef<'tcx>,
     ) -> Ty<'tcx> {
-        debug_assert_eq!(
-            coroutine_args.len(),
-            tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 6,
-            "coroutine constructed with incorrect number of generic parameters"
-        );
+        tcx.debug_assert_args_compatible(def_id, coroutine_args);
         Ty::new(tcx, Coroutine(def_id, coroutine_args))
     }
 
@@ -1954,7 +1940,7 @@ impl<'tcx> Ty<'tcx> {
             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::from_u32(0)].ty(tcx, args);
+                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
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index d60926bf796..0d74524276f 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -19,7 +19,7 @@ use rustc_hir::{
     hir_id::OwnerId,
     BindingAnnotation, ByRef, HirId, ItemLocalId, ItemLocalMap, ItemLocalSet, Mutability,
 };
-use rustc_index::{Idx, IndexVec};
+use rustc_index::IndexVec;
 use rustc_macros::HashStable;
 use rustc_middle::mir::FakeReadCause;
 use rustc_session::Session;
@@ -680,7 +680,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
                     return false;
                 }
 
-                iter::zip(user_args.args, BoundVar::new(0)..).all(|(kind, cvar)| {
+                iter::zip(user_args.args, BoundVar::ZERO..).all(|(kind, cvar)| {
                     match kind.unpack() {
                         GenericArgKind::Type(ty) => match ty.kind() {
                             ty::Bound(debruijn, b) => {
diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs
index 6200f4bda6b..00e99f330f7 100644
--- a/compiler/rustc_mir_build/src/build/block.rs
+++ b/compiler/rustc_mir_build/src/build/block.rs
@@ -13,31 +13,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         ast_block: BlockId,
         source_info: SourceInfo,
     ) -> BlockAnd<()> {
-        let Block { region_scope, span, ref stmts, expr, targeted_by_break, safety_mode } =
+        let Block { region_scope, span, ref stmts, expr, targeted_by_break, safety_mode: _ } =
             self.thir[ast_block];
         self.in_scope((region_scope, source_info), LintLevel::Inherited, move |this| {
             if targeted_by_break {
                 this.in_breakable_scope(None, destination, span, |this| {
-                    Some(this.ast_block_stmts(
-                        destination,
-                        block,
-                        span,
-                        stmts,
-                        expr,
-                        safety_mode,
-                        region_scope,
-                    ))
+                    Some(this.ast_block_stmts(destination, block, span, stmts, expr, region_scope))
                 })
             } else {
-                this.ast_block_stmts(
-                    destination,
-                    block,
-                    span,
-                    stmts,
-                    expr,
-                    safety_mode,
-                    region_scope,
-                )
+                this.ast_block_stmts(destination, block, span, stmts, expr, region_scope)
             }
         })
     }
@@ -49,7 +33,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         span: Span,
         stmts: &[StmtId],
         expr: Option<ExprId>,
-        safety_mode: BlockSafety,
         region_scope: Scope,
     ) -> BlockAnd<()> {
         let this = self;
@@ -72,13 +55,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         // First we build all the statements in the block.
         let mut let_scope_stack = Vec::with_capacity(8);
         let outer_source_scope = this.source_scope;
-        let outer_in_scope_unsafe = this.in_scope_unsafe;
         // This scope information is kept for breaking out of the parent remainder scope in case
         // one let-else pattern matching fails.
         // By doing so, we can be sure that even temporaries that receive extended lifetime
         // assignments are dropped, too.
         let mut last_remainder_scope = region_scope;
-        this.update_source_scope_for_safety_mode(span, safety_mode);
 
         let source_info = this.source_info(span);
         for stmt in stmts {
@@ -202,7 +183,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     let_scope_stack.push(remainder_scope);
 
                     let visibility_scope =
-                        Some(this.new_source_scope(remainder_span, LintLevel::Inherited, None));
+                        Some(this.new_source_scope(remainder_span, LintLevel::Inherited));
 
                     let initializer_span = this.thir[*initializer].span;
                     let scope = (*init_scope, source_info);
@@ -271,7 +252,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     let remainder_span = remainder_scope.span(this.tcx, this.region_scope_tree);
 
                     let visibility_scope =
-                        Some(this.new_source_scope(remainder_span, LintLevel::Inherited, None));
+                        Some(this.new_source_scope(remainder_span, LintLevel::Inherited));
 
                     // Evaluate the initializer, if present.
                     if let Some(init) = *initializer {
@@ -364,22 +345,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
         // Restore the original source scope.
         this.source_scope = outer_source_scope;
-        this.in_scope_unsafe = outer_in_scope_unsafe;
         block.unit()
     }
-
-    /// If we are entering an unsafe block, create a new source scope
-    fn update_source_scope_for_safety_mode(&mut self, span: Span, safety_mode: BlockSafety) {
-        debug!("update_source_scope_for({:?}, {:?})", span, safety_mode);
-        let new_unsafety = match safety_mode {
-            BlockSafety::Safe => return,
-            BlockSafety::BuiltinUnsafe => Safety::BuiltinUnsafe,
-            BlockSafety::ExplicitUnsafe(hir_id) => {
-                self.in_scope_unsafe = Safety::ExplicitUnsafe(hir_id);
-                Safety::ExplicitUnsafe(hir_id)
-            }
-        };
-
-        self.source_scope = self.new_source_scope(span, LintLevel::Inherited, Some(new_unsafety));
-    }
 }
diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs
index 0475bb8908b..30877e38318 100644
--- a/compiler/rustc_mir_build/src/build/custom/mod.rs
+++ b/compiler/rustc_mir_build/src/build/custom/mod.rs
@@ -72,10 +72,7 @@ pub(super) fn build_custom_mir<'tcx>(
         parent_scope: None,
         inlined: None,
         inlined_parent_scope: None,
-        local_data: ClearCrossCrate::Set(SourceScopeLocalData {
-            lint_root: hir_id,
-            safety: Safety::Safe,
-        }),
+        local_data: ClearCrossCrate::Set(SourceScopeLocalData { lint_root: hir_id }),
     });
     body.injection_phase = Some(parse_attribute(attr));
 
diff --git a/compiler/rustc_mir_build/src/build/custom/parse.rs b/compiler/rustc_mir_build/src/build/custom/parse.rs
index a6f9caada2d..0384b9bc154 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse.rs
@@ -215,7 +215,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
 
     fn parse_local_decls(&mut self, mut stmts: impl Iterator<Item = StmtId>) -> PResult<()> {
         let (ret_var, ..) = self.parse_let_statement(stmts.next().unwrap())?;
-        self.local_map.insert(ret_var, Local::from_u32(0));
+        self.local_map.insert(ret_var, Local::ZERO);
 
         for stmt in stmts {
             let (var, ty, span) = self.parse_let_statement(stmt)?;
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index c77f4a06d05..260ab058e60 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -118,19 +118,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             ExprKind::Box { value } => {
                 let value_ty = this.thir[value].ty;
                 let tcx = this.tcx;
-
-                // `exchange_malloc` is unsafe but box is safe, so need a new scope.
-                let synth_scope = this.new_source_scope(
-                    expr_span,
-                    LintLevel::Inherited,
-                    Some(Safety::BuiltinUnsafe),
-                );
-                let synth_info = SourceInfo { span: expr_span, scope: synth_scope };
+                let source_info = this.source_info(expr_span);
 
                 let size = this.temp(tcx.types.usize, expr_span);
                 this.cfg.push_assign(
                     block,
-                    synth_info,
+                    source_info,
                     size,
                     Rvalue::NullaryOp(NullOp::SizeOf, value_ty),
                 );
@@ -138,7 +131,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let align = this.temp(tcx.types.usize, expr_span);
                 this.cfg.push_assign(
                     block,
-                    synth_info,
+                    source_info,
                     align,
                     Rvalue::NullaryOp(NullOp::AlignOf, value_ty),
                 );
@@ -154,7 +147,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let success = this.cfg.start_new_block();
                 this.cfg.terminate(
                     block,
-                    synth_info,
+                    source_info,
                     TerminatorKind::Call {
                         func: exchange_malloc,
                         args: vec![
@@ -580,7 +573,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     result_value,
                     Rvalue::CheckedBinaryOp(op, Box::new((lhs.to_copy(), rhs.to_copy()))),
                 );
-                let val_fld = FieldIdx::new(0);
+                let val_fld = FieldIdx::ZERO;
                 let of_fld = FieldIdx::new(1);
 
                 let tcx = self.tcx;
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index b4eeeccc127..c8360b6a5fd 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -69,7 +69,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         // FIXME: Does this need extra logic to handle let-chains?
                         let source_info = if this.is_let(cond) {
                             let variable_scope =
-                                this.new_source_scope(then_span, LintLevel::Inherited, None);
+                                this.new_source_scope(then_span, LintLevel::Inherited);
                             this.source_scope = variable_scope;
                             SourceInfo { span: then_span, scope: variable_scope }
                         } else {
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index a6b513ce7d0..1ea671a4f79 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -732,7 +732,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             &mut |this, name, mode, var, span, ty, user_ty| {
                 if visibility_scope.is_none() {
                     visibility_scope =
-                        Some(this.new_source_scope(scope_span, LintLevel::Inherited, None));
+                        Some(this.new_source_scope(scope_span, LintLevel::Inherited));
                 }
                 let source_info = SourceInfo { span, scope: this.source_scope };
                 let visibility_scope = visibility_scope.unwrap();
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 274edf358e0..6972bc00e0b 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -66,17 +66,10 @@ pub(crate) fn mir_build<'tcx>(tcx: TyCtxtAt<'tcx>, def: LocalDefId) -> Body<'tcx
             // maybe move the check to a MIR pass?
             tcx.ensure().check_liveness(def);
 
-            if tcx.sess.opts.unstable_opts.thir_unsafeck {
-                // Don't steal here if THIR unsafeck is being used. Instead
-                // steal in unsafeck. This is so that pattern inline constants
-                // can be evaluated as part of building the THIR of the parent
-                // function without a cycle.
-                build_mir(&thir.borrow())
-            } else {
-                // We ran all queries that depended on THIR at the beginning
-                // of `mir_build`, so now we can steal it
-                build_mir(&thir.steal())
-            }
+            // Don't steal here, instead steal in unsafeck. This is so that
+            // pattern inline constants can be evaluated as part of building the
+            // THIR of the parent function without a cycle.
+            build_mir(&thir.borrow())
         }
     };
 
@@ -190,9 +183,6 @@ struct Builder<'a, 'tcx> {
     /// `{ STMTS; EXPR1 } + EXPR2`.
     block_context: BlockContext,
 
-    /// The current unsafe block in scope
-    in_scope_unsafe: Safety,
-
     /// The vector of all scopes that we have created thus far;
     /// we track this for debuginfo later.
     source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
@@ -470,11 +460,6 @@ fn construct_fn<'tcx>(
         .output
         .span();
 
-    let safety = match fn_sig.unsafety {
-        hir::Unsafety::Normal => Safety::Safe,
-        hir::Unsafety::Unsafe => Safety::FnUnsafe,
-    };
-
     let mut abi = fn_sig.abi;
     if let DefKind::Closure = tcx.def_kind(fn_def) {
         // HACK(eddyb) Avoid having RustCall on closures,
@@ -520,7 +505,6 @@ fn construct_fn<'tcx>(
         fn_id,
         span_with_body,
         arguments.len(),
-        safety,
         return_ty,
         return_ty_span,
         coroutine,
@@ -590,18 +574,8 @@ fn construct_const<'a, 'tcx>(
     };
 
     let infcx = tcx.infer_ctxt().build();
-    let mut builder = Builder::new(
-        thir,
-        infcx,
-        def,
-        hir_id,
-        span,
-        0,
-        Safety::Safe,
-        const_ty,
-        const_ty_span,
-        None,
-    );
+    let mut builder =
+        Builder::new(thir, infcx, def, hir_id, span, 0, const_ty, const_ty_span, None);
 
     let mut block = START_BLOCK;
     unpack!(block = builder.expr_into_dest(Place::return_place(), block, expr));
@@ -723,10 +697,7 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) -
         parent_scope: None,
         inlined: None,
         inlined_parent_scope: None,
-        local_data: ClearCrossCrate::Set(SourceScopeLocalData {
-            lint_root: hir_id,
-            safety: Safety::Safe,
-        }),
+        local_data: ClearCrossCrate::Set(SourceScopeLocalData { lint_root: hir_id }),
     });
 
     cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable);
@@ -753,7 +724,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         hir_id: hir::HirId,
         span: Span,
         arg_count: usize,
-        safety: Safety,
         return_ty: Ty<'tcx>,
         return_span: Span,
         coroutine: Option<Box<CoroutineInfo<'tcx>>>,
@@ -795,7 +765,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             guard_context: vec![],
             fixed_temps: Default::default(),
             fixed_temps_scope: None,
-            in_scope_unsafe: safety,
             local_decls: IndexVec::from_elem_n(LocalDecl::new(return_ty, return_span), 1),
             canonical_user_type_annotations: IndexVec::new(),
             upvars: CaptureMap::new(),
@@ -807,10 +776,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         };
 
         assert_eq!(builder.cfg.start_new_block(), START_BLOCK);
-        assert_eq!(
-            builder.new_source_scope(span, lint_level, Some(safety)),
-            OUTERMOST_SOURCE_SCOPE
-        );
+        assert_eq!(builder.new_source_scope(span, lint_level), OUTERMOST_SOURCE_SCOPE);
         builder.source_scopes[OUTERMOST_SOURCE_SCOPE].parent_scope = None;
 
         builder
@@ -1024,7 +990,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             .as_ref()
             .assert_crate_local()
             .lint_root;
-        self.maybe_new_source_scope(pattern_span, None, arg_hir_id, parent_id);
+        self.maybe_new_source_scope(pattern_span, arg_hir_id, parent_id);
     }
 
     fn get_unit_temp(&mut self) -> Place<'tcx> {
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index aef63896dde..2d31e84aba7 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -190,7 +190,7 @@ rustc_index::newtype_index! {
     struct DropIdx {}
 }
 
-const ROOT_NODE: DropIdx = DropIdx::from_u32(0);
+const ROOT_NODE: DropIdx = DropIdx::ZERO;
 
 /// A tree of drops that we have deferred lowering. It's used for:
 ///
@@ -578,7 +578,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         if let LintLevel::Explicit(current_hir_id) = lint_level {
             let parent_id =
                 self.source_scopes[source_scope].local_data.as_ref().assert_crate_local().lint_root;
-            self.maybe_new_source_scope(region_scope.1.span, None, current_hir_id, parent_id);
+            self.maybe_new_source_scope(region_scope.1.span, current_hir_id, parent_id);
         }
         self.push_scope(region_scope);
         let mut block;
@@ -767,7 +767,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     pub(crate) fn maybe_new_source_scope(
         &mut self,
         span: Span,
-        safety: Option<Safety>,
         current_id: HirId,
         parent_id: HirId,
     ) {
@@ -797,7 +796,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
         if current_root != parent_root {
             let lint_level = LintLevel::Explicit(current_root);
-            self.source_scope = self.new_source_scope(span, lint_level, safety);
+            self.source_scope = self.new_source_scope(span, lint_level);
         }
     }
 
@@ -846,18 +845,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     }
 
     /// Creates a new source scope, nested in the current one.
-    pub(crate) fn new_source_scope(
-        &mut self,
-        span: Span,
-        lint_level: LintLevel,
-        safety: Option<Safety>,
-    ) -> SourceScope {
+    pub(crate) fn new_source_scope(&mut self, span: Span, lint_level: LintLevel) -> SourceScope {
         let parent = self.source_scope;
         debug!(
-            "new_source_scope({:?}, {:?}, {:?}) - parent({:?})={:?}",
+            "new_source_scope({:?}, {:?}) - parent({:?})={:?}",
             span,
             lint_level,
-            safety,
             parent,
             self.source_scopes.get(parent)
         );
@@ -867,9 +860,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             } else {
                 self.source_scopes[parent].local_data.as_ref().assert_crate_local().lint_root
             },
-            safety: safety.unwrap_or_else(|| {
-                self.source_scopes[parent].local_data.as_ref().assert_crate_local().safety
-            }),
         };
         self.source_scopes.push(SourceScopeData {
             span,
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 07dc332b791..8aa9a75d96a 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -909,11 +909,6 @@ impl UnsafeOpKind {
 }
 
 pub fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
-    // THIR unsafeck can be disabled with `-Z thir-unsafeck=off`
-    if !tcx.sess.opts.unstable_opts.thir_unsafeck {
-        return;
-    }
-
     // Closures and inline consts are handled by their owner, if it has a body
     // Also, don't safety check custom MIR
     if tcx.is_typeck_child(def.to_def_id()) || tcx.has_attr(def, sym::custom_mir) {
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 848da56f981..26f10fdd333 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -456,8 +456,8 @@ pub enum UnusedUnsafeEnclosing {
 
 pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> {
     pub cx: &'m RustcPatCtxt<'p, 'tcx>,
-    pub expr_span: Span,
-    pub span: Span,
+    pub scrut_span: Span,
+    pub braces_span: Option<Span>,
     pub ty: Ty<'tcx>,
 }
 
@@ -465,7 +465,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo
     fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'_, G> {
         let mut diag =
             Diag::new(dcx, level, fluent::mir_build_non_exhaustive_patterns_type_not_empty);
-        diag.span(self.span);
+        diag.span(self.scrut_span);
         diag.code(E0004);
         let peeled_ty = self.ty.peel_refs();
         diag.arg("ty", self.ty);
@@ -502,26 +502,19 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo
             }
         }
 
-        let mut suggestion = None;
         let sm = self.cx.tcx.sess.source_map();
-        if self.span.eq_ctxt(self.expr_span) {
+        if let Some(braces_span) = self.braces_span {
             // Get the span for the empty match body `{}`.
-            let (indentation, more) = if let Some(snippet) = sm.indentation_before(self.span) {
+            let (indentation, more) = if let Some(snippet) = sm.indentation_before(self.scrut_span)
+            {
                 (format!("\n{snippet}"), "    ")
             } else {
                 (" ".to_string(), "")
             };
-            suggestion = Some((
-                self.span.shrink_to_hi().with_hi(self.expr_span.hi()),
-                format!(" {{{indentation}{more}_ => todo!(),{indentation}}}",),
-            ));
-        }
-
-        if let Some((span, sugg)) = suggestion {
             diag.span_suggestion_verbose(
-                span,
+                braces_span,
                 fluent::mir_build_suggestion,
-                sugg,
+                format!(" {{{indentation}{more}_ => todo!(),{indentation}}}"),
                 Applicability::HasPlaceholders,
             );
         } else {
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 1e508ffc1e7..c697e16217b 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -716,10 +716,11 @@ impl<'tcx> Cx<'tcx> {
                 then: self.mirror_expr(then),
                 else_opt: else_opt.map(|el| self.mirror_expr(el)),
             },
-            hir::ExprKind::Match(discr, arms, _) => ExprKind::Match {
+            hir::ExprKind::Match(discr, arms, match_source) => ExprKind::Match {
                 scrutinee: self.mirror_expr(discr),
                 scrutinee_hir_id: discr.hir_id,
                 arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
+                match_source,
             },
             hir::ExprKind::Loop(body, ..) => {
                 let block_ty = self.typeck_results().node_type(body.hir_id);
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 3a688a14dd5..a3e6c2abc51 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -144,16 +144,8 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> {
                 });
                 return;
             }
-            ExprKind::Match { scrutinee, scrutinee_hir_id, box ref arms } => {
-                let source = match ex.span.desugaring_kind() {
-                    Some(DesugaringKind::ForLoop) => hir::MatchSource::ForLoopDesugar,
-                    Some(DesugaringKind::QuestionMark) => {
-                        hir::MatchSource::TryDesugar(scrutinee_hir_id)
-                    }
-                    Some(DesugaringKind::Await) => hir::MatchSource::AwaitDesugar,
-                    _ => hir::MatchSource::Normal,
-                };
-                self.check_match(scrutinee, arms, source, ex.span);
+            ExprKind::Match { scrutinee, scrutinee_hir_id: _, box ref arms, match_source } => {
+                self.check_match(scrutinee, arms, match_source, ex.span);
             }
             ExprKind::Let { box ref pat, expr } => {
                 self.check_let(pat, Some(expr), ex.span);
@@ -505,8 +497,41 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
                     None,
                 );
             } else {
+                // span after scrutinee, or after `.match`. That is, the braces, arms,
+                // and any whitespace preceding the braces.
+                let braces_span = match source {
+                    hir::MatchSource::Normal => scrut
+                        .span
+                        .find_ancestor_in_same_ctxt(expr_span)
+                        .map(|scrut_span| scrut_span.shrink_to_hi().with_hi(expr_span.hi())),
+                    hir::MatchSource::Postfix => {
+                        // This is horrendous, and we should deal with it by just
+                        // stashing the span of the braces somewhere (like in the match source).
+                        scrut.span.find_ancestor_in_same_ctxt(expr_span).and_then(|scrut_span| {
+                            let sm = self.tcx.sess.source_map();
+                            let brace_span = sm.span_extend_to_next_char(scrut_span, '{', true);
+                            if sm.span_to_snippet(sm.next_point(brace_span)).as_deref() == Ok("{") {
+                                let sp = brace_span.shrink_to_hi().with_hi(expr_span.hi());
+                                // We also need to extend backwards for whitespace
+                                sm.span_extend_prev_while(sp, |c| c.is_whitespace()).ok()
+                            } else {
+                                None
+                            }
+                        })
+                    }
+                    hir::MatchSource::ForLoopDesugar
+                    | hir::MatchSource::TryDesugar(_)
+                    | hir::MatchSource::AwaitDesugar
+                    | hir::MatchSource::FormatArgs => None,
+                };
                 self.error = Err(report_non_exhaustive_match(
-                    &cx, self.thir, scrut.ty, scrut.span, witnesses, arms, expr_span,
+                    &cx,
+                    self.thir,
+                    scrut.ty,
+                    scrut.span,
+                    witnesses,
+                    arms,
+                    braces_span,
                 ));
             }
         }
@@ -929,7 +954,7 @@ fn report_non_exhaustive_match<'p, 'tcx>(
     sp: Span,
     witnesses: Vec<WitnessPat<'p, 'tcx>>,
     arms: &[ArmId],
-    expr_span: Span,
+    braces_span: Option<Span>,
 ) -> ErrorGuaranteed {
     let is_empty_match = arms.is_empty();
     let non_empty_enum = match scrut_ty.kind() {
@@ -941,8 +966,8 @@ fn report_non_exhaustive_match<'p, 'tcx>(
     if is_empty_match && !non_empty_enum {
         return cx.tcx.dcx().emit_err(NonExhaustivePatternsTypeNotEmpty {
             cx,
-            expr_span,
-            span: sp,
+            scrut_span: sp,
+            braces_span,
             ty: scrut_ty,
         });
     }
@@ -1028,7 +1053,7 @@ fn report_non_exhaustive_match<'p, 'tcx>(
     let mut suggestion = None;
     let sm = cx.tcx.sess.source_map();
     match arms {
-        [] if sp.eq_ctxt(expr_span) => {
+        [] if let Some(braces_span) = braces_span => {
             // Get the span for the empty match body `{}`.
             let (indentation, more) = if let Some(snippet) = sm.indentation_before(sp) {
                 (format!("\n{snippet}"), "    ")
@@ -1036,7 +1061,7 @@ fn report_non_exhaustive_match<'p, 'tcx>(
                 (" ".to_string(), "")
             };
             suggestion = Some((
-                sp.shrink_to_hi().with_hi(expr_span.hi()),
+                braces_span,
                 format!(" {{{indentation}{more}{suggested_arm},{indentation}}}",),
             ));
         }
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index 256add3153c..d63db6ea8ed 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -420,14 +420,14 @@ where
     ) -> BasicBlock {
         // drop glue is sent straight to codegen
         // box cannot be directly dereferenced
-        let unique_ty = adt.non_enum_variant().fields[FieldIdx::new(0)].ty(self.tcx(), args);
+        let unique_ty = adt.non_enum_variant().fields[FieldIdx::ZERO].ty(self.tcx(), args);
         let unique_variant = unique_ty.ty_adt_def().unwrap().non_enum_variant();
-        let nonnull_ty = unique_variant.fields[FieldIdx::from_u32(0)].ty(self.tcx(), args);
+        let nonnull_ty = unique_variant.fields[FieldIdx::ZERO].ty(self.tcx(), args);
         let ptr_ty = Ty::new_imm_ptr(self.tcx(), args[0].expect_ty());
 
-        let unique_place = self.tcx().mk_place_field(self.place, FieldIdx::new(0), unique_ty);
-        let nonnull_place = self.tcx().mk_place_field(unique_place, FieldIdx::new(0), nonnull_ty);
-        let ptr_place = self.tcx().mk_place_field(nonnull_place, FieldIdx::new(0), ptr_ty);
+        let unique_place = self.tcx().mk_place_field(self.place, FieldIdx::ZERO, unique_ty);
+        let nonnull_place = self.tcx().mk_place_field(unique_place, FieldIdx::ZERO, nonnull_ty);
+        let ptr_place = self.tcx().mk_place_field(nonnull_place, FieldIdx::ZERO, ptr_ty);
         let interior = self.tcx().mk_place_deref(ptr_place);
 
         let interior_path = self.elaborator.deref_subpath(self.path);
diff --git a/compiler/rustc_mir_transform/messages.ftl b/compiler/rustc_mir_transform/messages.ftl
index b8dbdf18db3..f9b79d72b05 100644
--- a/compiler/rustc_mir_transform/messages.ftl
+++ b/compiler/rustc_mir_transform/messages.ftl
@@ -1,6 +1,4 @@
 mir_transform_arithmetic_overflow = this arithmetic operation will overflow
-mir_transform_call_to_unsafe_label = call to unsafe function
-mir_transform_call_to_unsafe_note = consult the function's documentation for information on how to avoid undefined behavior
 mir_transform_const_defined_here = `const` item defined here
 
 mir_transform_const_modify = attempting to modify a `const` item
@@ -11,10 +9,6 @@ mir_transform_const_mut_borrow = taking a mutable reference to a `const` item
     .note2 = the mutable reference will refer to this temporary, not the original `const` item
     .note3 = mutable reference created due to call to this method
 
-mir_transform_const_ptr2int_label = cast of pointer to int
-mir_transform_const_ptr2int_note = casting pointers to integers in constants
-mir_transform_deref_ptr_label = dereference of raw pointer
-mir_transform_deref_ptr_note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
 mir_transform_ffi_unwind_call = call to {$foreign ->
     [true] foreign function
     *[false] function pointer
@@ -23,56 +17,13 @@ mir_transform_ffi_unwind_call = call to {$foreign ->
 mir_transform_fn_item_ref = taking a reference to a function item does not give a function pointer
     .suggestion = cast `{$ident}` to obtain a function pointer
 
-mir_transform_initializing_valid_range_label = initializing type with `rustc_layout_scalar_valid_range` attr
-mir_transform_initializing_valid_range_note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
 mir_transform_must_not_suspend = {$pre}`{$def_path}`{$post} held across a suspend point, but should not be
     .label = the value is held across this suspend point
     .note = {$reason}
     .help = consider using a block (`{"{ ... }"}`) to shrink the value's scope, ending before the suspend point
-
-mir_transform_mutation_layout_constrained_borrow_label = borrow of layout constrained field with interior mutability
-mir_transform_mutation_layout_constrained_borrow_note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
-mir_transform_mutation_layout_constrained_label = mutation of layout constrained field
-mir_transform_mutation_layout_constrained_note = mutating layout constrained fields cannot statically be checked for valid values
 mir_transform_operation_will_panic = this operation will panic at runtime
 
-mir_transform_requires_unsafe = {$details} is unsafe and requires unsafe {$op_in_unsafe_fn_allowed ->
-    [true] function or block
-    *[false] block
-    }
-    .not_inherited = items do not inherit unsafety from separate enclosing items
-
-mir_transform_target_feature_call_help = in order for the call to be safe, the context requires the following additional target {$missing_target_features_count ->
-    [1] feature
-    *[count] features
-    }: {$missing_target_features}
-
-mir_transform_target_feature_call_label = call to function with `#[target_feature]`
-mir_transform_target_feature_call_note = the {$build_target_features} target {$build_target_features_count ->
-    [1] feature
-    *[count] features
-    } being enabled in the build configuration does not remove the requirement to list {$build_target_features_count ->
-    [1] it
-    *[count] them
-    } in `#[target_feature]`
-
 mir_transform_unaligned_packed_ref = reference to packed field is unaligned
     .note = packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
     .note_ub = creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
     .help = copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
-
-mir_transform_union_access_label = access to union field
-mir_transform_union_access_note = the field may not be properly initialized: using uninitialized data will cause undefined behavior
-mir_transform_unsafe_op_in_unsafe_fn = {$details} is unsafe and requires unsafe block (error E0133)
-    .suggestion = consider wrapping the function body in an unsafe block
-    .note = an unsafe function restricts its caller, but its body is safe by default
-
-mir_transform_unused_unsafe = unnecessary `unsafe` block
-    .label = because it's nested under this `unsafe` block
-
-mir_transform_use_of_asm_label = use of inline assembly
-mir_transform_use_of_asm_note = inline assembly is entirely unchecked and can cause undefined behavior
-mir_transform_use_of_extern_static_label = use of extern static
-mir_transform_use_of_extern_static_note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
-mir_transform_use_of_static_mut_label = use of mutable static
-mir_transform_use_of_static_mut_note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
deleted file mode 100644
index a0c3de3af58..00000000000
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ /dev/null
@@ -1,615 +0,0 @@
-use rustc_data_structures::unord::{ExtendUnord, UnordItems, UnordSet};
-use rustc_hir as hir;
-use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::hir_id::HirId;
-use rustc_hir::intravisit;
-use rustc_hir::{BlockCheckMode, ExprKind, Node};
-use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
-use rustc_middle::mir::*;
-use rustc_middle::query::Providers;
-use rustc_middle::ty::{self, TyCtxt};
-use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
-use rustc_session::lint::Level;
-
-use std::ops::Bound;
-
-use crate::errors;
-
-pub struct UnsafetyChecker<'a, 'tcx> {
-    body: &'a Body<'tcx>,
-    body_did: LocalDefId,
-    violations: Vec<UnsafetyViolation>,
-    source_info: SourceInfo,
-    tcx: TyCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-
-    /// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint.
-    used_unsafe_blocks: UnordSet<HirId>,
-}
-
-impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
-    fn new(
-        body: &'a Body<'tcx>,
-        body_did: LocalDefId,
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> Self {
-        Self {
-            body,
-            body_did,
-            violations: vec![],
-            source_info: SourceInfo::outermost(body.span),
-            tcx,
-            param_env,
-            used_unsafe_blocks: Default::default(),
-        }
-    }
-}
-
-impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
-    fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
-        self.source_info = terminator.source_info;
-        match terminator.kind {
-            TerminatorKind::Goto { .. }
-            | TerminatorKind::SwitchInt { .. }
-            | TerminatorKind::Drop { .. }
-            | TerminatorKind::Yield { .. }
-            | TerminatorKind::Assert { .. }
-            | TerminatorKind::CoroutineDrop
-            | TerminatorKind::UnwindResume
-            | TerminatorKind::UnwindTerminate(_)
-            | TerminatorKind::Return
-            | TerminatorKind::Unreachable
-            | TerminatorKind::FalseEdge { .. }
-            | TerminatorKind::FalseUnwind { .. } => {
-                // safe (at least as emitted during MIR construction)
-            }
-
-            TerminatorKind::Call { ref func, .. } => {
-                let func_ty = func.ty(self.body, self.tcx);
-                let func_id =
-                    if let ty::FnDef(func_id, _) = func_ty.kind() { Some(func_id) } else { None };
-                let sig = func_ty.fn_sig(self.tcx);
-                if let hir::Unsafety::Unsafe = sig.unsafety() {
-                    self.require_unsafe(
-                        UnsafetyViolationKind::General,
-                        UnsafetyViolationDetails::CallToUnsafeFunction,
-                    )
-                }
-
-                if let Some(func_id) = func_id {
-                    self.check_target_features(*func_id);
-                }
-            }
-
-            TerminatorKind::InlineAsm { .. } => self.require_unsafe(
-                UnsafetyViolationKind::General,
-                UnsafetyViolationDetails::UseOfInlineAssembly,
-            ),
-        }
-        self.super_terminator(terminator, location);
-    }
-
-    fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
-        self.source_info = statement.source_info;
-        match statement.kind {
-            StatementKind::Assign(..)
-            | StatementKind::FakeRead(..)
-            | StatementKind::SetDiscriminant { .. }
-            | StatementKind::Deinit(..)
-            | StatementKind::StorageLive(..)
-            | StatementKind::StorageDead(..)
-            | StatementKind::Retag { .. }
-            | StatementKind::PlaceMention(..)
-            | StatementKind::Coverage(..)
-            | StatementKind::Intrinsic(..)
-            | StatementKind::ConstEvalCounter
-            | StatementKind::Nop => {
-                // safe (at least as emitted during MIR construction)
-            }
-            // `AscribeUserType` just exists to help MIR borrowck.
-            // It has no semantics, and everything is already reported by `PlaceMention`.
-            StatementKind::AscribeUserType(..) => return,
-        }
-        self.super_statement(statement, location);
-    }
-
-    fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
-        match rvalue {
-            Rvalue::Aggregate(box ref aggregate, _) => match aggregate {
-                &AggregateKind::Array(..) | &AggregateKind::Tuple => {}
-                &AggregateKind::Adt(adt_did, ..) => {
-                    match self.tcx.layout_scalar_valid_range(adt_did) {
-                        (Bound::Unbounded, Bound::Unbounded) => {}
-                        _ => self.require_unsafe(
-                            UnsafetyViolationKind::General,
-                            UnsafetyViolationDetails::InitializingTypeWith,
-                        ),
-                    }
-                }
-                &AggregateKind::Closure(def_id, _)
-                | &AggregateKind::CoroutineClosure(def_id, _)
-                | &AggregateKind::Coroutine(def_id, _) => {
-                    let def_id = def_id.expect_local();
-                    let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } =
-                        self.tcx.mir_unsafety_check_result(def_id);
-                    self.register_violations(violations, used_unsafe_blocks.items().copied());
-                }
-            },
-            _ => {}
-        }
-        self.super_rvalue(rvalue, location);
-    }
-
-    fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) {
-        if let Operand::Constant(constant) = op {
-            let maybe_uneval = match constant.const_ {
-                Const::Val(..) | Const::Ty(_) => None,
-                Const::Unevaluated(uv, _) => Some(uv),
-            };
-
-            if let Some(uv) = maybe_uneval {
-                if uv.promoted.is_none() {
-                    let def_id = uv.def;
-                    if self.tcx.def_kind(def_id) == DefKind::InlineConst {
-                        let local_def_id = def_id.expect_local();
-                        let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } =
-                            self.tcx.mir_unsafety_check_result(local_def_id);
-                        self.register_violations(violations, used_unsafe_blocks.items().copied());
-                    }
-                }
-            }
-        }
-        self.super_operand(op, location);
-    }
-
-    fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
-        // On types with `scalar_valid_range`, prevent
-        // * `&mut x.field`
-        // * `x.field = y;`
-        // * `&x.field` if `field`'s type has interior mutability
-        // because either of these would allow modifying the layout constrained field and
-        // insert values that violate the layout constraints.
-        if context.is_mutating_use() || context.is_borrow() {
-            self.check_mut_borrowing_layout_constrained_field(*place, context.is_mutating_use());
-        }
-
-        // Some checks below need the extra meta info of the local declaration.
-        let decl = &self.body.local_decls[place.local];
-
-        // Check the base local: it might be an unsafe-to-access static. We only check derefs of the
-        // temporary holding the static pointer to avoid duplicate errors
-        // <https://github.com/rust-lang/rust/pull/78068#issuecomment-731753506>.
-        if place.projection.first() == Some(&ProjectionElem::Deref) {
-            // If the projection root is an artificial local that we introduced when
-            // desugaring `static`, give a more specific error message
-            // (avoid the general "raw pointer" clause below, that would only be confusing).
-            if let LocalInfo::StaticRef { def_id, .. } = *decl.local_info() {
-                if self.tcx.is_mutable_static(def_id) {
-                    self.require_unsafe(
-                        UnsafetyViolationKind::General,
-                        UnsafetyViolationDetails::UseOfMutableStatic,
-                    );
-                    return;
-                } else if self.tcx.is_foreign_item(def_id) {
-                    self.require_unsafe(
-                        UnsafetyViolationKind::General,
-                        UnsafetyViolationDetails::UseOfExternStatic,
-                    );
-                    return;
-                }
-            }
-        }
-
-        // Check for raw pointer `Deref`.
-        for (base, proj) in place.iter_projections() {
-            if proj == ProjectionElem::Deref {
-                let base_ty = base.ty(self.body, self.tcx).ty;
-                if base_ty.is_unsafe_ptr() {
-                    self.require_unsafe(
-                        UnsafetyViolationKind::General,
-                        UnsafetyViolationDetails::DerefOfRawPointer,
-                    )
-                }
-            }
-        }
-
-        // Check for union fields. For this we traverse right-to-left, as the last `Deref` changes
-        // whether we *read* the union field or potentially *write* to it (if this place is being assigned to).
-        let mut saw_deref = false;
-        for (base, proj) in place.iter_projections().rev() {
-            if proj == ProjectionElem::Deref {
-                saw_deref = true;
-                continue;
-            }
-
-            let base_ty = base.ty(self.body, self.tcx).ty;
-            if base_ty.is_union() {
-                // If we did not hit a `Deref` yet and the overall place use is an assignment, the
-                // rules are different.
-                let assign_to_field = !saw_deref
-                    && matches!(
-                        context,
-                        PlaceContext::MutatingUse(
-                            MutatingUseContext::Store
-                                | MutatingUseContext::Drop
-                                | MutatingUseContext::AsmOutput
-                        )
-                    );
-                // If this is just an assignment, determine if the assigned type needs dropping.
-                if assign_to_field {
-                    // We have to check the actual type of the assignment, as that determines if the
-                    // old value is being dropped.
-                    let assigned_ty = place.ty(&self.body.local_decls, self.tcx).ty;
-                    if assigned_ty.needs_drop(self.tcx, self.param_env) {
-                        // This would be unsafe, but should be outright impossible since we reject
-                        // such unions.
-                        assert!(
-                            self.tcx.dcx().has_errors().is_some(),
-                            "union fields that need dropping should be impossible: {assigned_ty}"
-                        );
-                    }
-                } else {
-                    self.require_unsafe(
-                        UnsafetyViolationKind::General,
-                        UnsafetyViolationDetails::AccessToUnionField,
-                    )
-                }
-            }
-        }
-    }
-}
-
-impl<'tcx> UnsafetyChecker<'_, 'tcx> {
-    fn require_unsafe(&mut self, kind: UnsafetyViolationKind, details: UnsafetyViolationDetails) {
-        // Violations can turn out to be `UnsafeFn` during analysis, but they should not start out as such.
-        assert_ne!(kind, UnsafetyViolationKind::UnsafeFn);
-
-        let source_info = self.source_info;
-        let lint_root = self.body.source_scopes[self.source_info.scope]
-            .local_data
-            .as_ref()
-            .assert_crate_local()
-            .lint_root;
-        self.register_violations(
-            [&UnsafetyViolation { source_info, lint_root, kind, details }],
-            UnordItems::empty(),
-        );
-    }
-
-    fn register_violations<'a>(
-        &mut self,
-        violations: impl IntoIterator<Item = &'a UnsafetyViolation>,
-        new_used_unsafe_blocks: UnordItems<HirId, impl Iterator<Item = HirId>>,
-    ) {
-        let safety = self.body.source_scopes[self.source_info.scope]
-            .local_data
-            .as_ref()
-            .assert_crate_local()
-            .safety;
-        match safety {
-            // `unsafe` blocks are required in safe code
-            Safety::Safe => violations.into_iter().for_each(|violation| {
-                match violation.kind {
-                    UnsafetyViolationKind::General => {}
-                    UnsafetyViolationKind::UnsafeFn => {
-                        bug!("`UnsafetyViolationKind::UnsafeFn` in an `Safe` context")
-                    }
-                }
-                if !self.violations.contains(violation) {
-                    self.violations.push(violation.clone())
-                }
-            }),
-            // With the RFC 2585, no longer allow `unsafe` operations in `unsafe fn`s
-            Safety::FnUnsafe => violations.into_iter().for_each(|violation| {
-                let mut violation = violation.clone();
-                violation.kind = UnsafetyViolationKind::UnsafeFn;
-                if !self.violations.contains(&violation) {
-                    self.violations.push(violation)
-                }
-            }),
-            Safety::BuiltinUnsafe => {}
-            Safety::ExplicitUnsafe(hir_id) => violations.into_iter().for_each(|_violation| {
-                self.used_unsafe_blocks.insert(hir_id);
-            }),
-        };
-
-        self.used_unsafe_blocks.extend_unord(new_used_unsafe_blocks);
-    }
-    fn check_mut_borrowing_layout_constrained_field(
-        &mut self,
-        place: Place<'tcx>,
-        is_mut_use: bool,
-    ) {
-        for (place_base, elem) in place.iter_projections().rev() {
-            match elem {
-                // Modifications behind a dereference don't affect the value of
-                // the pointer.
-                ProjectionElem::Deref => return,
-                ProjectionElem::Field(..) => {
-                    let ty = place_base.ty(&self.body.local_decls, self.tcx).ty;
-                    if let ty::Adt(def, _) = ty.kind() {
-                        if self.tcx.layout_scalar_valid_range(def.did())
-                            != (Bound::Unbounded, Bound::Unbounded)
-                        {
-                            let details = if is_mut_use {
-                                UnsafetyViolationDetails::MutationOfLayoutConstrainedField
-
-                            // Check `is_freeze` as late as possible to avoid cycle errors
-                            // with opaque types.
-                            } else if !place
-                                .ty(self.body, self.tcx)
-                                .ty
-                                .is_freeze(self.tcx, self.param_env)
-                            {
-                                UnsafetyViolationDetails::BorrowOfLayoutConstrainedField
-                            } else {
-                                continue;
-                            };
-                            self.require_unsafe(UnsafetyViolationKind::General, details);
-                        }
-                    }
-                }
-                _ => {}
-            }
-        }
-    }
-
-    /// Checks whether calling `func_did` needs an `unsafe` context or not, i.e. whether
-    /// the called function has target features the calling function hasn't.
-    fn check_target_features(&mut self, func_did: DefId) {
-        // Unsafety isn't required on wasm targets. For more information see
-        // the corresponding check in typeck/src/collect.rs
-        if self.tcx.sess.target.options.is_like_wasm {
-            return;
-        }
-
-        let callee_features = &self.tcx.codegen_fn_attrs(func_did).target_features;
-        // The body might be a constant, so it doesn't have codegen attributes.
-        let self_features = &self.tcx.body_codegen_attrs(self.body_did.to_def_id()).target_features;
-
-        // Is `callee_features` a subset of `calling_features`?
-        if !callee_features.iter().all(|feature| self_features.contains(feature)) {
-            let missing: Vec<_> = callee_features
-                .iter()
-                .copied()
-                .filter(|feature| !self_features.contains(feature))
-                .collect();
-            let build_enabled = self
-                .tcx
-                .sess
-                .target_features
-                .iter()
-                .copied()
-                .filter(|feature| missing.contains(feature))
-                .collect();
-            self.require_unsafe(
-                UnsafetyViolationKind::General,
-                UnsafetyViolationDetails::CallToFunctionWith { missing, build_enabled },
-            )
-        }
-    }
-}
-
-pub(crate) fn provide(providers: &mut Providers) {
-    *providers = Providers { mir_unsafety_check_result, ..*providers };
-}
-
-/// Context information for [`UnusedUnsafeVisitor`] traversal,
-/// saves (innermost) relevant context
-#[derive(Copy, Clone, Debug)]
-enum Context {
-    Safe,
-    /// in an `unsafe fn`
-    UnsafeFn,
-    /// in a *used* `unsafe` block
-    /// (i.e. a block without unused-unsafe warning)
-    UnsafeBlock(HirId),
-}
-
-struct UnusedUnsafeVisitor<'a, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    used_unsafe_blocks: &'a UnordSet<HirId>,
-    context: Context,
-    unused_unsafes: &'a mut Vec<(HirId, UnusedUnsafe)>,
-}
-
-impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_, 'tcx> {
-    fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) {
-        if let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = block.rules {
-            let used = match self.tcx.lint_level_at_node(UNUSED_UNSAFE, block.hir_id) {
-                (Level::Allow, _) => true,
-                _ => self.used_unsafe_blocks.contains(&block.hir_id),
-            };
-            let unused_unsafe = match (self.context, used) {
-                (_, false) => UnusedUnsafe::Unused,
-                (Context::Safe, true) | (Context::UnsafeFn, true) => {
-                    let previous_context = self.context;
-                    self.context = Context::UnsafeBlock(block.hir_id);
-                    intravisit::walk_block(self, block);
-                    self.context = previous_context;
-                    return;
-                }
-                (Context::UnsafeBlock(hir_id), true) => UnusedUnsafe::InUnsafeBlock(hir_id),
-            };
-            self.unused_unsafes.push((block.hir_id, unused_unsafe));
-        }
-        intravisit::walk_block(self, block);
-    }
-
-    fn visit_inline_const(&mut self, c: &'tcx hir::ConstBlock) {
-        self.visit_body(self.tcx.hir().body(c.body))
-    }
-
-    fn visit_fn(
-        &mut self,
-        fk: intravisit::FnKind<'tcx>,
-        _fd: &'tcx hir::FnDecl<'tcx>,
-        b: hir::BodyId,
-        _s: rustc_span::Span,
-        _id: LocalDefId,
-    ) {
-        if matches!(fk, intravisit::FnKind::Closure) {
-            self.visit_body(self.tcx.hir().body(b))
-        }
-    }
-}
-
-fn check_unused_unsafe(
-    tcx: TyCtxt<'_>,
-    def_id: LocalDefId,
-    used_unsafe_blocks: &UnordSet<HirId>,
-) -> Vec<(HirId, UnusedUnsafe)> {
-    let body_id = tcx.hir().maybe_body_owned_by(def_id);
-
-    let Some(body_id) = body_id else {
-        debug!("check_unused_unsafe({:?}) - no body found", def_id);
-        return vec![];
-    };
-
-    let body = tcx.hir().body(body_id);
-    let hir_id = tcx.local_def_id_to_hir_id(def_id);
-    let context = match tcx.hir().fn_sig_by_hir_id(hir_id) {
-        Some(sig) if sig.header.unsafety == hir::Unsafety::Unsafe => Context::UnsafeFn,
-        _ => Context::Safe,
-    };
-
-    debug!(
-        "check_unused_unsafe({:?}, context={:?}, body={:?}, used_unsafe_blocks={:?})",
-        def_id, body, context, used_unsafe_blocks
-    );
-
-    let mut unused_unsafes = vec![];
-
-    let mut visitor = UnusedUnsafeVisitor {
-        tcx,
-        used_unsafe_blocks,
-        context,
-        unused_unsafes: &mut unused_unsafes,
-    };
-    intravisit::Visitor::visit_body(&mut visitor, body);
-
-    unused_unsafes
-}
-
-fn mir_unsafety_check_result(tcx: TyCtxt<'_>, def: LocalDefId) -> &UnsafetyCheckResult {
-    debug!("unsafety_violations({:?})", def);
-
-    // N.B., this borrow is valid because all the consumers of
-    // `mir_built` force this.
-    let body = &tcx.mir_built(def).borrow();
-
-    if body.is_custom_mir() || body.tainted_by_errors.is_some() {
-        return tcx.arena.alloc(UnsafetyCheckResult {
-            violations: Vec::new(),
-            used_unsafe_blocks: Default::default(),
-            unused_unsafes: Some(Vec::new()),
-        });
-    }
-
-    let param_env = tcx.param_env(def);
-
-    let mut checker = UnsafetyChecker::new(body, def, tcx, param_env);
-    checker.visit_body(body);
-
-    let unused_unsafes = (!tcx.is_typeck_child(def.to_def_id()))
-        .then(|| check_unused_unsafe(tcx, def, &checker.used_unsafe_blocks));
-
-    tcx.arena.alloc(UnsafetyCheckResult {
-        violations: checker.violations,
-        used_unsafe_blocks: checker.used_unsafe_blocks,
-        unused_unsafes,
-    })
-}
-
-fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) {
-    let span = tcx.sess.source_map().guess_head_span(tcx.hir().span(id));
-    let nested_parent = if let UnusedUnsafe::InUnsafeBlock(id) = kind {
-        Some(tcx.sess.source_map().guess_head_span(tcx.hir().span(id)))
-    } else {
-        None
-    };
-    tcx.emit_node_span_lint(UNUSED_UNSAFE, id, span, errors::UnusedUnsafe { span, nested_parent });
-}
-
-pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
-    debug!("check_unsafety({:?})", def_id);
-
-    // closures and inline consts are handled by their parent fn.
-    if tcx.is_typeck_child(def_id.to_def_id()) {
-        return;
-    }
-
-    let UnsafetyCheckResult { violations, unused_unsafes, .. } =
-        tcx.mir_unsafety_check_result(def_id);
-    // Only suggest wrapping the entire function body in an unsafe block once
-    let mut suggest_unsafe_block = true;
-
-    for &UnsafetyViolation { source_info, lint_root, kind, ref details } in violations.iter() {
-        let details =
-            errors::RequiresUnsafeDetail { violation: details.clone(), span: source_info.span };
-
-        match kind {
-            UnsafetyViolationKind::General => {
-                let op_in_unsafe_fn_allowed = unsafe_op_in_unsafe_fn_allowed(tcx, lint_root);
-                let note_non_inherited = tcx.hir().parent_iter(lint_root).find(|(id, node)| {
-                    if let Node::Expr(block) = node
-                        && let ExprKind::Block(block, _) = block.kind
-                        && let BlockCheckMode::UnsafeBlock(_) = block.rules
-                    {
-                        true
-                    } else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id)
-                        && sig.header.is_unsafe()
-                    {
-                        true
-                    } else {
-                        false
-                    }
-                });
-                let enclosing = if let Some((id, _)) = note_non_inherited {
-                    Some(tcx.sess.source_map().guess_head_span(tcx.hir().span(id)))
-                } else {
-                    None
-                };
-                tcx.dcx().emit_err(errors::RequiresUnsafe {
-                    span: source_info.span,
-                    enclosing,
-                    details,
-                    op_in_unsafe_fn_allowed,
-                });
-            }
-            UnsafetyViolationKind::UnsafeFn => {
-                tcx.emit_node_span_lint(
-                    UNSAFE_OP_IN_UNSAFE_FN,
-                    lint_root,
-                    source_info.span,
-                    errors::UnsafeOpInUnsafeFn {
-                        details,
-                        suggest_unsafe_block: suggest_unsafe_block.then(|| {
-                            let hir_id = tcx.local_def_id_to_hir_id(def_id);
-                            let fn_sig = tcx
-                                .hir()
-                                .fn_sig_by_hir_id(hir_id)
-                                .expect("this violation only occurs in fn");
-                            let body = tcx.hir().body_owned_by(def_id);
-                            let body_span = tcx.hir().body(body).value.span;
-                            let start = tcx.sess.source_map().start_point(body_span).shrink_to_hi();
-                            let end = tcx.sess.source_map().end_point(body_span).shrink_to_lo();
-                            (start, end, fn_sig.span)
-                        }),
-                    },
-                );
-                suggest_unsafe_block = false;
-            }
-        }
-    }
-
-    for &(block_id, kind) in unused_unsafes.as_ref().unwrap() {
-        report_unused_unsafe(tcx, kind, block_id);
-    }
-}
-
-fn unsafe_op_in_unsafe_fn_allowed(tcx: TyCtxt<'_>, id: HirId) -> bool {
-    tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, id).0 == Level::Allow
-}
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index c3f175f150d..e2a911f0dc7 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -168,7 +168,7 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
                 Place {
                     local: SELF_ARG,
                     projection: self.tcx().mk_place_elems(&[ProjectionElem::Field(
-                        FieldIdx::new(0),
+                        FieldIdx::ZERO,
                         self.ref_coroutine_ty,
                     )]),
                 },
@@ -267,7 +267,7 @@ impl<'tcx> TransformVisitor<'tcx> {
                 Rvalue::Aggregate(
                     Box::new(AggregateKind::Adt(
                         option_def_id,
-                        VariantIdx::from_usize(0),
+                        VariantIdx::ZERO,
                         self.tcx.mk_args(&[self.old_yield_ty.into()]),
                         None,
                         None,
@@ -329,7 +329,7 @@ impl<'tcx> TransformVisitor<'tcx> {
                     Rvalue::Aggregate(
                         Box::new(AggregateKind::Adt(
                             poll_def_id,
-                            VariantIdx::from_usize(0),
+                            VariantIdx::ZERO,
                             args,
                             None,
                             None,
@@ -358,7 +358,7 @@ impl<'tcx> TransformVisitor<'tcx> {
                     Rvalue::Aggregate(
                         Box::new(AggregateKind::Adt(
                             option_def_id,
-                            VariantIdx::from_usize(0),
+                            VariantIdx::ZERO,
                             args,
                             None,
                             None,
@@ -420,7 +420,7 @@ impl<'tcx> TransformVisitor<'tcx> {
                     Rvalue::Aggregate(
                         Box::new(AggregateKind::Adt(
                             coroutine_state_def_id,
-                            VariantIdx::from_usize(0),
+                            VariantIdx::ZERO,
                             args,
                             None,
                             None,
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index 99dbb342268..0866205dfd0 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -1,7 +1,66 @@
-//! A MIR pass which duplicates a coroutine's body and removes any derefs which
-//! would be present for upvars that are taken by-ref. The result of which will
-//! be a coroutine body that takes all of its upvars by-move, and which we stash
-//! into the `CoroutineInfo` for all coroutines returned by coroutine-closures.
+//! This pass constructs a second coroutine body sufficient for return from
+//! `FnOnce`/`AsyncFnOnce` implementations for coroutine-closures (e.g. async closures).
+//!
+//! Consider an async closure like:
+//! ```rust
+//! #![feature(async_closure)]
+//!
+//! let x = vec![1, 2, 3];
+//!
+//! let closure = async move || {
+//!     println!("{x:#?}");
+//! };
+//! ```
+//!
+//! This desugars to something like:
+//! ```rust,ignore (invalid-borrowck)
+//! let x = vec![1, 2, 3];
+//!
+//! let closure = move || {
+//!     async {
+//!         println!("{x:#?}");
+//!     }
+//! };
+//! ```
+//!
+//! Important to note here is that while the outer closure *moves* `x: Vec<i32>`
+//! into its upvars, the inner `async` coroutine simply captures a ref of `x`.
+//! This is the "magic" of async closures -- the futures that they return are
+//! allowed to borrow from their parent closure's upvars.
+//!
+//! However, what happens when we call `closure` with `AsyncFnOnce` (or `FnOnce`,
+//! since all async closures implement that too)? Well, recall the signature:
+//! ```
+//! use std::future::Future;
+//! pub trait AsyncFnOnce<Args>
+//! {
+//!     type CallOnceFuture: Future<Output = Self::Output>;
+//!     type Output;
+//!     fn async_call_once(
+//!         self,
+//!         args: Args
+//!     ) -> Self::CallOnceFuture;
+//! }
+//! ```
+//!
+//! This signature *consumes* the async closure (`self`) and returns a `CallOnceFuture`.
+//! How do we deal with the fact that the coroutine is supposed to take a reference
+//! to the captured `x` from the parent closure, when that parent closure has been
+//! destroyed?
+//!
+//! This is the second piece of magic of async closures. We can simply create a
+//! *second* `async` coroutine body where that `x` that was previously captured
+//! by reference is now captured by value. This means that we consume the outer
+//! closure and return a new coroutine that will hold onto all of these captures,
+//! and drop them when it is finished (i.e. after it has been `.await`ed).
+//!
+//! We do this with the analysis below, which detects the captures that come from
+//! borrowing from the outer closure, and we simply peel off a `deref` projection
+//! from them. This second body is stored alongside the first body, and optimized
+//! with it in lockstep. When we need to resolve a body for `FnOnce` or `AsyncFnOnce`,
+//! we use this "by move" body instead.
+
+use itertools::Itertools;
 
 use rustc_data_structures::unord::UnordSet;
 use rustc_hir as hir;
@@ -14,6 +73,8 @@ pub struct ByMoveBody;
 
 impl<'tcx> MirPass<'tcx> for ByMoveBody {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) {
+        // We only need to generate by-move coroutine bodies for coroutines that come
+        // from coroutine-closures.
         let Some(coroutine_def_id) = body.source.def_id().as_local() else {
             return;
         };
@@ -22,44 +83,70 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
         else {
             return;
         };
+
+        // Also, let's skip processing any bodies with errors, since there's no guarantee
+        // the MIR body will be constructed well.
         let coroutine_ty = body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty;
         if coroutine_ty.references_error() {
             return;
         }
-        let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!("{body:#?}") };
 
-        let coroutine_kind = args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap();
+        let ty::Coroutine(_, coroutine_args) = *coroutine_ty.kind() else { bug!("{body:#?}") };
+        // We don't need to generate a by-move coroutine if the kind of the coroutine is
+        // already `FnOnce` -- that means that any upvars that the closure consumes have
+        // already been taken by-value.
+        let coroutine_kind = coroutine_args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap();
         if coroutine_kind == ty::ClosureKind::FnOnce {
             return;
         }
 
+        let parent_def_id = tcx.local_parent(coroutine_def_id);
+        let ty::CoroutineClosure(_, parent_args) =
+            *tcx.type_of(parent_def_id).instantiate_identity().kind()
+        else {
+            bug!();
+        };
+        let parent_closure_args = parent_args.as_coroutine_closure();
+        let num_args = parent_closure_args
+            .coroutine_closure_sig()
+            .skip_binder()
+            .tupled_inputs_ty
+            .tuple_fields()
+            .len();
+
         let mut by_ref_fields = UnordSet::default();
-        let by_move_upvars = Ty::new_tup_from_iter(
-            tcx,
-            tcx.closure_captures(coroutine_def_id).iter().enumerate().map(|(idx, capture)| {
-                if capture.is_by_ref() {
-                    by_ref_fields.insert(FieldIdx::from_usize(idx));
-                }
-                capture.place.ty()
-            }),
-        );
-        let by_move_coroutine_ty = Ty::new_coroutine(
-            tcx,
-            coroutine_def_id.to_def_id(),
-            ty::CoroutineArgs::new(
+        for (idx, (coroutine_capture, parent_capture)) in tcx
+            .closure_captures(coroutine_def_id)
+            .iter()
+            // By construction we capture all the args first.
+            .skip(num_args)
+            .zip_eq(tcx.closure_captures(parent_def_id))
+            .enumerate()
+        {
+            // This upvar is captured by-move from the parent closure, but by-ref
+            // from the inner async block. That means that it's being borrowed from
+            // the outer closure body -- we need to change the coroutine to take the
+            // upvar by value.
+            if coroutine_capture.is_by_ref() && !parent_capture.is_by_ref() {
+                by_ref_fields.insert(FieldIdx::from_usize(num_args + idx));
+            }
+
+            // Make sure we're actually talking about the same capture.
+            // FIXME(async_closures): We could look at the `hir::Upvar` instead?
+            assert_eq!(coroutine_capture.place.ty(), parent_capture.place.ty());
+        }
+
+        let by_move_coroutine_ty = tcx
+            .instantiate_bound_regions_with_erased(parent_closure_args.coroutine_closure_sig())
+            .to_coroutine_given_kind_and_upvars(
                 tcx,
-                ty::CoroutineArgsParts {
-                    parent_args: args.as_coroutine().parent_args(),
-                    kind_ty: Ty::from_closure_kind(tcx, ty::ClosureKind::FnOnce),
-                    resume_ty: args.as_coroutine().resume_ty(),
-                    yield_ty: args.as_coroutine().yield_ty(),
-                    return_ty: args.as_coroutine().return_ty(),
-                    witness: args.as_coroutine().witness(),
-                    tupled_upvars_ty: by_move_upvars,
-                },
-            )
-            .args,
-        );
+                parent_closure_args.parent_args(),
+                coroutine_def_id.to_def_id(),
+                ty::ClosureKind::FnOnce,
+                tcx.lifetimes.re_erased,
+                parent_closure_args.tupled_upvars_ty(),
+                parent_closure_args.coroutine_captures_by_ref_ty(),
+            );
 
         let mut by_move_body = body.clone();
         MakeByMoveBody { tcx, by_ref_fields, by_move_coroutine_ty }.visit_body(&mut by_move_body);
diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
index 96943435bab..318674f24e7 100644
--- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
@@ -3,7 +3,6 @@
 //! Box is not actually a pointer so it is incorrect to dereference it directly.
 
 use rustc_hir::def_id::DefId;
-use rustc_index::Idx;
 use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::visit::MutVisitor;
 use rustc_middle::mir::*;
@@ -32,9 +31,9 @@ pub fn build_projection<'tcx>(
     ptr_ty: Ty<'tcx>,
 ) -> [PlaceElem<'tcx>; 3] {
     [
-        PlaceElem::Field(FieldIdx::new(0), unique_ty),
-        PlaceElem::Field(FieldIdx::new(0), nonnull_ty),
-        PlaceElem::Field(FieldIdx::new(0), ptr_ty),
+        PlaceElem::Field(FieldIdx::ZERO, unique_ty),
+        PlaceElem::Field(FieldIdx::ZERO, nonnull_ty),
+        PlaceElem::Field(FieldIdx::ZERO, ptr_ty),
     ]
 }
 
@@ -91,15 +90,14 @@ pub struct ElaborateBoxDerefs;
 impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         if let Some(def_id) = tcx.lang_items().owned_box() {
-            let unique_did =
-                tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::from_u32(0)].did;
+            let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::ZERO].did;
 
             let Some(nonnull_def) = tcx.type_of(unique_did).instantiate_identity().ty_adt_def()
             else {
                 span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique")
             };
 
-            let nonnull_did = nonnull_def.non_enum_variant().fields[FieldIdx::from_u32(0)].did;
+            let nonnull_did = nonnull_def.non_enum_variant().fields[FieldIdx::ZERO].did;
 
             let patch = MirPatch::new(body);
 
diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs
index 9297bc51fad..0634e321ea3 100644
--- a/compiler/rustc_mir_transform/src/errors.rs
+++ b/compiler/rustc_mir_transform/src/errors.rs
@@ -1,11 +1,6 @@
-use std::borrow::Cow;
-
-use rustc_errors::{
-    codes::*, Applicability, Diag, DiagArgValue, DiagCtxt, DiagMessage, Diagnostic,
-    EmissionGuarantee, Level, LintDiagnostic,
-};
+use rustc_errors::{codes::*, Diag, DiagMessage, LintDiagnostic};
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
-use rustc_middle::mir::{AssertKind, UnsafetyViolationDetails};
+use rustc_middle::mir::AssertKind;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::{self, Lint};
 use rustc_span::def_id::DefId;
@@ -42,168 +37,6 @@ pub(crate) struct UnalignedPackedRef {
     pub span: Span,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(mir_transform_unused_unsafe)]
-pub(crate) struct UnusedUnsafe {
-    #[label(mir_transform_unused_unsafe)]
-    pub span: Span,
-    #[label]
-    pub nested_parent: Option<Span>,
-}
-
-pub(crate) struct RequiresUnsafe {
-    pub span: Span,
-    pub details: RequiresUnsafeDetail,
-    pub enclosing: Option<Span>,
-    pub op_in_unsafe_fn_allowed: bool,
-}
-
-// The primary message for this diagnostic should be '{$label} is unsafe and...',
-// so we need to eagerly translate the label here, which isn't supported by the derive API
-// We could also exhaustively list out the primary messages for all unsafe violations,
-// but this would result in a lot of duplication.
-impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for RequiresUnsafe {
-    #[track_caller]
-    fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'a, G> {
-        let mut diag = Diag::new(dcx, level, fluent::mir_transform_requires_unsafe);
-        diag.code(E0133);
-        diag.span(self.span);
-        diag.span_label(self.span, self.details.label());
-        let desc = dcx.eagerly_translate_to_string(self.details.label(), [].into_iter());
-        diag.arg("details", desc);
-        diag.arg("op_in_unsafe_fn_allowed", self.op_in_unsafe_fn_allowed);
-        self.details.add_subdiagnostics(&mut diag);
-        if let Some(sp) = self.enclosing {
-            diag.span_label(sp, fluent::mir_transform_not_inherited);
-        }
-        diag
-    }
-}
-
-#[derive(Clone)]
-pub(crate) struct RequiresUnsafeDetail {
-    pub span: Span,
-    pub violation: UnsafetyViolationDetails,
-}
-
-impl RequiresUnsafeDetail {
-    // FIXME: make this translatable
-    #[allow(rustc::diagnostic_outside_of_impl)]
-    #[allow(rustc::untranslatable_diagnostic)]
-    fn add_subdiagnostics<G: EmissionGuarantee>(&self, diag: &mut Diag<'_, G>) {
-        use UnsafetyViolationDetails::*;
-        match self.violation {
-            CallToUnsafeFunction => {
-                diag.note(fluent::mir_transform_call_to_unsafe_note);
-            }
-            UseOfInlineAssembly => {
-                diag.note(fluent::mir_transform_use_of_asm_note);
-            }
-            InitializingTypeWith => {
-                diag.note(fluent::mir_transform_initializing_valid_range_note);
-            }
-            CastOfPointerToInt => {
-                diag.note(fluent::mir_transform_const_ptr2int_note);
-            }
-            UseOfMutableStatic => {
-                diag.note(fluent::mir_transform_use_of_static_mut_note);
-            }
-            UseOfExternStatic => {
-                diag.note(fluent::mir_transform_use_of_extern_static_note);
-            }
-            DerefOfRawPointer => {
-                diag.note(fluent::mir_transform_deref_ptr_note);
-            }
-            AccessToUnionField => {
-                diag.note(fluent::mir_transform_union_access_note);
-            }
-            MutationOfLayoutConstrainedField => {
-                diag.note(fluent::mir_transform_mutation_layout_constrained_note);
-            }
-            BorrowOfLayoutConstrainedField => {
-                diag.note(fluent::mir_transform_mutation_layout_constrained_borrow_note);
-            }
-            CallToFunctionWith { ref missing, ref build_enabled } => {
-                diag.help(fluent::mir_transform_target_feature_call_help);
-                diag.arg(
-                    "missing_target_features",
-                    DiagArgValue::StrListSepByAnd(
-                        missing.iter().map(|feature| Cow::from(feature.to_string())).collect(),
-                    ),
-                );
-                diag.arg("missing_target_features_count", missing.len());
-                if !build_enabled.is_empty() {
-                    diag.note(fluent::mir_transform_target_feature_call_note);
-                    diag.arg(
-                        "build_target_features",
-                        DiagArgValue::StrListSepByAnd(
-                            build_enabled
-                                .iter()
-                                .map(|feature| Cow::from(feature.to_string()))
-                                .collect(),
-                        ),
-                    );
-                    diag.arg("build_target_features_count", build_enabled.len());
-                }
-            }
-        }
-    }
-
-    fn label(&self) -> DiagMessage {
-        use UnsafetyViolationDetails::*;
-        match self.violation {
-            CallToUnsafeFunction => fluent::mir_transform_call_to_unsafe_label,
-            UseOfInlineAssembly => fluent::mir_transform_use_of_asm_label,
-            InitializingTypeWith => fluent::mir_transform_initializing_valid_range_label,
-            CastOfPointerToInt => fluent::mir_transform_const_ptr2int_label,
-            UseOfMutableStatic => fluent::mir_transform_use_of_static_mut_label,
-            UseOfExternStatic => fluent::mir_transform_use_of_extern_static_label,
-            DerefOfRawPointer => fluent::mir_transform_deref_ptr_label,
-            AccessToUnionField => fluent::mir_transform_union_access_label,
-            MutationOfLayoutConstrainedField => {
-                fluent::mir_transform_mutation_layout_constrained_label
-            }
-            BorrowOfLayoutConstrainedField => {
-                fluent::mir_transform_mutation_layout_constrained_borrow_label
-            }
-            CallToFunctionWith { .. } => fluent::mir_transform_target_feature_call_label,
-        }
-    }
-}
-
-pub(crate) struct UnsafeOpInUnsafeFn {
-    pub details: RequiresUnsafeDetail,
-
-    /// These spans point to:
-    ///  1. the start of the function body
-    ///  2. the end of the function body
-    ///  3. the function signature
-    pub suggest_unsafe_block: Option<(Span, Span, Span)>,
-}
-
-impl<'a> LintDiagnostic<'a, ()> for UnsafeOpInUnsafeFn {
-    #[track_caller]
-    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
-        let desc = diag.dcx.eagerly_translate_to_string(self.details.label(), [].into_iter());
-        diag.arg("details", desc);
-        diag.span_label(self.details.span, self.details.label());
-        self.details.add_subdiagnostics(diag);
-
-        if let Some((start, end, fn_sig)) = self.suggest_unsafe_block {
-            diag.span_note(fn_sig, fluent::mir_transform_note);
-            diag.tool_only_multipart_suggestion(
-                fluent::mir_transform_suggestion,
-                vec![(start, " unsafe {".into()), (end, "}".into())],
-                Applicability::MaybeIncorrect,
-            );
-        }
-    }
-
-    fn msg(&self) -> DiagMessage {
-        fluent::mir_transform_unsafe_op_in_unsafe_fn
-    }
-}
-
 pub(crate) struct AssertLint<P> {
     pub span: Span,
     pub assert_kind: AssertKind<P>,
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 59d6d89cf1f..d4f736d2a50 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -355,7 +355,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
     }
 
     fn insert_tuple(&mut self, values: Vec<VnIndex>) -> VnIndex {
-        self.insert(Value::Aggregate(AggregateTy::Tuple, VariantIdx::from_u32(0), values))
+        self.insert(Value::Aggregate(AggregateTy::Tuple, VariantIdx::ZERO, values))
     }
 
     #[instrument(level = "trace", skip(self), ret)]
diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs
index f2b6dcac586..85e74a69cce 100644
--- a/compiler/rustc_mir_transform/src/inline/cycle.rs
+++ b/compiler/rustc_mir_transform/src/inline/cycle.rs
@@ -5,6 +5,7 @@ use rustc_middle::mir::TerminatorKind;
 use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{self, GenericArgsRef, InstanceDef, TyCtxt};
 use rustc_session::Limit;
+use rustc_span::sym;
 
 // FIXME: check whether it is cheaper to precompute the entire call graph instead of invoking
 // this query ridiculously often.
@@ -164,11 +165,20 @@ pub(crate) fn mir_inliner_callees<'tcx>(
     let mut calls = FxIndexSet::default();
     for bb_data in body.basic_blocks.iter() {
         let terminator = bb_data.terminator();
-        if let TerminatorKind::Call { func, .. } = &terminator.kind {
+        if let TerminatorKind::Call { func, args: call_args, .. } = &terminator.kind {
             let ty = func.ty(&body.local_decls, tcx);
-            let call = match ty.kind() {
-                ty::FnDef(def_id, args) => (*def_id, *args),
-                _ => continue,
+            let ty::FnDef(def_id, generic_args) = ty.kind() else {
+                continue;
+            };
+            let call = if tcx.is_intrinsic(*def_id, sym::const_eval_select) {
+                let func = &call_args[2].node;
+                let ty = func.ty(&body.local_decls, tcx);
+                let ty::FnDef(def_id, generic_args) = ty.kind() else {
+                    continue;
+                };
+                (*def_id, *generic_args)
+            } else {
+                (*def_id, *generic_args)
             };
             calls.insert(call);
         }
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index a20958e74df..2218154ea5e 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -13,7 +13,7 @@ use rustc_const_eval::interpret::{
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::DefKind;
 use rustc_hir::HirId;
-use rustc_index::{bit_set::BitSet, Idx, IndexVec};
+use rustc_index::{bit_set::BitSet, IndexVec};
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
@@ -124,10 +124,8 @@ impl<'tcx> Value<'tcx> {
                     fields.ensure_contains_elem(*idx, || Value::Uninit)
                 }
                 (PlaceElem::Field(..), val @ Value::Uninit) => {
-                    *val = Value::Aggregate {
-                        variant: VariantIdx::new(0),
-                        fields: Default::default(),
-                    };
+                    *val =
+                        Value::Aggregate { variant: VariantIdx::ZERO, fields: Default::default() };
                     val.project_mut(&[*proj])?
                 }
                 _ => return None,
@@ -572,7 +570,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                     self.use_ecx(|this| this.ecx.overflowing_binary_op(bin_op, &left, &right))?;
                 let overflowed = ImmTy::from_bool(overflowed, self.tcx);
                 Value::Aggregate {
-                    variant: VariantIdx::new(0),
+                    variant: VariantIdx::ZERO,
                     fields: [Value::from(val), overflowed.into()].into_iter().collect(),
                 }
             }
@@ -607,7 +605,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                         | AggregateKind::Tuple
                         | AggregateKind::Closure(_, _)
                         | AggregateKind::Coroutine(_, _)
-                        | AggregateKind::CoroutineClosure(_, _) => VariantIdx::new(0),
+                        | AggregateKind::CoroutineClosure(_, _) => VariantIdx::ZERO,
                     },
                 }
             }
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index 15988c0ea6b..e477c068229 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -53,7 +53,6 @@ mod add_moves_for_packed_drops;
 mod add_retag;
 mod check_const_item_mutation;
 mod check_packed_ref;
-pub mod check_unsafety;
 mod remove_place_mention;
 // This pass is public to allow external drivers to perform MIR cleanup
 mod add_subtyping_projections;
@@ -110,7 +109,7 @@ pub mod simplify;
 mod simplify_branches;
 mod simplify_comparison_integral;
 mod sroa;
-mod uninhabited_enum_branching;
+mod unreachable_enum_branching;
 mod unreachable_prop;
 
 use rustc_const_eval::transform::check_consts::{self, ConstCx};
@@ -120,7 +119,6 @@ use rustc_mir_dataflow::rustc_peek;
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
 pub fn provide(providers: &mut Providers) {
-    check_unsafety::provide(providers);
     coverage::query::provide(providers);
     ffi_unwind_calls::provide(providers);
     shim::provide(providers);
@@ -280,11 +278,6 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
 }
 
 fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
-    // MIR unsafety check uses the raw mir, so make sure it is run.
-    if !tcx.sess.opts.unstable_opts.thir_unsafeck {
-        tcx.ensure_with_value().mir_unsafety_check_result(def);
-    }
-
     let mut body = tcx.build_mir(def);
 
     pass_manager::dump_mir_for_phase_change(tcx, &body);
@@ -580,9 +573,10 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
             &remove_zsts::RemoveZsts,
             &remove_unneeded_drops::RemoveUnneededDrops,
             // Type instantiation may create uninhabited enums.
-            &uninhabited_enum_branching::UninhabitedEnumBranching,
+            // Also eliminates some unreachable branches based on variants of enums.
+            &unreachable_enum_branching::UnreachableEnumBranching,
             &unreachable_prop::UnreachablePropagation,
-            &o1(simplify::SimplifyCfg::AfterUninhabitedEnumBranching),
+            &o1(simplify::SimplifyCfg::AfterUnreachableEnumBranching),
             // Inlining may have introduced a lot of redundant code and a large move pattern.
             // Now, we need to shrink the generated MIR.
 
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index d64cb9b12b2..a9d4b860b7a 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -434,7 +434,7 @@ impl<'tcx> Validator<'_, 'tcx> {
             Rvalue::ThreadLocalRef(_) => return Err(Unpromotable),
 
             // ptr-to-int casts are not possible in consts and thus not promotable
-            Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => return Err(Unpromotable),
+            Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => return Err(Unpromotable),
 
             // all other casts including int-to-ptr casts are fine, they just use the integer value
             // at pointer type.
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index b60ee7649b2..93bad882625 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -985,7 +985,7 @@ 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_addr` 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 574330cc355..5bbe3bb747f 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -44,7 +44,7 @@ pub enum SimplifyCfg {
     PreOptimizations,
     Final,
     MakeShim,
-    AfterUninhabitedEnumBranching,
+    AfterUnreachableEnumBranching,
 }
 
 impl SimplifyCfg {
@@ -57,8 +57,8 @@ impl SimplifyCfg {
             SimplifyCfg::PreOptimizations => "SimplifyCfg-pre-optimizations",
             SimplifyCfg::Final => "SimplifyCfg-final",
             SimplifyCfg::MakeShim => "SimplifyCfg-make_shim",
-            SimplifyCfg::AfterUninhabitedEnumBranching => {
-                "SimplifyCfg-after-uninhabited-enum-branching"
+            SimplifyCfg::AfterUnreachableEnumBranching => {
+                "SimplifyCfg-after-unreachable-enum-branching"
             }
         }
     }
@@ -415,7 +415,7 @@ fn make_local_map<V>(
     used_locals: &UsedLocals,
 ) -> IndexVec<Local, Option<Local>> {
     let mut map: IndexVec<Local, Option<Local>> = IndexVec::from_elem(None, local_decls);
-    let mut used = Local::new(0);
+    let mut used = Local::ZERO;
 
     for alive_index in local_decls.indices() {
         // `is_used` treats the `RETURN_PLACE` and arguments as used.
diff --git a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs
index 57fe46ad75a..66b6235eb93 100644
--- a/compiler/rustc_mir_transform/src/uninhabited_enum_branching.rs
+++ b/compiler/rustc_mir_transform/src/unreachable_enum_branching.rs
@@ -1,4 +1,4 @@
-//! A pass that eliminates branches on uninhabited enum variants.
+//! A pass that eliminates branches on uninhabited or unreachable enum variants.
 
 use crate::MirPass;
 use rustc_data_structures::fx::FxHashSet;
@@ -11,7 +11,7 @@ use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::{Ty, TyCtxt};
 use rustc_target::abi::{Abi, Variants};
 
-pub struct UninhabitedEnumBranching;
+pub struct UnreachableEnumBranching;
 
 fn get_discriminant_local(terminator: &TerminatorKind<'_>) -> Option<Local> {
     if let TerminatorKind::SwitchInt { discr: Operand::Move(p), .. } = terminator {
@@ -71,13 +71,13 @@ fn variant_discriminants<'tcx>(
     }
 }
 
-impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
+impl<'tcx> MirPass<'tcx> for UnreachableEnumBranching {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         sess.mir_opt_level() > 0
     }
 
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        trace!("UninhabitedEnumBranching starting for {:?}", body.source);
+        trace!("UnreachableEnumBranching starting for {:?}", body.source);
 
         let mut unreachable_targets = Vec::new();
         let mut patch = MirPatch::new(body);
@@ -96,8 +96,10 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
             );
 
             let mut allowed_variants = if let Ok(layout) = layout {
+                // Find allowed variants based on uninhabited.
                 variant_discriminants(&layout, discriminant_ty, tcx)
             } else if let Some(variant_range) = discriminant_ty.variant_range(tcx) {
+                // If there are some generics, we can still get the allowed variants.
                 variant_range
                     .map(|variant| {
                         discriminant_ty.discriminant_for_variant(tcx, variant).unwrap().val
@@ -121,9 +123,26 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
             }
             let otherwise_is_empty_unreachable =
                 body.basic_blocks[targets.otherwise()].is_empty_unreachable();
-            // After resolving https://github.com/llvm/llvm-project/issues/78578,
-            // we can remove the limit on the number of successors.
             fn check_successors(basic_blocks: &BasicBlocks<'_>, bb: BasicBlock) -> bool {
+                // After resolving https://github.com/llvm/llvm-project/issues/78578,
+                // We can remove this check.
+                // The main issue here is that `early-tailduplication` causes compile time overhead
+                // and potential performance problems.
+                // Simply put, when encounter a switch (indirect branch) statement,
+                // `early-tailduplication` tries to duplicate the switch branch statement with BB
+                // into (each) predecessors. This makes CFG very complex.
+                // We can understand it as it transforms the following code
+                // ```rust
+                // match a { ... many cases };
+                // match b { ... many cases };
+                // ```
+                // into
+                // ```rust
+                // match a { ... many match b { goto BB cases } }
+                // ... BB cases
+                // ```
+                // Abandon this transformation when it is possible (the best effort)
+                // to encounter the problem.
                 let mut successors = basic_blocks[bb].terminator().successors();
                 let Some(first_successor) = successors.next() else { return true };
                 if successors.next().is_some() {
@@ -136,11 +155,32 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
                 };
                 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
+            // ```rust
+            // match c {
+            //     Ordering::Less => 1,
+            //     Ordering::Equal => 2,
+            //     _ => 3,
+            // }
+            // ```
+            // to
+            // ```rust
+            // match c {
+            //     Ordering::Less => 1,
+            //     Ordering::Equal => 2,
+            //     Ordering::Greater => 3,
+            // }
+            // ```
             let otherwise_is_last_variant = !otherwise_is_empty_unreachable
                 && allowed_variants.len() == 1
-                && check_successors(&body.basic_blocks, targets.otherwise());
+                // Despite the LLVM issue, we hope that small enum can still be transformed.
+                // This is valuable for both `a <= b` and `if let Some/Ok(v)`.
+                && (targets.all_targets().len() <= 3
+                    || check_successors(&body.basic_blocks, targets.otherwise()));
             let replace_otherwise_to_unreachable = otherwise_is_last_variant
-                || !otherwise_is_empty_unreachable && allowed_variants.is_empty();
+                || (!otherwise_is_empty_unreachable && allowed_variants.is_empty());
 
             if unreachable_targets.is_empty() && !replace_otherwise_to_unreachable {
                 continue;
@@ -150,6 +190,7 @@ impl<'tcx> MirPass<'tcx> for UninhabitedEnumBranching {
             let mut targets = targets.clone();
             if replace_otherwise_to_unreachable {
                 if otherwise_is_last_variant {
+                    // We have checked that `allowed_variants` has only one element.
                     #[allow(rustc::potential_query_instability)]
                     let last_variant = *allowed_variants.iter().next().unwrap();
                     targets.add_target(last_variant, targets.otherwise());
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 18fb858c84c..012285e4644 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -860,6 +860,7 @@ impl<'a> Parser<'a> {
                     ExprKind::MethodCall(_) => "a method call",
                     ExprKind::Call(_, _) => "a function call",
                     ExprKind::Await(_, _) => "`.await`",
+                    ExprKind::Match(_, _, MatchKind::Postfix) => "a postfix match",
                     ExprKind::Err(_) => return Ok(with_postfix),
                     _ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"),
                 }
diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs
index 1c9a9ab0f72..44f09b66bf6 100644
--- a/compiler/rustc_pattern_analysis/src/constructor.rs
+++ b/compiler/rustc_pattern_analysis/src/constructor.rs
@@ -140,6 +140,34 @@
 //! [`ConstructorSet::split`]. The invariants of [`SplitConstructorSet`] are also of interest.
 //!
 //!
+//! ## Unions
+//!
+//! Unions allow us to match a value via several overlapping representations at the same time. For
+//! example, the following is exhaustive because when seeing the value as a boolean we handled all
+//! possible cases (other cases such as `n == 3` would trigger UB).
+//!
+//! ```rust
+//! # fn main() {
+//! union U8AsBool {
+//!     n: u8,
+//!     b: bool,
+//! }
+//! let x = U8AsBool { n: 1 };
+//! unsafe {
+//!     match x {
+//!         U8AsBool { n: 2 } => {}
+//!         U8AsBool { b: true } => {}
+//!         U8AsBool { b: false } => {}
+//!     }
+//! }
+//! # }
+//! ```
+//!
+//! Pattern-matching has no knowledge that e.g. `false as u8 == 0`, so the values we consider in the
+//! algorithm look like `U8AsBool { b: true, n: 2 }`. In other words, for the most part a union is
+//! treated like a struct with the same fields. The difference lies in how we construct witnesses of
+//! non-exhaustiveness.
+//!
 //!
 //! ## Opaque patterns
 //!
@@ -974,7 +1002,6 @@ impl<Cx: PatCx> ConstructorSet<Cx> {
     /// any) are missing; 2/ split constructors to handle non-trivial intersections e.g. on ranges
     /// or slices. This can get subtle; see [`SplitConstructorSet`] for details of this operation
     /// and its invariants.
-    #[instrument(level = "debug", skip(self, ctors), ret)]
     pub fn split<'a>(
         &self,
         ctors: impl Iterator<Item = &'a Constructor<Cx>> + Clone,
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index b0f506c3651..467f09e4c29 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -186,7 +186,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
 
     /// Returns the types of the fields for a given constructor. The result must have a length of
     /// `ctor.arity()`.
-    #[instrument(level = "trace", skip(self))]
     pub(crate) fn ctor_sub_tys<'a>(
         &'a self,
         ctor: &'a Constructor<'p, 'tcx>,
@@ -283,7 +282,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
     /// Creates a set that represents all the constructors of `ty`.
     ///
     /// See [`crate::constructor`] for considerations of emptiness.
-    #[instrument(level = "debug", skip(self), ret)]
     pub fn ctors_for_ty(
         &self,
         ty: RevealedTy<'tcx>,
diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs
index cdc03eaeb37..7246039174a 100644
--- a/compiler/rustc_pattern_analysis/src/usefulness.rs
+++ b/compiler/rustc_pattern_analysis/src/usefulness.rs
@@ -871,12 +871,14 @@ impl<Cx: PatCx> PlaceInfo<Cx> {
     where
         Cx: 'a,
     {
+        debug!(?self.ty);
         if self.private_uninhabited {
             // Skip the whole column
             return Ok((smallvec![Constructor::PrivateUninhabited], vec![]));
         }
 
         let ctors_for_ty = cx.ctors_for_ty(&self.ty)?;
+        debug!(?ctors_for_ty);
 
         // We treat match scrutinees of type `!` or `EmptyEnum` differently.
         let is_toplevel_exception =
@@ -895,6 +897,7 @@ impl<Cx: PatCx> PlaceInfo<Cx> {
 
         // Analyze the constructors present in this column.
         let mut split_set = ctors_for_ty.split(ctors);
+        debug!(?split_set);
         let all_missing = split_set.present.is_empty();
 
         // Build the set of constructors we will specialize with. It must cover the whole type, so
@@ -1254,7 +1257,7 @@ impl<'p, Cx: PatCx> Matrix<'p, Cx> {
 /// + true  + [Second(true)]    +
 /// + false + [_]               +
 /// + _     + [_, _, tail @ ..] +
-/// | ✓     | ?                 | // column validity
+/// | ✓     | ?                 | // validity
 /// ```
 impl<'p, Cx: PatCx> fmt::Debug for Matrix<'p, Cx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1285,7 +1288,7 @@ impl<'p, Cx: PatCx> fmt::Debug for Matrix<'p, Cx> {
                 write!(f, " {sep}")?;
             }
             if is_validity_row {
-                write!(f, " // column validity")?;
+                write!(f, " // validity")?;
             }
             write!(f, "\n")?;
         }
@@ -1381,12 +1384,35 @@ impl<Cx: PatCx> WitnessStack<Cx> {
     /// pats: [(false, "foo"), _, true]
     /// result: [Enum::Variant { a: (false, "foo"), b: _ }, true]
     /// ```
-    fn apply_constructor(&mut self, pcx: &PlaceCtxt<'_, Cx>, ctor: &Constructor<Cx>) {
+    fn apply_constructor(
+        mut self,
+        pcx: &PlaceCtxt<'_, Cx>,
+        ctor: &Constructor<Cx>,
+    ) -> SmallVec<[Self; 1]> {
         let len = self.0.len();
         let arity = pcx.ctor_arity(ctor);
-        let fields = self.0.drain((len - arity)..).rev().collect();
-        let pat = WitnessPat::new(ctor.clone(), fields, pcx.ty.clone());
-        self.0.push(pat);
+        let fields: Vec<_> = self.0.drain((len - arity)..).rev().collect();
+        if matches!(ctor, Constructor::UnionField)
+            && fields.iter().filter(|p| !matches!(p.ctor(), Constructor::Wildcard)).count() >= 2
+        {
+            // Convert a `Union { a: p, b: q }` witness into `Union { a: p }` and `Union { b: q }`.
+            // First add `Union { .. }` to `self`.
+            self.0.push(WitnessPat::wild_from_ctor(pcx.cx, ctor.clone(), pcx.ty.clone()));
+            fields
+                .into_iter()
+                .enumerate()
+                .filter(|(_, p)| !matches!(p.ctor(), Constructor::Wildcard))
+                .map(|(i, p)| {
+                    let mut ret = self.clone();
+                    // Fill the `i`th field of the union with `p`.
+                    ret.0.last_mut().unwrap().fields[i] = p;
+                    ret
+                })
+                .collect()
+        } else {
+            self.0.push(WitnessPat::new(ctor.clone(), fields, pcx.ty.clone()));
+            smallvec![self]
+        }
     }
 }
 
@@ -1459,8 +1485,8 @@ impl<Cx: PatCx> WitnessMatrix<Cx> {
             *self = ret;
         } else {
             // Any other constructor we unspecialize as expected.
-            for witness in self.0.iter_mut() {
-                witness.apply_constructor(pcx, ctor)
+            for witness in std::mem::take(&mut self.0) {
+                self.0.extend(witness.apply_constructor(pcx, ctor));
             }
         }
     }
@@ -1617,7 +1643,6 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: PatCx>(
     };
 
     // Analyze the constructors present in this column.
-    debug!("ty: {:?}", place.ty);
     let ctors = matrix.heads().map(|p| p.ctor());
     let (split_ctors, missing_ctors) = place.split_column_ctors(mcx.tycx, ctors)?;
 
@@ -1669,7 +1694,10 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: PatCx>(
     for row in matrix.rows() {
         if row.useful {
             if let PatOrWild::Pat(pat) = row.head() {
-                mcx.useful_subpatterns.insert(pat.uid);
+                let newly_useful = mcx.useful_subpatterns.insert(pat.uid);
+                if newly_useful {
+                    debug!("newly useful: {pat:?}");
+                }
             }
         }
     }
@@ -1768,6 +1796,7 @@ pub fn compute_match_usefulness<'p, Cx: PatCx>(
         .map(|arm| {
             debug!(?arm);
             let usefulness = collect_pattern_usefulness(&cx.useful_subpatterns, arm.pat);
+            debug!(?usefulness);
             (arm, usefulness)
         })
         .collect();
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 9f067273f35..f223f64f2c5 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -40,7 +40,7 @@ rustc_index::newtype_index! {
 }
 
 impl DepNodeIndex {
-    const SINGLETON_DEPENDENCYLESS_ANON_NODE: DepNodeIndex = DepNodeIndex::from_u32(0);
+    const SINGLETON_DEPENDENCYLESS_ANON_NODE: DepNodeIndex = DepNodeIndex::ZERO;
     pub const FOREVER_RED_NODE: DepNodeIndex = DepNodeIndex::from_u32(1);
 }
 
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 48711f43518..76fe36a77cb 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -532,7 +532,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         let mut seen_spans = FxHashSet::default();
         let mut errors = vec![];
-        let mut prev_root_id: NodeId = NodeId::from_u32(0);
+        let mut prev_root_id: NodeId = NodeId::ZERO;
         let determined_imports = mem::take(&mut self.determined_imports);
         let indeterminate_imports = mem::take(&mut self.indeterminate_imports);
 
@@ -556,8 +556,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     }
                 }
 
-                if prev_root_id.as_u32() != 0
-                    && prev_root_id.as_u32() != import.root_id.as_u32()
+                if prev_root_id != NodeId::ZERO
+                    && prev_root_id != import.root_id
                     && !errors.is_empty()
                 {
                     // In the case of a new import line, throw a diagnostic message
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 6204f868385..a76eb6b06aa 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1950,8 +1950,6 @@ written to standard error output)"),
     #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")]
     thinlto: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "enable ThinLTO when possible"),
-    thir_unsafeck: bool = (true, parse_bool, [TRACKED],
-        "use the THIR unsafety checker (default: yes)"),
     /// We default to 1 here since we want to behave like
     /// a sequential compiler for now. This'll likely be adjusted
     /// in the future. Note that -Zthreads=0 is the way to get
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index 9d91032c1d2..c9f66612590 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -267,7 +267,7 @@ impl<'tcx> Stable<'tcx> for mir::CastKind {
     fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
         use rustc_middle::mir::CastKind::*;
         match self {
-            PointerExposeAddress => stable_mir::mir::CastKind::PointerExposeAddress,
+            PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress,
             PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance,
             PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)),
             DynStar => stable_mir::mir::CastKind::DynStar,
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index 8f721bac951..8925b7a42d4 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -22,7 +22,7 @@ rustc_index::newtype_index! {
 
 /// Item definitions in the currently-compiled crate would have the `CrateNum`
 /// `LOCAL_CRATE` in their `DefId`.
-pub const LOCAL_CRATE: CrateNum = CrateNum::from_u32(0);
+pub const LOCAL_CRATE: CrateNum = CrateNum::ZERO;
 
 impl CrateNum {
     #[inline]
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 37fea6c122c..1df2b357ac1 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -165,7 +165,7 @@ pub enum Transparency {
 
 impl LocalExpnId {
     /// The ID of the theoretical expansion that generates freshly parsed, unexpanded AST.
-    pub const ROOT: LocalExpnId = LocalExpnId::from_u32(0);
+    pub const ROOT: LocalExpnId = LocalExpnId::ZERO;
 
     #[inline]
     fn from_raw(idx: ExpnIndex) -> LocalExpnId {
@@ -242,7 +242,7 @@ impl ExpnId {
     /// The ID of the theoretical expansion that generates freshly parsed, unexpanded AST.
     /// Invariant: we do not create any ExpnId with local_id == 0 and krate != 0.
     pub const fn root() -> ExpnId {
-        ExpnId { krate: LOCAL_CRATE, local_id: ExpnIndex::from_u32(0) }
+        ExpnId { krate: LOCAL_CRATE, local_id: ExpnIndex::ZERO }
     }
 
     #[inline]
diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs
index 81a9e470688..dcb02da3719 100644
--- a/compiler/rustc_span/src/source_map/tests.rs
+++ b/compiler/rustc_span/src/source_map/tests.rs
@@ -243,7 +243,7 @@ fn t10() {
         src_hash,
         stable_id,
         source_len.to_u32(),
-        CrateNum::new(0),
+        CrateNum::ZERO,
         FreezeLock::new(lines.read().clone()),
         multibyte_chars,
         non_narrow_chars,
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index b1d4a63812f..a13c9c9b278 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1659,7 +1659,7 @@ symbols! {
         simd_cttz,
         simd_div,
         simd_eq,
-        simd_expose_addr,
+        simd_expose_provenance,
         simd_extract,
         simd_fabs,
         simd_fcos,
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 706a7a310f2..cdd3f0afd79 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -251,9 +251,9 @@ pub struct Uniform {
     /// The total size of the argument, which can be:
     /// * equal to `unit.size` (one scalar/vector),
     /// * a multiple of `unit.size` (an array of scalar/vectors),
-    /// * if `unit.kind` is `Integer`, the last element
-    ///   can be shorter, i.e., `{ i64, i64, i32 }` for
-    ///   64-bit integers with a total size of 20 bytes.
+    /// * if `unit.kind` is `Integer`, the last element can be shorter, i.e., `{ i64, i64, i32 }`
+    ///   for 64-bit integers with a total size of 20 bytes. When the argument is actually passed,
+    ///   this size will be rounded up to the nearest multiple of `unit.size`.
     pub total: Size,
 }
 
@@ -319,14 +319,17 @@ impl CastTarget {
     }
 
     pub fn size<C: HasDataLayout>(&self, _cx: &C) -> Size {
-        let mut size = self.rest.total;
-        for i in 0..self.prefix.iter().count() {
-            match self.prefix[i] {
-                Some(v) => size += v.size,
-                None => {}
-            }
-        }
-        return size;
+        // Prefix arguments are passed in specific designated registers
+        let prefix_size = self
+            .prefix
+            .iter()
+            .filter_map(|x| x.map(|reg| reg.size))
+            .fold(Size::ZERO, |acc, size| acc + size);
+        // Remaining arguments are passed in chunks of the unit size
+        let rest_size =
+            self.rest.unit.size * self.rest.total.bytes().div_ceil(self.rest.unit.size.bytes());
+
+        prefix_size + rest_size
     }
 
     pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align {
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
index 66688893235..d8aeadd07b3 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -1,4 +1,4 @@
-use crate::traits::{check_args_compatible, specialization_graph};
+use crate::traits::specialization_graph;
 
 use super::assembly::structural_traits::AsyncCallableRelevantTypes;
 use super::assembly::{self, structural_traits, Candidate};
@@ -247,7 +247,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                 assoc_def.defining_node,
             );
 
-            if !check_args_compatible(tcx, assoc_def.item, args) {
+            if !tcx.check_args_compatible(assoc_def.item.def_id, args) {
                 return error_response(
                     ecx,
                     "associated item has mismatched generic item arguments",
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 6e768b23ef8..90e337a53b6 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -554,11 +554,7 @@ fn plug_infer_with_placeholders<'tcx>(
         }
     }
 
-    value.visit_with(&mut PlugInferWithPlaceholder {
-        infcx,
-        universe,
-        var: ty::BoundVar::from_u32(0),
-    });
+    value.visit_with(&mut PlugInferWithPlaceholder { infcx, universe, var: ty::BoundVar::ZERO });
 }
 
 fn try_prove_negated_where_clause<'tcx>(
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 3ab4872fffe..2c8116b779b 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -61,12 +61,12 @@ pub use self::specialize::{
 pub use self::structural_match::search_for_structural_match_violation;
 pub use self::structural_normalize::StructurallyNormalizeExt;
 pub use self::util::elaborate;
-pub use self::util::{
-    check_args_compatible, supertrait_def_ids, supertraits, transitive_bounds,
-    transitive_bounds_that_define_assoc_item, SupertraitDefIds,
-};
 pub use self::util::{expand_trait_aliases, TraitAliasExpander, TraitAliasExpansionInfo};
 pub use self::util::{get_vtable_index_of_object_method, impl_item_is_final, upcast_choices};
+pub use self::util::{
+    supertrait_def_ids, supertraits, transitive_bounds, transitive_bounds_that_define_assoc_item,
+    SupertraitDefIds,
+};
 pub use self::util::{with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer};
 
 pub use rustc_infer::traits::*;
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index c33e24b1094..9d744d9a032 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -2,7 +2,6 @@
 
 use std::ops::ControlFlow;
 
-use super::check_args_compatible;
 use super::specialization_graph;
 use super::translate_args;
 use super::util;
@@ -2030,7 +2029,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
     } else {
         ty.map_bound(|ty| ty.into())
     };
-    if !check_args_compatible(tcx, assoc_ty.item, args) {
+    if !tcx.check_args_compatible(assoc_ty.item.def_id, args) {
         let err = Ty::new_error_with_message(
             tcx,
             obligation.cause.span,
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 466a53d8ce0..d29fc7921bc 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -344,48 +344,6 @@ pub enum TupleArgumentsFlag {
     No,
 }
 
-// Verify that the trait item and its implementation have compatible args lists
-pub fn check_args_compatible<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    assoc_item: ty::AssocItem,
-    args: ty::GenericArgsRef<'tcx>,
-) -> bool {
-    fn check_args_compatible_inner<'tcx>(
-        tcx: TyCtxt<'tcx>,
-        generics: &'tcx ty::Generics,
-        args: &'tcx [ty::GenericArg<'tcx>],
-    ) -> bool {
-        if generics.count() != args.len() {
-            return false;
-        }
-
-        let (parent_args, own_args) = args.split_at(generics.parent_count);
-
-        if let Some(parent) = generics.parent
-            && let parent_generics = tcx.generics_of(parent)
-            && !check_args_compatible_inner(tcx, parent_generics, parent_args)
-        {
-            return false;
-        }
-
-        for (param, arg) in std::iter::zip(&generics.params, own_args) {
-            match (&param.kind, arg.unpack()) {
-                (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
-                | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
-                | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
-                _ => return false,
-            }
-        }
-
-        true
-    }
-
-    let generics = tcx.generics_of(assoc_item.def_id);
-    // Chop off any additional args (RPITIT) args
-    let args = &args[0..generics.count().min(args.len())];
-    check_args_compatible_inner(tcx, generics, args)
-}
-
 /// Executes `f` on `value` after replacing all escaping bound variables with placeholders
 /// and then replaces these placeholders with the original bound variables in the result.
 ///
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 331970ac362..dd1f2322c41 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -377,7 +377,7 @@ fn layout_of_uncached<'tcx>(
             }
 
             // Type of the first ADT field:
-            let f0_ty = fields[FieldIdx::from_u32(0)].ty(tcx, args);
+            let f0_ty = fields[FieldIdx::ZERO].ty(tcx, args);
 
             // Heterogeneous SIMD vectors are not supported:
             // (should be caught by typeck)
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index fc16edc6d13..a652bb78116 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -7,7 +7,6 @@ use rustc_middle::ty::util::{CheckRegions, NotUniqueParam};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
 use rustc_span::Span;
-use rustc_trait_selection::traits::check_args_compatible;
 
 use crate::errors::{DuplicateArg, NotParam};
 
@@ -250,7 +249,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
                                 ty::GenericArgs::identity_for_item(self.tcx, parent),
                             );
 
-                            if check_args_compatible(self.tcx, assoc, impl_args) {
+                            if self.tcx.check_args_compatible(assoc.def_id, impl_args) {
                                 self.tcx
                                     .type_of(assoc.def_id)
                                     .instantiate(self.tcx, impl_args)
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index c01baa58ae7..45e22b12a8b 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -314,7 +314,7 @@ rustc_index::newtype_index! {
 }
 
 impl UniverseIndex {
-    pub const ROOT: UniverseIndex = UniverseIndex::from_u32(0);
+    pub const ROOT: UniverseIndex = UniverseIndex::ZERO;
 
     /// Returns the "next" universe index in order -- this new index
     /// is considered to extend all previous universes. This
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 0d866f27dad..8f77a19fc0e 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -971,6 +971,7 @@ pub enum PointerCoercion {
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum CastKind {
+    // FIXME(smir-rename): rename this to PointerExposeProvenance
     PointerExposeAddress,
     PointerWithExposedProvenance,
     PointerCoercion(PointerCoercion),
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index d448c5338fc..44ae72bcd26 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -227,10 +227,13 @@ mod impls {
     impl_clone! {
         usize u8 u16 u32 u64 u128
         isize i8 i16 i32 i64 i128
-        f16 f32 f64 f128
+        f32 f64
         bool char
     }
 
+    #[cfg(not(bootstrap))]
+    impl_clone! { f16 f128 }
+
     #[unstable(feature = "never_type", issue = "35121")]
     impl Clone for ! {
         #[inline]
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index fa218600ed9..81bba927554 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -1497,9 +1497,12 @@ mod impls {
     }
 
     partial_eq_impl! {
-        bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128
+        bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
     }
 
+    #[cfg(not(bootstrap))]
+    partial_eq_impl! { f16 f128 }
+
     macro_rules! eq_impl {
         ($($t:ty)*) => ($(
             #[stable(feature = "rust1", since = "1.0.0")]
@@ -1550,7 +1553,10 @@ mod impls {
         }
     }
 
-    partial_ord_impl! { f16 f32 f64 f128 }
+    partial_ord_impl! { f32 f64 }
+
+    #[cfg(not(bootstrap))]
+    partial_ord_impl! { f16 f128 }
 
     macro_rules! ord_impl {
         ($($t:ty)*) => ($(
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index e880d5758ec..287f6c23c89 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -2438,8 +2438,8 @@ impl Display for char {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Pointer for *const T {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
-        // Cast is needed here because `.expose_addr()` requires `T: Sized`.
-        pointer_fmt_inner((*self as *const ()).expose_addr(), f)
+        // Cast is needed here because `.expose_provenance()` requires `T: Sized`.
+        pointer_fmt_inner((*self as *const ()).expose_provenance(), f)
     }
 }
 
diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs
index 614b4b589d3..eeff4ec609a 100644
--- a/library/core/src/intrinsics/simd.rs
+++ b/library/core/src/intrinsics/simd.rs
@@ -540,6 +540,10 @@ extern "rust-intrinsic" {
     /// `T` must be a vector of pointers.
     ///
     /// `U` must be a vector of `usize` with the same length as `T`.
+    #[cfg(not(bootstrap))]
+    #[rustc_nounwind]
+    pub fn simd_expose_provenance<T, U>(ptr: T) -> U;
+    #[cfg(bootstrap)]
     #[rustc_nounwind]
     pub fn simd_expose_addr<T, U>(ptr: T) -> U;
 
@@ -661,4 +665,6 @@ extern "rust-intrinsic" {
 }
 
 #[cfg(bootstrap)]
+pub use simd_expose_addr as simd_expose_provenance;
+#[cfg(bootstrap)]
 pub use simd_from_exposed_addr as simd_with_exposed_provenance;
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 0cc3ad1ead7..ba19ca1f45d 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -205,6 +205,8 @@
 //
 // Language features:
 // tidy-alphabetical-start
+#![cfg_attr(not(bootstrap), feature(f128))]
+#![cfg_attr(not(bootstrap), feature(f16))]
 #![feature(abi_unadjusted)]
 #![feature(adt_const_params)]
 #![feature(allow_internal_unsafe)]
@@ -229,8 +231,6 @@
 #![feature(doc_notable_trait)]
 #![feature(effects)]
 #![feature(extern_types)]
-#![feature(f128)]
-#![feature(f16)]
 #![feature(freeze_impls)]
 #![feature(fundamental)]
 #![feature(generic_arg_infer)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 1d073a6d649..fb97b3bfa09 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -422,11 +422,17 @@ marker_impls! {
     Copy for
         usize, u8, u16, u32, u64, u128,
         isize, i8, i16, i32, i64, i128,
-        f16, f32, f64, f128,
+        f32, f64,
         bool, char,
         {T: ?Sized} *const T,
         {T: ?Sized} *mut T,
+}
 
+#[cfg(not(bootstrap))]
+marker_impls! {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Copy for
+        f16, f128,
 }
 
 #[unstable(feature = "never_type", issue = "35121")]
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index e5713ee89df..01db050e666 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -136,7 +136,7 @@ impl<T: ?Sized> *const T {
     #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
     #[deprecated(
         since = "1.67.0",
-        note = "replaced by the `expose_addr` method, or update your code \
+        note = "replaced by the `expose_provenance` method, or update your code \
             to follow the strict provenance rules using its APIs"
     )]
     #[inline(always)]
@@ -187,7 +187,7 @@ impl<T: ?Sized> *const T {
     ///
     /// If using those APIs is not possible because there is no way to preserve a pointer with the
     /// required provenance, then Strict Provenance might not be for you. Use pointer-integer casts
-    /// or [`expose_addr`][pointer::expose_addr] and [`with_exposed_provenance`][with_exposed_provenance]
+    /// or [`expose_provenance`][pointer::expose_provenance] and [`with_exposed_provenance`][with_exposed_provenance]
     /// instead. However, note that this makes your code less portable and less amenable to tools
     /// that check for compliance with the Rust memory model.
     ///
@@ -210,8 +210,8 @@ impl<T: ?Sized> *const T {
         unsafe { mem::transmute(self.cast::<()>()) }
     }
 
-    /// Gets the "address" portion of the pointer, and 'exposes' the "provenance" part for future
-    /// use in [`with_exposed_provenance`][].
+    /// Exposes the "provenance" part of the pointer for future use in
+    /// [`with_exposed_provenance`][] and returns the "address" portion.
     ///
     /// This is equivalent to `self as usize`, which semantically discards *provenance* and
     /// *address-space* information. Furthermore, this (like the `as` cast) has the implicit
@@ -238,7 +238,7 @@ impl<T: ?Sized> *const T {
     #[must_use]
     #[inline(always)]
     #[unstable(feature = "exposed_provenance", issue = "95228")]
-    pub fn expose_addr(self) -> usize {
+    pub fn expose_provenance(self) -> usize {
         // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
         self.cast::<()>() as usize
     }
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 28df2b04c88..f12ab3d50cd 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -340,8 +340,8 @@
 //! clear where a satisfying unambiguous semantics can be defined for Exposed Provenance.
 //! Furthermore, Exposed Provenance will not work (well) with tools like [Miri] and [CHERI].
 //!
-//! Exposed Provenance is provided by the [`expose_addr`] and [`with_exposed_provenance`] methods, which
-//! are meant to replace `as` casts between pointers and integers. [`expose_addr`] is a lot like
+//! Exposed Provenance is provided by the [`expose_provenance`] and [`with_exposed_provenance`] methods,
+//! which are meant to replace `as` casts between pointers and integers. [`expose_provenance`] is a lot like
 //! [`addr`], but additionally adds the provenance of the pointer to a global list of 'exposed'
 //! provenances. (This list is purely conceptual, it exists for the purpose of specifying Rust but
 //! is not materialized in actual executions, except in tools like [Miri].) [`with_exposed_provenance`]
@@ -355,9 +355,9 @@
 //! there is *no* previously 'exposed' provenance that justifies the way the returned pointer will
 //! be used, the program has undefined behavior.
 //!
-//! Using [`expose_addr`] or [`with_exposed_provenance`] (or the `as` casts) means that code is
+//! Using [`expose_provenance`] or [`with_exposed_provenance`] (or the `as` casts) means that code is
 //! *not* following Strict Provenance rules. The goal of the Strict Provenance experiment is to
-//! determine how far one can get in Rust without the use of [`expose_addr`] and
+//! determine how far one can get in Rust without the use of [`expose_provenance`] and
 //! [`with_exposed_provenance`], and to encourage code to be written with Strict Provenance APIs only.
 //! Maximizing the amount of such code is a major win for avoiding specification complexity and to
 //! facilitate adoption of tools like [CHERI] and [Miri] that can be a big help in increasing the
@@ -374,7 +374,7 @@
 //! [`map_addr`]: pointer::map_addr
 //! [`addr`]: pointer::addr
 //! [`ptr::dangling`]: core::ptr::dangling
-//! [`expose_addr`]: pointer::expose_addr
+//! [`expose_provenance`]: pointer::expose_provenance
 //! [`with_exposed_provenance`]: with_exposed_provenance
 //! [Miri]: https://github.com/rust-lang/miri
 //! [CHERI]: https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/
@@ -663,7 +663,7 @@ pub const fn dangling_mut<T>() -> *mut T {
 ///
 /// This is a more rigorously specified alternative to `addr as *const T`. The provenance of the
 /// returned pointer is that of *any* pointer that was previously exposed by passing it to
-/// [`expose_addr`][pointer::expose_addr], or a `ptr as usize` cast. In addition, memory which is
+/// [`expose_provenance`][pointer::expose_provenance], or a `ptr as usize` cast. In addition, memory which is
 /// outside the control of the Rust abstract machine (MMIO registers, for example) is always
 /// considered to be exposed, so long as this memory is disjoint from memory that will be used by
 /// the abstract machine such as the stack, heap, and statics.
@@ -711,7 +711,7 @@ where
 ///
 /// This is a more rigorously specified alternative to `addr as *mut T`. The provenance of the
 /// returned pointer is that of *any* pointer that was previously passed to
-/// [`expose_addr`][pointer::expose_addr] or a `ptr as usize` cast. If there is no previously
+/// [`expose_provenance`][pointer::expose_provenance] or a `ptr as usize` cast. If there is no previously
 /// 'exposed' provenance that justifies the way this pointer will be used, the program has undefined
 /// behavior. Note that there is no algorithm that decides which provenance will be used. You can
 /// think of this as "guessing" the right provenance, and the guess will be "maximally in your
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 042658fa35f..41e5ba67458 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -142,7 +142,7 @@ impl<T: ?Sized> *mut T {
     #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
     #[deprecated(
         since = "1.67.0",
-        note = "replaced by the `expose_addr` method, or update your code \
+        note = "replaced by the `expose_provenance` method, or update your code \
             to follow the strict provenance rules using its APIs"
     )]
     #[inline(always)]
@@ -194,7 +194,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// If using those APIs is not possible because there is no way to preserve a pointer with the
     /// required provenance, then Strict Provenance might not be for you. Use pointer-integer casts
-    /// or [`expose_addr`][pointer::expose_addr] and [`with_exposed_provenance`][with_exposed_provenance]
+    /// or [`expose_provenance`][pointer::expose_provenance] and [`with_exposed_provenance`][with_exposed_provenance]
     /// instead. However, note that this makes your code less portable and less amenable to tools
     /// that check for compliance with the Rust memory model.
     ///
@@ -217,8 +217,8 @@ impl<T: ?Sized> *mut T {
         unsafe { mem::transmute(self.cast::<()>()) }
     }
 
-    /// Gets the "address" portion of the pointer, and 'exposes' the "provenance" part for future
-    /// use in [`with_exposed_provenance`][].
+    /// Exposes the "provenance" part of the pointer for future use in
+    /// [`with_exposed_provenance`][] and returns the "address" portion.
     ///
     /// This is equivalent to `self as usize`, which semantically discards *provenance* and
     /// *address-space* information. Furthermore, this (like the `as` cast) has the implicit
@@ -242,10 +242,9 @@ impl<T: ?Sized> *mut T {
     /// API and its claimed semantics are part of [Exposed Provenance][super#exposed-provenance].
     ///
     /// [`with_exposed_provenance_mut`]: with_exposed_provenance_mut
-    #[must_use]
     #[inline(always)]
     #[unstable(feature = "exposed_provenance", issue = "95228")]
-    pub fn expose_addr(self) -> usize {
+    pub fn expose_provenance(self) -> usize {
         // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
         self.cast::<()>() as usize
     }
diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
index 4d2fe999ca6..0f1719206c9 100644
--- a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
@@ -50,9 +50,9 @@ pub trait SimdConstPtr: Copy + Sealed {
     /// Equivalent to calling [`pointer::with_addr`] on each element.
     fn with_addr(self, addr: Self::Usize) -> Self;
 
-    /// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use
-    /// in [`Self::with_exposed_provenance`].
-    fn expose_addr(self) -> Self::Usize;
+    /// Exposes the "provenance" part of the pointer for future use in
+    /// [`Self::with_exposed_provenance`] and returns the "address" portion.
+    fn expose_provenance(self) -> Self::Usize;
 
     /// Convert an address back to a pointer, picking up a previously "exposed" provenance.
     ///
@@ -131,9 +131,9 @@ where
     }
 
     #[inline]
-    fn expose_addr(self) -> Self::Usize {
+    fn expose_provenance(self) -> Self::Usize {
         // Safety: `self` is a pointer vector
-        unsafe { core::intrinsics::simd::simd_expose_addr(self) }
+        unsafe { core::intrinsics::simd::simd_expose_provenance(self) }
     }
 
     #[inline]
diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
index b3437b9c499..7ba996d149c 100644
--- a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
@@ -47,9 +47,9 @@ pub trait SimdMutPtr: Copy + Sealed {
     /// Equivalent to calling [`pointer::with_addr`] on each element.
     fn with_addr(self, addr: Self::Usize) -> Self;
 
-    /// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use
-    /// in [`Self::with_exposed_provenance`].
-    fn expose_addr(self) -> Self::Usize;
+    /// Exposes the "provenance" part of the pointer for future use in
+    /// [`Self::with_exposed_provenance`] and returns the "address" portion.
+    fn expose_provenance(self) -> Self::Usize;
 
     /// Convert an address back to a pointer, picking up a previously "exposed" provenance.
     ///
@@ -128,9 +128,9 @@ where
     }
 
     #[inline]
-    fn expose_addr(self) -> Self::Usize {
+    fn expose_provenance(self) -> Self::Usize {
         // Safety: `self` is a pointer vector
-        unsafe { core::intrinsics::simd::simd_expose_addr(self) }
+        unsafe { core::intrinsics::simd::simd_expose_provenance(self) }
     }
 
     #[inline]
diff --git a/library/portable-simd/crates/core_simd/tests/pointers.rs b/library/portable-simd/crates/core_simd/tests/pointers.rs
index 5984fdae2f9..90bfc5d5fd6 100644
--- a/library/portable-simd/crates/core_simd/tests/pointers.rs
+++ b/library/portable-simd/crates/core_simd/tests/pointers.rs
@@ -32,10 +32,10 @@ macro_rules! common_tests {
                 );
             }
 
-            fn expose_addr<const LANES: usize>() {
+            fn expose_provenance<const LANES: usize>() {
                 test_helpers::test_unary_elementwise(
-                    &Simd::<*$constness u32, LANES>::expose_addr,
-                    &<*$constness u32>::expose_addr,
+                    &Simd::<*$constness u32, LANES>::expose_provenance,
+                    &<*$constness u32>::expose_provenance,
                     &|_| true,
                 );
             }
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 9017ba79714..b1102b440e0 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -37,7 +37,7 @@ use crate::time::SystemTime;
 ///
 /// # Examples
 ///
-/// Creates a new file and write bytes to it (you can also use [`write()`]):
+/// Creates a new file and write bytes to it (you can also use [`write`]):
 ///
 /// ```no_run
 /// use std::fs::File;
@@ -2018,7 +2018,7 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
 /// the length of the `to` file as reported by `metadata`.
 ///
 /// If you want to copy the contents of one file to another and you’re
-/// working with [`File`]s, see the [`io::copy()`] function.
+/// working with [`File`]s, see the [`io::copy`](io::copy()) function.
 ///
 /// # Platform-specific behavior
 ///
diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs
index 62c76a74cd4..40f88e33d4a 100644
--- a/library/std/src/sys/pal/hermit/thread.rs
+++ b/library/std/src/sys/pal/hermit/thread.rs
@@ -29,7 +29,7 @@ impl Thread {
         let p = Box::into_raw(Box::new(p));
         let tid = abi::spawn2(
             thread_start,
-            p.expose_addr(),
+            p.expose_provenance(),
             abi::Priority::into(abi::NORMAL_PRIO),
             stack,
             core_id,
diff --git a/library/std/src/sys/pal/itron/thread.rs b/library/std/src/sys/pal/itron/thread.rs
index 1c66bd79ce4..047513a6792 100644
--- a/library/std/src/sys/pal/itron/thread.rs
+++ b/library/std/src/sys/pal/itron/thread.rs
@@ -181,7 +181,7 @@ impl Thread {
             abi::acre_tsk(&abi::T_CTSK {
                 // Activate this task immediately
                 tskatr: abi::TA_ACT,
-                exinf: p_inner.as_ptr().expose_addr() as abi::EXINF,
+                exinf: p_inner.as_ptr().expose_provenance() as abi::EXINF,
                 // The entry point
                 task: Some(trampoline),
                 // Inherit the calling task's base priority
diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs
index 7c87deed371..8c75ac65299 100644
--- a/library/std/src/sys/pal/mod.rs
+++ b/library/std/src/sys/pal/mod.rs
@@ -37,12 +37,12 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "hermit")] {
         mod hermit;
         pub use self::hermit::*;
-    } else if #[cfg(target_os = "wasi")] {
-        mod wasi;
-        pub use self::wasi::*;
     } else if #[cfg(all(target_os = "wasi", target_env = "p2"))] {
         mod wasip2;
         pub use self::wasip2::*;
+    } else if #[cfg(target_os = "wasi")] {
+        mod wasi;
+        pub use self::wasi::*;
     } else if #[cfg(target_family = "wasm")] {
         mod wasm;
         pub use self::wasm::*;
diff --git a/library/std/src/sys/pal/wasip2/cabi_realloc.rs b/library/std/src/sys/pal/wasip2/cabi_realloc.rs
new file mode 100644
index 00000000000..820063173d6
--- /dev/null
+++ b/library/std/src/sys/pal/wasip2/cabi_realloc.rs
@@ -0,0 +1,65 @@
+//! This module contains a canonical definition of the `cabi_realloc` function
+//! for the component model.
+//!
+//! The component model's canonical ABI for representing datatypes in memory
+//! makes use of this function when transferring lists and strings, for example.
+//! This function behaves like C's `realloc` but also takes alignment into
+//! account.
+//!
+//! Components are notably not required to export this function, but nearly
+//! all components end up doing so currently. This definition in the standard
+//! library removes the need for all compilations to define this themselves.
+//!
+//! More information about the canonical ABI can be found at
+//! <https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md>
+//!
+//! Note that the name of this function is not standardized in the canonical ABI
+//! at this time. Instead it's a convention of the "componentization process"
+//! where a core wasm module is converted to a component to use this name.
+//! Additionally this is not the only possible definition of this function, so
+//! this is defined as a "weak" symbol. This means that other definitions are
+//! allowed to overwrite it if they are present in a compilation.
+
+use crate::alloc::{self, Layout};
+use crate::ptr;
+
+#[used]
+static FORCE_CODEGEN_OF_CABI_REALLOC: unsafe extern "C" fn(
+    *mut u8,
+    usize,
+    usize,
+    usize,
+) -> *mut u8 = cabi_realloc;
+
+#[linkage = "weak"]
+#[no_mangle]
+pub unsafe extern "C" fn cabi_realloc(
+    old_ptr: *mut u8,
+    old_len: usize,
+    align: usize,
+    new_len: usize,
+) -> *mut u8 {
+    let layout;
+    let ptr = if old_len == 0 {
+        if new_len == 0 {
+            return ptr::without_provenance_mut(align);
+        }
+        layout = Layout::from_size_align_unchecked(new_len, align);
+        alloc::alloc(layout)
+    } else {
+        debug_assert_ne!(new_len, 0, "non-zero old_len requires non-zero new_len!");
+        layout = Layout::from_size_align_unchecked(old_len, align);
+        alloc::realloc(old_ptr, layout, new_len)
+    };
+    if ptr.is_null() {
+        // Print a nice message in debug mode, but in release mode don't
+        // pull in so many dependencies related to printing so just emit an
+        // `unreachable` instruction.
+        if cfg!(debug_assertions) {
+            alloc::handle_alloc_error(layout);
+        } else {
+            super::abort_internal();
+        }
+    }
+    return ptr;
+}
diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs
index d1d444d7b79..94aa458d2f9 100644
--- a/library/std/src/sys/pal/wasip2/mod.rs
+++ b/library/std/src/sys/pal/wasip2/mod.rs
@@ -10,8 +10,6 @@
 pub mod alloc;
 #[path = "../wasi/args.rs"]
 pub mod args;
-#[path = "../unix/cmath.rs"]
-pub mod cmath;
 #[path = "../wasi/env.rs"]
 pub mod env;
 #[path = "../wasi/fd.rs"]
@@ -28,10 +26,6 @@ pub mod io;
 pub mod net;
 #[path = "../wasi/os.rs"]
 pub mod os;
-#[path = "../unix/os_str.rs"]
-pub mod os_str;
-#[path = "../unix/path.rs"]
-pub mod path;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
@@ -72,3 +66,5 @@ pub use helpers::decode_error_kind;
 use helpers::err2io;
 pub use helpers::hashmap_random_keys;
 pub use helpers::is_interrupted;
+
+mod cabi_realloc;
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index c051b818328..0cce5130f64 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -1194,20 +1194,11 @@ impl<'a> Builder<'a> {
     }
 
     pub fn cargo_clippy_cmd(&self, run_compiler: Compiler) -> Command {
-        let initial_sysroot_bin = self.initial_rustc.parent().unwrap();
-        // Set PATH to include the sysroot bin dir so clippy can find cargo.
-        // FIXME: once rust-clippy#11944 lands on beta, set `CARGO` directly instead.
-        let path = t!(env::join_paths(
-            // The sysroot comes first in PATH to avoid using rustup's cargo.
-            std::iter::once(PathBuf::from(initial_sysroot_bin))
-                .chain(env::split_paths(&t!(env::var("PATH"))))
-        ));
-
         if run_compiler.stage == 0 {
             // `ensure(Clippy { stage: 0 })` *builds* clippy with stage0, it doesn't use the beta clippy.
             let cargo_clippy = self.build.config.download_clippy();
             let mut cmd = Command::new(cargo_clippy);
-            cmd.env("PATH", &path);
+            cmd.env("CARGO", &self.initial_cargo);
             return cmd;
         }
 
@@ -1227,7 +1218,7 @@ impl<'a> Builder<'a> {
 
         let mut cmd = Command::new(cargo_clippy);
         cmd.env(helpers::dylib_path_var(), env::join_paths(&dylib_path).unwrap());
-        cmd.env("PATH", path);
+        cmd.env("CARGO", &self.initial_cargo);
         cmd
     }
 
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 0f977640559..178df633cec 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -599,7 +599,6 @@ mod dist {
             pass: None,
             run: None,
             only_modified: false,
-            skip: vec![],
             extra_checks: None,
         };
 
@@ -664,7 +663,6 @@ mod dist {
             no_fail_fast: false,
             doc: true,
             no_doc: false,
-            skip: vec![],
             bless: false,
             force_rerun: false,
             compare_mode: None,
diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs
index 7262b785ee0..a66f743a1c5 100644
--- a/src/bootstrap/src/core/config/flags.rs
+++ b/src/bootstrap/src/core/config/flags.rs
@@ -339,9 +339,6 @@ pub enum Subcommand {
         #[arg(long)]
         /// run all tests regardless of failure
         no_fail_fast: bool,
-        #[arg(long, value_name = "SUBSTRING")]
-        /// skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times
-        skip: Vec<PathBuf>,
         #[arg(long, value_name = "ARGS", allow_hyphen_values(true))]
         /// extra arguments to be passed for the test tool being used
         /// (e.g. libtest, compiletest or rustdoc)
diff --git a/src/ci/scripts/upload-artifacts.sh b/src/ci/scripts/upload-artifacts.sh
index 9755edb6dce..c9c85ec20b4 100755
--- a/src/ci/scripts/upload-artifacts.sh
+++ b/src/ci/scripts/upload-artifacts.sh
@@ -45,3 +45,17 @@ deploy_url="s3://${DEPLOY_BUCKET}/${deploy_dir}/$(ciCommit)"
 
 retry aws s3 cp --storage-class INTELLIGENT_TIERING \
     --no-progress --recursive --acl public-read "${upload_dir}" "${deploy_url}"
+
+access_url="https://ci-artifacts.rust-lang.org/${deploy_dir}/$(ciCommit)"
+
+# Output URLs to the uploaded artifacts to GitHub summary (if it is available)
+# to make them easily accessible.
+if [ -n "${GITHUB_STEP_SUMMARY}" ]
+then
+  echo "# CI artifacts" >> "${GITHUB_STEP_SUMMARY}"
+
+  for filename in "${upload_dir}"/*.xz; do
+    filename=`basename "${filename}"`
+    echo "- [${filename}](${access_url}/${filename})" >> "${GITHUB_STEP_SUMMARY}"
+  done
+fi
diff --git a/src/doc/rustc/src/platform-support/netbsd.md b/src/doc/rustc/src/platform-support/netbsd.md
index 3891d6d3148..ef9337befa6 100644
--- a/src/doc/rustc/src/platform-support/netbsd.md
+++ b/src/doc/rustc/src/platform-support/netbsd.md
@@ -13,7 +13,7 @@ are currently defined running NetBSD:
 
 |          Target name           | NetBSD Platform |
 |--------------------------------|-----------------|
-| `amd64-unknown-netbsd`         | [amd64 / x86_64 systems](https://wiki.netbsd.org/ports/amd64/) |
+| `x86_64-unknown-netbsd`        | [amd64 / x86_64 systems](https://wiki.netbsd.org/ports/amd64/) |
 | `armv7-unknown-netbsd-eabihf`  | [32-bit ARMv7 systems with hard-float](https://wiki.netbsd.org/ports/evbarm/) |
 | `armv6-unknown-netbsd-eabihf`  | [32-bit ARMv6 systems with hard-float](https://wiki.netbsd.org/ports/evbarm/) |
 | `aarch64-unknown-netbsd`       | [64-bit ARM systems, little-endian](https://wiki.netbsd.org/ports/evbarm/) |
@@ -22,7 +22,7 @@ are currently defined running NetBSD:
 | `i686-unknown-netbsd`          | [32-bit i386 with SSE](https://wiki.netbsd.org/ports/i386/) |
 | `mipsel-unknown-netbsd`        | [32-bit mips, requires mips32 cpu support](https://wiki.netbsd.org/ports/evbmips/) |
 | `powerpc-unknown-netbsd`       | [Various 32-bit PowerPC systems, e.g. MacPPC](https://wiki.netbsd.org/ports/macppc/) |
-| `riscv64gc-unknown-netbsd`     | [64-bit RISC-V](https://wiki.netbsd.org/ports/riscv/)
+| `riscv64gc-unknown-netbsd`     | [64-bit RISC-V](https://wiki.netbsd.org/ports/riscv/) |
 | `sparc64-unknown-netbsd`       | [Sun UltraSPARC systems](https://wiki.netbsd.org/ports/sparc64/) |
 
 All use the "native" `stdc++` library which goes along with the natively
@@ -43,7 +43,7 @@ bug reporting system.
 
 ## Requirements
 
-The `amd64-unknown-netbsd` artifacts is being distributed by the
+The `x86_64-unknown-netbsd` artifacts is being distributed by the
 rust project.
 
 The other targets are built by the designated developers (see above),
@@ -95,7 +95,7 @@ capable systems we build and test `firefox` (amd64, i386, aarch64).
 
 ## Building Rust programs
 
-Rust ships pre-compiled artifacts for the `amd64-unknown-netbsd`
+Rust ships pre-compiled artifacts for the `x86_64-unknown-netbsd`
 target.
 
 For the other systems mentioned above, using the `pkgsrc` route is
diff --git a/src/doc/unstable-book/src/compiler-flags/external-clangrt.md b/src/doc/unstable-book/src/compiler-flags/external-clangrt.md
new file mode 100644
index 00000000000..76b78d733e5
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/external-clangrt.md
@@ -0,0 +1,6 @@
+# `external-clangrt`
+
+This option controls whether the compiler links in its own runtime library for
+[sanitizers](./sanitizer.md). Passing this flag makes the compiler *not* link
+its own library. For more information, see the section in the sanitizers doc on
+[working with other languages.](./sanitizer.md#working-with-other-languages)
diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md
index c8fd154a00e..72b44e002b4 100644
--- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md
+++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md
@@ -45,6 +45,9 @@ To enable a sanitizer compile with `-Zsanitizer=address`, `-Zsanitizer=cfi`,
 `-Zsanitizer=dataflow`,`-Zsanitizer=hwaddress`, `-Zsanitizer=leak`,
 `-Zsanitizer=memory`, `-Zsanitizer=memtag`, `-Zsanitizer=shadow-call-stack`, or
 `-Zsanitizer=thread`. You might also need the `--target` and `build-std` flags.
+If you're working with other languages that are also instrumented with sanitizers,
+you might need the `external-clangrt` flag. See the section on
+[working with other languages](#working-with-other-languages).
 
 Example:
 ```shell
@@ -853,6 +856,18 @@ functionality][build-std].
 
 [build-std]: ../../cargo/reference/unstable.html#build-std
 
+# Working with other languages
+
+Sanitizers rely on compiler runtime libraries to function properly. Rust links
+in its own compiler runtime which might conflict with runtimes required by
+languages such as C++. Since Rust's runtime doesn't always contain the symbols
+required by C++ instrumented code, you might need to skip linking it so another
+runtime can be linked instead.
+
+A separate unstable option `-Zexternal-clangrt` can be used to make rustc skip
+linking the compiler runtime for the sanitizer. This will require you to link
+in an external runtime, such as from clang instead.
+
 # Build scripts and procedural macros
 
 Use of sanitizers together with build scripts and procedural macros is
diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish
index 9fc95fd09ba..c95516494ae 100644
--- a/src/etc/completions/x.py.fish
+++ b/src/etc/completions/x.py.fish
@@ -261,7 +261,6 @@ complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-profile-generate -
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
 complete -c x.py -n "__fish_seen_subcommand_from doc" -s h -l help -d 'Print help (see more with \'--help\')'
-complete -c x.py -n "__fish_seen_subcommand_from test" -l skip -d 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
 complete -c x.py -n "__fish_seen_subcommand_from test" -l rustc-args -d 'extra options to pass the compiler when running tests' -r
 complete -c x.py -n "__fish_seen_subcommand_from test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell)' -r
@@ -274,6 +273,7 @@ complete -c x.py -n "__fish_seen_subcommand_from test" -l build -d 'build target
 complete -c x.py -n "__fish_seen_subcommand_from test" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from test" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from test" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from test" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from test" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from test" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from test" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1
index 6359b7ff086..8e505afaf75 100644
--- a/src/etc/completions/x.py.ps1
+++ b/src/etc/completions/x.py.ps1
@@ -333,7 +333,6 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             break
         }
         'x.py;test' {
-            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times')
             [CompletionResult]::new('--test-args', 'test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)')
             [CompletionResult]::new('--rustc-args', 'rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running tests')
             [CompletionResult]::new('--extra-checks', 'extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell)')
@@ -346,6 +345,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh
index e1436dcde67..742f61f1622 100644
--- a/src/etc/completions/x.py.sh
+++ b/src/etc/completions/x.py.sh
@@ -1625,16 +1625,12 @@ _x.py() {
             return 0
             ;;
         x.py__test)
-            opts="-v -i -j -h --no-fail-fast --skip --test-args --rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --no-fail-fast --test-args --rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
             fi
             case "${prev}" in
-                --skip)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
                 --test-args)
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
@@ -1683,6 +1679,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh
index ea7e4ba6758..eec610629a1 100644
--- a/src/etc/completions/x.py.zsh
+++ b/src/etc/completions/x.py.zsh
@@ -335,7 +335,6 @@ _arguments "${_arguments_options[@]}" \
 ;;
 (test)
 _arguments "${_arguments_options[@]}" \
-'*--skip=[skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times]:SUBSTRING:_files' \
 '*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS: ' \
 '*--rustc-args=[extra options to pass the compiler when running tests]:ARGS: ' \
 '--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell)]:EXTRA_CHECKS: ' \
@@ -348,6 +347,7 @@ _arguments "${_arguments_options[@]}" \
 '--host=[host targets to build]:HOST:( )' \
 '--target=[target targets to build]:TARGET:( )' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
+'*--skip=[build paths to skip]:PATH:_files' \
 '--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
 '--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject a59aba136aab5510c16b0750a36cbd9916f9179
+Subproject 0637083df5bbdcc951845f0d2eff6999cdb6d30
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 12b08005997..325c9bee057 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -149,7 +149,7 @@ fn check_rvalue<'tcx>(
                 Err((span, "unsizing casts are not allowed in const fn".into()))
             }
         },
-        Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => {
+        Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
             Err((span, "casting pointers to ints is unstable in const fn".into()))
         },
         Rvalue::Cast(CastKind::DynStar, _, _) => {
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index 6b8e1510a6b..fec39ec2b8e 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -18,8 +18,8 @@ use reuse_pool::ReusePool;
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub enum ProvenanceMode {
-    /// We support `expose_addr`/`with_exposed_provenance` via "wildcard" provenance.
-    /// However, we want on `with_exposed_provenance` to alert the user of the precision loss.
+    /// We support `expose_provenance`/`with_exposed_provenance` via "wildcard" provenance.
+    /// However, we warn on `with_exposed_provenance` to alert the user of the precision loss.
     Default,
     /// Like `Default`, but without the warning.
     Permissive,
diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs
index 9d268f09edb..a2fc4f0f761 100644
--- a/src/tools/miri/src/shims/intrinsics/simd.rs
+++ b/src/tools/miri/src/shims/intrinsics/simd.rs
@@ -514,7 +514,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     dest.transmute(this.machine.layouts.uint(dest.layout.size).unwrap(), this)?;
                 this.write_int(res, &dest)?;
             }
-            "cast" | "as" | "cast_ptr" | "expose_addr" | "with_exposed_provenance" => {
+            "cast" | "as" | "cast_ptr" | "expose_provenance" | "with_exposed_provenance" => {
                 let [op] = check_arg_count(args)?;
                 let (op, op_len) = this.operand_to_simd(op)?;
                 let (dest, dest_len) = this.mplace_to_simd(dest)?;
@@ -524,7 +524,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let unsafe_cast = intrinsic_name == "cast";
                 let safe_cast = intrinsic_name == "as";
                 let ptr_cast = intrinsic_name == "cast_ptr";
-                let expose_cast = intrinsic_name == "expose_addr";
+                let expose_cast = intrinsic_name == "expose_provenance";
                 let from_exposed_cast = intrinsic_name == "with_exposed_provenance";
 
                 for i in 0..dest_len {
@@ -557,7 +557,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                             this.ptr_to_ptr(&op, dest.layout)?,
                         // Ptr/Int casts
                         (ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast =>
-                            this.pointer_expose_address_cast(&op, dest.layout)?,
+                            this.pointer_expose_provenance_cast(&op, dest.layout)?,
                         (ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast =>
                             this.pointer_with_exposed_provenance_cast(&op, dest.layout)?,
                         // Error otherwise
diff --git a/src/tools/miri/tests/fail/provenance/ptr_invalid.rs b/src/tools/miri/tests/fail/provenance/ptr_invalid.rs
index 730859684a0..512473cd894 100644
--- a/src/tools/miri/tests/fail/provenance/ptr_invalid.rs
+++ b/src/tools/miri/tests/fail/provenance/ptr_invalid.rs
@@ -4,6 +4,6 @@
 fn main() {
     let x = 42;
     let xptr = &x as *const i32;
-    let xptr_invalid = std::ptr::without_provenance::<i32>(xptr.expose_addr());
+    let xptr_invalid = std::ptr::without_provenance::<i32>(xptr.expose_provenance());
     let _val = unsafe { *xptr_invalid }; //~ ERROR: is a dangling pointer
 }
diff --git a/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs b/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs
index aa05649d550..608ab718919 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs
@@ -6,7 +6,7 @@
 fn main() {
     let mut x = 0;
     let _fool = &mut x as *mut i32; // this would have fooled the old untagged pointer logic
-    let addr = (&x as *const i32).expose_addr();
+    let addr = (&x as *const i32).expose_provenance();
     let ptr = std::ptr::with_exposed_provenance_mut::<i32>(addr);
     unsafe { *ptr = 0 }; //~ ERROR: /write access using <wildcard> .* no exposed tags have suitable permission in the borrow stack/
 }
diff --git a/src/tools/miri/tests/pass/async-closure-captures.rs b/src/tools/miri/tests/pass/async-closure-captures.rs
new file mode 100644
index 00000000000..3e33de32efb
--- /dev/null
+++ b/src/tools/miri/tests/pass/async-closure-captures.rs
@@ -0,0 +1,91 @@
+// Same as rustc's `tests/ui/async-await/async-closures/captures.rs`, keep in sync
+
+#![feature(async_closure, noop_waker)]
+
+use std::future::Future;
+use std::pin::pin;
+use std::task::*;
+
+pub fn block_on<T>(fut: impl Future<Output = T>) -> T {
+    let mut fut = pin!(fut);
+    let ctx = &mut Context::from_waker(Waker::noop());
+
+    loop {
+        match fut.as_mut().poll(ctx) {
+            Poll::Pending => {}
+            Poll::Ready(t) => break t,
+        }
+    }
+}
+
+fn main() {
+    block_on(async_main());
+}
+
+async fn call<T>(f: &impl async Fn() -> T) -> T {
+    f().await
+}
+
+async fn call_once<T>(f: impl async FnOnce() -> T) -> T {
+    f().await
+}
+
+#[derive(Debug)]
+#[allow(unused)]
+struct Hello(i32);
+
+async fn async_main() {
+    // Capture something by-ref
+    {
+        let x = Hello(0);
+        let c = async || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+
+        let x = &Hello(1);
+        let c = async || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+    }
+
+    // Capture something and consume it (force to `AsyncFnOnce`)
+    {
+        let x = Hello(2);
+        let c = async || {
+            println!("{x:?}");
+            drop(x);
+        };
+        call_once(c).await;
+    }
+
+    // Capture something with `move`, don't consume it
+    {
+        let x = Hello(3);
+        let c = async move || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+
+        let x = &Hello(4);
+        let c = async move || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+    }
+
+    // Capture something with `move`, also consume it (so `AsyncFnOnce`)
+    {
+        let x = Hello(5);
+        let c = async move || {
+            println!("{x:?}");
+            drop(x);
+        };
+        call_once(c).await;
+    }
+}
diff --git a/src/tools/miri/tests/pass/async-closure-captures.stdout b/src/tools/miri/tests/pass/async-closure-captures.stdout
new file mode 100644
index 00000000000..a0db6d236fe
--- /dev/null
+++ b/src/tools/miri/tests/pass/async-closure-captures.stdout
@@ -0,0 +1,10 @@
+Hello(0)
+Hello(0)
+Hello(1)
+Hello(1)
+Hello(2)
+Hello(3)
+Hello(3)
+Hello(4)
+Hello(4)
+Hello(5)
diff --git a/src/tools/miri/tests/pass/portable-simd-ptrs.rs b/src/tools/miri/tests/pass/portable-simd-ptrs.rs
index 3b2d221bd8e..096ec78da1a 100644
--- a/src/tools/miri/tests/pass/portable-simd-ptrs.rs
+++ b/src/tools/miri/tests/pass/portable-simd-ptrs.rs
@@ -7,6 +7,6 @@ use std::simd::prelude::*;
 fn main() {
     // Pointer casts
     let _val: Simd<*const u8, 4> = Simd::<*const i32, 4>::splat(ptr::null()).cast();
-    let addrs = Simd::<*const i32, 4>::splat(ptr::null()).expose_addr();
+    let addrs = Simd::<*const i32, 4>::splat(ptr::null()).expose_provenance();
     let _ptrs = Simd::<*const i32, 4>::with_exposed_provenance(addrs);
 }
diff --git a/src/tools/miri/tests/pass/ptr_int_from_exposed.rs b/src/tools/miri/tests/pass/ptr_int_from_exposed.rs
index 8555de986f0..5690d7865bb 100644
--- a/src/tools/miri/tests/pass/ptr_int_from_exposed.rs
+++ b/src/tools/miri/tests/pass/ptr_int_from_exposed.rs
@@ -10,7 +10,7 @@ fn ptr_roundtrip_out_of_bounds() {
     let x: i32 = 3;
     let x_ptr = &x as *const i32;
 
-    let x_usize = x_ptr.wrapping_offset(128).expose_addr();
+    let x_usize = x_ptr.wrapping_offset(128).expose_provenance();
 
     let ptr = ptr::with_exposed_provenance::<i32>(x_usize).wrapping_offset(-128);
     assert_eq!(unsafe { *ptr }, 3);
@@ -24,8 +24,8 @@ fn ptr_roundtrip_confusion() {
     let x_ptr = &x as *const i32;
     let y_ptr = &y as *const i32;
 
-    let x_usize = x_ptr.expose_addr();
-    let y_usize = y_ptr.expose_addr();
+    let x_usize = x_ptr.expose_provenance();
+    let y_usize = y_ptr.expose_provenance();
 
     let ptr = ptr::with_exposed_provenance::<i32>(y_usize);
     let ptr = ptr.with_addr(x_usize);
@@ -37,7 +37,7 @@ fn ptr_roundtrip_imperfect() {
     let x: u8 = 3;
     let x_ptr = &x as *const u8;
 
-    let x_usize = x_ptr.expose_addr() + 128;
+    let x_usize = x_ptr.expose_provenance() + 128;
 
     let ptr = ptr::with_exposed_provenance::<u8>(x_usize).wrapping_offset(-128);
     assert_eq!(unsafe { *ptr }, 3);
@@ -48,7 +48,7 @@ fn ptr_roundtrip_null() {
     let x = &42;
     let x_ptr = x as *const i32;
     let x_null_ptr = x_ptr.with_addr(0); // addr 0, but still the provenance of x
-    let null = x_null_ptr.expose_addr();
+    let null = x_null_ptr.expose_provenance();
     assert_eq!(null, 0);
 
     let x_null_ptr_copy = ptr::with_exposed_provenance::<i32>(null); // just a roundtrip, so has provenance of x (angelically)
diff --git a/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs b/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs
index 5622bf18654..c89d79b42e3 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs
@@ -17,7 +17,7 @@ fn example(variant: bool) {
     unsafe {
         fn not_so_innocent(x: &mut u32) -> usize {
             let x_raw4 = x as *mut u32;
-            x_raw4.expose_addr()
+            x_raw4.expose_provenance()
         }
 
         let mut c = 42u32;
@@ -26,7 +26,7 @@ fn example(variant: bool) {
         // stack: [..., Unique(1)]
 
         let x_raw2 = x_unique1 as *mut u32;
-        let x_raw2_addr = x_raw2.expose_addr();
+        let x_raw2_addr = x_raw2.expose_provenance();
         // stack: [..., Unique(1), SharedRW(2)]
 
         let x_unique3 = &mut *x_raw2;
diff --git a/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs b/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs
index 6e177a6e4ab..55356814a1a 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs
@@ -9,7 +9,7 @@ fn main() {
 
     // Expose the allocation and use the exposed pointer, creating an unknown bottom
     unsafe {
-        let p: *mut u8 = ptr::with_exposed_provenance::<u8>(ptr.expose_addr()) as *mut u8;
+        let p: *mut u8 = ptr::with_exposed_provenance::<u8>(ptr.expose_provenance()) as *mut u8;
         *p = 1;
     }
 
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index f6b1d45ee94..6e845249342 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -434,6 +434,7 @@
 "ui/closures/issue-111932.rs",
 "ui/closures/issue-113087.rs",
 "ui/closures/issue-11873.rs",
+"ui/closures/issue-1460.rs",
 "ui/closures/issue-23012-supertrait-signature-inference.rs",
 "ui/closures/issue-25439.rs",
 "ui/closures/issue-41366.rs",
@@ -1007,6 +1008,8 @@
 "ui/fmt/issue-86085.rs",
 "ui/fmt/issue-89173.rs",
 "ui/fmt/issue-91556.rs",
+"ui/fn/issue-1451.rs",
+"ui/fn/issue-1900.rs",
 "ui/fn/issue-3044.rs",
 "ui/fn/issue-3099.rs",
 "ui/fn/issue-3904.rs",
@@ -1550,7 +1553,6 @@
 "ui/issues/issue-13497-2.rs",
 "ui/issues/issue-13497.rs",
 "ui/issues/issue-13507-2.rs",
-"ui/issues/issue-1362.rs",
 "ui/issues/issue-13620.rs",
 "ui/issues/issue-13665.rs",
 "ui/issues/issue-13703.rs",
@@ -1576,12 +1578,8 @@
 "ui/issues/issue-14399.rs",
 "ui/issues/issue-14421.rs",
 "ui/issues/issue-14422.rs",
-"ui/issues/issue-1448-2.rs",
-"ui/issues/issue-1451.rs",
 "ui/issues/issue-14541.rs",
-"ui/issues/issue-1460.rs",
 "ui/issues/issue-14721.rs",
-"ui/issues/issue-1476.rs",
 "ui/issues/issue-14821.rs",
 "ui/issues/issue-14845.rs",
 "ui/issues/issue-14853.rs",
@@ -1631,7 +1629,6 @@
 "ui/issues/issue-16560.rs",
 "ui/issues/issue-16562.rs",
 "ui/issues/issue-16596.rs",
-"ui/issues/issue-1660.rs",
 "ui/issues/issue-16643.rs",
 "ui/issues/issue-16648.rs",
 "ui/issues/issue-16668.rs",
@@ -1645,7 +1642,6 @@
 "ui/issues/issue-16819.rs",
 "ui/issues/issue-16922-rpass.rs",
 "ui/issues/issue-16939.rs",
-"ui/issues/issue-1696.rs",
 "ui/issues/issue-16966.rs",
 "ui/issues/issue-16994.rs",
 "ui/issues/issue-17001.rs",
@@ -1725,7 +1721,6 @@
 "ui/issues/issue-18952.rs",
 "ui/issues/issue-18959.rs",
 "ui/issues/issue-18988.rs",
-"ui/issues/issue-1900.rs",
 "ui/issues/issue-19001.rs",
 "ui/issues/issue-19037.rs",
 "ui/issues/issue-19086.rs",
@@ -1753,12 +1748,10 @@
 "ui/issues/issue-19482.rs",
 "ui/issues/issue-19499.rs",
 "ui/issues/issue-19601.rs",
-"ui/issues/issue-1962.rs",
 "ui/issues/issue-19631.rs",
 "ui/issues/issue-19632.rs",
 "ui/issues/issue-19692.rs",
 "ui/issues/issue-19734.rs",
-"ui/issues/issue-1974.rs",
 "ui/issues/issue-19811-escape-unicode.rs",
 "ui/issues/issue-19850.rs",
 "ui/issues/issue-19922.rs",
@@ -2856,6 +2849,8 @@
 "ui/lint/unused/issue-92751.rs",
 "ui/lint/unused/issue-96606.rs",
 "ui/lint/use-redundant/issue-92904.rs",
+"ui/loops/issue-1962.rs",
+"ui/loops/issue-1974.rs",
 "ui/loops/issue-43162.rs",
 "ui/loops/issue-50576.rs",
 "ui/loops/issue-69225-SCEVAddExpr-wrap-flag.rs",
@@ -3045,6 +3040,8 @@
 "ui/mismatched_types/issue-118145-unwrap-for-shorthand.rs",
 "ui/mismatched_types/issue-118510.rs",
 "ui/mismatched_types/issue-13033.rs",
+"ui/mismatched_types/issue-1362.rs",
+"ui/mismatched_types/issue-1448-2.rs",
 "ui/mismatched_types/issue-19109.rs",
 "ui/mismatched_types/issue-26480.rs",
 "ui/mismatched_types/issue-35030.rs",
@@ -3860,6 +3857,7 @@
 "ui/stability-attribute/issue-28388-3.rs",
 "ui/stability-attribute/issue-99286-stable-intrinsics.rs",
 "ui/static/auxiliary/issue_24843.rs",
+"ui/static/issue-1660.rs",
 "ui/static/issue-18118-2.rs",
 "ui/static/issue-18118.rs",
 "ui/static/issue-24446.rs",
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index fe27964981e..454811c5fbb 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -17,7 +17,7 @@ use std::path::{Path, PathBuf};
 const ENTRY_LIMIT: usize = 900;
 // FIXME: The following limits should be reduced eventually.
 
-const ISSUES_ENTRY_LIMIT: usize = 1750;
+const ISSUES_ENTRY_LIMIT: usize = 1733;
 const ROOT_ENTRY_LIMIT: usize = 860;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
diff --git a/tests/auxiliary/rust_test_helpers.c b/tests/auxiliary/rust_test_helpers.c
index 977ea487a98..965df44c676 100644
--- a/tests/auxiliary/rust_test_helpers.c
+++ b/tests/auxiliary/rust_test_helpers.c
@@ -118,6 +118,30 @@ rust_dbg_extern_identity_TwoDoubles(struct TwoDoubles u) {
     return u;
 }
 
+struct FiveU16s {
+    uint16_t one;
+    uint16_t two;
+    uint16_t three;
+    uint16_t four;
+    uint16_t five;
+};
+
+struct FiveU16s
+rust_dbg_extern_return_FiveU16s() {
+    struct FiveU16s s;
+    s.one = 10;
+    s.two = 20;
+    s.three = 30;
+    s.four = 40;
+    s.five = 50;
+    return s;
+}
+
+struct FiveU16s
+rust_dbg_extern_identity_FiveU16s(struct FiveU16s u) {
+    return u;
+}
+
 struct ManyInts {
     int8_t arg1;
     int16_t arg2;
diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs
new file mode 100644
index 00000000000..e6024f03425
--- /dev/null
+++ b/tests/codegen/cast-target-abi.rs
@@ -0,0 +1,280 @@
+// ignore-tidy-linelength
+//@ revisions:aarch64 loongarch64 powerpc64 sparc64
+//@ compile-flags: -O -C no-prepopulate-passes
+
+//@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
+//@[aarch64] needs-llvm-components: arm
+//@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
+//@[loongarch64] needs-llvm-components: loongarch
+//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
+//@[powerpc64] needs-llvm-components: powerpc
+//@[sparc64] compile-flags: --target sparc64-unknown-linux-gnu
+//@[sparc64] needs-llvm-components: sparc
+
+// Tests that arguments with `PassMode::Cast` are handled correctly.
+
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+#[lang="sized"] trait Sized { }
+#[lang="freeze"] trait Freeze { }
+#[lang="copy"] trait Copy { }
+
+// This struct will be passed as a single `i64` or `i32`.
+// This may be (if `i64)) larger than the Rust layout, which is just `{ i16, i16 }`.
+#[repr(C)]
+pub struct TwoU16s {
+    a: u16,
+    b: u16,
+}
+
+// This struct will be passed as `[2 x i64]`.
+// This is larger than the Rust layout.
+#[repr(C)]
+pub struct FiveU16s {
+    a: u16,
+    b: u16,
+    c: u16,
+    d: u16,
+    e: u16,
+}
+
+// This struct will be passed as `[2 x double]`.
+// This is the same as the Rust layout.
+#[repr(C)]
+pub struct DoubleDouble {
+    f: f64,
+    g: f64,
+}
+
+// On loongarch, this struct will be passed as `{ double, float }`.
+// This is smaller than the Rust layout, which has trailing padding (`{ f64, f32, <f32 padding> }`)
+#[repr(C)]
+pub struct DoubleFloat {
+    f: f64,
+    g: f32,
+}
+
+extern "C" {
+    fn receives_twou16s(x: TwoU16s);
+    fn returns_twou16s() -> TwoU16s;
+
+    fn receives_fiveu16s(x: FiveU16s);
+    fn returns_fiveu16s() -> FiveU16s;
+
+    fn receives_doubledouble(x: DoubleDouble);
+    fn returns_doubledouble() -> DoubleDouble;
+
+    // These functions cause an ICE in sparc64 ABI code (https://github.com/rust-lang/rust/issues/122620)
+    #[cfg(not(target_arch = "sparc64"))]
+    fn receives_doublefloat(x: DoubleFloat);
+    #[cfg(not(target_arch = "sparc64"))]
+    fn returns_doublefloat() -> DoubleFloat;
+}
+
+// CHECK-LABEL: @call_twou16s
+#[no_mangle]
+pub unsafe fn call_twou16s() {
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]]
+    // powerpc64:   [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i32]], align [[ABI_ALIGN:4]]
+    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]]
+
+    // CHECK: [[RUST_ALLOCA:%.+]] = alloca %TwoU16s, align [[RUST_ALIGN:2]]
+
+    // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 4, i1 false)
+    // CHECK: [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // CHECK: call void @receives_twou16s([[ABI_TYPE]] [[ABI_VALUE]])
+    let x = TwoU16s { a: 1, b: 2 };
+    receives_twou16s(x);
+}
+
+// CHECK-LABEL: @return_twou16s
+#[no_mangle]
+pub unsafe fn return_twou16s() -> TwoU16s {
+    // powerpc returns this struct via sret pointer, it doesn't use the cast ABI.
+
+    // powerpc64: [[RETVAL:%.+]] = alloca %TwoU16s, align 2
+    // powerpc64: call void @returns_twou16s(ptr {{.+}} [[RETVAL]])
+
+
+    // The other targets copy the cast ABI type to an alloca.
+
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]]
+    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]]
+
+    // aarch64:     [[RUST_ALLOCA:%.+]] = alloca %TwoU16s, align [[RUST_ALIGN:2]]
+    // loongarch64: [[RUST_ALLOCA:%.+]] = alloca %TwoU16s, align [[RUST_ALIGN:2]]
+    // sparc64:     [[RUST_ALLOCA:%.+]] = alloca %TwoU16s, align [[RUST_ALIGN:2]]
+
+    // aarch64:     [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_twou16s()
+    // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_twou16s()
+    // sparc64:     [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_twou16s()
+
+    // aarch64:     store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // sparc64:     store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+
+    // aarch64:     call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 4, i1 false)
+    // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 4, i1 false)
+    // sparc64:     call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 4, i1 false)
+    returns_twou16s()
+}
+
+// CHECK-LABEL: @call_fiveu16s
+#[no_mangle]
+pub unsafe fn call_fiveu16s() {
+    // CHECK: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+
+    // CHECK: [[RUST_ALLOCA:%.+]] = alloca %FiveU16s, align 2
+
+    // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 10, i1 false)
+    // CHECK: [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // CHECK: call void @receives_fiveu16s([[ABI_TYPE]] [[ABI_VALUE]])
+    let x = FiveU16s { a: 1, b: 2, c: 3, d: 4, e: 5 };
+    receives_fiveu16s(x);
+}
+
+// CHECK-LABEL: @return_fiveu16s
+// CHECK-SAME: (ptr {{.+}} sret([10 x i8]) align [[RUST_ALIGN:2]] dereferenceable(10) [[RET_PTR:%.+]])
+#[no_mangle]
+pub unsafe fn return_fiveu16s() -> FiveU16s {
+    // powerpc returns this struct via sret pointer, it doesn't use the cast ABI.
+
+    // powerpc64: call void @returns_fiveu16s(ptr {{.+}} [[RET_PTR]])
+
+
+    // The other targets copy the cast ABI type to the sret pointer.
+
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+
+    // aarch64:     [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_fiveu16s()
+    // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_fiveu16s()
+    // sparc64:     [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_fiveu16s()
+
+    // aarch64:     store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // sparc64:     store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+
+    // aarch64:     call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RET_PTR]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 10, i1 false)
+    // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RET_PTR]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 10, i1 false)
+    // sparc64:     call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RET_PTR]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 10, i1 false)
+    returns_fiveu16s()
+}
+
+// CHECK-LABEL: @call_doubledouble
+#[no_mangle]
+pub unsafe fn call_doubledouble() {
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x double\]]], align [[ABI_ALIGN:8]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, double }]], align [[ABI_ALIGN:8]]
+    // powerpc64:   [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, double }]], align [[ABI_ALIGN:8]]
+
+    // CHECK: [[RUST_ALLOCA:%.+]] = alloca %DoubleDouble, align [[RUST_ALIGN:8]]
+
+    // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 16, i1 false)
+    // CHECK: [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // CHECK: call void @receives_doubledouble([[ABI_TYPE]] [[ABI_VALUE]])
+    let x = DoubleDouble { f: 1., g: 2. };
+    receives_doubledouble(x);
+}
+
+// CHECK-LABEL: @return_doubledouble
+#[no_mangle]
+pub unsafe fn return_doubledouble() -> DoubleDouble {
+    // powerpc returns this struct via sret pointer, it doesn't use the cast ABI.
+
+    // powerpc64: [[RETVAL:%.+]] = alloca %DoubleDouble, align 8
+    // powerpc64: call void @returns_doubledouble(ptr {{.+}} [[RETVAL]])
+
+
+    // The other targets copy the cast ABI type to an alloca.
+
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x double\]]], align [[ABI_ALIGN:8]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, double }]], align [[ABI_ALIGN:8]]
+    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, double }]], align [[ABI_ALIGN:8]]
+
+    // aarch64:     [[RUST_ALLOCA:%.+]] = alloca %DoubleDouble, align [[RUST_ALIGN:8]]
+    // loongarch64: [[RUST_ALLOCA:%.+]] = alloca %DoubleDouble, align [[RUST_ALIGN:8]]
+    // sparc64:     [[RUST_ALLOCA:%.+]] = alloca %DoubleDouble, align [[RUST_ALIGN:8]]
+
+    // aarch64:     [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doubledouble()
+    // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doubledouble()
+    // sparc64:     [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doubledouble()
+
+    // aarch64:     store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // sparc64:     store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+
+    // aarch64:     call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false)
+    // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false)
+    // sparc64:     call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false)
+    returns_doubledouble()
+}
+
+// This test causes an ICE in sparc64 ABI code (https://github.com/rust-lang/rust/issues/122620)
+#[cfg(not(target_arch = "sparc64"))]
+// aarch64-LABEL:     @call_doublefloat
+// loongarch64-LABEL: @call_doublefloat
+// powerpc64-LABEL:   @call_doublefloat
+#[no_mangle]
+pub unsafe fn call_doublefloat() {
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, float }]], align [[ABI_ALIGN:8]]
+    // powerpc64:   [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+
+    // aarch64:     [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]]
+    // loongarch64: [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]]
+    // powerpc64:   [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]]
+
+    // aarch64:     call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 16, i1 false)
+    // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 12, i1 false)
+    // powerpc64:   call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 16, i1 false)
+
+    // aarch64:     [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // powerpc64:   [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+
+    // aarch64:     call void @receives_doublefloat([[ABI_TYPE]] {{(inreg )?}}[[ABI_VALUE]])
+    // loongarch64: call void @receives_doublefloat([[ABI_TYPE]] {{(inreg )?}}[[ABI_VALUE]])
+    // powerpc64:   call void @receives_doublefloat([[ABI_TYPE]] {{(inreg )?}}[[ABI_VALUE]])
+    let x = DoubleFloat { f: 1., g: 2. };
+    receives_doublefloat(x);
+}
+
+// This test causes an ICE in sparc64 ABI code (https://github.com/rust-lang/rust/issues/122620)
+#[cfg(not(target_arch = "sparc64"))]
+// aarch64-LABEL:     @return_doublefloat
+// loongarch64-LABEL: @return_doublefloat
+// powerpc64-LABEL:   @return_doublefloat
+#[no_mangle]
+pub unsafe fn return_doublefloat() -> DoubleFloat {
+    // powerpc returns this struct via sret pointer, it doesn't use the cast ABI.
+
+    // powerpc64: [[RETVAL:%.+]] = alloca %DoubleFloat, align 8
+    // powerpc64: call void @returns_doublefloat(ptr {{.+}} [[RETVAL]])
+
+
+    // The other targets copy the cast ABI type to an alloca.
+
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, float }]], align [[ABI_ALIGN:8]]
+
+    // aarch64:     [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]]
+    // loongarch64: [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]]
+
+    // aarch64:     [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doublefloat()
+    // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doublefloat()
+
+    // aarch64:     store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+
+    // aarch64:     call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false)
+    // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 12, i1 false)
+    returns_doublefloat()
+}
diff --git a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
index 7eda6cf4d57..8b32e902b3f 100644
--- a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
+++ b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
@@ -1,8 +1,21 @@
+//@ revisions: linux apple
+//@ compile-flags: -C opt-level=0 -C no-prepopulate-passes
+
+//@[linux] compile-flags: --target x86_64-unknown-linux-gnu
+//@[linux] needs-llvm-components: x86
+//@[apple] compile-flags: --target x86_64-apple-darwin
+//@[apple] needs-llvm-components: x86
+
 // Regression test for #29988
 
-//@ compile-flags: -C no-prepopulate-passes
-//@ only-x86_64
-//@ ignore-windows
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+#[lang="sized"] trait Sized { }
+#[lang="freeze"] trait Freeze { }
+#[lang="copy"] trait Copy { }
 
 #[repr(C)]
 struct S {
@@ -15,11 +28,14 @@ extern "C" {
     fn foo(s: S);
 }
 
-fn main() {
+// CHECK-LABEL: @test
+#[no_mangle]
+pub fn test() {
     let s = S { f1: 1, f2: 2, f3: 3 };
     unsafe {
-        // CHECK: load { i64, i32 }, {{.*}}, align 4
-        // CHECK: call void @foo({ i64, i32 } {{.*}})
+        // CHECK: [[ALLOCA:%.+]] = alloca { i64, i32 }, align 8
+        // CHECK: [[LOAD:%.+]] = load { i64, i32 }, ptr [[ALLOCA]], align 8
+        // CHECK: call void @foo({ i64, i32 } [[LOAD]])
         foo(s);
     }
 }
diff --git a/tests/codegen/enum/uninhabited_enum_default_branch.rs b/tests/codegen/enum/uninhabited_enum_default_branch.rs
deleted file mode 100644
index 5f318f18dec..00000000000
--- a/tests/codegen/enum/uninhabited_enum_default_branch.rs
+++ /dev/null
@@ -1,24 +0,0 @@
-//@ compile-flags: -O
-
-#![crate_type = "lib"]
-
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
-pub struct Int(u32);
-
-const A: Int = Int(201);
-const B: Int = Int(270);
-const C: Int = Int(153);
-
-// CHECK-LABEL: @foo(
-// CHECK-SAME: [[TMP0:%.*]])
-// CHECK-NEXT:  start:
-// CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[TMP0]], -201
-// CHECK-NEXT:    icmp ult i32 [[TMP1]], 70
-// CHECK-NEXT:    icmp eq i32 [[TMP0]], 153
-// CHECK-NEXT:    [[SPEC_SELECT:%.*]] = or i1
-// CHECK-NEXT:    ret i1 [[SPEC_SELECT]]
-#[no_mangle]
-pub fn foo(x: Int) -> bool {
-    (x >= A && x <= B)
-        || x == C
-}
diff --git a/tests/codegen/enum/unreachable_enum_default_branch.rs b/tests/codegen/enum/unreachable_enum_default_branch.rs
new file mode 100644
index 00000000000..dae01cfb055
--- /dev/null
+++ b/tests/codegen/enum/unreachable_enum_default_branch.rs
@@ -0,0 +1,43 @@
+//@ compile-flags: -O
+
+#![crate_type = "lib"]
+
+#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+pub struct Int(u32);
+
+const A: Int = Int(201);
+const B: Int = Int(270);
+const C: Int = Int(153);
+
+// The code is from https://github.com/rust-lang/rust/issues/119520.
+// This code will basically turn into `matches!(x.partial_cmp(&A), Some(Greater | Equal))`.
+// The otherwise branch must be `Less`.
+// CHECK-LABEL: @implicit_match(
+// CHECK-SAME: [[TMP0:%.*]])
+// CHECK-NEXT:  start:
+// CHECK-NEXT:    [[TMP1:%.*]] = add i32 [[TMP0]], -201
+// CHECK-NEXT:    icmp ult i32 [[TMP1]], 70
+// CHECK-NEXT:    icmp eq i32 [[TMP0]], 153
+// CHECK-NEXT:    [[SPEC_SELECT:%.*]] = or i1
+// CHECK-NEXT:    ret i1 [[SPEC_SELECT]]
+#[no_mangle]
+pub fn implicit_match(x: Int) -> bool {
+    (x >= A && x <= B)
+        || x == C
+}
+
+// The code is from https://github.com/rust-lang/rust/issues/110097.
+// We expect it to generate the same optimized code as a full match.
+// CHECK-LABEL: @if_let(
+// CHECK-NEXT:  start:
+// CHECK-NEXT: insertvalue
+// CHECK-NEXT: insertvalue
+// CHECK-NEXT: ret
+#[no_mangle]
+pub fn if_let(val: Result<i32, ()>) -> Result<i32, ()> {
+    if let Ok(x) = val {
+        Ok(x)
+    } else {
+        Err(())
+    }
+}
diff --git a/tests/incremental/hashes/function_interfaces.rs b/tests/incremental/hashes/function_interfaces.rs
index 4fa2762099c..ab4d578458d 100644
--- a/tests/incremental/hashes/function_interfaces.rs
+++ b/tests/incremental/hashes/function_interfaces.rs
@@ -104,17 +104,17 @@ pub fn order_of_parameters(p2: i64, p1: i32) {}
 // Unsafe ----------------------------------------------------------------------
 
 #[cfg(any(cfail1,cfail4))]
-pub fn make_unsafe() {}
+pub        fn make_unsafe() {}
 
 #[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(
     cfg = "cfail2",
-    except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig"
+    except = "opt_hir_owner_nodes, typeck, fn_sig"
 )]
 #[rustc_clean(cfg = "cfail3")]
 #[rustc_clean(
     cfg = "cfail5",
-    except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig"
+    except = "opt_hir_owner_nodes, typeck, fn_sig"
 )]
 #[rustc_clean(cfg = "cfail6")]
 pub unsafe fn make_unsafe() {}
diff --git a/tests/incremental/hashes/inherent_impls.rs b/tests/incremental/hashes/inherent_impls.rs
index 2b0de1edc0c..caea394977a 100644
--- a/tests/incremental/hashes/inherent_impls.rs
+++ b/tests/incremental/hashes/inherent_impls.rs
@@ -348,9 +348,9 @@ impl Foo {
 // Make method unsafe ----------------------------------------------------------
 #[cfg(any(cfail1,cfail4))]
 impl Foo {
-    //------------------------------------------------------------------------------------
+    //----------------------------------------------------------------------
     //--------------------------
-    //------------------------------------------------------------------------------------
+    //----------------------------------------------------------------------
     //--------------------------
     pub        fn make_method_unsafe(&self) { }
 }
@@ -361,9 +361,9 @@ impl Foo {
 #[rustc_clean(cfg="cfail5")]
 #[rustc_clean(cfg="cfail6")]
 impl Foo {
-    #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,typeck,optimized_mir")]
+    #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,typeck")]
     #[rustc_clean(cfg="cfail3")]
-    #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,typeck,optimized_mir")]
+    #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,typeck")]
     #[rustc_clean(cfg="cfail6")]
     pub unsafe fn make_method_unsafe(&self) { }
 }
diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
index 3b7c4b8796e..ef51b07827f 100644
--- a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
+++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
@@ -17,8 +17,6 @@ fn main() -> () {
             let _3: *mut usize;
             scope 3 {
                 debug z => _3;
-                scope 4 {
-                }
             }
         }
     }
diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
index 3dcddea0353..d1aa9382a2c 100644
--- a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
+++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
@@ -17,8 +17,6 @@ fn main() -> () {
             let _3: *mut usize;
             scope 3 {
                 debug z => _3;
-                scope 4 {
-                }
             }
         }
     }
diff --git a/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir b/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
index 6c3128f8c36..005b3ee3b24 100644
--- a/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
+++ b/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
@@ -3,8 +3,6 @@
 fn main() -> () {
     let mut _0: ();
     let _1: ();
-    scope 1 {
-    }
 
     bb0: {
         StorageLive(_1);
diff --git a/tests/mir-opt/box_expr.main.ElaborateDrops.diff b/tests/mir-opt/box_expr.main.ElaborateDrops.diff
index 88b12f19e64..ec40fac2894 100644
--- a/tests/mir-opt/box_expr.main.ElaborateDrops.diff
+++ b/tests/mir-opt/box_expr.main.ElaborateDrops.diff
@@ -15,8 +15,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
index d697ea49231..d2a0fb0cb3c 100644
--- a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
+++ b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
@@ -93,17 +93,13 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
         debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()});
         let _17: ();
         scope 2 {
-        }
-        scope 3 {
             debug result => _17;
         }
     }
-    scope 4 {
+    scope 3 {
         debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()});
         let _33: ();
-        scope 5 {
-        }
-        scope 6 {
+        scope 4 {
             debug result => _33;
         }
     }
diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
index 128af9c5602..db758368a13 100644
--- a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
+++ b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
@@ -16,14 +16,10 @@ fn move_out_by_subslice() -> () {
     scope 1 {
         debug a => _1;
         let _12: [std::boxed::Box<i32>; 2];
-        scope 4 {
+        scope 2 {
             debug _y => _12;
         }
     }
-    scope 2 {
-    }
-    scope 3 {
-    }
 
     bb0: {
         StorageLive(_1);
diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
index d50a6872a41..84cd557715c 100644
--- a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
+++ b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
@@ -16,14 +16,10 @@ fn move_out_from_end() -> () {
     scope 1 {
         debug a => _1;
         let _12: std::boxed::Box<i32>;
-        scope 4 {
+        scope 2 {
             debug _y => _12;
         }
     }
-    scope 2 {
-    }
-    scope 3 {
-    }
 
     bb0: {
         StorageLive(_1);
diff --git a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
index 3596671f614..bfefd2b8c95 100644
--- a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
+++ b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
@@ -9,8 +9,6 @@
       let mut _4: &i32;
       let _5: *const i32;
 +     let mut _6: &[&i32; 1];
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/address_of_pair.fn0.GVN.diff b/tests/mir-opt/const_prop/address_of_pair.fn0.GVN.diff
index a044cfc62e2..3f4958f60e8 100644
--- a/tests/mir-opt/const_prop/address_of_pair.fn0.GVN.diff
+++ b/tests/mir-opt/const_prop/address_of_pair.fn0.GVN.diff
@@ -14,8 +14,6 @@
               debug ptr => _3;
               let _5: bool;
               scope 3 {
-              }
-              scope 4 {
                   debug ret => _5;
               }
           }
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
index 20fda589c39..826f4c34277 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
@@ -13,11 +13,9 @@
       let mut _9: &[i32; 3];
       scope 1 {
           debug a => _1;
+          let _5: i32;
           scope 2 {
-              let _5: i32;
-              scope 3 {
-                  debug _b => _5;
-              }
+              debug _b => _5;
           }
       }
   
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
index f1b90c28e72..0e2ec65652f 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
@@ -13,11 +13,9 @@
       let mut _9: &[i32; 3];
       scope 1 {
           debug a => _1;
+          let _5: i32;
           scope 2 {
-              let _5: i32;
-              scope 3 {
-                  debug _b => _5;
-              }
+              debug _b => _5;
           }
       }
   
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
index 20fda589c39..826f4c34277 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
@@ -13,11 +13,9 @@
       let mut _9: &[i32; 3];
       scope 1 {
           debug a => _1;
+          let _5: i32;
           scope 2 {
-              let _5: i32;
-              scope 3 {
-                  debug _b => _5;
-              }
+              debug _b => _5;
           }
       }
   
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
index f1b90c28e72..0e2ec65652f 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
@@ -13,11 +13,9 @@
       let mut _9: &[i32; 3];
       scope 1 {
           debug a => _1;
+          let _5: i32;
           scope 2 {
-              let _5: i32;
-              scope 3 {
-                  debug _b => _5;
-              }
+              debug _b => _5;
           }
       }
   
diff --git a/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff b/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff
index 59ee38f5a2b..a408c197fd1 100644
--- a/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff
+++ b/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff
@@ -15,8 +15,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff
index 9d87bd809d1..5706a739602 100644
--- a/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff
@@ -15,8 +15,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/indirect_mutation.bar.GVN.diff b/tests/mir-opt/const_prop/indirect_mutation.bar.GVN.diff
index b389080c497..99a6ba7d08a 100644
--- a/tests/mir-opt/const_prop/indirect_mutation.bar.GVN.diff
+++ b/tests/mir-opt/const_prop/indirect_mutation.bar.GVN.diff
@@ -11,8 +11,6 @@
           debug v => _1;
           let _4: bool;
           scope 2 {
-          }
-          scope 3 {
               debug y => _4;
           }
       }
diff --git a/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff b/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff
index da5bf1cf42c..f5041365604 100644
--- a/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff
+++ b/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff
@@ -12,24 +12,18 @@
       scope 1 {
           debug _invalid_char => _1;
           let _3: [E; 1];
-          scope 3 {
+          scope 2 {
               debug _invalid_tag => _3;
               let _6: [Empty; 1];
-              scope 5 {
+              scope 3 {
                   debug _enum_without_variants => const [ZeroSized: Empty];
                   let _9: main::Str<"���">;
-                  scope 7 {
+                  scope 4 {
                       debug _non_utf8_str => const Str::<"���">;
                   }
               }
-              scope 6 {
-              }
-          }
-          scope 4 {
           }
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff b/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff
index 455c2375eff..6e5ad8d6b81 100644
--- a/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff
+++ b/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff
@@ -12,26 +12,20 @@
       scope 1 {
           debug _invalid_char => _1;
           let _3: [E; 1];
-          scope 3 {
+          scope 2 {
               debug _invalid_tag => _3;
               let _6: [Empty; 1];
-              scope 5 {
+              scope 3 {
 -                 debug _enum_without_variants => _6;
 +                 debug _enum_without_variants => const [ZeroSized: Empty];
                   let _9: main::Str<"���">;
-                  scope 7 {
+                  scope 4 {
 -                     debug _non_utf8_str => _9;
 +                     debug _non_utf8_str => const Str::<"���">;
                   }
               }
-              scope 6 {
-              }
-          }
-          scope 4 {
           }
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/mutable_variable_no_prop.main.GVN.diff b/tests/mir-opt/const_prop/mutable_variable_no_prop.main.GVN.diff
index e113f43a56e..31c839f6749 100644
--- a/tests/mir-opt/const_prop/mutable_variable_no_prop.main.GVN.diff
+++ b/tests/mir-opt/const_prop/mutable_variable_no_prop.main.GVN.diff
@@ -11,8 +11,6 @@
           debug x => _1;
           let _5: u32;
           scope 2 {
-          }
-          scope 3 {
               debug y => _5;
           }
       }
diff --git a/tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-abort.diff b/tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-abort.diff
index 596eb1a9966..79a95b618d1 100644
--- a/tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-abort.diff
+++ b/tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-abort.diff
@@ -19,7 +19,7 @@
           StorageLive(_3);
           _3 = const main::FOO;
           _2 = &raw const (*_3);
-          _1 = move _2 as usize (PointerExposeAddress);
+          _1 = move _2 as usize (PointerExposeProvenance);
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_4);
diff --git a/tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-unwind.diff
index 995f281ecf5..9d1bcd92fef 100644
--- a/tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-unwind.diff
@@ -19,7 +19,7 @@
           StorageLive(_3);
           _3 = const main::FOO;
           _2 = &raw const (*_3);
-          _1 = move _2 as usize (PointerExposeAddress);
+          _1 = move _2 as usize (PointerExposeProvenance);
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_4);
diff --git a/tests/mir-opt/const_prop/pointer_expose_address.rs b/tests/mir-opt/const_prop/pointer_expose_provenance.rs
index a6b4f8857c3..840a4d65f3d 100644
--- a/tests/mir-opt/const_prop/pointer_expose_address.rs
+++ b/tests/mir-opt/const_prop/pointer_expose_provenance.rs
@@ -4,12 +4,12 @@
 #[inline(never)]
 fn read(_: usize) { }
 
-// EMIT_MIR pointer_expose_address.main.GVN.diff
+// EMIT_MIR pointer_expose_provenance.main.GVN.diff
 fn main() {
     // CHECK-LABEL: fn main(
     // CHECK: [[ptr:_.*]] = const main::FOO;
     // CHECK: [[ref:_.*]] = &raw const (*[[ptr]]);
-    // CHECK: [[x:_.*]] = move [[ref]] as usize (PointerExposeAddress);
+    // CHECK: [[x:_.*]] = move [[ref]] as usize (PointerExposeProvenance);
     // CHECK: = read([[x]])
     const FOO: &i32 = &1;
     let x = FOO as *const i32 as usize;
diff --git a/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff b/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff
index 2f76e74a3f8..e5786bcf701 100644
--- a/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff
+++ b/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff
@@ -14,7 +14,7 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = main as fn() (PointerCoercion(ReifyFnPointer));
-          _2 = move _3 as usize (PointerExposeAddress);
+          _2 = move _3 as usize (PointerExposeProvenance);
           StorageDead(_3);
           _1 = move _2 as *const fn() (PointerWithExposedProvenance);
           StorageDead(_2);
diff --git a/tests/mir-opt/const_prop/reify_fn_ptr.rs b/tests/mir-opt/const_prop/reify_fn_ptr.rs
index 4e897d22768..55dca24f3d2 100644
--- a/tests/mir-opt/const_prop/reify_fn_ptr.rs
+++ b/tests/mir-opt/const_prop/reify_fn_ptr.rs
@@ -4,7 +4,7 @@
 fn main() {
     // CHECK-LABEL: fn main(
     // CHECK: [[ptr:_.*]] = main as fn() (PointerCoercion(ReifyFnPointer));
-    // CHECK: [[addr:_.*]] = move [[ptr]] as usize (PointerExposeAddress);
+    // CHECK: [[addr:_.*]] = move [[ptr]] as usize (PointerExposeProvenance);
     // CHECK: [[back:_.*]] = move [[addr]] as *const fn() (PointerWithExposedProvenance);
     let _ = main as usize as *const fn();
 }
diff --git a/tests/mir-opt/const_prop/transmute.from_char.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.from_char.GVN.32bit.diff
index 47dfb421ebc..2b38e88ae4c 100644
--- a/tests/mir-opt/const_prop/transmute.from_char.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.from_char.GVN.32bit.diff
@@ -3,8 +3,6 @@
   
   fn from_char() -> i32 {
       let mut _0: i32;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 'R' as i32 (Transmute);
diff --git a/tests/mir-opt/const_prop/transmute.from_char.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.from_char.GVN.64bit.diff
index 47dfb421ebc..2b38e88ae4c 100644
--- a/tests/mir-opt/const_prop/transmute.from_char.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.from_char.GVN.64bit.diff
@@ -3,8 +3,6 @@
   
   fn from_char() -> i32 {
       let mut _0: i32;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 'R' as i32 (Transmute);
diff --git a/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.32bit.diff
index f0c6f55f775..45c48e9046e 100644
--- a/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.32bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_bool() -> bool {
       let mut _0: bool;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const -1_i8 as bool (Transmute);
diff --git a/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.64bit.diff
index f0c6f55f775..45c48e9046e 100644
--- a/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.64bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_bool() -> bool {
       let mut _0: bool;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const -1_i8 as bool (Transmute);
diff --git a/tests/mir-opt/const_prop/transmute.invalid_char.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.invalid_char.GVN.32bit.diff
index 03a7706401f..b4fe64d0aff 100644
--- a/tests/mir-opt/const_prop/transmute.invalid_char.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.invalid_char.GVN.32bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const core::num::<impl i32>::MAX as char (Transmute);
diff --git a/tests/mir-opt/const_prop/transmute.invalid_char.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.invalid_char.GVN.64bit.diff
index 03a7706401f..b4fe64d0aff 100644
--- a/tests/mir-opt/const_prop/transmute.invalid_char.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.invalid_char.GVN.64bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const core::num::<impl i32>::MAX as char (Transmute);
diff --git a/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.32bit.diff
index 5e0c076b981..ab3481a3be5 100644
--- a/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.32bit.diff
@@ -4,8 +4,6 @@
   fn less_as_i8() -> i8 {
       let mut _0: i8;
       let mut _1: std::cmp::Ordering;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.64bit.diff
index 5e0c076b981..ab3481a3be5 100644
--- a/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.64bit.diff
@@ -4,8 +4,6 @@
   fn less_as_i8() -> i8 {
       let mut _0: i8;
       let mut _1: std::cmp::Ordering;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff
index c6a428019d8..febb6bfb0a4 100644
--- a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff
@@ -5,8 +5,6 @@
       let mut _0: u32;
       let mut _1: undef_union_as_integer::Union32;
       let mut _2: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff
index c6a428019d8..febb6bfb0a4 100644
--- a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff
@@ -5,8 +5,6 @@
       let mut _0: u32;
       let mut _1: undef_union_as_integer::Union32;
       let mut _2: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff
index 2ef83abfac0..7a289563c50 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff
index 2ef83abfac0..7a289563c50 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff
index b2e91014625..3364782022d 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff
index b2e91014625..3364782022d 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.32bit.diff
index 0ff31b1a981..a7020793237 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.32bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.64bit.diff
index 0ff31b1a981..a7020793237 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.64bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.32bit.diff
index 430d16c97a6..d44b0872035 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.32bit.diff
@@ -7,8 +7,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.64bit.diff
index 430d16c97a6..d44b0872035 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.64bit.diff
@@ -7,8 +7,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.valid_char.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.valid_char.GVN.32bit.diff
index f9d002f96ab..069ff906ec5 100644
--- a/tests/mir-opt/const_prop/transmute.valid_char.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.valid_char.GVN.32bit.diff
@@ -3,8 +3,6 @@
   
   fn valid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 82_u32 as char (Transmute);
diff --git a/tests/mir-opt/const_prop/transmute.valid_char.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.valid_char.GVN.64bit.diff
index f9d002f96ab..069ff906ec5 100644
--- a/tests/mir-opt/const_prop/transmute.valid_char.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.valid_char.GVN.64bit.diff
@@ -3,8 +3,6 @@
   
   fn valid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 82_u32 as char (Transmute);
diff --git a/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-abort.diff
index ffb0c4b23fb..ef30ac2fc8c 100644
--- a/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-abort.diff
+++ b/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-abort.diff
@@ -14,13 +14,11 @@
           scope 2 {
               debug b => _3;
               let _5: *mut u8;
-              scope 4 {
+              scope 3 {
 -                 debug c => _5;
 +                 debug c => _2;
               }
           }
-          scope 3 {
-          }
       }
   
       bb0: {
diff --git a/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff
index 66a0f49cfb9..a743a3e829a 100644
--- a/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff
@@ -14,13 +14,11 @@
           scope 2 {
               debug b => _3;
               let _5: *mut u8;
-              scope 4 {
+              scope 3 {
 -                 debug c => _5;
 +                 debug c => _2;
               }
           }
-          scope 3 {
-          }
       }
   
       bb0: {
diff --git a/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-abort.diff
index 0777a913523..2de6f85ce64 100644
--- a/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-abort.diff
+++ b/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-abort.diff
@@ -13,13 +13,11 @@
           scope 2 {
               debug b => _3;
               let _4: *mut u8;
-              scope 4 {
+              scope 3 {
 -                 debug c => _4;
 +                 debug c => _2;
               }
           }
-          scope 3 {
-          }
       }
   
       bb0: {
diff --git a/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff
index f5a512b8995..2afec4898bc 100644
--- a/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff
@@ -13,13 +13,11 @@
           scope 2 {
               debug b => _3;
               let _4: *mut u8;
-              scope 4 {
+              scope 3 {
 -                 debug c => _4;
 +                 debug c => _2;
               }
           }
-          scope 3 {
-          }
       }
   
       bb0: {
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
index 21cf745b680..44e73b56098 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
index ee58a974480..6cef8b692ba 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
index 9fc9c8ed409..6efccded993 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
index 30d93347afd..a705d0064cb 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
index 3a46edbc849..f9c854ca3f4 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
index 3c71214c35f..333726689d7 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
index 4557e7b26d6..e1841760077 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
index 5ab2d5e0fdc..7aa02556ec5 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-abort.diff
index 9b0093c454e..a5e40990751 100644
--- a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-abort.diff
@@ -9,14 +9,12 @@
       let mut _5: *mut u8;
       scope 1 {
           debug x => _1;
+          let _3: *mut u8;
           let _6: u8;
           scope 2 {
-              let _3: *mut u8;
-              scope 3 {
-                  debug p => _3;
-              }
+              debug p => _3;
           }
-          scope 4 {
+          scope 3 {
               debug x1 => _6;
           }
       }
diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff
index 635a214251b..ce2178ddbee 100644
--- a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff
@@ -9,14 +9,12 @@
       let mut _5: *mut u8;
       scope 1 {
           debug x => _1;
+          let _3: *mut u8;
           let _6: u8;
           scope 2 {
-              let _3: *mut u8;
-              scope 3 {
-                  debug p => _3;
-              }
+              debug p => _3;
           }
-          scope 4 {
+          scope 3 {
               debug x1 => _6;
           }
       }
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.32bit.diff
index 52f096ac0e4..a5529253762 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.32bit.diff
@@ -3,8 +3,6 @@
   
   fn from_char() -> i32 {
       let mut _0: i32;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 'R' as i32 (Transmute);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.64bit.diff
index 52f096ac0e4..a5529253762 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.64bit.diff
@@ -3,8 +3,6 @@
   
   fn from_char() -> i32 {
       let mut _0: i32;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 'R' as i32 (Transmute);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.32bit.diff
index 3972eb209a1..a66d8dbe844 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.32bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_bool() -> bool {
       let mut _0: bool;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const -1_i8 as bool (Transmute);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.64bit.diff
index 3972eb209a1..a66d8dbe844 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.64bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_bool() -> bool {
       let mut _0: bool;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const -1_i8 as bool (Transmute);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.32bit.diff
index dd737017ffd..4f3f3e03d75 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.32bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const core::num::<impl i32>::MAX as char (Transmute);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.64bit.diff
index dd737017ffd..4f3f3e03d75 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.64bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const core::num::<impl i32>::MAX as char (Transmute);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.32bit.diff
index 6091e169e8e..44dd4017409 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.32bit.diff
@@ -4,8 +4,6 @@
   fn less_as_i8() -> i8 {
       let mut _0: i8;
       let mut _1: std::cmp::Ordering;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.64bit.diff
index 6091e169e8e..44dd4017409 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.64bit.diff
@@ -4,8 +4,6 @@
   fn less_as_i8() -> i8 {
       let mut _0: i8;
       let mut _1: std::cmp::Ordering;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.32bit.diff
index fb28aa8f6d9..14a34a1ce38 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.32bit.diff
@@ -5,8 +5,6 @@
       let mut _0: u32;
       let mut _1: undef_union_as_integer::Union32;
       let mut _2: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.64bit.diff
index fb28aa8f6d9..14a34a1ce38 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.64bit.diff
@@ -5,8 +5,6 @@
       let mut _0: u32;
       let mut _1: undef_union_as_integer::Union32;
       let mut _2: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff
index 5d17c47ae66..258e2b454eb 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff
index 5d17c47ae66..258e2b454eb 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.32bit.diff
index c8d4d6edba1..a0b4fb2f5e4 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.32bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.64bit.diff
index c8d4d6edba1..a0b4fb2f5e4 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.64bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.32bit.diff
index 2ffaeea72db..ef461423c32 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.32bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.64bit.diff
index 2ffaeea72db..ef461423c32 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.64bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.32bit.diff
index 31fcaafc5bc..c8910029a03 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.32bit.diff
@@ -7,8 +7,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.64bit.diff
index 31fcaafc5bc..c8910029a03 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.64bit.diff
@@ -7,8 +7,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.32bit.diff
index 402ef754a64..580c5044bb8 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.32bit.diff
@@ -3,8 +3,6 @@
   
   fn valid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 82_u32 as char (Transmute);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.64bit.diff
index 402ef754a64..580c5044bb8 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.64bit.diff
@@ -3,8 +3,6 @@
   
   fn valid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 82_u32 as char (Transmute);
diff --git a/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff b/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff
index 9b0dc6b6af6..56d5c24ae1d 100644
--- a/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff
+++ b/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff
@@ -19,12 +19,12 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = _1;
-          _2 = move _3 as usize (PointerExposeAddress);
+          _2 = move _3 as usize (PointerExposeProvenance);
           StorageDead(_3);
           StorageLive(_4);
           StorageLive(_5);
           _5 = _1;
-          _4 = move _5 as isize (PointerExposeAddress);
+          _4 = move _5 as isize (PointerExposeProvenance);
           StorageDead(_5);
           _0 = const ();
           StorageDead(_4);
diff --git a/tests/mir-opt/dead-store-elimination/provenance_soundness.rs b/tests/mir-opt/dead-store-elimination/provenance_soundness.rs
index 96268cd957e..20517a00489 100644
--- a/tests/mir-opt/dead-store-elimination/provenance_soundness.rs
+++ b/tests/mir-opt/dead-store-elimination/provenance_soundness.rs
@@ -5,8 +5,8 @@
 // EMIT_MIR provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff
 fn pointer_to_int(p: *mut i32) {
     // CHECK-LABEL: fn pointer_to_int(
-    // CHECK: {{_.*}} = {{.*}} as usize (PointerExposeAddress);
-    // CHECK: {{_.*}} = {{.*}} as isize (PointerExposeAddress);
+    // CHECK: {{_.*}} = {{.*}} as usize (PointerExposeProvenance);
+    // CHECK: {{_.*}} = {{.*}} as isize (PointerExposeProvenance);
     let _x = p as usize;
     let _y = p as isize;
 }
diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff
index 0af3faf28f0..570ec129f06 100644
--- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff
+++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff
@@ -8,13 +8,11 @@
       let mut _3: u32;
       scope 1 {
           debug un => _1;
-          scope 2 {
-          }
-          scope 4 (inlined std::mem::drop::<u32>) {
+          scope 3 (inlined std::mem::drop::<u32>) {
               debug _x => _3;
           }
       }
-      scope 3 (inlined val) {
+      scope 2 (inlined val) {
       }
   
       bb0: {
diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
index 0af3faf28f0..570ec129f06 100644
--- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
+++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
@@ -8,13 +8,11 @@
       let mut _3: u32;
       scope 1 {
           debug un => _1;
-          scope 2 {
-          }
-          scope 4 (inlined std::mem::drop::<u32>) {
+          scope 3 (inlined std::mem::drop::<u32>) {
               debug _x => _3;
           }
       }
-      scope 3 (inlined val) {
+      scope 2 (inlined val) {
       }
   
       bb0: {
diff --git a/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff b/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff
index 46bf13985da..906835530d8 100644
--- a/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff
@@ -37,17 +37,9 @@
           debug z => _8;
           let _13: *mut u32;
           scope 2 {
-          }
-          scope 3 {
-          }
-          scope 4 {
               debug z => _13;
               let _18: &u32;
-              scope 5 {
-              }
-              scope 6 {
-              }
-              scope 7 {
+              scope 3 {
                   debug z => _18;
               }
           }
diff --git a/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff b/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff
index 3e731ead859..006b5da646c 100644
--- a/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff
@@ -37,17 +37,9 @@
           debug z => _8;
           let _13: *mut u32;
           scope 2 {
-          }
-          scope 3 {
-          }
-          scope 4 {
               debug z => _13;
               let _18: &u32;
-              scope 5 {
-              }
-              scope 6 {
-              }
-              scope 7 {
+              scope 3 {
                   debug z => _18;
               }
           }
diff --git a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
index f3f9073909e..2389d98b5b3 100644
--- a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
@@ -69,17 +69,15 @@
                   debug u => _29;
                   let _41: &*const u8;
                   let _42: &*const u8;
-                  scope 7 {
+                  scope 6 {
                       debug left_val => _41;
                       debug right_val => _42;
                       let _47: core::panicking::AssertKind;
-                      scope 8 {
+                      scope 7 {
                           debug kind => _47;
                       }
                   }
               }
-              scope 6 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
index 383152cce5e..50715d748e7 100644
--- a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
@@ -69,17 +69,15 @@
                   debug u => _29;
                   let _41: &*const u8;
                   let _42: &*const u8;
-                  scope 7 {
+                  scope 6 {
                       debug left_val => _41;
                       debug right_val => _42;
                       let _47: core::panicking::AssertKind;
-                      scope 8 {
+                      scope 7 {
                           debug kind => _47;
                       }
                   }
               }
-              scope 6 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff
index 3ecd4650d81..ba9e507560d 100644
--- a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff
@@ -175,18 +175,16 @@
           let _135: &mut u64;
           scope 2 {
               debug b => _135;
+              let _145: *const u64;
               let _163: &u64;
               scope 3 {
-                  let _145: *const u64;
+                  debug c => _145;
+                  let _154: *mut u64;
                   scope 4 {
-                      debug c => _145;
-                      let _154: *mut u64;
-                      scope 5 {
-                          debug d => _154;
-                      }
+                      debug d => _154;
                   }
               }
-              scope 6 {
+              scope 5 {
                   debug e => _163;
               }
           }
diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff
index bf448280b1e..41c01536130 100644
--- a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff
@@ -175,18 +175,16 @@
           let _135: &mut u64;
           scope 2 {
               debug b => _135;
+              let _145: *const u64;
               let _163: &u64;
               scope 3 {
-                  let _145: *const u64;
+                  debug c => _145;
+                  let _154: *mut u64;
                   scope 4 {
-                      debug c => _145;
-                      let _154: *mut u64;
-                      scope 5 {
-                          debug d => _154;
-                      }
+                      debug d => _154;
                   }
               }
-              scope 6 {
+              scope 5 {
                   debug e => _163;
               }
           }
diff --git a/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-abort.diff b/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-abort.diff
index 11cd43fc0e0..07c4c7663c1 100644
--- a/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-abort.diff
@@ -33,13 +33,9 @@
       scope 1 {
           debug a => _1;
           let _3: *const [u8];
-          scope 3 {
+          scope 2 {
               debug b => _3;
           }
-          scope 4 {
-          }
-      }
-      scope 2 {
       }
   
       bb0: {
diff --git a/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-unwind.diff b/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-unwind.diff
index c77cd07c60c..df0f93f1077 100644
--- a/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-unwind.diff
@@ -33,13 +33,9 @@
       scope 1 {
           debug a => _1;
           let _3: *const [u8];
-          scope 3 {
+          scope 2 {
               debug b => _3;
           }
-          scope 4 {
-          }
-      }
-      scope 2 {
       }
   
       bb0: {
diff --git a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff
index 86e6aae1191..c5ee0d9c44d 100644
--- a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff
@@ -7,12 +7,10 @@
       let mut _2: E;
       let mut _3: &U;
       let _4: U;
+      let mut _5: &U;
       scope 1 {
           debug i => _1;
       }
-      scope 2 {
-          let mut _5: &U;
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff
index 86e6aae1191..c5ee0d9c44d 100644
--- a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff
@@ -7,12 +7,10 @@
       let mut _2: E;
       let mut _3: &U;
       let _4: U;
+      let mut _5: &U;
       scope 1 {
           debug i => _1;
       }
-      scope 2 {
-          let mut _5: &U;
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff
index ea9c360aa7b..dc0004105a7 100644
--- a/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff
@@ -8,8 +8,6 @@
 +         let _2: D;
 +         scope 2 {
 +             debug _d => const D;
-+             scope 3 {
-+             }
 +         }
 +     }
   
diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff
index a38b8246bde..859082c3111 100644
--- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff
@@ -15,13 +15,11 @@
 +     }
 +     scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new) {
 +         debug pointer => _3;
-+         scope 4 {
-+             scope 5 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new_unchecked) {
-+                 debug pointer => _3;
-+             }
++         scope 4 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new_unchecked) {
++             debug pointer => _3;
 +         }
 +     }
-+     scope 6 (inlined g::{closure#0}) {
++     scope 5 (inlined g::{closure#0}) {
 +         debug a => _5;
 +         let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8};
 +         let mut _7: u32;
diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff
index dc6628ab44c..44b06c34972 100644
--- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff
@@ -15,13 +15,11 @@
 +     }
 +     scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new) {
 +         debug pointer => _3;
-+         scope 4 {
-+             scope 5 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new_unchecked) {
-+                 debug pointer => _3;
-+             }
++         scope 4 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new_unchecked) {
++             debug pointer => _3;
 +         }
 +     }
-+     scope 6 (inlined g::{closure#0}) {
++     scope 5 (inlined g::{closure#0}) {
 +         debug a => _5;
 +         let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8};
 +         let mut _7: u32;
diff --git a/tests/mir-opt/inline/inline_instruction_set.default.Inline.diff b/tests/mir-opt/inline/inline_instruction_set.default.Inline.diff
index e38daba27fc..158cc973779 100644
--- a/tests/mir-opt/inline/inline_instruction_set.default.Inline.diff
+++ b/tests/mir-opt/inline/inline_instruction_set.default.Inline.diff
@@ -10,8 +10,6 @@
 +     scope 1 (inlined instruction_set_default) {
 +     }
 +     scope 2 (inlined inline_always_and_using_inline_asm) {
-+         scope 3 {
-+         }
 +     }
   
       bb0: {
diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff
index 4fcd49994f0..2a36ccaab11 100644
--- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff
@@ -8,18 +8,14 @@
       let _3: ();
       let mut _4: *mut std::vec::Vec<A>;
       let mut _5: *mut std::option::Option<B>;
-      scope 1 {
-+         scope 3 (inlined std::ptr::drop_in_place::<Vec<A>> - shim(Some(Vec<A>))) {
-+             let mut _6: &mut std::vec::Vec<A>;
-+             let mut _7: ();
-+         }
-      }
-      scope 2 {
-+         scope 4 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
-+             let mut _8: isize;
-+             let mut _9: isize;
-+         }
-      }
++     scope 1 (inlined std::ptr::drop_in_place::<Vec<A>> - shim(Some(Vec<A>))) {
++         let mut _6: &mut std::vec::Vec<A>;
++         let mut _7: ();
++     }
++     scope 2 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
++         let mut _8: isize;
++         let mut _9: isize;
++     }
   
       bb0: {
           StorageLive(_3);
diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff
index 4270ae00b66..e11561076e6 100644
--- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff
@@ -8,14 +8,10 @@
       let _3: ();
       let mut _4: *mut std::vec::Vec<A>;
       let mut _5: *mut std::option::Option<B>;
-      scope 1 {
-      }
-      scope 2 {
-+         scope 3 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
-+             let mut _6: isize;
-+             let mut _7: isize;
-+         }
-      }
++     scope 1 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
++         let mut _6: isize;
++         let mut _7: isize;
++     }
   
       bb0: {
           StorageLive(_3);
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff
index 51e506142a9..cc1b8b9b70f 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff
@@ -10,8 +10,6 @@
 +     scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
 +         debug self => _3;
 +         debug rhs => _4;
-+         scope 2 {
-+         }
 +     }
   
       bb0: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
index 053ccc077a4..f244f378bce 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
@@ -10,8 +10,6 @@
 +     scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
 +         debug self => _3;
 +         debug rhs => _4;
-+         scope 2 {
-+         }
 +     }
   
       bb0: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir
index 2be887e9b5a..c96983c18cb 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir
@@ -7,8 +7,6 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 {
     scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
         debug self => _1;
         debug rhs => _2;
-        scope 2 {
-        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir
index 2be887e9b5a..c96983c18cb 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir
@@ -7,8 +7,6 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 {
     scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
         debug self => _1;
         debug rhs => _2;
-        scope 2 {
-        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff
index 816d03b4405..74518db370f 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff
@@ -10,8 +10,6 @@
 +     scope 1 (inlined core::num::<impl i64>::unchecked_shr) {
 +         debug self => _3;
 +         debug rhs => _4;
-+         scope 2 {
-+         }
 +     }
   
       bb0: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff
index d4121f89baf..aab04624f6c 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff
@@ -10,8 +10,6 @@
 +     scope 1 (inlined core::num::<impl i64>::unchecked_shr) {
 +         debug self => _3;
 +         debug rhs => _4;
-+         scope 2 {
-+         }
 +     }
   
       bb0: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir
index 4696112175e..1dd8cb27314 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir
@@ -7,8 +7,6 @@ fn unchecked_shr_signed_bigger(_1: i64, _2: u32) -> i64 {
     scope 1 (inlined core::num::<impl i64>::unchecked_shr) {
         debug self => _1;
         debug rhs => _2;
-        scope 2 {
-        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir
index 4696112175e..1dd8cb27314 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir
@@ -7,8 +7,6 @@ fn unchecked_shr_signed_bigger(_1: i64, _2: u32) -> i64 {
     scope 1 (inlined core::num::<impl i64>::unchecked_shr) {
         debug self => _1;
         debug rhs => _2;
-        scope 2 {
-        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
index 028040edc85..814eda10459 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
@@ -11,15 +11,11 @@
 +         scope 2 {
 +             debug val => _0;
 +         }
-+         scope 3 {
-+             scope 4 (inlined unreachable_unchecked) {
-+                 let mut _4: bool;
-+                 let _5: ();
-+                 scope 5 {
-+                 }
-+                 scope 6 (inlined core::ub_checks::check_language_ub) {
-+                     scope 7 (inlined core::ub_checks::check_language_ub::runtime) {
-+                     }
++         scope 3 (inlined unreachable_unchecked) {
++             let mut _4: bool;
++             let _5: ();
++             scope 4 (inlined core::ub_checks::check_language_ub) {
++                 scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
 +                 }
 +             }
 +         }
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
index 484fd37248c..d5d69074382 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
@@ -11,15 +11,11 @@
 +         scope 2 {
 +             debug val => _0;
 +         }
-+         scope 3 {
-+             scope 4 (inlined unreachable_unchecked) {
-+                 let mut _4: bool;
-+                 let _5: ();
-+                 scope 5 {
-+                 }
-+                 scope 6 (inlined core::ub_checks::check_language_ub) {
-+                     scope 7 (inlined core::ub_checks::check_language_ub::runtime) {
-+                     }
++         scope 3 (inlined unreachable_unchecked) {
++             let mut _4: bool;
++             let _5: ();
++             scope 4 (inlined core::ub_checks::check_language_ub) {
++                 scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
 +                 }
 +             }
 +         }
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir
index d629336d385..7c24a97166c 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir
@@ -9,13 +9,9 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
         scope 2 {
             debug val => _0;
         }
-        scope 3 {
-            scope 4 (inlined unreachable_unchecked) {
-                scope 5 {
-                }
-                scope 6 (inlined core::ub_checks::check_language_ub) {
-                    scope 7 (inlined core::ub_checks::check_language_ub::runtime) {
-                    }
+        scope 3 (inlined unreachable_unchecked) {
+            scope 4 (inlined core::ub_checks::check_language_ub) {
+                scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
                 }
             }
         }
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir
index d629336d385..7c24a97166c 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir
@@ -9,13 +9,9 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
         scope 2 {
             debug val => _0;
         }
-        scope 3 {
-            scope 4 (inlined unreachable_unchecked) {
-                scope 5 {
-                }
-                scope 6 (inlined core::ub_checks::check_language_ub) {
-                    scope 7 (inlined core::ub_checks::check_language_ub::runtime) {
-                    }
+        scope 3 (inlined unreachable_unchecked) {
+            scope 4 (inlined core::ub_checks::check_language_ub) {
+                scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
                 }
             }
         }
diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff
index 0243e31cb1a..f8cceacd7e6 100644
--- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff
@@ -18,9 +18,9 @@
           let _4: std::pin::Pin<&mut {async fn body of ActionPermit<'_, T>::perform()}>;
           scope 2 {
               debug fut => _4;
-              scope 4 {
+              scope 3 {
               }
-+             scope 7 (inlined ActionPermit::<'_, T>::perform::{closure#0}) {
++             scope 6 (inlined ActionPermit::<'_, T>::perform::{closure#0}) {
 +                 debug _task_context => _31;
 +                 debug self => ((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})).0: ActionPermit<'_, T>);
 +                 let _11: ActionPermit<'_, T>;
@@ -51,32 +51,28 @@
 +                 let mut _38: &mut {async fn body of ActionPermit<'_, T>::perform()};
 +                 let mut _39: &mut {async fn body of ActionPermit<'_, T>::perform()};
 +                 let mut _40: &mut {async fn body of ActionPermit<'_, T>::perform()};
-+                 scope 8 {
++                 scope 7 {
 +                     debug self => (((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})) as variant#3).0: ActionPermit<'_, T>);
 +                     let mut _15: std::future::Ready<()>;
-+                     scope 9 {
++                     scope 8 {
 +                         debug __awaitee => (((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})) as variant#3).1: std::future::Ready<()>);
 +                         let _26: ();
-+                         scope 10 {
-+                         }
-+                         scope 11 {
++                         scope 9 {
 +                             debug result => _26;
 +                         }
 +                     }
-+                     scope 12 (inlined ready::<()>) {
++                     scope 10 (inlined ready::<()>) {
 +                         debug t => _14;
 +                         let mut _41: std::option::Option<()>;
 +                     }
 +                 }
 +             }
           }
-          scope 3 {
-+             scope 6 (inlined Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked) {
-+                 debug pointer => _5;
-+             }
-          }
++         scope 5 (inlined Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked) {
++             debug pointer => _5;
++         }
       }
-+     scope 5 (inlined ActionPermit::<'_, T>::perform) {
++     scope 4 (inlined ActionPermit::<'_, T>::perform) {
 +         debug self => _3;
 +     }
   
diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff
index 96a93cdda3d..fd080d22d3a 100644
--- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff
@@ -18,9 +18,9 @@
           let _4: std::pin::Pin<&mut {async fn body of ActionPermit<'_, T>::perform()}>;
           scope 2 {
               debug fut => _4;
-              scope 4 {
+              scope 3 {
               }
-+             scope 7 (inlined ActionPermit::<'_, T>::perform::{closure#0}) {
++             scope 6 (inlined ActionPermit::<'_, T>::perform::{closure#0}) {
 +                 debug _task_context => _31;
 +                 debug self => ((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})).0: ActionPermit<'_, T>);
 +                 let _11: ActionPermit<'_, T>;
@@ -53,32 +53,28 @@
 +                 let mut _40: &mut {async fn body of ActionPermit<'_, T>::perform()};
 +                 let mut _41: &mut {async fn body of ActionPermit<'_, T>::perform()};
 +                 let mut _42: &mut {async fn body of ActionPermit<'_, T>::perform()};
-+                 scope 8 {
++                 scope 7 {
 +                     debug self => (((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})) as variant#3).0: ActionPermit<'_, T>);
 +                     let mut _15: std::future::Ready<()>;
-+                     scope 9 {
++                     scope 8 {
 +                         debug __awaitee => (((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})) as variant#3).1: std::future::Ready<()>);
 +                         let _26: ();
-+                         scope 10 {
-+                         }
-+                         scope 11 {
++                         scope 9 {
 +                             debug result => _26;
 +                         }
 +                     }
-+                     scope 12 (inlined ready::<()>) {
++                     scope 10 (inlined ready::<()>) {
 +                         debug t => _14;
 +                         let mut _43: std::option::Option<()>;
 +                     }
 +                 }
 +             }
           }
-          scope 3 {
-+             scope 6 (inlined Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked) {
-+                 debug pointer => _5;
-+             }
-          }
++         scope 5 (inlined Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked) {
++             debug pointer => _5;
++         }
       }
-+     scope 5 (inlined ActionPermit::<'_, T>::perform) {
++     scope 4 (inlined ActionPermit::<'_, T>::perform) {
 +         debug self => _3;
 +     }
   
diff --git a/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify.diff b/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify.diff
index f3402fde05b..6d6c9c9a7a1 100644
--- a/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify.diff
+++ b/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify.diff
@@ -5,23 +5,17 @@
       debug x => _1;
       let mut _0: i32;
       let mut _2: std::option::Option<i32>;
-      scope 1 {
-          scope 2 (inlined #[track_caller] Option::<i32>::unwrap_unchecked) {
-              debug self => _2;
-              let mut _3: isize;
-              scope 3 {
-                  debug val => _0;
-              }
-              scope 4 {
-                  scope 5 (inlined unreachable_unchecked) {
-                      let mut _4: bool;
-                      let _5: ();
-                      scope 6 {
-                      }
-                      scope 7 (inlined core::ub_checks::check_language_ub) {
-                          scope 8 (inlined core::ub_checks::check_language_ub::runtime) {
-                          }
-                      }
+      scope 1 (inlined #[track_caller] Option::<i32>::unwrap_unchecked) {
+          debug self => _2;
+          let mut _3: isize;
+          scope 2 {
+              debug val => _0;
+          }
+          scope 3 (inlined unreachable_unchecked) {
+              let mut _4: bool;
+              let _5: ();
+              scope 4 (inlined core::ub_checks::check_language_ub) {
+                  scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
                   }
               }
           }
diff --git a/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-abort.mir b/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-abort.mir
index b4f21240939..53912adc003 100644
--- a/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-abort.mir
+++ b/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-abort.mir
@@ -4,8 +4,6 @@ fn main() -> () {
     let mut _0: ();
     let mut _1: !;
     let mut _2: ();
-    scope 1 {
-    }
 
     bb0: {
         StorageLive(_1);
diff --git a/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir b/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir
index 1851747f0a6..50416300094 100644
--- a/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir
+++ b/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir
@@ -4,8 +4,6 @@ fn main() -> () {
     let mut _0: ();
     let mut _1: !;
     let mut _2: ();
-    scope 1 {
-    }
 
     bb0: {
         StorageLive(_1);
diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir
index 91dee82fde0..3104baa5fdb 100644
--- a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir
+++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir
@@ -15,15 +15,13 @@ fn test() -> Option<Box<u32>> {
     let mut _11: std::option::Option<std::convert::Infallible>;
     let _12: u32;
     scope 1 {
-    }
-    scope 2 {
         debug residual => _9;
-        scope 3 {
+        scope 2 {
         }
     }
-    scope 4 {
+    scope 3 {
         debug val => _12;
-        scope 5 {
+        scope 4 {
         }
     }
 
diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
index ff7fc74ff61..da33c830115 100644
--- a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
+++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
@@ -15,15 +15,13 @@ fn test() -> Option<Box<u32>> {
     let mut _11: std::option::Option<std::convert::Infallible>;
     let _12: u32;
     scope 1 {
-    }
-    scope 2 {
         debug residual => _9;
-        scope 3 {
+        scope 2 {
         }
     }
-    scope 4 {
+    scope 3 {
         debug val => _12;
-        scope 5 {
+        scope 4 {
         }
     }
 
diff --git a/tests/mir-opt/issue_72181.main.built.after.mir b/tests/mir-opt/issue_72181.main.built.after.mir
index cff20702bf7..fa101512d72 100644
--- a/tests/mir-opt/issue_72181.main.built.after.mir
+++ b/tests/mir-opt/issue_72181.main.built.after.mir
@@ -15,8 +15,6 @@ fn main() -> () {
             debug f => _2;
             scope 3 {
             }
-            scope 4 {
-            }
         }
     }
 
diff --git a/tests/mir-opt/issue_72181_1.main.built.after.mir b/tests/mir-opt/issue_72181_1.main.built.after.mir
index d35aada95f8..ae0dc9a0b6a 100644
--- a/tests/mir-opt/issue_72181_1.main.built.after.mir
+++ b/tests/mir-opt/issue_72181_1.main.built.after.mir
@@ -14,8 +14,6 @@ fn main() -> () {
     scope 1 {
         debug v => _2;
     }
-    scope 2 {
-    }
 
     bb0: {
         StorageLive(_2);
diff --git a/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff b/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
index f11c993340f..25ed1b4d0c7 100644
--- a/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
+++ b/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
@@ -10,15 +10,11 @@
       let mut _6: u32;
       scope 1 {
           debug dwords => _2;
-          scope 3 {
+          scope 2 {
               debug ip => _4;
               let _4: u32;
-              scope 4 {
-              }
           }
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff
index 80a42263643..e9d4352014f 100644
--- a/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff
+++ b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff
@@ -12,8 +12,6 @@
           let _2: *mut i32;
           scope 2 {
               debug a => _2;
-              scope 3 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff
index 80a42263643..e9d4352014f 100644
--- a/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff
+++ b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff
@@ -12,8 +12,6 @@
           let _2: *mut i32;
           scope 2 {
               debug a => _2;
-              scope 3 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff
index f9f73bf991d..633a344a2ed 100644
--- a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff
@@ -14,8 +14,6 @@
           let _5: *const [u8];
           scope 2 {
               debug arr => _5;
-              scope 3 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff
index f9f73bf991d..633a344a2ed 100644
--- a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff
@@ -14,8 +14,6 @@
           let _5: *const [u8];
           scope 2 {
               debug arr => _5;
-              scope 3 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-abort.diff
index 79635f23e8e..6c1f457cb5f 100644
--- a/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-abort.diff
@@ -4,8 +4,6 @@
   fn assume() -> () {
       let mut _0: ();
       let _1: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-unwind.diff
index 79635f23e8e..6c1f457cb5f 100644
--- a/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-unwind.diff
@@ -4,8 +4,6 @@
   fn assume() -> () {
       let mut _0: ();
       let _1: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-abort.diff
index 6de5f2c4f07..96b66af66a2 100644
--- a/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-abort.diff
@@ -18,8 +18,6 @@
           let mut _2: ();
           scope 2 {
               debug dst => _2;
-              scope 3 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-unwind.diff
index 6de5f2c4f07..96b66af66a2 100644
--- a/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-unwind.diff
@@ -18,8 +18,6 @@
           let mut _2: ();
           scope 2 {
               debug dst => _2;
-              scope 3 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-abort.diff
index 147c48a3c01..781104be290 100644
--- a/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-abort.diff
@@ -5,8 +5,6 @@
       debug r => _1;
       let mut _0: i32;
       let mut _2: *const i32;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-unwind.diff
index 147c48a3c01..781104be290 100644
--- a/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-unwind.diff
@@ -5,8 +5,6 @@
       debug r => _1;
       let mut _0: i32;
       let mut _2: *const i32;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-abort.diff
index b2cf3cc1cca..56c357b3776 100644
--- a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-abort.diff
@@ -5,8 +5,6 @@
       debug r => _1;
       let mut _0: Never;
       let mut _2: *const Never;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-unwind.diff
index b2cf3cc1cca..56c357b3776 100644
--- a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-unwind.diff
@@ -5,8 +5,6 @@
       debug r => _1;
       let mut _0: Never;
       let mut _2: *const Never;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff
index 3b4051e4ae2..6e542c4b5a7 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff
@@ -5,8 +5,6 @@
       debug c => _1;
       let mut _0: i8;
       let mut _2: std::cmp::Ordering;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff
index 3b4051e4ae2..6e542c4b5a7 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff
@@ -5,8 +5,6 @@
       debug c => _1;
       let mut _0: i8;
       let mut _2: std::cmp::Ordering;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff
index 91276a1b5c4..ab4646370f1 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff
@@ -5,8 +5,6 @@
       debug u => _1;
       let mut _0: *const T;
       let mut _2: &T;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff
index 91276a1b5c4..ab4646370f1 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff
@@ -5,8 +5,6 @@
       debug u => _1;
       let mut _0: *const T;
       let mut _2: &T;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff
index 792c77d575b..6d3ad348988 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff
@@ -5,8 +5,6 @@
       debug u => _1;
       let mut _0: Never;
       let mut _2: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff
index 792c77d575b..6d3ad348988 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff
@@ -5,8 +5,6 @@
       debug u => _1;
       let mut _0: Never;
       let mut _2: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-abort.diff
index f5646e7f1e9..2b715ac1d63 100644
--- a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-abort.diff
@@ -5,8 +5,6 @@
       let mut _0: !;
       let _1: ();
       let mut _2: !;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-unwind.diff
index f5646e7f1e9..2b715ac1d63 100644
--- a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-unwind.diff
@@ -5,8 +5,6 @@
       let mut _0: !;
       let _1: ();
       let mut _2: !;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-abort.diff
index ddc8cf9a3d9..cc9177c9002 100644
--- a/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-abort.diff
@@ -7,8 +7,6 @@
       let mut _0: ();
       let mut _3: *mut std::string::String;
       let mut _4: std::string::String;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_3);
diff --git a/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-unwind.diff
index ddc8cf9a3d9..cc9177c9002 100644
--- a/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-unwind.diff
@@ -7,8 +7,6 @@
       let mut _0: ();
       let mut _3: *mut std::string::String;
       let mut _4: std::string::String;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_3);
diff --git a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.mir
index 656934fce42..845673601b2 100644
--- a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.mir
@@ -21,13 +21,9 @@ fn checked_shl(_1: u32, _2: u32) -> Option<u32> {
                 debug self => _1;
                 debug rhs => _2;
                 let mut _3: u32;
-                scope 5 {
-                    scope 6 (inlined core::num::<impl u32>::unchecked_shl) {
-                        debug self => _1;
-                        debug rhs => _3;
-                        scope 7 {
-                        }
-                    }
+                scope 5 (inlined core::num::<impl u32>::unchecked_shl) {
+                    debug self => _1;
+                    debug rhs => _3;
                 }
             }
         }
diff --git a/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir
index ebe846e8a51..518fedffc16 100644
--- a/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir
@@ -5,10 +5,8 @@ fn ub_if_b(_1: Thing) -> Thing {
     let mut _0: Thing;
     let mut _2: isize;
     scope 1 (inlined unreachable_unchecked) {
-        scope 2 {
-        }
-        scope 3 (inlined core::ub_checks::check_language_ub) {
-            scope 4 (inlined core::ub_checks::check_language_ub::runtime) {
+        scope 2 (inlined core::ub_checks::check_language_ub) {
+            scope 3 (inlined core::ub_checks::check_language_ub::runtime) {
             }
         }
     }
diff --git a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
index 0b5ed6ee169..cdb7eea74fb 100644
--- a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
@@ -26,10 +26,8 @@ fn int_range(_1: usize, _2: usize) -> () {
                 let mut _12: usize;
                 scope 6 {
                     debug old => _11;
-                    scope 7 {
-                    }
                 }
-                scope 8 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
+                scope 7 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
                     debug self => _6;
                     debug other => _7;
                     let mut _8: usize;
diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir
index 26919dd98dd..c744787fce2 100644
--- a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir
@@ -8,21 +8,15 @@ fn mem_replace(_1: &mut u32, _2: u32) -> u32 {
         debug dest => _1;
         debug src => _2;
         scope 2 {
-            scope 3 {
-                debug result => _0;
-                scope 6 (inlined std::ptr::write::<u32>) {
-                    debug dst => _1;
-                    debug src => _2;
-                    scope 7 {
-                    }
-                }
-            }
-            scope 4 (inlined std::ptr::read::<u32>) {
-                debug src => _1;
-                scope 5 {
-                }
+            debug result => _0;
+            scope 4 (inlined std::ptr::write::<u32>) {
+                debug dst => _1;
+                debug src => _2;
             }
         }
+        scope 3 (inlined std::ptr::read::<u32>) {
+            debug src => _1;
+        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir
index 26919dd98dd..c744787fce2 100644
--- a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir
@@ -8,21 +8,15 @@ fn mem_replace(_1: &mut u32, _2: u32) -> u32 {
         debug dest => _1;
         debug src => _2;
         scope 2 {
-            scope 3 {
-                debug result => _0;
-                scope 6 (inlined std::ptr::write::<u32>) {
-                    debug dst => _1;
-                    debug src => _2;
-                    scope 7 {
-                    }
-                }
-            }
-            scope 4 (inlined std::ptr::read::<u32>) {
-                debug src => _1;
-                scope 5 {
-                }
+            debug result => _0;
+            scope 4 (inlined std::ptr::write::<u32>) {
+                debug dst => _1;
+                debug src => _2;
             }
         }
+        scope 3 (inlined std::ptr::read::<u32>) {
+            debug src => _1;
+        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir
index ed965770adb..002d55ad9d9 100644
--- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir
@@ -29,10 +29,8 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
                 let mut _13: u32;
                 scope 6 {
                     debug old => _12;
-                    scope 7 {
-                    }
                 }
-                scope 8 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
+                scope 7 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
                     debug self => _7;
                     debug other => _8;
                     let mut _9: u32;
diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index a7ee9be19bd..d5021ac84d2 100644
--- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -29,10 +29,8 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
                 let mut _13: u32;
                 scope 6 {
                     debug old => _12;
-                    scope 7 {
-                    }
                 }
-                scope 8 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
+                scope 7 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
                     debug self => _7;
                     debug other => _8;
                     let mut _9: u32;
diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir
index f674f6a3009..7faae1d863c 100644
--- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir
@@ -14,10 +14,8 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
             let mut _8: u32;
             scope 3 {
                 debug old => _7;
-                scope 4 {
-                }
             }
-            scope 5 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
+            scope 4 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
                 debug self => _2;
                 debug other => _3;
                 let mut _4: u32;
diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
index a5029dcad3a..37f00533b60 100644
--- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
@@ -14,10 +14,8 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
             let mut _8: u32;
             scope 3 {
                 debug old => _7;
-                scope 4 {
-                }
             }
-            scope 5 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
+            scope 4 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
                 debug self => _2;
                 debug other => _3;
                 let mut _4: u32;
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
index bcc540ae6fc..e5490955a36 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
@@ -9,8 +9,6 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
         debug index => _2;
         let mut _3: *mut [u32];
         let mut _4: *mut [u32];
-        scope 2 {
-        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
index 1fe7da7d2fd..810fee9a149 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
@@ -9,8 +9,6 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
         debug index => _2;
         let mut _3: *mut [u32];
         let mut _4: *mut [u32];
-        scope 2 {
-        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
index f698e15d302..1ec85906385 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
@@ -37,52 +37,42 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                 let _7: std::ptr::NonNull<T>;
                 scope 6 {
                     debug ptr => _7;
+                    let _11: *const T;
                     scope 7 {
-                        let _11: *const T;
-                        scope 8 {
-                            debug end_or_len => _11;
-                        }
-                        scope 14 (inlined without_provenance::<T>) {
-                            debug addr => _3;
-                            scope 15 {
-                            }
-                        }
-                        scope 16 (inlined NonNull::<T>::as_ptr) {
-                            debug self => _7;
-                        }
-                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
-                            debug self => _9;
-                            debug count => _3;
-                            scope 18 {
-                            }
-                        }
+                        debug end_or_len => _11;
+                    }
+                    scope 11 (inlined without_provenance::<T>) {
+                        debug addr => _3;
+                    }
+                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                        debug self => _7;
+                    }
+                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                        debug self => _9;
+                        debug count => _3;
                     }
                 }
-                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
                     debug reference => _1;
                     let mut _4: *const [T];
-                    scope 10 {
-                    }
                 }
-                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     debug self => _5;
                     let mut _6: *const T;
-                    scope 12 {
-                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
-                            debug self => _5;
-                        }
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                        debug self => _5;
                     }
                 }
             }
         }
     }
-    scope 19 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
+    scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
         debug self => _13;
-        scope 20 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
+        scope 15 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
             debug iter => _13;
         }
     }
-    scope 21 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 16 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
         debug self => _14;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
index eae9f5909e6..70cdf3f41c2 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
@@ -37,52 +37,42 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                 let _7: std::ptr::NonNull<T>;
                 scope 6 {
                     debug ptr => _7;
+                    let _11: *const T;
                     scope 7 {
-                        let _11: *const T;
-                        scope 8 {
-                            debug end_or_len => _11;
-                        }
-                        scope 14 (inlined without_provenance::<T>) {
-                            debug addr => _3;
-                            scope 15 {
-                            }
-                        }
-                        scope 16 (inlined NonNull::<T>::as_ptr) {
-                            debug self => _7;
-                        }
-                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
-                            debug self => _9;
-                            debug count => _3;
-                            scope 18 {
-                            }
-                        }
+                        debug end_or_len => _11;
+                    }
+                    scope 11 (inlined without_provenance::<T>) {
+                        debug addr => _3;
+                    }
+                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                        debug self => _7;
+                    }
+                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                        debug self => _9;
+                        debug count => _3;
                     }
                 }
-                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
                     debug reference => _1;
                     let mut _4: *const [T];
-                    scope 10 {
-                    }
                 }
-                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     debug self => _5;
                     let mut _6: *const T;
-                    scope 12 {
-                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
-                            debug self => _5;
-                        }
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                        debug self => _5;
                     }
                 }
             }
         }
     }
-    scope 19 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
+    scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
         debug self => _13;
-        scope 20 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
+        scope 15 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
             debug iter => _13;
         }
     }
-    scope 21 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 16 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
         debug self => _14;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
index 158ae0de890..d8252e7267a 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
@@ -34,46 +34,36 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                 let _7: std::ptr::NonNull<T>;
                 scope 6 {
                     debug ptr => _7;
+                    let _11: *const T;
                     scope 7 {
-                        let _11: *const T;
-                        scope 8 {
-                            debug end_or_len => _11;
-                        }
-                        scope 14 (inlined without_provenance::<T>) {
-                            debug addr => _3;
-                            scope 15 {
-                            }
-                        }
-                        scope 16 (inlined NonNull::<T>::as_ptr) {
-                            debug self => _7;
-                        }
-                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
-                            debug self => _9;
-                            debug count => _3;
-                            scope 18 {
-                            }
-                        }
+                        debug end_or_len => _11;
+                    }
+                    scope 11 (inlined without_provenance::<T>) {
+                        debug addr => _3;
+                    }
+                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                        debug self => _7;
+                    }
+                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                        debug self => _9;
+                        debug count => _3;
                     }
                 }
-                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
                     debug reference => _1;
                     let mut _4: *const [T];
-                    scope 10 {
-                    }
                 }
-                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     debug self => _5;
                     let mut _6: *const T;
-                    scope 12 {
-                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
-                            debug self => _5;
-                        }
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                        debug self => _5;
                     }
                 }
             }
         }
     }
-    scope 19 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
+    scope 14 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
         debug self => _13;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index ac9e31a0da8..b3904dc70a6 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -34,46 +34,36 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                 let _7: std::ptr::NonNull<T>;
                 scope 6 {
                     debug ptr => _7;
+                    let _11: *const T;
                     scope 7 {
-                        let _11: *const T;
-                        scope 8 {
-                            debug end_or_len => _11;
-                        }
-                        scope 14 (inlined without_provenance::<T>) {
-                            debug addr => _3;
-                            scope 15 {
-                            }
-                        }
-                        scope 16 (inlined NonNull::<T>::as_ptr) {
-                            debug self => _7;
-                        }
-                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
-                            debug self => _9;
-                            debug count => _3;
-                            scope 18 {
-                            }
-                        }
+                        debug end_or_len => _11;
+                    }
+                    scope 11 (inlined without_provenance::<T>) {
+                        debug addr => _3;
+                    }
+                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                        debug self => _7;
+                    }
+                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                        debug self => _9;
+                        debug count => _3;
                     }
                 }
-                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
                     debug reference => _1;
                     let mut _4: *const [T];
-                    scope 10 {
-                    }
                 }
-                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     debug self => _5;
                     let mut _6: *const T;
-                    scope 12 {
-                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
-                            debug self => _5;
-                        }
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                        debug self => _5;
                     }
                 }
             }
         }
     }
-    scope 19 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
+    scope 14 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
         debug self => _13;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
index 543e8918e39..5ab88c9b855 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
@@ -35,10 +35,8 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                 let mut _13: usize;
                 scope 7 {
                     debug old => _12;
-                    scope 8 {
-                    }
                 }
-                scope 9 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
+                scope 8 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
                     debug self => _7;
                     debug other => _8;
                     let mut _9: usize;
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
index a16e9cd9e51..513651090a8 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
@@ -35,10 +35,8 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                 let mut _13: usize;
                 scope 7 {
                     debug old => _12;
-                    scope 8 {
-                    }
                 }
-                scope 9 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
+                scope 8 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
                     debug self => _7;
                     debug other => _8;
                     let mut _9: usize;
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
index 9550df012f8..091c8a0e968 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
@@ -19,7 +19,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         scope 2 {
             debug x => _20;
         }
-        scope 22 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
+        scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
             debug self => _16;
             let mut _17: &mut std::slice::Iter<'_, T>;
         }
@@ -39,52 +39,42 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                 let _7: std::ptr::NonNull<T>;
                 scope 6 {
                     debug ptr => _7;
+                    let _11: *const T;
                     scope 7 {
-                        let _11: *const T;
-                        scope 8 {
-                            debug end_or_len => _11;
-                        }
-                        scope 14 (inlined without_provenance::<T>) {
-                            debug addr => _3;
-                            scope 15 {
-                            }
-                        }
-                        scope 16 (inlined NonNull::<T>::as_ptr) {
-                            debug self => _7;
-                        }
-                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
-                            debug self => _9;
-                            debug count => _3;
-                            scope 18 {
-                            }
-                        }
+                        debug end_or_len => _11;
+                    }
+                    scope 11 (inlined without_provenance::<T>) {
+                        debug addr => _3;
+                    }
+                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                        debug self => _7;
+                    }
+                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                        debug self => _9;
+                        debug count => _3;
                     }
                 }
-                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
                     debug reference => _1;
                     let mut _4: *const [T];
-                    scope 10 {
-                    }
                 }
-                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     debug self => _5;
                     let mut _6: *const T;
-                    scope 12 {
-                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
-                            debug self => _5;
-                        }
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                        debug self => _5;
                     }
                 }
             }
         }
     }
-    scope 19 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
+    scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
         debug self => _13;
-        scope 20 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
+        scope 15 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
             debug iter => _13;
         }
     }
-    scope 21 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 16 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
         debug self => _14;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
index d75aabd12fc..1873d452f34 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
@@ -19,7 +19,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         scope 2 {
             debug x => _20;
         }
-        scope 22 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
+        scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
             debug self => _16;
             let mut _17: &mut std::slice::Iter<'_, T>;
         }
@@ -39,52 +39,42 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                 let _7: std::ptr::NonNull<T>;
                 scope 6 {
                     debug ptr => _7;
+                    let _11: *const T;
                     scope 7 {
-                        let _11: *const T;
-                        scope 8 {
-                            debug end_or_len => _11;
-                        }
-                        scope 14 (inlined without_provenance::<T>) {
-                            debug addr => _3;
-                            scope 15 {
-                            }
-                        }
-                        scope 16 (inlined NonNull::<T>::as_ptr) {
-                            debug self => _7;
-                        }
-                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
-                            debug self => _9;
-                            debug count => _3;
-                            scope 18 {
-                            }
-                        }
+                        debug end_or_len => _11;
+                    }
+                    scope 11 (inlined without_provenance::<T>) {
+                        debug addr => _3;
+                    }
+                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                        debug self => _7;
+                    }
+                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                        debug self => _9;
+                        debug count => _3;
                     }
                 }
-                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
                     debug reference => _1;
                     let mut _4: *const [T];
-                    scope 10 {
-                    }
                 }
-                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     debug self => _5;
                     let mut _6: *const T;
-                    scope 12 {
-                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
-                            debug self => _5;
-                        }
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                        debug self => _5;
                     }
                 }
             }
         }
     }
-    scope 19 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
+    scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
         debug self => _13;
-        scope 20 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
+        scope 15 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
             debug iter => _13;
         }
     }
-    scope 21 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 16 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
         debug self => _14;
     }
 
diff --git a/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff
index 747028e128f..859097d3966 100644
--- a/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff
@@ -25,8 +25,6 @@
                       let _7: i32;
                       scope 5 {
                           debug a => _7;
-                          scope 6 {
-                          }
                       }
                   }
               }
diff --git a/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
index ce5ddbfdd12..1e6a168f756 100644
--- a/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
@@ -6,218 +6,196 @@
       debug multiple => _2;
       let mut _0: ();
       let _3: ();
+      let _4: usize;
       let _7: ();
       let mut _8: ();
       let _9: ();
+      let _10: usize;
       let mut _13: *const usize;
       let _15: ();
       let mut _16: ();
       let _17: ();
+      let _18: usize;
       let _22: ();
       let mut _23: &*const usize;
       let _24: ();
+      let _25: usize;
       let _29: ();
       let mut _30: *mut *const usize;
       let _31: ();
+      let _32: usize;
       let _35: ();
       let mut _36: *const usize;
       let _37: ();
+      let _38: usize;
       let _44: ();
       let mut _45: *const usize;
       let _46: ();
+      let _47: *const T;
       let _49: ();
       let mut _50: ();
       let _51: ();
+      let _52: *const T;
       let mut _53: *const T;
       let _55: ();
       let mut _56: ();
       let _57: ();
+      let _58: usize;
       let _62: ();
       let mut _63: ();
       let _64: ();
+      let _65: usize;
       let _69: ();
       let mut _70: ();
+      let _71: usize;
       let _75: ();
       let mut _76: ();
       scope 1 {
-          let _4: usize;
+          debug a => _4;
+          let _5: *const usize;
           scope 2 {
-              debug a => _4;
-              let _5: *const usize;
+              debug b => _5;
+              let _6: usize;
               scope 3 {
-                  debug b => _5;
-                  let _6: usize;
-                  scope 4 {
-                      debug c => _6;
-                  }
+                  debug c => _6;
               }
           }
       }
-      scope 5 {
-          let _10: usize;
-          scope 6 {
-              debug a => _10;
-              let _11: usize;
-              scope 7 {
-                  debug a2 => _11;
-                  let mut _12: *const usize;
-                  scope 8 {
-                      debug b => _12;
-                      let _14: usize;
-                      scope 9 {
-                          debug c => _14;
-                      }
+      scope 4 {
+          debug a => _10;
+          let _11: usize;
+          scope 5 {
+              debug a2 => _11;
+              let mut _12: *const usize;
+              scope 6 {
+                  debug b => _12;
+                  let _14: usize;
+                  scope 7 {
+                      debug c => _14;
                   }
               }
           }
       }
-      scope 10 {
-          let _18: usize;
-          scope 11 {
-              debug a => _18;
-              let _19: *const usize;
-              scope 12 {
-                  debug b => _19;
-                  let _20: &*const usize;
-                  scope 13 {
-                      debug d => _20;
-                      let _21: usize;
-                      scope 14 {
-                          debug c => _21;
-                      }
+      scope 8 {
+          debug a => _18;
+          let _19: *const usize;
+          scope 9 {
+              debug b => _19;
+              let _20: &*const usize;
+              scope 10 {
+                  debug d => _20;
+                  let _21: usize;
+                  scope 11 {
+                      debug c => _21;
                   }
               }
           }
       }
-      scope 15 {
-          let _25: usize;
-          scope 16 {
-              debug a => _25;
-              let mut _26: *const usize;
-              scope 17 {
-                  debug b => _26;
-                  let _27: *mut *const usize;
-                  scope 18 {
-                      debug d => _27;
-                      let _28: usize;
-                      scope 19 {
-                          debug c => _28;
-                      }
+      scope 12 {
+          debug a => _25;
+          let mut _26: *const usize;
+          scope 13 {
+              debug b => _26;
+              let _27: *mut *const usize;
+              scope 14 {
+                  debug d => _27;
+                  let _28: usize;
+                  scope 15 {
+                      debug c => _28;
                   }
               }
           }
       }
-      scope 20 {
-          let _32: usize;
-          scope 21 {
-              debug a => _32;
-              let _33: *const usize;
-              scope 22 {
-                  debug b => _33;
-                  let _34: usize;
-                  scope 23 {
-                      debug c => _34;
-                  }
+      scope 16 {
+          debug a => _32;
+          let _33: *const usize;
+          scope 17 {
+              debug b => _33;
+              let _34: usize;
+              scope 18 {
+                  debug c => _34;
               }
           }
       }
-      scope 24 {
-          let _38: usize;
-          scope 25 {
-              debug a => _38;
-              let _39: *const usize;
-              scope 26 {
-                  debug b1 => _39;
-                  let _40: usize;
-                  scope 27 {
-                      debug c => _40;
-                      let _41: *const usize;
-                      scope 28 {
-                          debug b2 => _41;
-                          let _42: usize;
-                          scope 29 {
-                              debug c2 => _42;
-                              let _43: *const usize;
-                              scope 30 {
-                                  debug b3 => _43;
-                              }
+      scope 19 {
+          debug a => _38;
+          let _39: *const usize;
+          scope 20 {
+              debug b1 => _39;
+              let _40: usize;
+              scope 21 {
+                  debug c => _40;
+                  let _41: *const usize;
+                  scope 22 {
+                      debug b2 => _41;
+                      let _42: usize;
+                      scope 23 {
+                          debug c2 => _42;
+                          let _43: *const usize;
+                          scope 24 {
+                              debug b3 => _43;
                           }
                       }
                   }
               }
           }
       }
-      scope 31 {
-          let _47: *const T;
-          scope 32 {
--             debug a => _47;
-+             debug a => _1;
-              let _48: T;
-              scope 33 {
-                  debug b => _48;
-              }
+      scope 25 {
+-         debug a => _47;
++         debug a => _1;
+          let _48: T;
+          scope 26 {
+              debug b => _48;
           }
       }
-      scope 34 {
-          let _52: *const T;
-          scope 35 {
-              debug a => _52;
-              let _54: T;
-              scope 36 {
-                  debug b => _54;
-              }
+      scope 27 {
+          debug a => _52;
+          let _54: T;
+          scope 28 {
+              debug b => _54;
           }
       }
-      scope 37 {
-          let _58: usize;
-          scope 38 {
-              debug a => _58;
-              let _59: *const usize;
-              scope 39 {
-                  debug b => _59;
-                  let _60: *const usize;
-                  scope 40 {
-                      debug c => _60;
-                      let _61: usize;
-                      scope 41 {
-                          debug e => _61;
-                      }
+      scope 29 {
+          debug a => _58;
+          let _59: *const usize;
+          scope 30 {
+              debug b => _59;
+              let _60: *const usize;
+              scope 31 {
+                  debug c => _60;
+                  let _61: usize;
+                  scope 32 {
+                      debug e => _61;
                   }
               }
           }
       }
-      scope 42 {
-          let _65: usize;
-          scope 43 {
-              debug a => _65;
-              let _66: *const usize;
-              scope 44 {
-                  debug b => _66;
-                  let _67: &*const usize;
-                  scope 45 {
-                      debug d => _67;
-                      let _68: usize;
-                      scope 46 {
-                          debug c => _68;
-                      }
+      scope 33 {
+          debug a => _65;
+          let _66: *const usize;
+          scope 34 {
+              debug b => _66;
+              let _67: &*const usize;
+              scope 35 {
+                  debug d => _67;
+                  let _68: usize;
+                  scope 36 {
+                      debug c => _68;
                   }
               }
           }
       }
-      scope 47 {
-          let _71: usize;
-          scope 48 {
-              debug a => _71;
-              let mut _72: *const usize;
-              scope 49 {
-                  debug b => _72;
-                  let _73: &mut *const usize;
-                  scope 50 {
-                      debug d => _73;
-                      let _74: usize;
-                      scope 51 {
-                          debug c => _74;
-                      }
+      scope 37 {
+          debug a => _71;
+          let mut _72: *const usize;
+          scope 38 {
+              debug b => _72;
+              let _73: &mut *const usize;
+              scope 39 {
+                  debug d => _73;
+                  let _74: usize;
+                  scope 40 {
+                      debug c => _74;
                   }
               }
           }
diff --git a/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
index b6b2acc0b43..5629d04f1b1 100644
--- a/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
@@ -6,197 +6,177 @@
       debug multiple => _2;
       let mut _0: ();
       let _3: ();
+      let mut _4: usize;
       let _7: ();
       let mut _8: ();
       let _9: ();
+      let mut _10: usize;
       let mut _13: *mut usize;
       let _15: ();
       let mut _16: ();
       let _17: ();
+      let mut _18: usize;
       let _22: ();
       let mut _23: &*mut usize;
       let _24: ();
+      let mut _25: usize;
       let _29: ();
       let mut _30: *mut *mut usize;
       let _31: ();
+      let mut _32: usize;
       let _35: ();
       let mut _36: *mut usize;
       let _37: ();
+      let mut _38: usize;
       let _44: ();
       let mut _45: *mut usize;
       let _46: ();
+      let _47: *mut T;
       let _49: ();
       let mut _50: ();
       let _51: ();
+      let _52: *mut T;
       let mut _53: *mut T;
       let _55: ();
       let mut _56: ();
       let _57: ();
+      let mut _58: usize;
       let _62: ();
       let mut _63: ();
+      let mut _64: usize;
       let _68: ();
       let mut _69: ();
       scope 1 {
-          let mut _4: usize;
+          debug a => _4;
+          let _5: *mut usize;
           scope 2 {
-              debug a => _4;
-              let _5: *mut usize;
+              debug b => _5;
+              let _6: usize;
               scope 3 {
-                  debug b => _5;
-                  let _6: usize;
-                  scope 4 {
-                      debug c => _6;
-                  }
+                  debug c => _6;
               }
           }
       }
-      scope 5 {
-          let mut _10: usize;
-          scope 6 {
-              debug a => _10;
-              let mut _11: usize;
-              scope 7 {
-                  debug a2 => _11;
-                  let mut _12: *mut usize;
-                  scope 8 {
-                      debug b => _12;
-                      let _14: usize;
-                      scope 9 {
-                          debug c => _14;
-                      }
+      scope 4 {
+          debug a => _10;
+          let mut _11: usize;
+          scope 5 {
+              debug a2 => _11;
+              let mut _12: *mut usize;
+              scope 6 {
+                  debug b => _12;
+                  let _14: usize;
+                  scope 7 {
+                      debug c => _14;
                   }
               }
           }
       }
-      scope 10 {
-          let mut _18: usize;
-          scope 11 {
-              debug a => _18;
-              let _19: *mut usize;
-              scope 12 {
-                  debug b => _19;
-                  let _20: &*mut usize;
-                  scope 13 {
-                      debug d => _20;
-                      let _21: usize;
-                      scope 14 {
-                          debug c => _21;
-                      }
+      scope 8 {
+          debug a => _18;
+          let _19: *mut usize;
+          scope 9 {
+              debug b => _19;
+              let _20: &*mut usize;
+              scope 10 {
+                  debug d => _20;
+                  let _21: usize;
+                  scope 11 {
+                      debug c => _21;
                   }
               }
           }
       }
-      scope 15 {
-          let mut _25: usize;
-          scope 16 {
-              debug a => _25;
-              let mut _26: *mut usize;
-              scope 17 {
-                  debug b => _26;
-                  let _27: *mut *mut usize;
-                  scope 18 {
-                      debug d => _27;
-                      let _28: usize;
-                      scope 19 {
-                          debug c => _28;
-                      }
+      scope 12 {
+          debug a => _25;
+          let mut _26: *mut usize;
+          scope 13 {
+              debug b => _26;
+              let _27: *mut *mut usize;
+              scope 14 {
+                  debug d => _27;
+                  let _28: usize;
+                  scope 15 {
+                      debug c => _28;
                   }
               }
           }
       }
-      scope 20 {
-          let mut _32: usize;
-          scope 21 {
-              debug a => _32;
-              let _33: *mut usize;
-              scope 22 {
-                  debug b => _33;
-                  let _34: usize;
-                  scope 23 {
-                      debug c => _34;
-                  }
+      scope 16 {
+          debug a => _32;
+          let _33: *mut usize;
+          scope 17 {
+              debug b => _33;
+              let _34: usize;
+              scope 18 {
+                  debug c => _34;
               }
           }
       }
-      scope 24 {
-          let mut _38: usize;
-          scope 25 {
-              debug a => _38;
-              let _39: *mut usize;
-              scope 26 {
-                  debug b1 => _39;
-                  let _40: usize;
-                  scope 27 {
-                      debug c => _40;
-                      let _41: *mut usize;
-                      scope 28 {
-                          debug b2 => _41;
-                          let _42: usize;
-                          scope 29 {
-                              debug c2 => _42;
-                              let _43: *mut usize;
-                              scope 30 {
-                                  debug b3 => _43;
-                              }
+      scope 19 {
+          debug a => _38;
+          let _39: *mut usize;
+          scope 20 {
+              debug b1 => _39;
+              let _40: usize;
+              scope 21 {
+                  debug c => _40;
+                  let _41: *mut usize;
+                  scope 22 {
+                      debug b2 => _41;
+                      let _42: usize;
+                      scope 23 {
+                          debug c2 => _42;
+                          let _43: *mut usize;
+                          scope 24 {
+                              debug b3 => _43;
                           }
                       }
                   }
               }
           }
       }
-      scope 31 {
-          let _47: *mut T;
-          scope 32 {
--             debug a => _47;
-+             debug a => _1;
-              let _48: T;
-              scope 33 {
-                  debug b => _48;
-              }
+      scope 25 {
+-         debug a => _47;
++         debug a => _1;
+          let _48: T;
+          scope 26 {
+              debug b => _48;
           }
       }
-      scope 34 {
-          let _52: *mut T;
-          scope 35 {
-              debug a => _52;
-              let _54: T;
-              scope 36 {
-                  debug b => _54;
-              }
+      scope 27 {
+          debug a => _52;
+          let _54: T;
+          scope 28 {
+              debug b => _54;
           }
       }
-      scope 37 {
-          let mut _58: usize;
-          scope 38 {
-              debug a => _58;
-              let _59: *mut usize;
-              scope 39 {
-                  debug b => _59;
-                  let _60: &*mut usize;
-                  scope 40 {
-                      debug d => _60;
-                      let _61: usize;
-                      scope 41 {
-                          debug c => _61;
-                      }
+      scope 29 {
+          debug a => _58;
+          let _59: *mut usize;
+          scope 30 {
+              debug b => _59;
+              let _60: &*mut usize;
+              scope 31 {
+                  debug d => _60;
+                  let _61: usize;
+                  scope 32 {
+                      debug c => _61;
                   }
               }
           }
       }
-      scope 42 {
-          let mut _64: usize;
-          scope 43 {
-              debug a => _64;
-              let mut _65: *mut usize;
-              scope 44 {
-                  debug b => _65;
-                  let _66: &mut *mut usize;
-                  scope 45 {
-                      debug d => _66;
-                      let _67: usize;
-                      scope 46 {
-                          debug c => _67;
-                      }
+      scope 33 {
+          debug a => _64;
+          let mut _65: *mut usize;
+          scope 34 {
+              debug b => _65;
+              let _66: &mut *mut usize;
+              scope 35 {
+                  debug d => _66;
+                  let _67: usize;
+                  scope 36 {
+                      debug c => _67;
                   }
               }
           }
diff --git a/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff b/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff
index b4912a918ba..a5427cea1f8 100644
--- a/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff
@@ -12,16 +12,12 @@
       scope 1 {
 -         debug y => _1;
 +         debug y => _3;
-          scope 5 {
-          }
       }
       scope 2 {
           debug a => _2;
           let _3: *mut i32;
           scope 3 {
               debug x => _3;
-              scope 4 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir
index 7124b4c1cd8..f9d58ea60a3 100644
--- a/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir
+++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir
@@ -36,22 +36,18 @@ fn array_casts() -> () {
             debug p => _2;
             let _8: [usize; 2];
             scope 3 {
-            }
-            scope 4 {
                 debug x => _8;
                 let _9: *const usize;
-                scope 5 {
+                scope 4 {
                     debug p => _9;
                     let _20: &usize;
                     let _21: &usize;
                     let mut _34: &usize;
-                    scope 6 {
-                    }
-                    scope 7 {
+                    scope 5 {
                         debug left_val => _20;
                         debug right_val => _21;
                         let _26: core::panicking::AssertKind;
-                        scope 8 {
+                        scope 6 {
                             debug kind => _26;
                         }
                     }
diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
index be04757f2a3..b0b70cd5d91 100644
--- a/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
+++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
@@ -36,22 +36,18 @@ fn array_casts() -> () {
             debug p => _2;
             let _8: [usize; 2];
             scope 3 {
-            }
-            scope 4 {
                 debug x => _8;
                 let _9: *const usize;
-                scope 5 {
+                scope 4 {
                     debug p => _9;
                     let _20: &usize;
                     let _21: &usize;
                     let mut _34: &usize;
-                    scope 6 {
-                    }
-                    scope 7 {
+                    scope 5 {
                         debug left_val => _20;
                         debug right_val => _21;
                         let _26: core::panicking::AssertKind;
-                        scope 8 {
+                        scope 6 {
                             debug kind => _26;
                         }
                     }
diff --git a/tests/mir-opt/simplify_dead_blocks.assert_nonzero_nonmax.SimplifyCfg-after-unreachable-enum-branching.diff b/tests/mir-opt/simplify_dead_blocks.assert_nonzero_nonmax.SimplifyCfg-after-unreachable-enum-branching.diff
new file mode 100644
index 00000000000..4400cfaef81
--- /dev/null
+++ b/tests/mir-opt/simplify_dead_blocks.assert_nonzero_nonmax.SimplifyCfg-after-unreachable-enum-branching.diff
@@ -0,0 +1,33 @@
+- // MIR for `assert_nonzero_nonmax` before SimplifyCfg-after-unreachable-enum-branching
++ // MIR for `assert_nonzero_nonmax` after SimplifyCfg-after-unreachable-enum-branching
+  
+  fn assert_nonzero_nonmax(_1: u8) -> u8 {
+      let mut _0: u8;
+  
+      bb0: {
+-         switchInt(_1) -> [0: bb3, 1: bb2, 255: bb3, otherwise: bb4];
++         switchInt(_1) -> [0: bb2, 1: bb1, 255: bb2, otherwise: bb3];
+      }
+  
+      bb1: {
+-         _0 = const 1_u8;
+-         return;
+-     }
+- 
+-     bb2: {
+          _0 = const 2_u8;
+          return;
+      }
+  
+-     bb3: {
++     bb2: {
+          unreachable;
+      }
+  
+-     bb4: {
++     bb3: {
+          _0 = _1;
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/simplify_dead_blocks.rs b/tests/mir-opt/simplify_dead_blocks.rs
new file mode 100644
index 00000000000..d4de85622d4
--- /dev/null
+++ b/tests/mir-opt/simplify_dead_blocks.rs
@@ -0,0 +1,52 @@
+//@ unit-test: SimplifyCfg-after-unreachable-enum-branching
+#![feature(custom_mir, core_intrinsics)]
+#![crate_type = "lib"]
+
+use std::intrinsics::mir::*;
+
+// Check that we correctly cleaned up the dead BB.
+// EMIT_MIR simplify_dead_blocks.assert_nonzero_nonmax.SimplifyCfg-after-unreachable-enum-branching.diff
+#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
+pub unsafe fn assert_nonzero_nonmax(x: u8) -> u8 {
+    // CHECK-LABEL: fn assert_nonzero_nonmax(
+    // CHECK: bb0: {
+    // CHECK-NEXT: switchInt({{.*}}) -> [0: [[unreachable:bb.*]], 1: [[retblock2:bb.*]], 255: [[unreachable:bb.*]], otherwise: [[retblock:bb.*]]];
+    // CHECK-NEXT: }
+    // CHECK-NOT: _0 = const 1_u8;
+    // CHECK: [[retblock2]]: {
+    // CHECK-NEXT: _0 = const 2_u8;
+    // CHECK-NEXT: return;
+    // CHECK-NEXT: }
+    // CHECK: [[unreachable]]: {
+    // CHECK-NEXT: unreachable;
+    // CHECK-NEXT: }
+    // CHECK: [[retblock]]: {
+    // CHECK-NEXT: _0 = _1;
+    // CHECK-NEXT: return;
+    // CHECK-NEXT: }
+    mir!(
+        {
+            match x {
+                0 => unreachable,
+                1 => retblock2,
+                u8::MAX => unreachable,
+                _ => retblock,
+            }
+        }
+        deadRetblock1 = {
+            RET = 1;
+            Return()
+        }
+        retblock2 = {
+            RET = 2;
+            Return()
+        }
+        unreachable = {
+            Unreachable()
+        }
+        retblock = {
+            RET = x;
+            Return()
+        }
+    )
+}
diff --git a/tests/mir-opt/simplify_duplicate_unreachable_blocks.assert_nonzero_nonmax.SimplifyCfg-after-uninhabited-enum-branching.diff b/tests/mir-opt/simplify_duplicate_unreachable_blocks.assert_nonzero_nonmax.SimplifyCfg-after-uninhabited-enum-branching.diff
deleted file mode 100644
index 35c0a4d45df..00000000000
--- a/tests/mir-opt/simplify_duplicate_unreachable_blocks.assert_nonzero_nonmax.SimplifyCfg-after-uninhabited-enum-branching.diff
+++ /dev/null
@@ -1,25 +0,0 @@
-- // MIR for `assert_nonzero_nonmax` before SimplifyCfg-after-uninhabited-enum-branching
-+ // MIR for `assert_nonzero_nonmax` after SimplifyCfg-after-uninhabited-enum-branching
-  
-  fn assert_nonzero_nonmax(_1: u8) -> u8 {
-      let mut _0: u8;
-  
-      bb0: {
--         switchInt(_1) -> [0: bb1, 255: bb2, otherwise: bb3];
-+         switchInt(_1) -> [0: bb1, 255: bb1, otherwise: bb2];
-      }
-  
-      bb1: {
-          unreachable;
-      }
-  
-      bb2: {
--         unreachable;
--     }
-- 
--     bb3: {
-          _0 = _1;
-          return;
-      }
-  }
-  
diff --git a/tests/mir-opt/simplify_duplicate_unreachable_blocks.rs b/tests/mir-opt/simplify_duplicate_unreachable_blocks.rs
deleted file mode 100644
index d94e6111855..00000000000
--- a/tests/mir-opt/simplify_duplicate_unreachable_blocks.rs
+++ /dev/null
@@ -1,31 +0,0 @@
-// skip-filecheck
-#![feature(custom_mir, core_intrinsics)]
-#![crate_type = "lib"]
-
-use std::intrinsics::mir::*;
-
-//@ unit-test: SimplifyCfg-after-uninhabited-enum-branching
-
-// EMIT_MIR simplify_duplicate_unreachable_blocks.assert_nonzero_nonmax.SimplifyCfg-after-uninhabited-enum-branching.diff
-#[custom_mir(dialect = "runtime", phase = "post-cleanup")]
-pub unsafe fn assert_nonzero_nonmax(x: u8) -> u8 {
-    mir!(
-        {
-            match x {
-                0 => unreachable1,
-                u8::MAX => unreachable2,
-                _ => retblock,
-            }
-        }
-        unreachable1 = {
-            Unreachable()
-        }
-        unreachable2 = {
-            Unreachable()
-        }
-        retblock = {
-            RET = x;
-            Return()
-        }
-    )
-}
diff --git a/tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.expose_provenance.SimplifyLocals-before-const-prop.diff
index 9ebee3df62c..cc5c642407e 100644
--- a/tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff
+++ b/tests/mir-opt/simplify_locals.expose_provenance.SimplifyLocals-before-const-prop.diff
@@ -1,7 +1,7 @@
-- // MIR for `expose_addr` before SimplifyLocals-before-const-prop
-+ // MIR for `expose_addr` after SimplifyLocals-before-const-prop
+- // MIR for `expose_provenance` before SimplifyLocals-before-const-prop
++ // MIR for `expose_provenance` after SimplifyLocals-before-const-prop
   
-  fn expose_addr(_1: *const usize) -> () {
+  fn expose_provenance(_1: *const usize) -> () {
       debug p => _1;
       let mut _0: ();
       let _2: usize;
@@ -11,7 +11,7 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = _1;
-          _2 = move _3 as usize (PointerExposeAddress);
+          _2 = move _3 as usize (PointerExposeProvenance);
           StorageDead(_3);
           StorageDead(_2);
           _0 = const ();
diff --git a/tests/mir-opt/simplify_locals.rs b/tests/mir-opt/simplify_locals.rs
index f95e9185f44..756679e77e3 100644
--- a/tests/mir-opt/simplify_locals.rs
+++ b/tests/mir-opt/simplify_locals.rs
@@ -63,8 +63,8 @@ fn t4() -> u32 {
     unsafe { X + 1 }
 }
 
-// EMIT_MIR simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff
-fn expose_addr(p: *const usize) {
+// EMIT_MIR simplify_locals.expose_provenance.SimplifyLocals-before-const-prop.diff
+fn expose_provenance(p: *const usize) {
     // Used pointer to address cast. Has a side effect of exposing the provenance.
     p as usize;
 }
@@ -78,5 +78,5 @@ fn main() {
     t2();
     t3();
     t4();
-    expose_addr(&0);
+    expose_provenance(&0);
 }
diff --git a/tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff
index a903e8d789e..526ff2f25cf 100644
--- a/tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff
+++ b/tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff
@@ -5,8 +5,6 @@
       let mut _0: ();
 -     let _1: u32;
 -     let mut _2: *mut u32;
-      scope 1 {
-      }
   
       bb0: {
 -         StorageLive(_1);
diff --git a/tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff
index e72e71a13a2..a88f6d40115 100644
--- a/tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff
+++ b/tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff
@@ -5,8 +5,6 @@
       let mut _0: ();
 -     let _1: &mut u32;
 -     let mut _2: *mut u32;
-      scope 1 {
-      }
   
       bb0: {
 -         StorageLive(_1);
diff --git a/tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff
index 37c367c82ca..5d45d7ac781 100644
--- a/tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff
+++ b/tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff
@@ -6,8 +6,6 @@
 -     let _1: u32;
 -     let mut _2: &mut u32;
 -     let mut _3: *mut u32;
-      scope 1 {
-      }
   
       bb0: {
 -         StorageLive(_1);
diff --git a/tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff
index 006e3c4232d..4f4855dbaaf 100644
--- a/tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff
+++ b/tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff
@@ -5,8 +5,6 @@
       let mut _0: u32;
       let mut _1: u32;
       let mut _2: *mut u32;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/sroa/structs.unions.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/structs.unions.ScalarReplacementOfAggregates.diff
index 6c99d3efd29..2f8dfcc5d63 100644
--- a/tests/mir-opt/sroa/structs.unions.ScalarReplacementOfAggregates.diff
+++ b/tests/mir-opt/sroa/structs.unions.ScalarReplacementOfAggregates.diff
@@ -6,8 +6,6 @@
       let mut _0: u32;
       let mut _2: unions::Repr;
       let mut _3: f32;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/tls_access.main.PreCodegen.after.mir b/tests/mir-opt/tls_access.main.PreCodegen.after.mir
index 43c7051f027..1c59e938423 100644
--- a/tests/mir-opt/tls_access.main.PreCodegen.after.mir
+++ b/tests/mir-opt/tls_access.main.PreCodegen.after.mir
@@ -3,12 +3,10 @@
 fn main() -> () {
     let mut _0: ();
     let _1: *mut u8;
+    let _2: &u8;
     let mut _3: *mut u8;
     scope 1 {
-        let _2: &u8;
-        scope 2 {
-            debug a => _2;
-        }
+        debug a => _2;
     }
 
     bb0: {
diff --git a/tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir b/tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir
index 89f7016fee4..240f409817d 100644
--- a/tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir
+++ b/tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir
@@ -7,8 +7,6 @@ fn process_never(_1: *const !) -> () {
     scope 1 {
         debug _input => _2;
     }
-    scope 2 {
-    }
 
     bb0: {
         unreachable;
diff --git a/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir b/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir
index 51905f982b8..51514ba5e5d 100644
--- a/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir
+++ b/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir
@@ -6,8 +6,6 @@ fn process_void(_1: *const Void) -> () {
     scope 1 {
         debug _input => _1;
     }
-    scope 2 {
-    }
 
     bb0: {
         return;
diff --git a/tests/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UnreachableEnumBranching.diff
index daff4f9c85b..098b620dfaa 100644
--- a/tests/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff
+++ b/tests/mir-opt/uninhabited_fallthrough_elimination.eliminate_fallthrough.UnreachableEnumBranching.diff
@@ -1,5 +1,5 @@
-- // MIR for `eliminate_fallthrough` before UninhabitedEnumBranching
-+ // MIR for `eliminate_fallthrough` after UninhabitedEnumBranching
+- // MIR for `eliminate_fallthrough` before UnreachableEnumBranching
++ // MIR for `eliminate_fallthrough` after UnreachableEnumBranching
   
   fn eliminate_fallthrough(_1: S) -> u32 {
       debug s => _1;
diff --git a/tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff b/tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UnreachableEnumBranching.diff
index 28a8c251d95..995e32b033f 100644
--- a/tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff
+++ b/tests/mir-opt/uninhabited_fallthrough_elimination.keep_fallthrough.UnreachableEnumBranching.diff
@@ -1,5 +1,5 @@
-- // MIR for `keep_fallthrough` before UninhabitedEnumBranching
-+ // MIR for `keep_fallthrough` after UninhabitedEnumBranching
+- // MIR for `keep_fallthrough` before UnreachableEnumBranching
++ // MIR for `keep_fallthrough` after UnreachableEnumBranching
   
   fn keep_fallthrough(_1: S) -> u32 {
       debug s => _1;
diff --git a/tests/mir-opt/uninhabited_fallthrough_elimination.rs b/tests/mir-opt/uninhabited_fallthrough_elimination.rs
index 7dd41aea5ed..537935d8ae4 100644
--- a/tests/mir-opt/uninhabited_fallthrough_elimination.rs
+++ b/tests/mir-opt/uninhabited_fallthrough_elimination.rs
@@ -9,7 +9,7 @@ enum S {
 
 use S::*;
 
-// EMIT_MIR uninhabited_fallthrough_elimination.keep_fallthrough.UninhabitedEnumBranching.diff
+// EMIT_MIR uninhabited_fallthrough_elimination.keep_fallthrough.UnreachableEnumBranching.diff
 fn keep_fallthrough(s: S) -> u32 {
     match s {
         A(_) => 1,
@@ -18,7 +18,7 @@ fn keep_fallthrough(s: S) -> u32 {
     }
 }
 
-// EMIT_MIR uninhabited_fallthrough_elimination.eliminate_fallthrough.UninhabitedEnumBranching.diff
+// EMIT_MIR uninhabited_fallthrough_elimination.eliminate_fallthrough.UnreachableEnumBranching.diff
 fn eliminate_fallthrough(s: S) -> u32 {
     match s {
         C => 1,
diff --git a/tests/mir-opt/unnamed-fields/field_access.bar.SimplifyCfg-initial.after.mir b/tests/mir-opt/unnamed-fields/field_access.bar.SimplifyCfg-initial.after.mir
index 8edc7b5df88..f0311422c17 100644
--- a/tests/mir-opt/unnamed-fields/field_access.bar.SimplifyCfg-initial.after.mir
+++ b/tests/mir-opt/unnamed-fields/field_access.bar.SimplifyCfg-initial.after.mir
@@ -11,8 +11,6 @@ fn bar(_1: Bar) -> () {
     let mut _7: bool;
     let _8: ();
     let mut _9: [u8; 1];
-    scope 1 {
-    }
 
     bb0: {
         StorageLive(_2);
diff --git a/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.byref.UnreachableEnumBranching.panic-abort.diff
index 1b7517c8d01..e5dab5d52a6 100644
--- a/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-abort.diff
+++ b/tests/mir-opt/unreachable_enum_branching.byref.UnreachableEnumBranching.panic-abort.diff
@@ -1,5 +1,5 @@
-- // MIR for `byref` before UninhabitedEnumBranching
-+ // MIR for `byref` after UninhabitedEnumBranching
+- // MIR for `byref` before UnreachableEnumBranching
++ // MIR for `byref` after UnreachableEnumBranching
   
   fn byref() -> () {
       let mut _0: ();
diff --git a/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.byref.UnreachableEnumBranching.panic-unwind.diff
index 1b7517c8d01..e5dab5d52a6 100644
--- a/tests/mir-opt/uninhabited_enum_branching.byref.UninhabitedEnumBranching.panic-unwind.diff
+++ b/tests/mir-opt/unreachable_enum_branching.byref.UnreachableEnumBranching.panic-unwind.diff
@@ -1,5 +1,5 @@
-- // MIR for `byref` before UninhabitedEnumBranching
-+ // MIR for `byref` after UninhabitedEnumBranching
+- // MIR for `byref` before UnreachableEnumBranching
++ // MIR for `byref` after UnreachableEnumBranching
   
   fn byref() -> () {
       let mut _0: ();
diff --git a/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.panic-abort.diff
index f9a43480917..ea6cdbfbe66 100644
--- a/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-abort.diff
+++ b/tests/mir-opt/unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.panic-abort.diff
@@ -1,5 +1,5 @@
-- // MIR for `custom_discriminant` before UninhabitedEnumBranching
-+ // MIR for `custom_discriminant` after UninhabitedEnumBranching
+- // MIR for `custom_discriminant` before UnreachableEnumBranching
++ // MIR for `custom_discriminant` after UnreachableEnumBranching
   
   fn custom_discriminant() -> () {
       let mut _0: ();
diff --git a/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.panic-unwind.diff
index f9a43480917..ea6cdbfbe66 100644
--- a/tests/mir-opt/uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.panic-unwind.diff
+++ b/tests/mir-opt/unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.panic-unwind.diff
@@ -1,5 +1,5 @@
-- // MIR for `custom_discriminant` before UninhabitedEnumBranching
-+ // MIR for `custom_discriminant` after UninhabitedEnumBranching
+- // MIR for `custom_discriminant` before UnreachableEnumBranching
++ // MIR for `custom_discriminant` after UnreachableEnumBranching
   
   fn custom_discriminant() -> () {
       let mut _0: ();
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.panic-abort.diff
index 383fde4d787..02b9f02f4c0 100644
--- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.panic-abort.diff
+++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.panic-abort.diff
@@ -1,5 +1,5 @@
-- // MIR for `otherwise_t1` before UninhabitedEnumBranching
-+ // MIR for `otherwise_t1` after UninhabitedEnumBranching
+- // MIR for `otherwise_t1` before UnreachableEnumBranching
++ // MIR for `otherwise_t1` after UnreachableEnumBranching
   
   fn otherwise_t1() -> () {
       let mut _0: ();
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.panic-unwind.diff
index 383fde4d787..02b9f02f4c0 100644
--- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.panic-unwind.diff
+++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.panic-unwind.diff
@@ -1,5 +1,5 @@
-- // MIR for `otherwise_t1` before UninhabitedEnumBranching
-+ // MIR for `otherwise_t1` after UninhabitedEnumBranching
+- // MIR for `otherwise_t1` before UnreachableEnumBranching
++ // MIR for `otherwise_t1` after UnreachableEnumBranching
   
   fn otherwise_t1() -> () {
       let mut _0: ();
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.panic-abort.diff
index 3a2dc19db71..a6d6e0861b1 100644
--- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.panic-abort.diff
+++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.panic-abort.diff
@@ -1,5 +1,5 @@
-- // MIR for `otherwise_t2` before UninhabitedEnumBranching
-+ // MIR for `otherwise_t2` after UninhabitedEnumBranching
+- // MIR for `otherwise_t2` before UnreachableEnumBranching
++ // MIR for `otherwise_t2` after UnreachableEnumBranching
   
   fn otherwise_t2() -> () {
       let mut _0: ();
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.panic-unwind.diff
index 3a2dc19db71..a6d6e0861b1 100644
--- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.panic-unwind.diff
+++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.panic-unwind.diff
@@ -1,5 +1,5 @@
-- // MIR for `otherwise_t2` before UninhabitedEnumBranching
-+ // MIR for `otherwise_t2` after UninhabitedEnumBranching
+- // MIR for `otherwise_t2` before UnreachableEnumBranching
++ // MIR for `otherwise_t2` after UnreachableEnumBranching
   
   fn otherwise_t2() -> () {
       let mut _0: ();
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.panic-abort.diff
index 5dc1e2b73f6..d3376442376 100644
--- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.panic-abort.diff
+++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.panic-abort.diff
@@ -1,5 +1,5 @@
-- // MIR for `otherwise_t3` before UninhabitedEnumBranching
-+ // MIR for `otherwise_t3` after UninhabitedEnumBranching
+- // MIR for `otherwise_t3` before UnreachableEnumBranching
++ // MIR for `otherwise_t3` after UnreachableEnumBranching
   
   fn otherwise_t3() -> () {
       let mut _0: ();
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.panic-unwind.diff
index 5dc1e2b73f6..d3376442376 100644
--- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.panic-unwind.diff
+++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.panic-unwind.diff
@@ -1,5 +1,5 @@
-- // MIR for `otherwise_t3` before UninhabitedEnumBranching
-+ // MIR for `otherwise_t3` after UninhabitedEnumBranching
+- // MIR for `otherwise_t3` before UnreachableEnumBranching
++ // MIR for `otherwise_t3` after UnreachableEnumBranching
   
   fn otherwise_t3() -> () {
       let mut _0: ();
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.panic-abort.diff
index 1352dda4971..8f0d5b7cd99 100644
--- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.panic-abort.diff
+++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.panic-abort.diff
@@ -1,5 +1,5 @@
-- // MIR for `otherwise_t4` before UninhabitedEnumBranching
-+ // MIR for `otherwise_t4` after UninhabitedEnumBranching
+- // MIR for `otherwise_t4` before UnreachableEnumBranching
++ // MIR for `otherwise_t4` after UnreachableEnumBranching
   
   fn otherwise_t4() -> () {
       let mut _0: ();
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.panic-unwind.diff
index 1352dda4971..8f0d5b7cd99 100644
--- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.panic-unwind.diff
+++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.panic-unwind.diff
@@ -1,5 +1,5 @@
-- // MIR for `otherwise_t4` before UninhabitedEnumBranching
-+ // MIR for `otherwise_t4` after UninhabitedEnumBranching
+- // MIR for `otherwise_t4` before UnreachableEnumBranching
++ // MIR for `otherwise_t4` after UnreachableEnumBranching
   
   fn otherwise_t4() -> () {
       let mut _0: ();
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.panic-abort.diff
index 40dd961fbac..b1ecd008582 100644
--- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.panic-abort.diff
+++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.panic-abort.diff
@@ -1,7 +1,7 @@
-- // MIR for `otherwise_t4_uninhabited_default` before UninhabitedEnumBranching
-+ // MIR for `otherwise_t4_uninhabited_default` after UninhabitedEnumBranching
+- // MIR for `otherwise_t4_unreachable_default` before UnreachableEnumBranching
++ // MIR for `otherwise_t4_unreachable_default` after UnreachableEnumBranching
   
-  fn otherwise_t4_uninhabited_default() -> () {
+  fn otherwise_t4_unreachable_default() -> () {
       let mut _0: ();
       let _1: &str;
       let mut _2: Test4;
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.panic-unwind.diff
index 40dd961fbac..b1ecd008582 100644
--- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.panic-unwind.diff
+++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.panic-unwind.diff
@@ -1,7 +1,7 @@
-- // MIR for `otherwise_t4_uninhabited_default` before UninhabitedEnumBranching
-+ // MIR for `otherwise_t4_uninhabited_default` after UninhabitedEnumBranching
+- // MIR for `otherwise_t4_unreachable_default` before UnreachableEnumBranching
++ // MIR for `otherwise_t4_unreachable_default` after UnreachableEnumBranching
   
-  fn otherwise_t4_uninhabited_default() -> () {
+  fn otherwise_t4_unreachable_default() -> () {
       let mut _0: ();
       let _1: &str;
       let mut _2: Test4;
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.panic-abort.diff
index ac39f6be6c6..28c6d4fb675 100644
--- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.panic-abort.diff
+++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.panic-abort.diff
@@ -1,7 +1,7 @@
-- // MIR for `otherwise_t4_uninhabited_default_2` before UninhabitedEnumBranching
-+ // MIR for `otherwise_t4_uninhabited_default_2` after UninhabitedEnumBranching
+- // MIR for `otherwise_t4_unreachable_default_2` before UnreachableEnumBranching
++ // MIR for `otherwise_t4_unreachable_default_2` after UnreachableEnumBranching
   
-  fn otherwise_t4_uninhabited_default_2() -> () {
+  fn otherwise_t4_unreachable_default_2() -> () {
       let mut _0: ();
       let _1: &str;
       let mut _2: Test4;
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.panic-unwind.diff
index ac39f6be6c6..28c6d4fb675 100644
--- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.panic-unwind.diff
+++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.panic-unwind.diff
@@ -1,7 +1,7 @@
-- // MIR for `otherwise_t4_uninhabited_default_2` before UninhabitedEnumBranching
-+ // MIR for `otherwise_t4_uninhabited_default_2` after UninhabitedEnumBranching
+- // MIR for `otherwise_t4_unreachable_default_2` before UnreachableEnumBranching
++ // MIR for `otherwise_t4_unreachable_default_2` after UnreachableEnumBranching
   
-  fn otherwise_t4_uninhabited_default_2() -> () {
+  fn otherwise_t4_unreachable_default_2() -> () {
       let mut _0: ();
       let _1: &str;
       let mut _2: Test4;
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.panic-abort.diff
index 8180428a6f4..f36a7efd80d 100644
--- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.panic-abort.diff
+++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.panic-abort.diff
@@ -1,7 +1,7 @@
-- // MIR for `otherwise_t5_uninhabited_default` before UninhabitedEnumBranching
-+ // MIR for `otherwise_t5_uninhabited_default` after UninhabitedEnumBranching
+- // MIR for `otherwise_t5_unreachable_default` before UnreachableEnumBranching
++ // MIR for `otherwise_t5_unreachable_default` after UnreachableEnumBranching
   
-  fn otherwise_t5_uninhabited_default() -> () {
+  fn otherwise_t5_unreachable_default() -> () {
       let mut _0: ();
       let _1: &str;
       let mut _2: Test5<T>;
diff --git a/tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.panic-unwind.diff
index b13d5816aed..20e31c24c84 100644
--- a/tests/mir-opt/uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.panic-unwind.diff
+++ b/tests/mir-opt/unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.panic-unwind.diff
@@ -1,7 +1,7 @@
-- // MIR for `otherwise_t5_uninhabited_default` before UninhabitedEnumBranching
-+ // MIR for `otherwise_t5_uninhabited_default` after UninhabitedEnumBranching
+- // MIR for `otherwise_t5_unreachable_default` before UnreachableEnumBranching
++ // MIR for `otherwise_t5_unreachable_default` after UnreachableEnumBranching
   
-  fn otherwise_t5_uninhabited_default() -> () {
+  fn otherwise_t5_unreachable_default() -> () {
       let mut _0: ();
       let _1: &str;
       let mut _2: Test5<T>;
diff --git a/tests/mir-opt/uninhabited_enum_branching.rs b/tests/mir-opt/unreachable_enum_branching.rs
index 6de001be979..156b23657b7 100644
--- a/tests/mir-opt/uninhabited_enum_branching.rs
+++ b/tests/mir-opt/unreachable_enum_branching.rs
@@ -1,4 +1,4 @@
-//@ unit-test: UninhabitedEnumBranching
+//@ unit-test: UnreachableEnumBranching
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 
 enum Empty {}
@@ -45,7 +45,7 @@ struct Plop {
     test3: Test3,
 }
 
-// EMIT_MIR uninhabited_enum_branching.simple.UninhabitedEnumBranching.diff
+// EMIT_MIR unreachable_enum_branching.simple.UnreachableEnumBranching.diff
 fn simple() {
     // CHECK-LABEL: fn simple(
     // CHECK: [[discr:_.*]] = discriminant(
@@ -59,7 +59,7 @@ fn simple() {
     };
 }
 
-// EMIT_MIR uninhabited_enum_branching.custom_discriminant.UninhabitedEnumBranching.diff
+// EMIT_MIR unreachable_enum_branching.custom_discriminant.UnreachableEnumBranching.diff
 fn custom_discriminant() {
     // CHECK-LABEL: fn custom_discriminant(
     // CHECK: [[discr:_.*]] = discriminant(
@@ -72,7 +72,7 @@ fn custom_discriminant() {
     };
 }
 
-// EMIT_MIR uninhabited_enum_branching.otherwise_t1.UninhabitedEnumBranching.diff
+// EMIT_MIR unreachable_enum_branching.otherwise_t1.UnreachableEnumBranching.diff
 fn otherwise_t1() {
     // CHECK-LABEL: fn otherwise_t1(
     // CHECK: [[discr:_.*]] = discriminant(
@@ -86,7 +86,7 @@ fn otherwise_t1() {
     };
 }
 
-// EMIT_MIR uninhabited_enum_branching.otherwise_t2.UninhabitedEnumBranching.diff
+// EMIT_MIR unreachable_enum_branching.otherwise_t2.UnreachableEnumBranching.diff
 fn otherwise_t2() {
     // CHECK-LABEL: fn otherwise_t2(
     // CHECK: [[discr:_.*]] = discriminant(
@@ -99,7 +99,7 @@ fn otherwise_t2() {
     };
 }
 
-// EMIT_MIR uninhabited_enum_branching.otherwise_t3.UninhabitedEnumBranching.diff
+// EMIT_MIR unreachable_enum_branching.otherwise_t3.UnreachableEnumBranching.diff
 fn otherwise_t3() {
     // CHECK-LABEL: fn otherwise_t3(
     // CHECK: [[discr:_.*]] = discriminant(
@@ -116,9 +116,9 @@ fn otherwise_t3() {
     };
 }
 
-// EMIT_MIR uninhabited_enum_branching.otherwise_t4_uninhabited_default.UninhabitedEnumBranching.diff
-fn otherwise_t4_uninhabited_default() {
-    // CHECK-LABEL: fn otherwise_t4_uninhabited_default(
+// EMIT_MIR unreachable_enum_branching.otherwise_t4_unreachable_default.UnreachableEnumBranching.diff
+fn otherwise_t4_unreachable_default() {
+    // CHECK-LABEL: fn otherwise_t4_unreachable_default(
     // CHECK: [[discr:_.*]] = discriminant(
     // CHECK: switchInt(move [[discr]]) -> [0: bb2, 1: bb3, 2: bb4, 3: bb1, otherwise: [[unreachable:bb.*]]];
     // CHECK: [[unreachable]]: {
@@ -131,9 +131,9 @@ fn otherwise_t4_uninhabited_default() {
     };
 }
 
-// EMIT_MIR uninhabited_enum_branching.otherwise_t4_uninhabited_default_2.UninhabitedEnumBranching.diff
-fn otherwise_t4_uninhabited_default_2() {
-    // CHECK-LABEL: fn otherwise_t4_uninhabited_default_2(
+// EMIT_MIR unreachable_enum_branching.otherwise_t4_unreachable_default_2.UnreachableEnumBranching.diff
+fn otherwise_t4_unreachable_default_2() {
+    // CHECK-LABEL: fn otherwise_t4_unreachable_default_2(
     // CHECK: [[discr:_.*]] = discriminant(
     // CHECK: switchInt(move [[discr]]) -> [0: bb2, 1: bb5, 2: bb6, 3: bb1, otherwise: [[unreachable:bb.*]]];
     // CHECK: [[unreachable]]: {
@@ -147,7 +147,7 @@ fn otherwise_t4_uninhabited_default_2() {
     };
 }
 
-// EMIT_MIR uninhabited_enum_branching.otherwise_t4.UninhabitedEnumBranching.diff
+// EMIT_MIR unreachable_enum_branching.otherwise_t4.UnreachableEnumBranching.diff
 fn otherwise_t4() {
     // CHECK-LABEL: fn otherwise_t4(
     // CHECK: [[discr:_.*]] = discriminant(
@@ -162,9 +162,9 @@ fn otherwise_t4() {
     };
 }
 
-// EMIT_MIR uninhabited_enum_branching.otherwise_t5_uninhabited_default.UninhabitedEnumBranching.diff
-fn otherwise_t5_uninhabited_default<T>() {
-    // CHECK-LABEL: fn otherwise_t5_uninhabited_default(
+// EMIT_MIR unreachable_enum_branching.otherwise_t5_unreachable_default.UnreachableEnumBranching.diff
+fn otherwise_t5_unreachable_default<T>() {
+    // CHECK-LABEL: fn otherwise_t5_unreachable_default(
     // CHECK: [[discr:_.*]] = discriminant(
     // CHECK: switchInt(move [[discr]]) -> [255: bb2, 0: bb3, 5: bb4, 3: bb1, otherwise: [[unreachable:bb.*]]];
     // CHECK: [[unreachable]]: {
@@ -177,7 +177,7 @@ fn otherwise_t5_uninhabited_default<T>() {
     };
 }
 
-// EMIT_MIR uninhabited_enum_branching.byref.UninhabitedEnumBranching.diff
+// EMIT_MIR unreachable_enum_branching.byref.UnreachableEnumBranching.diff
 fn byref() {
     // CHECK-LABEL: fn byref(
     let plop = Plop { xx: 51, test3: Test3::C };
@@ -210,9 +210,9 @@ fn main() {
     otherwise_t1();
     otherwise_t2();
     otherwise_t3();
-    otherwise_t4_uninhabited_default();
-    otherwise_t4_uninhabited_default_2();
+    otherwise_t4_unreachable_default();
+    otherwise_t4_unreachable_default_2();
     otherwise_t4();
-    otherwise_t5_uninhabited_default::<i32>();
+    otherwise_t5_unreachable_default::<i32>();
     byref();
 }
diff --git a/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-abort.diff b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff
index 674d3a25504..a85fc0da992 100644
--- a/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-abort.diff
+++ b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-abort.diff
@@ -1,5 +1,5 @@
-- // MIR for `simple` before UninhabitedEnumBranching
-+ // MIR for `simple` after UninhabitedEnumBranching
+- // MIR for `simple` before UnreachableEnumBranching
++ // MIR for `simple` after UnreachableEnumBranching
   
   fn simple() -> () {
       let mut _0: ();
diff --git a/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-unwind.diff b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff
index 674d3a25504..a85fc0da992 100644
--- a/tests/mir-opt/uninhabited_enum_branching.simple.UninhabitedEnumBranching.panic-unwind.diff
+++ b/tests/mir-opt/unreachable_enum_branching.simple.UnreachableEnumBranching.panic-unwind.diff
@@ -1,5 +1,5 @@
-- // MIR for `simple` before UninhabitedEnumBranching
-+ // MIR for `simple` after UninhabitedEnumBranching
+- // MIR for `simple` before UnreachableEnumBranching
++ // MIR for `simple` after UnreachableEnumBranching
   
   fn simple() -> () {
       let mut _0: ();
diff --git a/tests/ui/abi/extern/extern-pass-FiveU16s.rs b/tests/ui/abi/extern/extern-pass-FiveU16s.rs
new file mode 100644
index 00000000000..5f1307beb28
--- /dev/null
+++ b/tests/ui/abi/extern/extern-pass-FiveU16s.rs
@@ -0,0 +1,30 @@
+//@ run-pass
+#![allow(improper_ctypes)]
+
+// Test a foreign function that accepts and returns a struct by value.
+
+// FiveU16s in particular is interesting because it is larger than a single 64 bit or 32 bit
+// register, which are used as cast destinations on some targets, but does not evenly divide those
+// sizes, causing there to be padding in the last element.
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub struct FiveU16s {
+    one: u16,
+    two: u16,
+    three: u16,
+    four: u16,
+    five: u16,
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern "C" {
+    pub fn rust_dbg_extern_identity_FiveU16s(v: FiveU16s) -> FiveU16s;
+}
+
+pub fn main() {
+    unsafe {
+        let x = FiveU16s { one: 22, two: 23, three: 24, four: 25, five: 26 };
+        let y = rust_dbg_extern_identity_FiveU16s(x);
+        assert_eq!(x, y);
+    }
+}
diff --git a/tests/ui/abi/extern/extern-return-FiveU16s.rs b/tests/ui/abi/extern/extern-return-FiveU16s.rs
new file mode 100644
index 00000000000..d8ae8b2661c
--- /dev/null
+++ b/tests/ui/abi/extern/extern-return-FiveU16s.rs
@@ -0,0 +1,26 @@
+//@ run-pass
+#![allow(improper_ctypes)]
+
+pub struct FiveU16s {
+    one: u16,
+    two: u16,
+    three: u16,
+    four: u16,
+    five: u16,
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern "C" {
+    pub fn rust_dbg_extern_return_FiveU16s() -> FiveU16s;
+}
+
+pub fn main() {
+    unsafe {
+        let y = rust_dbg_extern_return_FiveU16s();
+        assert_eq!(y.one, 10);
+        assert_eq!(y.two, 20);
+        assert_eq!(y.three, 30);
+        assert_eq!(y.four, 40);
+        assert_eq!(y.five, 50);
+    }
+}
diff --git a/tests/ui/asm/x86_64/goto.mirunsafeck.stderr b/tests/ui/asm/x86_64/goto.mirunsafeck.stderr
deleted file mode 100644
index fe189c14f0a..00000000000
--- a/tests/ui/asm/x86_64/goto.mirunsafeck.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-warning: unreachable statement
-  --> $DIR/goto.rs:99:9
-   |
-LL | /         asm!(
-LL | |             "jmp {}",
-LL | |             label {
-LL | |                 return;
-LL | |             },
-LL | |             options(noreturn)
-LL | |         );
-   | |_________- any code following this expression is unreachable
-LL |           unreachable!();
-   |           ^^^^^^^^^^^^^^ unreachable statement
-   |
-note: the lint level is defined here
-  --> $DIR/goto.rs:89:8
-   |
-LL | #[warn(unreachable_code)]
-   |        ^^^^^^^^^^^^^^^^
-   = note: this warning originates in the macro `unreachable` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/asm/x86_64/goto.rs b/tests/ui/asm/x86_64/goto.rs
index 6a567efbb2c..6c14bb57ac6 100644
--- a/tests/ui/asm/x86_64/goto.rs
+++ b/tests/ui/asm/x86_64/goto.rs
@@ -1,8 +1,6 @@
 //@ only-x86_64
 //@ run-pass
 //@ needs-asm-support
-//@ revisions: mirunsafeck thirunsafeck
-//@ [thirunsafeck]compile-flags: -Z thir-unsafeck
 
 #![deny(unreachable_code)]
 #![feature(asm_goto)]
diff --git a/tests/ui/asm/x86_64/goto.thirunsafeck.stderr b/tests/ui/asm/x86_64/goto.stderr
index fe189c14f0a..27e227d71a5 100644
--- a/tests/ui/asm/x86_64/goto.thirunsafeck.stderr
+++ b/tests/ui/asm/x86_64/goto.stderr
@@ -1,5 +1,5 @@
 warning: unreachable statement
-  --> $DIR/goto.rs:99:9
+  --> $DIR/goto.rs:97:9
    |
 LL | /         asm!(
 LL | |             "jmp {}",
@@ -13,7 +13,7 @@ LL |           unreachable!();
    |           ^^^^^^^^^^^^^^ unreachable statement
    |
 note: the lint level is defined here
-  --> $DIR/goto.rs:89:8
+  --> $DIR/goto.rs:87:8
    |
 LL | #[warn(unreachable_code)]
    |        ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/async-await/async-closures/captures.rs b/tests/ui/async-await/async-closures/captures.rs
new file mode 100644
index 00000000000..e3ab8713709
--- /dev/null
+++ b/tests/ui/async-await/async-closures/captures.rs
@@ -0,0 +1,82 @@
+//@ aux-build:block-on.rs
+//@ edition:2021
+//@ run-pass
+//@ check-run-results
+
+// Same as miri's `tests/pass/async-closure-captures.rs`, keep in sync
+
+#![feature(async_closure)]
+
+extern crate block_on;
+
+fn main() {
+    block_on::block_on(async_main());
+}
+
+async fn call<T>(f: &impl async Fn() -> T) -> T {
+    f().await
+}
+
+async fn call_once<T>(f: impl async FnOnce() -> T) -> T {
+    f().await
+}
+
+#[derive(Debug)]
+#[allow(unused)]
+struct Hello(i32);
+
+async fn async_main() {
+    // Capture something by-ref
+    {
+        let x = Hello(0);
+        let c = async || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+
+        let x = &Hello(1);
+        let c = async || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+    }
+
+    // Capture something and consume it (force to `AsyncFnOnce`)
+    {
+        let x = Hello(2);
+        let c = async || {
+            println!("{x:?}");
+            drop(x);
+        };
+        call_once(c).await;
+    }
+
+    // Capture something with `move`, don't consume it
+    {
+        let x = Hello(3);
+        let c = async move || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+
+        let x = &Hello(4);
+        let c = async move || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+    }
+
+    // Capture something with `move`, also consume it (so `AsyncFnOnce`)
+    {
+        let x = Hello(5);
+        let c = async move || {
+            println!("{x:?}");
+            drop(x);
+        };
+        call_once(c).await;
+    }
+}
diff --git a/tests/ui/async-await/async-closures/captures.run.stdout b/tests/ui/async-await/async-closures/captures.run.stdout
new file mode 100644
index 00000000000..a0db6d236fe
--- /dev/null
+++ b/tests/ui/async-await/async-closures/captures.run.stdout
@@ -0,0 +1,10 @@
+Hello(0)
+Hello(0)
+Hello(1)
+Hello(1)
+Hello(2)
+Hello(3)
+Hello(3)
+Hello(4)
+Hello(4)
+Hello(5)
diff --git a/tests/ui/async-await/coroutine-desc.stderr b/tests/ui/async-await/coroutine-desc.stderr
index e4cb0915a10..1f1e303ea4c 100644
--- a/tests/ui/async-await/coroutine-desc.stderr
+++ b/tests/ui/async-await/coroutine-desc.stderr
@@ -5,6 +5,7 @@ LL |     fun(async {}, async {});
    |     --- --------  ^^^^^^^^ expected `async` block, found a different `async` block
    |     |   |
    |     |   the expected `async` block
+   |     |   expected all arguments to be this `async` block type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected `async` block `{async block@$DIR/coroutine-desc.rs:10:9: 10:17}`
@@ -13,14 +14,18 @@ note: function defined here
   --> $DIR/coroutine-desc.rs:8:4
    |
 LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
-   |    ^^^                                -----
+   |    ^^^ -                       -----  ----- this parameter needs to match the `async` block type of `f1`
+   |        |                       |
+   |        |                       `f2` needs to match the `async` block type of this parameter
+   |        `f1` and `f2` all reference this parameter F
 
 error[E0308]: mismatched types
   --> $DIR/coroutine-desc.rs:12:16
    |
 LL |     fun(one(), two());
-   |     ---        ^^^^^ expected future, found a different future
-   |     |
+   |     --- -----  ^^^^^ expected future, found a different future
+   |     |   |
+   |     |   expected all arguments to be this future type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = help: consider `await`ing on both `Future`s
@@ -29,15 +34,19 @@ note: function defined here
   --> $DIR/coroutine-desc.rs:8:4
    |
 LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
-   |    ^^^                                -----
+   |    ^^^ -                       -----  ----- this parameter needs to match the future type of `f1`
+   |        |                       |
+   |        |                       `f2` needs to match the future type of this parameter
+   |        `f1` and `f2` all reference this parameter F
 
 error[E0308]: mismatched types
   --> $DIR/coroutine-desc.rs:14:26
    |
 LL |     fun((async || {})(), (async || {})());
-   |     ---           --     ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body
-   |     |             |
-   |     |             the expected `async` closure body
+   |     --- ---------------  ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body
+   |     |   |         |
+   |     |   |         the expected `async` closure body
+   |     |   expected all arguments to be this `async` closure body type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected `async` closure body `{async closure body@$DIR/coroutine-desc.rs:14:19: 14:21}`
@@ -46,7 +55,10 @@ note: function defined here
   --> $DIR/coroutine-desc.rs:8:4
    |
 LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
-   |    ^^^                                -----
+   |    ^^^ -                       -----  ----- this parameter needs to match the `async` closure body type of `f1`
+   |        |                       |
+   |        |                       `f2` needs to match the `async` closure body type of this parameter
+   |        `f1` and `f2` all reference this parameter F
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/issues/issue-1460.rs b/tests/ui/closures/issue-1460.rs
index c201f026bca..c201f026bca 100644
--- a/tests/ui/issues/issue-1460.rs
+++ b/tests/ui/closures/issue-1460.rs
diff --git a/tests/ui/issues/issue-1460.stderr b/tests/ui/closures/issue-1460.stderr
index d4a8c8955e2..d4a8c8955e2 100644
--- a/tests/ui/issues/issue-1460.stderr
+++ b/tests/ui/closures/issue-1460.stderr
diff --git a/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr b/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
index 498ef33d52e..46723c5a297 100644
--- a/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
+++ b/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
@@ -2,8 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/coerce-reborrow-multi-arg-fail.rs:4:18
    |
 LL |     test(&mut 7, &7);
-   |     ----         ^^ types differ in mutability
-   |     |
+   |     ---- ------  ^^ types differ in mutability
+   |     |    |
+   |     |    expected all arguments to be this `&mut {integer}` type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected mutable reference `&mut {integer}`
@@ -12,7 +13,10 @@ note: function defined here
   --> $DIR/coerce-reborrow-multi-arg-fail.rs:1:4
    |
 LL | fn test<T>(_a: T, _b: T) {}
-   |    ^^^^           -----
+   |    ^^^^ -  -----  ----- this parameter needs to match the `&mut {integer}` type of `_a`
+   |         |  |
+   |         |  `_b` needs to match the `&mut {integer}` type of this parameter
+   |         `_a` and `_b` all reference this parameter T
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/fn/fn-item-type.stderr b/tests/ui/fn/fn-item-type.stderr
index da90b8b81c8..76cdbcceac8 100644
--- a/tests/ui/fn/fn-item-type.stderr
+++ b/tests/ui/fn/fn-item-type.stderr
@@ -2,8 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:22:19
    |
 LL |     eq(foo::<u8>, bar::<u8>);
-   |     --            ^^^^^^^^^ expected fn item, found a different fn item
-   |     |
+   |     -- ---------  ^^^^^^^^^ expected fn item, found a different fn item
+   |     |  |
+   |     |  expected all arguments to be this fn item type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected fn item `fn(_) -> _ {foo::<u8>}`
@@ -13,15 +14,19 @@ note: function defined here
   --> $DIR/fn-item-type.rs:11:4
    |
 LL | fn eq<T>(x: T, y: T) {}
-   |    ^^          ----
+   |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
+   |       |  |
+   |       |  `y` needs to match the fn item type of this parameter
+   |       `x` and `y` all reference this parameter T
    = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:29:19
    |
 LL |     eq(foo::<u8>, foo::<i8>);
-   |     --            ^^^^^^^^^ expected `u8`, found `i8`
-   |     |
+   |     -- ---------  ^^^^^^^^^ expected `u8`, found `i8`
+   |     |  |
+   |     |  expected all arguments to be this fn item type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected fn item `fn(_) -> _ {foo::<u8>}`
@@ -31,15 +36,19 @@ note: function defined here
   --> $DIR/fn-item-type.rs:11:4
    |
 LL | fn eq<T>(x: T, y: T) {}
-   |    ^^          ----
+   |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
+   |       |  |
+   |       |  `y` needs to match the fn item type of this parameter
+   |       `x` and `y` all reference this parameter T
    = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:34:23
    |
 LL |     eq(bar::<String>, bar::<Vec<u8>>);
-   |     --                ^^^^^^^^^^^^^^ expected `String`, found `Vec<u8>`
-   |     |
+   |     -- -------------  ^^^^^^^^^^^^^^ expected `String`, found `Vec<u8>`
+   |     |  |
+   |     |  expected all arguments to be this fn item type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected fn item `fn(_) -> _ {bar::<String>}`
@@ -49,15 +58,19 @@ note: function defined here
   --> $DIR/fn-item-type.rs:11:4
    |
 LL | fn eq<T>(x: T, y: T) {}
-   |    ^^          ----
+   |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
+   |       |  |
+   |       |  `y` needs to match the fn item type of this parameter
+   |       `x` and `y` all reference this parameter T
    = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:40:26
    |
 LL |     eq(<u8 as Foo>::foo, <u16 as Foo>::foo);
-   |     --                   ^^^^^^^^^^^^^^^^^ expected `u8`, found `u16`
-   |     |
+   |     -- ----------------  ^^^^^^^^^^^^^^^^^ expected `u8`, found `u16`
+   |     |  |
+   |     |  expected all arguments to be this fn item type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected fn item `fn() {<u8 as Foo>::foo}`
@@ -67,15 +80,19 @@ note: function defined here
   --> $DIR/fn-item-type.rs:11:4
    |
 LL | fn eq<T>(x: T, y: T) {}
-   |    ^^          ----
+   |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
+   |       |  |
+   |       |  `y` needs to match the fn item type of this parameter
+   |       `x` and `y` all reference this parameter T
    = help: consider casting both fn items to fn pointers using `as fn()`
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:45:19
    |
 LL |     eq(foo::<u8>, bar::<u8> as fn(isize) -> isize);
-   |     --            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn item, found fn pointer
-   |     |
+   |     -- ---------  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn item, found fn pointer
+   |     |  |
+   |     |  expected all arguments to be this fn item type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected fn item `fn(_) -> _ {foo::<u8>}`
@@ -85,7 +102,10 @@ note: function defined here
   --> $DIR/fn-item-type.rs:11:4
    |
 LL | fn eq<T>(x: T, y: T) {}
-   |    ^^          ----
+   |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
+   |       |  |
+   |       |  `y` needs to match the fn item type of this parameter
+   |       `x` and `y` all reference this parameter T
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/issues/issue-1451.rs b/tests/ui/fn/issue-1451.rs
index 735b766bd0c..735b766bd0c 100644
--- a/tests/ui/issues/issue-1451.rs
+++ b/tests/ui/fn/issue-1451.rs
diff --git a/tests/ui/issues/issue-1900.rs b/tests/ui/fn/issue-1900.rs
index 761bd317027..761bd317027 100644
--- a/tests/ui/issues/issue-1900.rs
+++ b/tests/ui/fn/issue-1900.rs
diff --git a/tests/ui/issues/issue-1900.stderr b/tests/ui/fn/issue-1900.stderr
index 31fd46c8e2a..31fd46c8e2a 100644
--- a/tests/ui/issues/issue-1900.stderr
+++ b/tests/ui/fn/issue-1900.stderr
diff --git a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs
index ab21dae7dc5..7a51037324f 100644
--- a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs
+++ b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs
@@ -14,6 +14,7 @@ impl<'a, I: 'a + Iterable> Iterable for &'a I {
     //~^ ERROR binding for associated type `Item` references lifetime `'missing`
     //~| ERROR binding for associated type `Item` references lifetime `'missing`
     //~| ERROR `()` is not an iterator
+    //~| WARNING impl trait in impl method signature does not match trait method signature
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr
index d8a2eef94a1..67c4df0f3a9 100644
--- a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr
+++ b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr
@@ -32,7 +32,24 @@ LL |     fn iter(&self) -> impl for<'missing> Iterator<Item = Self::Item<'missin
    |
    = help: the trait `Iterator` is not implemented for `()`
 
-error: aborting due to 4 previous errors
+warning: impl trait in impl method signature does not match trait method signature
+  --> $DIR/span-bug-issue-121457.rs:13:51
+   |
+LL |     fn iter(&self) -> impl Iterator;
+   |                       ------------- return type from trait method defined here
+...
+LL |     fn iter(&self) -> impl for<'missing> Iterator<Item = Self::Item<'missing>> {}
+   |                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this bound is stronger than that defined on the trait
+   |
+   = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
+   = note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
+   = note: `#[warn(refining_impl_trait_reachable)]` on by default
+help: replace the return type so that it matches the trait
+   |
+LL |     fn iter(&self) -> impl Iterator {}
+   |                       ~~~~~~~~~~~~~
+
+error: aborting due to 4 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0195, E0277, E0582.
 For more information about an error, try `rustc --explain E0195`.
diff --git a/tests/ui/issues/issue-1476.rs b/tests/ui/issues/issue-1476.rs
deleted file mode 100644
index 138570a93c4..00000000000
--- a/tests/ui/issues/issue-1476.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-fn main() {
-    println!("{}", x); //~ ERROR cannot find value `x` in this scope
-}
diff --git a/tests/ui/issues/issue-1476.stderr b/tests/ui/issues/issue-1476.stderr
deleted file mode 100644
index e30dbfd205b..00000000000
--- a/tests/ui/issues/issue-1476.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0425]: cannot find value `x` in this scope
-  --> $DIR/issue-1476.rs:2:20
-   |
-LL |     println!("{}", x);
-   |                    ^ not found in this scope
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/issues/issue-1696.rs b/tests/ui/issues/issue-1696.rs
deleted file mode 100644
index 08002ad3c58..00000000000
--- a/tests/ui/issues/issue-1696.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ run-pass
-use std::collections::HashMap;
-
-pub fn main() {
-    let mut m = HashMap::new();
-    m.insert(b"foo".to_vec(), b"bar".to_vec());
-    println!("{:?}", m);
-}
diff --git a/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr b/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr
index aa151fe2d21..390028b349e 100644
--- a/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr
+++ b/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr
@@ -4,7 +4,7 @@ error: under strict provenance it is considered bad style to cast pointer `*cons
 LL |     let addr: usize = &x as *const u8 as usize;
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
+   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
 note: the lint level is defined here
   --> $DIR/lint-strict-provenance-lossy-casts.rs:2:9
    |
@@ -21,7 +21,7 @@ error: under strict provenance it is considered bad style to cast pointer `*cons
 LL |     let addr_32bit = &x as *const u8 as u32;
    |                      ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
+   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
 help: use `.addr()` to obtain the address of a pointer
    |
 LL |     let addr_32bit = (&x as *const u8).addr() as u32;
@@ -35,7 +35,7 @@ LL |     let ptr_addr = ptr as usize;
    |                       |
    |                       help: use `.addr()` to obtain the address of a pointer: `.addr()`
    |
-   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
+   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
 
 error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
   --> $DIR/lint-strict-provenance-lossy-casts.rs:16:26
@@ -45,7 +45,7 @@ LL |     let ptr_addr_32bit = ptr as u32;
    |                             |
    |                             help: use `.addr()` to obtain the address of a pointer: `.addr() as u32`
    |
-   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
+   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/issues/issue-1962.fixed b/tests/ui/loops/issue-1962.fixed
index f0002be4bea..f0002be4bea 100644
--- a/tests/ui/issues/issue-1962.fixed
+++ b/tests/ui/loops/issue-1962.fixed
diff --git a/tests/ui/issues/issue-1962.rs b/tests/ui/loops/issue-1962.rs
index 9c8fb500ba3..9c8fb500ba3 100644
--- a/tests/ui/issues/issue-1962.rs
+++ b/tests/ui/loops/issue-1962.rs
diff --git a/tests/ui/issues/issue-1962.stderr b/tests/ui/loops/issue-1962.stderr
index db235d47303..db235d47303 100644
--- a/tests/ui/issues/issue-1962.stderr
+++ b/tests/ui/loops/issue-1962.stderr
diff --git a/tests/ui/issues/issue-1974.rs b/tests/ui/loops/issue-1974.rs
index ea67b2541de..ea67b2541de 100644
--- a/tests/ui/issues/issue-1974.rs
+++ b/tests/ui/loops/issue-1974.rs
diff --git a/tests/ui/match/postfix-match/match-after-as.rs b/tests/ui/match/postfix-match/match-after-as.rs
new file mode 100644
index 00000000000..7c648bfcf03
--- /dev/null
+++ b/tests/ui/match/postfix-match/match-after-as.rs
@@ -0,0 +1,7 @@
+#![feature(postfix_match)]
+
+fn main() {
+    1 as i32.match {};
+    //~^ ERROR cast cannot be followed by a postfix match
+    //~| ERROR non-exhaustive patterns
+}
diff --git a/tests/ui/match/postfix-match/match-after-as.stderr b/tests/ui/match/postfix-match/match-after-as.stderr
new file mode 100644
index 00000000000..68e4762b8d9
--- /dev/null
+++ b/tests/ui/match/postfix-match/match-after-as.stderr
@@ -0,0 +1,28 @@
+error: cast cannot be followed by a postfix match
+  --> $DIR/match-after-as.rs:4:5
+   |
+LL |     1 as i32.match {};
+   |     ^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     (1 as i32).match {};
+   |     +        +
+
+error[E0004]: non-exhaustive patterns: type `i32` is non-empty
+  --> $DIR/match-after-as.rs:4:5
+   |
+LL |     1 as i32.match {};
+   |     ^^^^^^^^
+   |
+   = note: the matched value is of type `i32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     1 as i32.match {
+LL +         _ => todo!(),
+LL ~     };
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/mir/const_eval_select_cycle.rs b/tests/ui/mir/const_eval_select_cycle.rs
new file mode 100644
index 00000000000..0b84455b2f7
--- /dev/null
+++ b/tests/ui/mir/const_eval_select_cycle.rs
@@ -0,0 +1,18 @@
+// Regression test for #122659
+//@ build-pass
+//@ compile-flags: -O --crate-type=lib
+
+#![feature(core_intrinsics)]
+#![feature(const_eval_select)]
+
+use std::intrinsics::const_eval_select;
+
+#[inline]
+pub const fn f() {
+    const_eval_select((), g, g)
+}
+
+#[inline]
+pub const fn g() {
+    const_eval_select((), f, f)
+}
diff --git a/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.rs b/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.rs
new file mode 100644
index 00000000000..2bd10e762d9
--- /dev/null
+++ b/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.rs
@@ -0,0 +1,14 @@
+fn foo<T>(a: T, b: T) {}
+fn foo_multi_same<T>(a: T, b: T, c: T, d: T, e: T, f: i32) {}
+fn foo_multi_generics<S, T>(a: T, b: T, c: T, d: T, e: T, f: S, g: S) {}
+
+fn main() {
+    foo(1, 2.);
+    //~^  ERROR mismatched types
+    foo_multi_same("a", "b", false, true, (), 32);
+    //~^  ERROR arguments to this function are incorrect
+    foo_multi_generics("a", "b", "c", true, false, 32, 2.);
+    //~^  ERROR arguments to this function are incorrect
+    foo_multi_same("a", 1, 2, "d", "e", 32);
+    //~^  ERROR arguments to this function are incorrect
+}
diff --git a/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr b/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr
new file mode 100644
index 00000000000..a845dfabe93
--- /dev/null
+++ b/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr
@@ -0,0 +1,97 @@
+error[E0308]: mismatched types
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:6:12
+   |
+LL |     foo(1, 2.);
+   |     --- -  ^^ expected integer, found floating-point number
+   |     |   |
+   |     |   expected all arguments to be this integer type because they need to match the type of this parameter
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:1:4
+   |
+LL | fn foo<T>(a: T, b: T) {}
+   |    ^^^ -  ----  ---- this parameter needs to match the integer type of `a`
+   |        |  |
+   |        |  `b` needs to match the integer type of this parameter
+   |        `a` and `b` all reference this parameter T
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:8:5
+   |
+LL |     foo_multi_same("a", "b", false, true, (), 32);
+   |     ^^^^^^^^^^^^^^ ---  ---  -----  ----  -- expected `&str`, found `()`
+   |                    |    |    |      |
+   |                    |    |    |      expected `&str`, found `bool`
+   |                    |    |    expected `&str`, found `bool`
+   |                    |    expected some other arguments to be an `&str` type to match the type of this parameter
+   |                    expected some other arguments to be an `&str` type to match the type of this parameter
+   |
+note: function defined here
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:2:4
+   |
+LL | fn foo_multi_same<T>(a: T, b: T, c: T, d: T, e: T, f: i32) {}
+   |    ^^^^^^^^^^^^^^ -  ----  ----  ----  ----  ----  ------
+   |                   |  |     |     |     |     |
+   |                   |  |     |     |     |     this parameter needs to match the `&str` type of `a` and `b`
+   |                   |  |     |     |     this parameter needs to match the `&str` type of `a` and `b`
+   |                   |  |     |     this parameter needs to match the `&str` type of `a` and `b`
+   |                   |  |     `c`, `d` and `e` need to match the `&str` type of this parameter
+   |                   |  `c`, `d` and `e` need to match the `&str` type of this parameter
+   |                   `a`, `b`, `c`, `d` and `e` all reference this parameter T
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:10:5
+   |
+LL |     foo_multi_generics("a", "b", "c", true, false, 32, 2.);
+   |     ^^^^^^^^^^^^^^^^^^ ---  ---  ---  ----  -----  --  -- expected integer, found floating-point number
+   |                        |    |    |    |     |      |
+   |                        |    |    |    |     |      expected some other arguments to be an integer type to match the type of this parameter
+   |                        |    |    |    |     expected `&str`, found `bool`
+   |                        |    |    |    expected `&str`, found `bool`
+   |                        |    |    expected some other arguments to be an `&str` type to match the type of this parameter
+   |                        |    expected some other arguments to be an `&str` type to match the type of this parameter
+   |                        expected some other arguments to be an `&str` type to match the type of this parameter
+   |
+note: function defined here
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:3:4
+   |
+LL | fn foo_multi_generics<S, T>(a: T, b: T, c: T, d: T, e: T, f: S, g: S) {}
+   |    ^^^^^^^^^^^^^^^^^^ -  -  ----  ----  ----  ----  ----  ----  ---- this parameter needs to match the integer type of `f`
+   |                       |  |  |     |     |     |     |     |
+   |                       |  |  |     |     |     |     |     `g` needs to match the integer type of this parameter
+   |                       |  |  |     |     |     |     this parameter needs to match the `&str` type of `a`, `b` and `c`
+   |                       |  |  |     |     |     this parameter needs to match the `&str` type of `a`, `b` and `c`
+   |                       |  |  |     |     `d` and `e` need to match the `&str` type of this parameter
+   |                       |  |  |     `d` and `e` need to match the `&str` type of this parameter
+   |                       |  |  `d` and `e` need to match the `&str` type of this parameter
+   |                       |  `a`, `b`, `c`, `d` and `e` all reference this parameter T
+   |                       `f` and `g` all reference this parameter S
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:12:5
+   |
+LL |     foo_multi_same("a", 1, 2, "d", "e", 32);
+   |     ^^^^^^^^^^^^^^ ---  -  -  ---  --- expected some other arguments to be an `&str` type to match the type of this parameter
+   |                    |    |  |  |
+   |                    |    |  |  expected some other arguments to be an `&str` type to match the type of this parameter
+   |                    |    |  expected `&str`, found integer
+   |                    |    expected `&str`, found integer
+   |                    expected some other arguments to be an `&str` type to match the type of this parameter
+   |
+note: function defined here
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:2:4
+   |
+LL | fn foo_multi_same<T>(a: T, b: T, c: T, d: T, e: T, f: i32) {}
+   |    ^^^^^^^^^^^^^^ -  ----  ----  ----  ----  ----  ------
+   |                   |  |     |     |     |     |
+   |                   |  |     |     |     |     `b` and `c` need to match the `&str` type of this parameter
+   |                   |  |     |     |     `b` and `c` need to match the `&str` type of this parameter
+   |                   |  |     |     this parameter needs to match the `&str` type of `a`, `d` and `e`
+   |                   |  |     this parameter needs to match the `&str` type of `a`, `d` and `e`
+   |                   |  `b` and `c` need to match the `&str` type of this parameter
+   |                   `a`, `b`, `c`, `d` and `e` all reference this parameter T
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/issues/issue-1362.rs b/tests/ui/mismatched_types/issue-1362.rs
index 6fd43f50e4d..6fd43f50e4d 100644
--- a/tests/ui/issues/issue-1362.rs
+++ b/tests/ui/mismatched_types/issue-1362.rs
diff --git a/tests/ui/issues/issue-1362.stderr b/tests/ui/mismatched_types/issue-1362.stderr
index 6f6fdff6678..6f6fdff6678 100644
--- a/tests/ui/issues/issue-1362.stderr
+++ b/tests/ui/mismatched_types/issue-1362.stderr
diff --git a/tests/ui/issues/issue-1448-2.rs b/tests/ui/mismatched_types/issue-1448-2.rs
index 829e81b9c24..829e81b9c24 100644
--- a/tests/ui/issues/issue-1448-2.rs
+++ b/tests/ui/mismatched_types/issue-1448-2.rs
diff --git a/tests/ui/issues/issue-1448-2.stderr b/tests/ui/mismatched_types/issue-1448-2.stderr
index a6f1daefe63..a6f1daefe63 100644
--- a/tests/ui/issues/issue-1448-2.stderr
+++ b/tests/ui/mismatched_types/issue-1448-2.stderr
diff --git a/tests/ui/pattern/usefulness/unions.rs b/tests/ui/pattern/usefulness/unions.rs
new file mode 100644
index 00000000000..80a7f36a09a
--- /dev/null
+++ b/tests/ui/pattern/usefulness/unions.rs
@@ -0,0 +1,35 @@
+fn main() {
+    #[derive(Copy, Clone)]
+    union U8AsBool {
+        n: u8,
+        b: bool,
+    }
+
+    let x = U8AsBool { n: 1 };
+    unsafe {
+        match x {
+            // exhaustive
+            U8AsBool { n: 2 } => {}
+            U8AsBool { b: true } => {}
+            U8AsBool { b: false } => {}
+        }
+        match x {
+            // exhaustive
+            U8AsBool { b: true } => {}
+            U8AsBool { n: 0 } => {}
+            U8AsBool { n: 1.. } => {}
+        }
+        match x {
+            //~^ ERROR non-exhaustive patterns: `U8AsBool { n: 0_u8 }` and `U8AsBool { b: false }` not covered
+            U8AsBool { b: true } => {}
+            U8AsBool { n: 1.. } => {}
+        }
+        // Our approach can report duplicate witnesses sometimes.
+        match (x, true) {
+            //~^ ERROR non-exhaustive patterns: `(U8AsBool { n: 0_u8 }, false)`, `(U8AsBool { b: false }, false)`, `(U8AsBool { n: 0_u8 }, false)` and 1 more not covered
+            (U8AsBool { b: true }, true) => {}
+            (U8AsBool { b: false }, true) => {}
+            (U8AsBool { n: 1.. }, true) => {}
+        }
+    }
+}
diff --git a/tests/ui/pattern/usefulness/unions.stderr b/tests/ui/pattern/usefulness/unions.stderr
new file mode 100644
index 00000000000..4b397dc25db
--- /dev/null
+++ b/tests/ui/pattern/usefulness/unions.stderr
@@ -0,0 +1,34 @@
+error[E0004]: non-exhaustive patterns: `U8AsBool { n: 0_u8 }` and `U8AsBool { b: false }` not covered
+  --> $DIR/unions.rs:22:15
+   |
+LL |         match x {
+   |               ^ patterns `U8AsBool { n: 0_u8 }` and `U8AsBool { b: false }` not covered
+   |
+note: `U8AsBool` defined here
+  --> $DIR/unions.rs:3:11
+   |
+LL |     union U8AsBool {
+   |           ^^^^^^^^
+   = note: the matched value is of type `U8AsBool`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~             U8AsBool { n: 1.. } => {},
+LL +             U8AsBool { n: 0_u8 } | U8AsBool { b: false } => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `(U8AsBool { n: 0_u8 }, false)`, `(U8AsBool { b: false }, false)`, `(U8AsBool { n: 0_u8 }, false)` and 1 more not covered
+  --> $DIR/unions.rs:28:15
+   |
+LL |         match (x, true) {
+   |               ^^^^^^^^^ patterns `(U8AsBool { n: 0_u8 }, false)`, `(U8AsBool { b: false }, false)`, `(U8AsBool { n: 0_u8 }, false)` and 1 more not covered
+   |
+   = note: the matched value is of type `(U8AsBool, bool)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~             (U8AsBool { n: 1.. }, true) => {},
+LL +             _ => todo!()
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/simd/intrinsic/ptr-cast.rs b/tests/ui/simd/intrinsic/ptr-cast.rs
index 62820346241..0490734b48a 100644
--- a/tests/ui/simd/intrinsic/ptr-cast.rs
+++ b/tests/ui/simd/intrinsic/ptr-cast.rs
@@ -4,7 +4,7 @@
 
 extern "rust-intrinsic" {
     fn simd_cast_ptr<T, U>(x: T) -> U;
-    fn simd_expose_addr<T, U>(x: T) -> U;
+    fn simd_expose_provenance<T, U>(x: T) -> U;
     fn simd_with_exposed_provenance<T, U>(x: T) -> U;
 }
 
@@ -22,7 +22,7 @@ fn main() {
         // change constness and type
         let const_ptrs: V<*const u8> = simd_cast_ptr(ptrs);
 
-        let exposed_addr: V<usize> = simd_expose_addr(const_ptrs);
+        let exposed_addr: V<usize> = simd_expose_provenance(const_ptrs);
 
         let with_exposed_provenance: V<*mut i8> = simd_with_exposed_provenance(exposed_addr);
 
diff --git a/tests/ui/issues/issue-1660.rs b/tests/ui/static/issue-1660.rs
index a114a908313..a114a908313 100644
--- a/tests/ui/issues/issue-1660.rs
+++ b/tests/ui/static/issue-1660.rs