about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/ci.yml12
-rw-r--r--.mailmap2
-rw-r--r--Cargo.lock173
-rw-r--r--compiler/rustc/Cargo.toml1
-rw-r--r--compiler/rustc_arena/src/lib.rs5
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs2
-rw-r--r--compiler/rustc_ast_passes/src/feature_gate.rs24
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_errors.rs4
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/region_name.rs8
-rw-r--r--compiler/rustc_borrowck/src/region_infer/mod.rs2
-rw-r--r--compiler/rustc_borrowck/src/renumber.rs14
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs11
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs9
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs25
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/bounds.rs2
-rwxr-xr-xcompiler/rustc_codegen_cranelift/scripts/filter_profile.rs6
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/common.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs50
-rw-r--r--compiler/rustc_codegen_cranelift/src/value_and_place.rs8
-rw-r--r--compiler/rustc_codegen_llvm/messages.ftl2
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs15
-rw-r--r--compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs103
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs73
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/errors.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs57
-rw-r--r--compiler/rustc_codegen_llvm/src/lib.rs9
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs6
-rw-r--r--compiler/rustc_codegen_ssa/messages.ftl2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs31
-rw-r--r--compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs1
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/debuginfo.rs43
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/mod.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/operand.rs23
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/place.rs4
-rw-r--r--compiler/rustc_const_eval/src/const_eval/valtrees.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs3
-rw-r--r--compiler/rustc_const_eval/src/interpret/projection.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/util.rs5
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs1
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs12
-rw-r--r--compiler/rustc_const_eval/src/util/type_name.rs3
-rw-r--r--compiler/rustc_data_structures/src/lib.rs3
-rw-r--r--compiler/rustc_data_structures/src/profiling.rs4
-rw-r--r--compiler/rustc_data_structures/src/small_c_str.rs6
-rw-r--r--compiler/rustc_data_structures/src/sync/worker_local.rs8
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0038.md7
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0094.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0211.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0698.md4
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0760.md2
-rw-r--r--compiler/rustc_feature/src/accepted.rs4
-rw-r--r--compiler/rustc_feature/src/active.rs10
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs5
-rw-r--r--compiler/rustc_hir/src/def.rs10
-rw-r--r--compiler/rustc_hir/src/target.rs2
-rw-r--r--compiler/rustc_hir_analysis/messages.ftl25
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/bounds.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/generics.rs17
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs25
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs167
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs101
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs29
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs52
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs78
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs121
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs200
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/orphan.rs1
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs3
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs35
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs22
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs124
-rw-r--r--compiler/rustc_hir_analysis/src/variance/constraints.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/variance/terms.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/_match.rs23
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/check.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs131
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs19
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs19
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs601
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_propagate.rs92
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs96
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs306
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs242
-rw-r--r--compiler/rustc_hir_typeck/src/generator_interior/mod.rs711
-rw-r--r--compiler/rustc_hir_typeck/src/lib.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/mem_categorization.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs15
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs6
-rw-r--r--compiler/rustc_incremental/src/lib.rs2
-rw-r--r--compiler/rustc_incremental/src/persist/load.rs132
-rw-r--r--compiler/rustc_incremental/src/persist/mod.rs3
-rw-r--r--compiler/rustc_incremental/src/persist/save.rs2
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs13
-rw-r--r--compiler/rustc_infer/src/errors/note_and_explain.rs7
-rw-r--r--compiler/rustc_infer/src/infer/at.rs23
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs3
-rw-r--r--compiler/rustc_infer/src/infer/equate.rs20
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs22
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs39
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs6
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs6
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs10
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs2
-rw-r--r--compiler/rustc_infer/src/infer/outlives/components.rs2
-rw-r--r--compiler/rustc_infer/src/infer/sub.rs19
-rw-r--r--compiler/rustc_interface/src/passes.rs14
-rw-r--r--compiler/rustc_interface/src/queries.rs47
-rw-r--r--compiler/rustc_interface/src/tests.rs2
-rw-r--r--compiler/rustc_lint/src/builtin.rs6
-rw-r--r--compiler/rustc_lint/src/context.rs39
-rw-r--r--compiler/rustc_lint/src/foreign_modules.rs7
-rw-r--r--compiler/rustc_lint/src/invalid_from_utf8.rs4
-rw-r--r--compiler/rustc_lint/src/lib.rs10
-rw-r--r--compiler/rustc_lint/src/noop_method_call.rs6
-rw-r--r--compiler/rustc_lint/src/passes.rs156
-rw-r--r--compiler/rustc_lint/src/reference_casting.rs147
-rw-r--r--compiler/rustc_lint/src/types.rs1
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs53
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs13
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp4
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder.rs19
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs2
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs51
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs4
-rw-r--r--compiler/rustc_metadata/src/rmeta/table.rs3
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs4
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs2
-rw-r--r--compiler/rustc_middle/src/mir/basic_blocks.rs7
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs4
-rw-r--r--compiler/rustc_middle/src/mir/query.rs3
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs3
-rw-r--r--compiler/rustc_middle/src/mir/traversal.rs110
-rw-r--r--compiler/rustc_middle/src/query/mod.rs17
-rw-r--r--compiler/rustc_middle/src/thir.rs16
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/adt.rs2
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs1
-rw-r--r--compiler/rustc_middle/src/ty/context.rs7
-rw-r--r--compiler/rustc_middle/src/ty/diagnostics.rs4
-rw-r--r--compiler/rustc_middle/src/ty/error.rs5
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs13
-rw-r--r--compiler/rustc_middle/src/ty/flags.rs6
-rw-r--r--compiler/rustc_middle/src/ty/fold.rs2
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs12
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs1
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs5
-rw-r--r--compiler/rustc_middle/src/ty/normalize_erasing_regions.rs24
-rw-r--r--compiler/rustc_middle/src/ty/opaque_types.rs4
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs1
-rw-r--r--compiler/rustc_middle/src/ty/print/mod.rs3
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs15
-rw-r--r--compiler/rustc_middle/src/ty/relate.rs14
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs10
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs28
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs70
-rw-r--r--compiler/rustc_middle/src/ty/util.rs24
-rw-r--r--compiler/rustc_middle/src/ty/walk.rs5
-rw-r--r--compiler/rustc_middle/src/values.rs2
-rw-r--r--compiler/rustc_mir_build/messages.ftl3
-rw-r--r--compiler/rustc_mir_build/src/errors.rs6
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs4
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs65
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs2
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs7
-rw-r--r--compiler/rustc_mir_dataflow/src/move_paths/builder.rs6
-rw-r--r--compiler/rustc_mir_dataflow/src/value_analysis.rs4
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs2
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_drops.rs1
-rw-r--r--compiler/rustc_mir_transform/src/errors.rs34
-rw-r--r--compiler/rustc_mir_transform/src/generator.rs110
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs538
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs21
-rw-r--r--compiler/rustc_mir_transform/src/inline/cycle.rs2
-rw-r--r--compiler/rustc_mir_transform/src/large_enums.rs7
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs8
-rw-r--r--compiler/rustc_mir_transform/src/ref_prop.rs2
-rw-r--r--compiler/rustc_mir_transform/src/reveal_all.rs32
-rw-r--r--compiler/rustc_mir_transform/src/simplify.rs43
-rw-r--r--compiler/rustc_mir_transform/src/ssa.rs50
-rw-r--r--compiler/rustc_mir_transform/src/unreachable_prop.rs6
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs2
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs2
-rw-r--r--compiler/rustc_monomorphize/src/polymorphize.rs2
-rw-r--r--compiler/rustc_monomorphize/src/util.rs4
-rw-r--r--compiler/rustc_parse/messages.ftl2
-rw-r--r--compiler/rustc_parse/src/errors.rs13
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs7
-rw-r--r--compiler/rustc_passes/messages.ftl4
-rw-r--r--compiler/rustc_passes/src/abi_test.rs2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs31
-rw-r--r--compiler/rustc_passes/src/dead.rs4
-rw-r--r--compiler/rustc_passes/src/errors.rs9
-rw-r--r--compiler/rustc_passes/src/layout_test.rs2
-rw-r--r--compiler/rustc_privacy/src/lib.rs9
-rw-r--r--compiler/rustc_query_system/src/query/job.rs4
-rw-r--r--compiler/rustc_query_system/src/query/plumbing.rs4
-rw-r--r--compiler/rustc_resolve/src/build_reduced_graph.rs7
-rw-r--r--compiler/rustc_resolve/src/diagnostics.rs4
-rw-r--r--compiler/rustc_resolve/src/late.rs26
-rw-r--r--compiler/rustc_resolve/src/late/diagnostics.rs142
-rw-r--r--compiler/rustc_session/src/options.rs6
-rw-r--r--compiler/rustc_smir/Cargo.toml26
-rw-r--r--compiler/rustc_smir/src/lib.rs16
-rw-r--r--compiler/rustc_smir/src/rustc_internal/mod.rs97
-rw-r--r--compiler/rustc_smir/src/rustc_smir/alloc.rs8
-rw-r--r--compiler/rustc_smir/src/rustc_smir/mod.rs116
-rw-r--r--compiler/rustc_span/src/lib.rs8
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs8
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs5
-rw-r--r--compiler/rustc_target/src/spec/apple_base.rs56
-rw-r--r--compiler/rustc_target/src/spec/armv7_apple_ios.rs21
-rw-r--r--compiler/rustc_target/src/spec/armv7s_apple_ios.rs4
-rw-r--r--compiler/rustc_target/src/spec/mod.rs1
-rw-r--r--compiler/rustc_target/src/spec/riscv64_linux_android.rs2
-rw-r--r--compiler/rustc_target/src/spec/uefi_msvc_base.rs1
-rw-r--r--compiler/rustc_target/src/spec/x86_64_apple_darwin.rs2
-rw-r--r--compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs3
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs8
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs17
-rw-r--r--compiler/rustc_trait_selection/src/solve/canonicalize.rs5
-rw-r--r--compiler/rustc_trait_selection/src/solve/project_goals.rs4
-rw-r--r--compiler/rustc_trait_selection/src/solve/search_graph/cache.rs102
-rw-r--r--compiler/rustc_trait_selection/src/solve/search_graph/mod.rs148
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs3
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs276
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs13
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs60
-rw-r--r--compiler/rustc_trait_selection/src/traits/structural_match.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs1
-rw-r--r--compiler/rustc_ty_utils/src/implied_bounds.rs4
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs6
-rw-r--r--compiler/rustc_ty_utils/src/needs_drop.rs28
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs8
-rw-r--r--compiler/rustc_ty_utils/src/ty.rs8
-rw-r--r--compiler/rustc_type_ir/src/sty.rs90
-rw-r--r--compiler/stable_mir/Cargo.toml8
-rw-r--r--compiler/stable_mir/README.md (renamed from compiler/rustc_smir/README.md)0
-rw-r--r--compiler/stable_mir/rust-toolchain.toml (renamed from compiler/rustc_smir/rust-toolchain.toml)0
-rw-r--r--compiler/stable_mir/src/fold.rs (renamed from compiler/rustc_smir/src/stable_mir/fold.rs)31
-rw-r--r--compiler/stable_mir/src/lib.rs (renamed from compiler/rustc_smir/src/stable_mir/mod.rs)78
-rw-r--r--compiler/stable_mir/src/mir.rs (renamed from compiler/rustc_smir/src/stable_mir/mir.rs)0
-rw-r--r--compiler/stable_mir/src/mir/body.rs (renamed from compiler/rustc_smir/src/stable_mir/mir/body.rs)22
-rw-r--r--compiler/stable_mir/src/ty.rs (renamed from compiler/rustc_smir/src/stable_mir/ty.rs)85
-rw-r--r--compiler/stable_mir/src/visitor.rs (renamed from compiler/rustc_smir/src/stable_mir/visitor.rs)22
-rw-r--r--library/alloc/src/rc.rs21
-rw-r--r--library/alloc/src/sync.rs29
-rw-r--r--library/alloc/src/vec/mod.rs30
-rw-r--r--library/alloc/tests/vec.rs10
-rw-r--r--library/core/src/cmp.rs6
-rw-r--r--library/core/src/fmt/mod.rs4
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/macros/mod.rs89
-rw-r--r--library/core/src/marker.rs7
-rw-r--r--library/core/src/num/int_macros.rs54
-rw-r--r--library/core/src/num/uint_macros.rs64
-rw-r--r--library/core/src/pin.rs5
-rw-r--r--library/core/src/ptr/const_ptr.rs23
-rw-r--r--library/core/src/ptr/mut_ptr.rs23
-rw-r--r--library/core/src/slice/mod.rs2
-rw-r--r--library/core/src/sync/exclusive.rs46
-rw-r--r--library/core/tests/lib.rs3
-rw-r--r--library/core/tests/macros.rs154
-rw-r--r--library/core/tests/num/int_macros.rs32
-rw-r--r--library/core/tests/num/uint_macros.rs29
-rw-r--r--library/panic_abort/src/lib.rs3
-rw-r--r--library/proc_macro/src/lib.rs17
-rw-r--r--library/std/Cargo.toml4
-rw-r--r--library/std/build.rs2
-rw-r--r--library/std/src/io/error.rs8
-rw-r--r--library/std/src/io/mod.rs35
-rw-r--r--library/std/src/lib.rs3
-rw-r--r--library/std/src/os/mod.rs2
-rw-r--r--library/std/src/os/uefi/env.rs92
-rw-r--r--library/std/src/os/uefi/mod.rs8
-rw-r--r--library/std/src/os/unix/io/mod.rs11
-rw-r--r--library/std/src/os/unix/process.rs42
-rw-r--r--library/std/src/os/windows/io/mod.rs11
-rw-r--r--library/std/src/os/windows/io/socket.rs8
-rw-r--r--library/std/src/os/windows/process.rs39
-rw-r--r--library/std/src/process.rs146
-rw-r--r--library/std/src/sys/common/thread_local/mod.rs2
-rw-r--r--library/std/src/sys/mod.rs4
-rw-r--r--library/std/src/sys/uefi/alloc.rs33
-rw-r--r--library/std/src/sys/uefi/env.rs9
-rw-r--r--library/std/src/sys/uefi/helpers.rs141
-rw-r--r--library/std/src/sys/uefi/mod.rs244
-rw-r--r--library/std/src/sys/uefi/os.rs237
-rw-r--r--library/std/src/sys/uefi/path.rs25
-rw-r--r--library/std/src/sys/uefi/tests.rs21
-rw-r--r--library/std/src/sys/unix/pipe.rs8
-rw-r--r--library/std/src/sys/unix/thread_local_dtor.rs2
-rw-r--r--library/std/src/sys/unix/thread_parking/darwin.rs3
-rw-r--r--library/std/src/sys/windows/c.rs6
-rw-r--r--library/std/src/sys/windows/c/windows_sys.lst16
-rw-r--r--library/std/src/sys/windows/c/windows_sys.rs164
-rw-r--r--library/std/src/sys/windows/handle.rs9
-rw-r--r--library/std/src/sys/windows/net.rs38
-rw-r--r--library/std/src/sys/windows/pipe.rs8
-rw-r--r--library/std/src/sys_common/mod.rs1
-rw-r--r--src/bootstrap/bootstrap.py90
-rw-r--r--src/bootstrap/compile.rs5
-rw-r--r--src/bootstrap/config.rs6
-rw-r--r--src/bootstrap/llvm.rs9
-rw-r--r--src/ci/docker/README.md4
-rw-r--r--src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile5
-rw-r--r--src/ci/docker/host-x86_64/dist-various-2/Dockerfile2
-rw-r--r--src/ci/docker/scripts/crosstool-ng-git.sh17
-rw-r--r--src/ci/docker/scripts/crosstool-ng.sh2
-rw-r--r--src/ci/github-actions/ci.yml8
-rwxr-xr-xsrc/ci/scripts/setup-environment.sh2
m---------src/doc/embedded-book0
m---------src/doc/nomicon0
m---------src/doc/reference0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/doc/rustc/src/platform-support.md9
-rw-r--r--src/doc/rustc/src/platform-support/loongarch-none.md2
-rw-r--r--src/doc/rustc/src/platform-support/unknown-uefi.md77
-rw-r--r--src/doc/rustdoc/src/unstable-features.md2
-rw-r--r--src/doc/style-guide/src/items.md38
-rw-r--r--src/doc/unstable-book/src/compiler-flags/link-native-libraries.md8
-rw-r--r--src/doc/unstable-book/src/language-features/lang-items.md2
-rw-r--r--src/doc/unstable-book/src/language-features/plugin.md10
-rw-r--r--src/etc/installer/pkg/Distribution.xml2
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/librustdoc/clean/mod.rs34
-rw-r--r--src/librustdoc/clean/types.rs65
-rw-r--r--src/librustdoc/doctest.rs2
-rw-r--r--src/librustdoc/formats/item_type.rs2
-rw-r--r--src/librustdoc/html/markdown.rs2
-rw-r--r--src/librustdoc/html/templates/type_layout.html4
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs5
m---------src/llvm-project0
-rw-r--r--src/tools/build-manifest/src/main.rs3
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/.github/workflows/remark.yml8
-rw-r--r--src/tools/clippy/CHANGELOG.md5
-rw-r--r--src/tools/clippy/Cargo.toml1
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md14
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/await_holding_invalid.rs43
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/mod.rs26
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs39
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/default_union_representation.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs375
-rw-r--r--src/tools/clippy/clippy_lints/src/doc.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/enum_variants.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/error_impl_error.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/explicit_write.rs90
-rw-r--r--src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/format.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/format_impl.rs41
-rw-r--r--src/tools/clippy/clippy_lints/src/init_numbered_fields.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/large_const_arrays.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/large_futures.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/utils.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/needless_match.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs101
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs89
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs53
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/redundant_as_str.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/misc.rs176
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs410
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs71
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/non_canonical_impls.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs21
-rw-r--r--src/tools/clippy/clippy_lints/src/raw_strings.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/types/mod.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs93
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs110
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/conf.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs37
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs5
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs31
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs35
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/mod.rs72
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs16
-rw-r--r--src/tools/clippy/rust-toolchain2
-rw-r--r--src/tools/clippy/tests/compile-test.rs2
-rw-r--r--src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs6
-rw-r--r--src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr6
-rw-r--r--src/tools/clippy/tests/ui-toml/decimal_literal_representation/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.fixed6
-rw-r--r--src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.rs6
-rw-r--r--src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_script_idents/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.rs6
-rw-r--r--src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_names/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs16
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr18
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_size/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.fixed11
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.rs11
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr21
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variants_threshold0/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/enum_variants_threshold0/enum_variants_name_threshold.rs3
-rw-r--r--src/tools/clippy/tests/ui-toml/explicit_iter_loop/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.fixed10
-rw-r--r--src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs10
-rw-r--r--src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.stderr17
-rw-r--r--src/tools/clippy/tests/ui-toml/large_stack_frames/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.rs17
-rw-r--r--src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.stderr15
-rw-r--r--src/tools/clippy/tests/ui-toml/large_types_passed_by_value/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.fixed7
-rw-r--r--src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.rs7
-rw-r--r--src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/manual_let_else/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.fixed10
-rw-r--r--src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.rs14
-rw-r--r--src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.stderr15
-rw-r--r--src/tools/clippy/tests/ui-toml/path_ends_with_ext/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs9
-rw-r--r--src/tools/clippy/tests/ui-toml/result_large_err/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.rs10
-rw-r--r--src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.stderr12
-rw-r--r--src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr2
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.rs5
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.fixed9
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.rs9
-rw-r--r--src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/too_many_arguments/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.rs7
-rw-r--r--src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/type_complexity/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.rs7
-rw-r--r--src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.rs18
-rw-r--r--src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.stderr12
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml2
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/default/clippy.toml2
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/disabled/clippy.toml3
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr (renamed from src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr)74
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr (renamed from src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr)132
-rw-r--r--src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs30
-rw-r--r--src/tools/clippy/tests/ui-toml/unnecessary_box_returns/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.fixed11
-rw-r--r--src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.rs11
-rw-r--r--src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.stderr12
-rw-r--r--src/tools/clippy/tests/ui-toml/verbose_bit_mask/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.fixed7
-rw-r--r--src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.rs7
-rw-r--r--src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.stderr11
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml1
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed11
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs11
-rw-r--r--src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr11
-rw-r--r--src/tools/clippy/tests/ui/await_holding_lock.stderr137
-rw-r--r--src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr67
-rw-r--r--src/tools/clippy/tests/ui/cast.rs4
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_integer.fixed11
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_integer.rs11
-rw-r--r--src/tools/clippy/tests/ui/cast_lossless_integer.stderr14
-rw-r--r--src/tools/clippy/tests/ui/eta.fixed3
-rw-r--r--src/tools/clippy/tests/ui/eta.rs3
-rw-r--r--src/tools/clippy/tests/ui/eta.stderr54
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed15
-rw-r--r--src/tools/clippy/tests/ui/extra_unused_type_parameters.rs15
-rw-r--r--src/tools/clippy/tests/ui/filter_map_bool_then.fixed24
-rw-r--r--src/tools/clippy/tests/ui/filter_map_bool_then.rs24
-rw-r--r--src/tools/clippy/tests/ui/filter_map_bool_then.stderr26
-rw-r--r--src/tools/clippy/tests/ui/future_not_send.rs1
-rw-r--r--src/tools/clippy/tests/ui/future_not_send.stderr36
-rw-r--r--src/tools/clippy/tests/ui/len_without_is_empty.rs23
-rw-r--r--src/tools/clippy/tests/ui/len_without_is_empty.stderr8
-rw-r--r--src/tools/clippy/tests/ui/let_unit.fixed2
-rw-r--r--src/tools/clippy/tests/ui/let_unit.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_map_option.fixed1
-rw-r--r--src/tools/clippy/tests/ui/manual_map_option.rs1
-rw-r--r--src/tools/clippy/tests/ui/manual_map_option.stderr42
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.fixed290
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.rs290
-rw-r--r--src/tools/clippy/tests/ui/needless_borrow.stderr90
-rw-r--r--src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed287
-rw-r--r--src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs287
-rw-r--r--src/tools/clippy/tests/ui/needless_borrows_for_generic_args.stderr77
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs40
-rw-r--r--src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr34
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed3
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string_hashes.rs3
-rw-r--r--src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr26
-rw-r--r--src/tools/clippy/tests/ui/no_effect_return.rs1
-rw-r--r--src/tools/clippy/tests/ui/no_effect_return.stderr8
-rw-r--r--src/tools/clippy/tests/ui/option_filter_map.fixed2
-rw-r--r--src/tools/clippy/tests/ui/option_filter_map.rs2
-rw-r--r--src/tools/clippy/tests/ui/path_ends_with_ext.fixed36
-rw-r--r--src/tools/clippy/tests/ui/path_ends_with_ext.rs36
-rw-r--r--src/tools/clippy/tests/ui/path_ends_with_ext.stderr17
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation.rs5
-rw-r--r--src/tools/clippy/tests/ui/redundant_as_str.fixed24
-rw-r--r--src/tools/clippy/tests/ui/redundant_as_str.rs24
-rw-r--r--src/tools/clippy/tests/ui/redundant_as_str.stderr17
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.fixed11
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.rs11
-rw-r--r--src/tools/clippy/tests/ui/redundant_field_names.stderr2
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.fixed50
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.rs50
-rw-r--r--src/tools/clippy/tests/ui/redundant_guards.stderr116
-rw-r--r--src/tools/clippy/tests/ui/regex.rs3
-rw-r--r--src/tools/clippy/tests/ui/regex.stderr48
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/transmute_null_to_fn.rs11
-rw-r--r--src/tools/clippy/tests/ui/transmute_null_to_fn.stderr26
-rw-r--r--src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs534
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_on_constructor.fixed56
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_on_constructor.rs56
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_map_on_constructor.stderr53
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.fixed2
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_to_owned.rs2
-rw-r--r--src/tools/clippy/tests/ui/used_underscore_binding.rs28
-rw-r--r--src/tools/clippy/tests/ui/used_underscore_binding.stderr47
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.fixed91
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.rs91
-rw-r--r--src/tools/clippy/tests/ui/useless_conversion.stderr70
-rw-r--r--src/tools/clippy/tests/ui/vec_box_sized.fixed5
-rw-r--r--src/tools/clippy/tests/ui/vec_box_sized.rs5
-rw-r--r--src/tools/compiletest/src/common.rs6
-rw-r--r--src/tools/compiletest/src/header/needs.rs5
-rw-r--r--src/tools/generate-windows-sys/Cargo.toml2
-rw-r--r--src/tools/generate-windows-sys/src/main.rs31
-rw-r--r--src/tools/miri/.github/workflows/ci.yml4
-rw-r--r--src/tools/miri/Cargo.lock202
-rw-r--r--src/tools/miri/Cargo.toml2
-rw-r--r--src/tools/miri/README.md4
-rw-r--r--src/tools/miri/bench-cargo-miri/invalidate/Cargo.lock7
-rw-r--r--src/tools/miri/bench-cargo-miri/invalidate/Cargo.toml8
-rw-r--r--src/tools/miri/bench-cargo-miri/invalidate/src/main.rs4
-rw-r--r--src/tools/miri/cargo-miri/src/phases.rs4
-rw-r--r--src/tools/miri/miri-script/src/commands.rs4
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/bin/miri.rs8
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs7
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs1
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/exhaustive.rs111
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs10
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs165
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs115
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs658
-rw-r--r--src/tools/miri/src/helpers.rs6
-rw-r--r--src/tools/miri/src/helpers/convert.rs49
-rw-r--r--src/tools/miri/src/operator.rs14
-rw-r--r--src/tools/miri/src/shims/backtrace.rs5
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs60
-rw-r--r--src/tools/miri/src/shims/intrinsics/mod.rs5
-rw-r--r--src/tools/miri/src/shims/intrinsics/simd.rs35
-rw-r--r--src/tools/miri/src/shims/x86/mod.rs91
-rw-r--r--src/tools/miri/src/shims/x86/sse.rs4
-rw-r--r--src/tools/miri/src/shims/x86/sse2.rs43
-rw-r--r--src/tools/miri/tests/compiletest.rs105
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.rs (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.stderr (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.rs (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_join_detached.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.stderr (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_join_detached.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.rs (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_join_joined.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.stderr (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_join_joined.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.rs (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_join_main.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_join_main.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.rs (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_join_multiple.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_join_multiple.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.rs (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_join_self.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr (renamed from src/tools/miri/tests/fail/concurrency/libc_pthread_join_self.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/unwind_top_of_stack.rs (renamed from src/tools/miri/tests/fail/concurrency/unwind_top_of_stack.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/concurrency/unwind_top_of_stack.stderr (renamed from src/tools/miri/tests/fail/concurrency/unwind_top_of_stack.stderr)2
-rw-r--r--src/tools/miri/tests/fail-dep/shims/fs/close_stdout.rs (renamed from src/tools/miri/tests/fail/shims/fs/close_stdout.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr (renamed from src/tools/miri/tests/fail/shims/fs/close_stdout.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.rs (renamed from src/tools/miri/tests/fail/shims/fs/isolated_stdin.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.stderr (renamed from src/tools/miri/tests/fail/shims/fs/isolated_stdin.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.rs (renamed from src/tools/miri/tests/fail/shims/fs/mkstemp_immutable_arg.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.stderr (renamed from src/tools/miri/tests/fail/shims/fs/mkstemp_immutable_arg.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.rs (renamed from src/tools/miri/tests/fail/shims/fs/read_from_stdout.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr (renamed from src/tools/miri/tests/fail/shims/fs/read_from_stdout.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.rs (renamed from src/tools/miri/tests/fail/shims/fs/unix_open_missing_required_mode.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.stderr (renamed from src/tools/miri/tests/fail/shims/fs/unix_open_missing_required_mode.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.rs (renamed from src/tools/miri/tests/fail/shims/fs/write_to_stdin.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr (renamed from src/tools/miri/tests/fail/shims/fs/write_to_stdin.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/memchr_null.rs (renamed from src/tools/miri/tests/fail/shims/memchr_null.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/memchr_null.stderr (renamed from src/tools/miri/tests/fail/shims/memchr_null.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/memcmp_null.rs (renamed from src/tools/miri/tests/fail/shims/memcmp_null.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/memcmp_null.stderr (renamed from src/tools/miri/tests/fail/shims/memcmp_null.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/memcmp_zero.rs (renamed from src/tools/miri/tests/fail/shims/memcmp_zero.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/memcmp_zero.stderr (renamed from src/tools/miri/tests/fail/shims/memcmp_zero.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/memcpy_zero.rs (renamed from src/tools/miri/tests/fail/shims/memcpy_zero.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/memcpy_zero.stderr (renamed from src/tools/miri/tests/fail/shims/memcpy_zero.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/memrchr_null.rs (renamed from src/tools/miri/tests/fail/shims/memrchr_null.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/memrchr_null.stderr (renamed from src/tools/miri/tests/fail/shims/memrchr_null.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.rs (renamed from src/tools/miri/tests/fail/shims/mmap_invalid_dealloc.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.stderr (renamed from src/tools/miri/tests/fail/shims/mmap_invalid_dealloc.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.rs (renamed from src/tools/miri/tests/fail/shims/mmap_use_after_munmap.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.stderr (renamed from src/tools/miri/tests/fail/shims/mmap_use_after_munmap.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/munmap.rs (renamed from src/tools/miri/tests/fail/shims/munmap.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/munmap.stderr (renamed from src/tools/miri/tests/fail/shims/munmap.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/munmap_partial.rs (renamed from src/tools/miri/tests/fail/shims/munmap_partial.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/munmap_partial.stderr (renamed from src/tools/miri/tests/fail/shims/munmap_partial.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_cond_double_destroy.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_cond_double_destroy.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_condattr_double_destroy.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_condattr_double_destroy.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_NULL_deadlock.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_NULL_deadlock.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_deadlock.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_deadlock.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_default_deadlock.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_default_deadlock.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_destroy_locked.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_destroy_locked.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_double_destroy.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_double_destroy.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_deadlock.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_deadlock.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_wrong_owner.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_wrong_owner.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutexattr_double_destroy.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_mutexattr_double_destroy.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_read_locked.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_read_locked.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_write_locked.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_write_locked.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_double_destroy.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_double_destroy.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_wrong_owner.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_wrong_owner.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_unlock_unlocked.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_unlock_unlocked.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.rs (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_wrong_owner.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.stderr (renamed from src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_wrong_owner.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/tokio/sleep.rs (renamed from src/tools/miri/tests/fail/tokio/sleep.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/tokio/sleep.stderr (renamed from src/tools/miri/tests/fail/tokio/sleep.stderr)0
-rw-r--r--src/tools/miri/tests/fail-dep/unsupported_incomplete_function.rs (renamed from src/tools/miri/tests/fail/unsupported_incomplete_function.rs)0
-rw-r--r--src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr (renamed from src/tools/miri/tests/fail/unsupported_incomplete_function.stderr)0
-rw-r--r--src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr2
-rw-r--r--src/tools/miri/tests/fail/panic/bad_miri_start_panic.stderr2
-rw-r--r--src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr4
-rw-r--r--src/tools/miri/tests/pass/backtrace/backtrace-api-v0.rs2
-rw-r--r--src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stderr15
-rw-r--r--src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stdout2
-rw-r--r--src/tools/miri/tests/pass/backtrace/backtrace-api-v1.rs2
-rw-r--r--src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr15
-rw-r--r--src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stdout2
-rw-r--r--src/tools/miri/tests/pass/function_calls/disable_abi_check.stderr2
-rw-r--r--src/tools/miri/tests/pass/function_pointers.rs20
-rw-r--r--src/tools/miri/tests/pass/intrinsics-x86-avx512.rs217
-rw-r--r--src/tools/miri/tests/pass/intrinsics-x86-sse.rs2019
-rw-r--r--src/tools/miri/tests/pass/intrinsics-x86-sse2.rs1495
-rw-r--r--src/tools/miri/tests/pass/intrinsics-x86.rs79
-rw-r--r--src/tools/miri/tests/pass/portable-simd.rs21
-rw-r--r--src/tools/miri/triagebot.toml5
-rw-r--r--src/tools/tidy/src/deps.rs8
-rw-r--r--src/tools/tidy/src/pal.rs1
-rw-r--r--tests/assembly/closure-inherit-target-feature.rs58
-rw-r--r--tests/codegen/async-fn-debug-awaitee-field.rs10
-rw-r--r--tests/codegen/macos/i686-macosx-deployment-target.rs4
-rw-r--r--tests/codegen/macos/i686-no-macosx-deployment-target.rs2
-rw-r--r--tests/codegen/macos/x86_64-macosx-deployment-target.rs4
-rw-r--r--tests/codegen/macos/x86_64-no-macosx-deployment-target.rs2
-rw-r--r--tests/codegen/vecdeque-nonempty-get-no-panic.rs17
-rw-r--r--tests/incremental/change_crate_dep_kind.rs1
-rw-r--r--tests/incremental/hashes/function_interfaces.rs2
-rw-r--r--tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir16
-rw-r--r--tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir102
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-abort.diff119
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-unwind.diff123
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-abort.diff119
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-unwind.diff123
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff111
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff115
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff111
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff115
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs17
-rw-r--r--tests/mir-opt/gvn.arithmetic.GVN.panic-abort.diff342
-rw-r--r--tests/mir-opt/gvn.arithmetic.GVN.panic-unwind.diff342
-rw-r--r--tests/mir-opt/gvn.arithmetic_checked.GVN.panic-abort.diff389
-rw-r--r--tests/mir-opt/gvn.arithmetic_checked.GVN.panic-unwind.diff389
-rw-r--r--tests/mir-opt/gvn.arithmetic_float.GVN.panic-abort.diff165
-rw-r--r--tests/mir-opt/gvn.arithmetic_float.GVN.panic-unwind.diff165
-rw-r--r--tests/mir-opt/gvn.cast.GVN.panic-abort.diff501
-rw-r--r--tests/mir-opt/gvn.cast.GVN.panic-unwind.diff501
-rw-r--r--tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff191
-rw-r--r--tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff191
-rw-r--r--tests/mir-opt/gvn.multiple_branches.GVN.panic-abort.diff198
-rw-r--r--tests/mir-opt/gvn.multiple_branches.GVN.panic-unwind.diff198
-rw-r--r--tests/mir-opt/gvn.references.GVN.panic-abort.diff105
-rw-r--r--tests/mir-opt/gvn.references.GVN.panic-unwind.diff113
-rw-r--r--tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff76
-rw-r--r--tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff76
-rw-r--r--tests/mir-opt/gvn.rs253
-rw-r--r--tests/mir-opt/gvn.slices.GVN.panic-abort.diff275
-rw-r--r--tests/mir-opt/gvn.slices.GVN.panic-unwind.diff275
-rw-r--r--tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff883
-rw-r--r--tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff883
-rw-r--r--tests/mir-opt/gvn.wrap_unwrap.GVN.panic-abort.diff45
-rw-r--r--tests/mir-opt/gvn.wrap_unwrap.GVN.panic-unwind.diff45
-rw-r--r--tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir4
-rw-r--r--tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff81
-rw-r--r--tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff54
-rw-r--r--tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff26
-rw-r--r--tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff24
-rw-r--r--tests/mir-opt/ssa_unreachable_116212.rs14
-rw-r--r--tests/run-make/macos-deployment-target/Makefile4
-rw-r--r--tests/run-make/rlib-format-packed-bundled-libs-3/Makefile4
-rw-r--r--tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs2
-rw-r--r--tests/rustdoc-gui/default-settings.goml2
-rw-r--r--tests/rustdoc-ui/issue-102467.rs15
-rw-r--r--tests/rustdoc-ui/issue-102467.stderr9
-rw-r--r--tests/rustdoc/anchor-id-trait-method-15169.rs (renamed from tests/rustdoc/issue-15169.rs)4
-rw-r--r--tests/rustdoc/assoc-type-bindings-20646.rs (renamed from tests/rustdoc/issue-20646.rs)2
-rw-r--r--tests/rustdoc/deref-methods-19190-foreign-type.rs (renamed from tests/rustdoc/issue-19190-2.rs)4
-rw-r--r--tests/rustdoc/deref-methods-19190-inline.rs (renamed from tests/rustdoc/issue-19190-3.rs)3
-rw-r--r--tests/rustdoc/deref-methods-19190.rs (renamed from tests/rustdoc/issue-19190.rs)3
-rw-r--r--tests/rustdoc/doc-hidden-method-13698.rs (renamed from tests/rustdoc/issue-13698.rs)3
-rw-r--r--tests/rustdoc/doc-test-attr-18199.rs (renamed from tests/rustdoc/issue-18199.rs)1
-rw-r--r--tests/rustdoc/document-hidden-items-15347.rs (renamed from tests/rustdoc/issue-15347.rs)3
-rw-r--r--tests/rustdoc/highlight-invalid-rust-12834.rs (renamed from tests/rustdoc/issue-12834.rs)2
-rw-r--r--tests/rustdoc/ice-type-error-19181.rs (renamed from tests/rustdoc/issue-19181.rs)1
-rw-r--r--tests/rustdoc/impl-ref-20175.rs (renamed from tests/rustdoc/issue-20175.rs)4
-rw-r--r--tests/rustdoc/infinite-redirection-16265-1.rs (renamed from tests/rustdoc/issue-16265-1.rs)3
-rw-r--r--tests/rustdoc/infinite-redirection-16265-2.rs (renamed from tests/rustdoc/issue-16265-2.rs)3
-rw-r--r--tests/rustdoc/inline-assoc-type-20727-bindings.rs (renamed from tests/rustdoc/issue-20727-2.rs)3
-rw-r--r--tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs (renamed from tests/rustdoc/issue-20727-3.rs)3
-rw-r--r--tests/rustdoc/inline-assoc-type-20727-bounds-index.rs (renamed from tests/rustdoc/issue-20727-4.rs)3
-rw-r--r--tests/rustdoc/inline-assoc-type-20727-bounds.rs (renamed from tests/rustdoc/issue-20727.rs)3
-rw-r--r--tests/rustdoc/inline_cross/async-fn.rs19
-rw-r--r--tests/rustdoc/inline_cross/auxiliary/async-fn.rs18
-rw-r--r--tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs6
-rw-r--r--tests/rustdoc/inline_cross/impl_trait.rs8
-rw-r--r--tests/rustdoc/macro-ice-16019.rs (renamed from tests/rustdoc/issue-16019.rs)2
-rw-r--r--tests/rustdoc/method-link-foreign-trait-impl-17476.rs (renamed from tests/rustdoc/issue-17476.rs)3
-rw-r--r--tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs (renamed from tests/rustdoc/issue-15318-3.rs)2
-rw-r--r--tests/rustdoc/primitive-raw-pointer-link-15318.rs (renamed from tests/rustdoc/issue-15318.rs)2
-rw-r--r--tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs (renamed from tests/rustdoc/issue-15318-2.rs)3
-rw-r--r--tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs2
-rw-r--r--tests/ui-fulldeps/internal-lints/ty_tykind_usage.rs1
-rw-r--r--tests/ui-fulldeps/internal-lints/ty_tykind_usage.stderr32
-rw-r--r--tests/ui-fulldeps/lint-pass-macros.rs2
-rw-r--r--tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs3
-rw-r--r--tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs6
-rw-r--r--tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs6
-rw-r--r--tests/ui-fulldeps/stable-mir/compilation-result.rs3
-rw-r--r--tests/ui-fulldeps/stable-mir/crate-info.rs30
-rw-r--r--tests/ui/abi/compatibility.rs183
-rw-r--r--tests/ui/abi/relocation_model_pic.rs3
-rw-r--r--tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs8
-rw-r--r--tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.stderr55
-rw-r--r--tests/ui/associated-types/defaults-specialization.stderr4
-rw-r--r--tests/ui/async-await/async-await-let-else.drop-tracking.stderr106
-rw-r--r--tests/ui/async-await/async-await-let-else.drop_tracking.stderr106
-rw-r--r--tests/ui/async-await/async-await-let-else.no-drop-tracking.stderr90
-rw-r--r--tests/ui/async-await/async-await-let-else.no_drop_tracking.stderr90
-rw-r--r--tests/ui/async-await/async-await-let-else.rs3
-rw-r--r--tests/ui/async-await/async-await-let-else.stderr (renamed from tests/ui/async-await/async-await-let-else.drop_tracking_mir.stderr)26
-rw-r--r--tests/ui/async-await/async-error-span.drop_tracking.stderr25
-rw-r--r--tests/ui/async-await/async-error-span.no_drop_tracking.stderr25
-rw-r--r--tests/ui/async-await/async-error-span.rs7
-rw-r--r--tests/ui/async-await/async-error-span.stderr (renamed from tests/ui/async-await/async-error-span.drop_tracking_mir.stderr)4
-rw-r--r--tests/ui/async-await/async-fn-nonsend.drop_tracking.stderr49
-rw-r--r--tests/ui/async-await/async-fn-nonsend.no_drop_tracking.stderr120
-rw-r--r--tests/ui/async-await/async-fn-nonsend.rs6
-rw-r--r--tests/ui/async-await/async-fn-nonsend.stderr (renamed from tests/ui/async-await/async-fn-nonsend.drop_tracking_mir.stderr)12
-rw-r--r--tests/ui/async-await/async-is-unwindsafe.stderr14
-rw-r--r--tests/ui/async-await/await-sequence.rs1
-rw-r--r--tests/ui/async-await/awaiting-unsized-param.rs13
-rw-r--r--tests/ui/async-await/awaiting-unsized-param.stderr21
-rw-r--r--tests/ui/async-await/const-async-fn-in-main.rs7
-rw-r--r--tests/ui/async-await/const-async-fn-in-main.stderr11
-rw-r--r--tests/ui/async-await/default-struct-update.rs3
-rw-r--r--tests/ui/async-await/drop-and-assign.rs3
-rw-r--r--tests/ui/async-await/drop-track-bad-field-in-fru.rs1
-rw-r--r--tests/ui/async-await/drop-track-bad-field-in-fru.stderr4
-rw-r--r--tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking.stderr25
-rw-r--r--tests/ui/async-await/drop-track-field-assign-nonsend.no_drop_tracking.stderr25
-rw-r--r--tests/ui/async-await/drop-track-field-assign-nonsend.rs3
-rw-r--r--tests/ui/async-await/drop-track-field-assign-nonsend.stderr (renamed from tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking_mir.stderr)6
-rw-r--r--tests/ui/async-await/drop-track-field-assign.rs3
-rw-r--r--tests/ui/async-await/drop-tracking-unresolved-typeck-results.rs3
-rw-r--r--tests/ui/async-await/drop-tracking-unresolved-typeck-results.stderr40
-rw-r--r--tests/ui/async-await/feature-self-return-type.rs1
-rw-r--r--tests/ui/async-await/feature-self-return-type.stderr2
-rw-r--r--tests/ui/async-await/field-assign-nonsend.drop_tracking.stderr25
-rw-r--r--tests/ui/async-await/field-assign-nonsend.no_drop_tracking.stderr25
-rw-r--r--tests/ui/async-await/field-assign-nonsend.rs3
-rw-r--r--tests/ui/async-await/field-assign-nonsend.stderr (renamed from tests/ui/async-await/field-assign-nonsend.drop_tracking_mir.stderr)6
-rw-r--r--tests/ui/async-await/field-assign.rs3
-rw-r--r--tests/ui/async-await/in-trait/async-associated-types.rs1
-rw-r--r--tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs2
-rw-r--r--tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr9
-rw-r--r--tests/ui/async-await/issue-61949-self-return-type.rs28
-rw-r--r--tests/ui/async-await/issue-61949-self-return-type.stderr26
-rw-r--r--tests/ui/async-await/issue-64130-1-sync.drop_tracking.stderr25
-rw-r--r--tests/ui/async-await/issue-64130-1-sync.no_drop_tracking.stderr25
-rw-r--r--tests/ui/async-await/issue-64130-1-sync.rs3
-rw-r--r--tests/ui/async-await/issue-64130-1-sync.stderr (renamed from tests/ui/async-await/issue-64130-1-sync.drop_tracking_mir.stderr)6
-rw-r--r--tests/ui/async-await/issue-64130-2-send.drop_tracking.stderr28
-rw-r--r--tests/ui/async-await/issue-64130-2-send.no_drop_tracking.stderr28
-rw-r--r--tests/ui/async-await/issue-64130-2-send.rs6
-rw-r--r--tests/ui/async-await/issue-64130-2-send.stderr (renamed from tests/ui/async-await/issue-64130-2-send.drop_tracking_mir.stderr)16
-rw-r--r--tests/ui/async-await/issue-64130-3-other.drop_tracking.stderr27
-rw-r--r--tests/ui/async-await/issue-64130-3-other.no_drop_tracking.stderr27
-rw-r--r--tests/ui/async-await/issue-64130-3-other.rs6
-rw-r--r--tests/ui/async-await/issue-64130-3-other.stderr (renamed from tests/ui/async-await/issue-64130-3-other.drop_tracking_mir.stderr)10
-rw-r--r--tests/ui/async-await/issue-64130-4-async-move.drop-tracking.stderr26
-rw-r--r--tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr26
-rw-r--r--tests/ui/async-await/issue-64130-4-async-move.rs7
-rw-r--r--tests/ui/async-await/issue-64130-non-send-future-diags.stderr2
-rw-r--r--tests/ui/async-await/issue-67252-unnamed-future.drop_tracking.stderr30
-rw-r--r--tests/ui/async-await/issue-67252-unnamed-future.no_drop_tracking.stderr30
-rw-r--r--tests/ui/async-await/issue-67252-unnamed-future.rs5
-rw-r--r--tests/ui/async-await/issue-67252-unnamed-future.stderr (renamed from tests/ui/async-await/issue-67252-unnamed-future.drop_tracking_mir.stderr)8
-rw-r--r--tests/ui/async-await/issue-68112.drop_tracking.stderr82
-rw-r--r--tests/ui/async-await/issue-68112.no_drop_tracking.stderr82
-rw-r--r--tests/ui/async-await/issue-68112.rs3
-rw-r--r--tests/ui/async-await/issue-68112.stderr (renamed from tests/ui/async-await/issue-68112.drop_tracking_mir.stderr)22
-rw-r--r--tests/ui/async-await/issue-70818.drop_tracking.stderr18
-rw-r--r--tests/ui/async-await/issue-70818.no_drop_tracking.stderr18
-rw-r--r--tests/ui/async-await/issue-70818.rs3
-rw-r--r--tests/ui/async-await/issue-70818.stderr (renamed from tests/ui/async-await/issue-70818.drop_tracking_mir.stderr)4
-rw-r--r--tests/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr41
-rw-r--r--tests/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr21
-rw-r--r--tests/ui/async-await/issue-70935-complex-spans.rs6
-rw-r--r--tests/ui/async-await/issue-70935-complex-spans.stderr (renamed from tests/ui/async-await/issue-70935-complex-spans.drop_tracking_mir.stderr)10
-rw-r--r--tests/ui/async-await/issue-71137.stderr3
-rw-r--r--tests/ui/async-await/issue-73137.rs3
-rw-r--r--tests/ui/async-await/issue-73741-type-err-drop-tracking.drop_tracking.stderr11
-rw-r--r--tests/ui/async-await/issue-73741-type-err-drop-tracking.drop_tracking_mir.stderr11
-rw-r--r--tests/ui/async-await/issue-73741-type-err-drop-tracking.no_drop_tracking.stderr11
-rw-r--r--tests/ui/async-await/issue-73741-type-err-drop-tracking.rs17
-rw-r--r--tests/ui/async-await/issue-86507.drop_tracking_mir.stderr23
-rw-r--r--tests/ui/async-await/issue-86507.no_drop_tracking.stderr23
-rw-r--r--tests/ui/async-await/issue-86507.rs3
-rw-r--r--tests/ui/async-await/issue-86507.stderr (renamed from tests/ui/async-await/issue-86507.drop_tracking.stderr)6
-rw-r--r--tests/ui/async-await/issue-93197.rs1
-rw-r--r--tests/ui/async-await/issue-93648.rs3
-rw-r--r--tests/ui/async-await/issues/auxiliary/issue_67893.rs7
-rw-r--r--tests/ui/async-await/issues/issue-107280.rs5
-rw-r--r--tests/ui/async-await/issues/issue-107280.stderr67
-rw-r--r--tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr32
-rw-r--r--tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs7
-rw-r--r--tests/ui/async-await/issues/issue-67611-static-mut-refs.rs4
-rw-r--r--tests/ui/async-await/issues/issue-67893.rs2
-rw-r--r--tests/ui/async-await/issues/issue-67893.stderr28
-rw-r--r--tests/ui/async-await/issues/issue-78600.rs2
-rw-r--r--tests/ui/async-await/issues/issue-78600.stderr14
-rw-r--r--tests/ui/async-await/mutually-recursive-async-impl-trait-type.drop_tracking.stderr21
-rw-r--r--tests/ui/async-await/mutually-recursive-async-impl-trait-type.no_drop_tracking.stderr21
-rw-r--r--tests/ui/async-await/mutually-recursive-async-impl-trait-type.rs4
-rw-r--r--tests/ui/async-await/mutually-recursive-async-impl-trait-type.stderr (renamed from tests/ui/async-await/mutually-recursive-async-impl-trait-type.drop_tracking_mir.stderr)4
-rw-r--r--tests/ui/async-await/non-trivial-drop.rs3
-rw-r--r--tests/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr35
-rw-r--r--tests/ui/async-await/partial-drop-partial-reinit.rs3
-rw-r--r--tests/ui/async-await/partial-drop-partial-reinit.stderr (renamed from tests/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr)8
-rw-r--r--tests/ui/async-await/recursive-async-impl-trait-type.drop_tracking.stderr12
-rw-r--r--tests/ui/async-await/recursive-async-impl-trait-type.no_drop_tracking.stderr12
-rw-r--r--tests/ui/async-await/recursive-async-impl-trait-type.rs3
-rw-r--r--tests/ui/async-await/recursive-async-impl-trait-type.stderr (renamed from tests/ui/async-await/recursive-async-impl-trait-type.drop_tracking_mir.stderr)2
-rw-r--r--tests/ui/async-await/return-type-notation/issue-110963-early.current.stderr25
-rw-r--r--tests/ui/async-await/return-type-notation/issue-110963-early.next.stderr25
-rw-r--r--tests/ui/async-await/return-type-notation/issue-110963-early.stderr25
-rw-r--r--tests/ui/async-await/unresolved_type_param.drop_tracking.stderr39
-rw-r--r--tests/ui/async-await/unresolved_type_param.no_drop_tracking.stderr63
-rw-r--r--tests/ui/async-await/unresolved_type_param.rs26
-rw-r--r--tests/ui/async-await/unresolved_type_param.stderr (renamed from tests/ui/async-await/unresolved_type_param.drop_tracking_mir.stderr)2
-rw-r--r--tests/ui/async-await/unsized-across-await.rs16
-rw-r--r--tests/ui/async-await/unsized-across-await.stderr21
-rw-r--r--tests/ui/borrowck/async-reference-generality.rs3
-rw-r--r--tests/ui/borrowck/async-reference-generality.stderr27
-rw-r--r--tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs23
-rw-r--r--tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr24
-rw-r--r--tests/ui/closures/capture-unsized-by-move.rs10
-rw-r--r--tests/ui/closures/capture-unsized-by-move.stderr14
-rw-r--r--tests/ui/closures/capture-unsized-by-ref.rs10
-rw-r--r--tests/ui/closures/issue-112547.rs15
-rw-r--r--tests/ui/closures/issue-112547.stderr23
-rw-r--r--tests/ui/codegen/issue-79865-llvm-miscompile.rs38
-rw-r--r--tests/ui/codegen/subtyping-enforces-type-equality.stderr1
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs2
-rw-r--r--tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr35
-rw-r--r--tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs44
-rw-r--r--tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr80
-rw-r--r--tests/ui/const-generics/const-param-elided-lifetime.min.stderr10
-rw-r--r--tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr4
-rw-r--r--tests/ui/const-generics/float-generic.simple.stderr1
-rw-r--r--tests/ui/const-generics/fn-const-param-call.min.stderr4
-rw-r--r--tests/ui/const-generics/fn-const-param-infer.min.stderr2
-rw-r--r--tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr2
-rw-r--r--tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-56445-1.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-62878.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-68615-adt.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-68615-array.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-71169.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-71381.min.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-71382.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-71611.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-72352.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-73491.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-74101.min.stderr4
-rw-r--r--tests/ui/const-generics/issues/issue-74255.min.stderr2
-rw-r--r--tests/ui/const-generics/issues/issue-74950.min.stderr10
-rw-r--r--tests/ui/const-generics/issues/issue-75047.min.stderr2
-rw-r--r--tests/ui/const-generics/lifetime-in-const-param.stderr2
-rw-r--r--tests/ui/const-generics/min_const_generics/complex-types.stderr13
-rw-r--r--tests/ui/const-generics/nested-type.min.stderr2
-rw-r--r--tests/ui/const-generics/projection-as-arg-const.stderr1
-rw-r--r--tests/ui/const-generics/raw-ptr-const-param-deref.min.stderr4
-rw-r--r--tests/ui/const-generics/raw-ptr-const-param.min.stderr2
-rw-r--r--tests/ui/const-generics/slice-const-param-mismatch.min.stderr4
-rw-r--r--tests/ui/const-generics/std/const-generics-range.min.stderr12
-rw-r--r--tests/ui/const-generics/transmute-const-param-static-reference.min.stderr2
-rw-r--r--tests/ui/const-generics/type-dependent/issue-71348.min.stderr4
-rw-r--r--tests/ui/const-generics/type-dependent/issue-71382.stderr2
-rw-r--r--tests/ui/consts/const_in_pattern/issue-65466.rs3
-rw-r--r--tests/ui/consts/const_in_pattern/issue-65466.stderr23
-rw-r--r--tests/ui/did_you_mean/bad-assoc-expr.stderr62
-rw-r--r--tests/ui/did_you_mean/bad-assoc-pat.stderr41
-rw-r--r--tests/ui/did_you_mean/bad-assoc-ty.stderr62
-rw-r--r--tests/ui/error-codes/E0094.rs2
-rw-r--r--tests/ui/error-codes/E0374.stderr4
-rw-r--r--tests/ui/error-codes/E0377.stderr4
-rw-r--r--tests/ui/extern/extern-with-type-bounds.rs2
-rw-r--r--tests/ui/feature-gates/feature-gate-adt_const_params.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-proc_macro_byte_character.rs10
-rw-r--r--tests/ui/feature-gates/feature-gate-proc_macro_byte_character.stderr12
-rw-r--r--tests/ui/foreign/foreign-fn-linkname.rs3
-rw-r--r--tests/ui/generator/addassign-yield.rs3
-rw-r--r--tests/ui/generator/auto-trait-regions.drop_tracking.stderr55
-rw-r--r--tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr55
-rw-r--r--tests/ui/generator/auto-trait-regions.rs3
-rw-r--r--tests/ui/generator/auto-trait-regions.stderr (renamed from tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr)8
-rw-r--r--tests/ui/generator/borrowing.drop_tracking.stderr31
-rw-r--r--tests/ui/generator/borrowing.no_drop_tracking.stderr31
-rw-r--r--tests/ui/generator/borrowing.rs4
-rw-r--r--tests/ui/generator/borrowing.stderr (renamed from tests/ui/generator/borrowing.drop_tracking_mir.stderr)4
-rw-r--r--tests/ui/generator/clone-impl.stderr30
-rw-r--r--tests/ui/generator/derived-drop-parent-expr.rs1
-rw-r--r--tests/ui/generator/drop-control-flow.rs1
-rw-r--r--tests/ui/generator/drop-track-addassign-yield.rs1
-rw-r--r--tests/ui/generator/drop-tracking-error-body.rs18
-rw-r--r--tests/ui/generator/drop-tracking-error-body.stderr17
-rw-r--r--tests/ui/generator/drop-tracking-parent-expression.drop_tracking.stderr128
-rw-r--r--tests/ui/generator/drop-tracking-parent-expression.no_drop_tracking.stderr334
-rw-r--r--tests/ui/generator/drop-tracking-parent-expression.rs11
-rw-r--r--tests/ui/generator/drop-tracking-parent-expression.stderr (renamed from tests/ui/generator/drop-tracking-parent-expression.drop_tracking_mir.stderr)24
-rw-r--r--tests/ui/generator/drop-tracking-yielding-in-match-guards.rs3
-rw-r--r--tests/ui/generator/drop-yield-twice.stderr15
-rw-r--r--tests/ui/generator/issue-102645.rs2
-rw-r--r--tests/ui/generator/issue-102645.stderr2
-rw-r--r--tests/ui/generator/issue-105084.rs12
-rw-r--r--tests/ui/generator/issue-105084.stderr (renamed from tests/ui/generator/issue-105084.drop_tracking_mir.stderr)18
-rw-r--r--tests/ui/generator/issue-110929-generator-conflict-error-ice.rs1
-rw-r--r--tests/ui/generator/issue-110929-generator-conflict-error-ice.stderr2
-rw-r--r--tests/ui/generator/issue-57017.no_drop_tracking.stderr248
-rw-r--r--tests/ui/generator/issue-57017.rs13
-rw-r--r--tests/ui/generator/issue-57478.no_drop_tracking.stderr31
-rw-r--r--tests/ui/generator/issue-57478.rs7
-rw-r--r--tests/ui/generator/issue-68112.drop_tracking.stderr66
-rw-r--r--tests/ui/generator/issue-68112.no_drop_tracking.stderr66
-rw-r--r--tests/ui/generator/issue-68112.rs6
-rw-r--r--tests/ui/generator/issue-68112.stderr (renamed from tests/ui/generator/issue-68112.drop_tracking_mir.stderr)18
-rw-r--r--tests/ui/generator/issue-93161.rs3
-rw-r--r--tests/ui/generator/not-send-sync.drop_tracking.stderr60
-rw-r--r--tests/ui/generator/not-send-sync.no_drop_tracking.stderr60
-rw-r--r--tests/ui/generator/not-send-sync.rs3
-rw-r--r--tests/ui/generator/not-send-sync.stderr (renamed from tests/ui/generator/not-send-sync.drop_tracking_mir.stderr)16
-rw-r--r--tests/ui/generator/parent-expression.drop_tracking.stderr128
-rw-r--r--tests/ui/generator/parent-expression.no_drop_tracking.stderr334
-rw-r--r--tests/ui/generator/parent-expression.rs9
-rw-r--r--tests/ui/generator/parent-expression.stderr (renamed from tests/ui/generator/parent-expression.drop_tracking_mir.stderr)24
-rw-r--r--tests/ui/generator/partial-drop.drop_tracking.stderr61
-rw-r--r--tests/ui/generator/partial-drop.no_drop_tracking.stderr61
-rw-r--r--tests/ui/generator/partial-drop.rs15
-rw-r--r--tests/ui/generator/print/generator-print-verbose-1.drop_tracking.stderr64
-rw-r--r--tests/ui/generator/print/generator-print-verbose-1.no_drop_tracking.stderr64
-rw-r--r--tests/ui/generator/print/generator-print-verbose-1.rs3
-rw-r--r--tests/ui/generator/print/generator-print-verbose-1.stderr (renamed from tests/ui/generator/print/generator-print-verbose-1.drop_tracking_mir.stderr)18
-rw-r--r--tests/ui/generator/print/generator-print-verbose-2.drop_tracking.stderr60
-rw-r--r--tests/ui/generator/print/generator-print-verbose-2.no_drop_tracking.stderr60
-rw-r--r--tests/ui/generator/print/generator-print-verbose-2.rs3
-rw-r--r--tests/ui/generator/print/generator-print-verbose-2.stderr (renamed from tests/ui/generator/print/generator-print-verbose-2.drop_tracking_mir.stderr)12
-rw-r--r--tests/ui/generator/retain-resume-ref.drop_tracking.stderr13
-rw-r--r--tests/ui/generator/retain-resume-ref.no_drop_tracking.stderr13
-rw-r--r--tests/ui/generator/retain-resume-ref.rs4
-rw-r--r--tests/ui/generator/retain-resume-ref.stderr (renamed from tests/ui/generator/retain-resume-ref.drop_tracking_mir.stderr)2
-rw-r--r--tests/ui/generator/static-mut-reference-across-yield.rs4
-rw-r--r--tests/ui/generator/unresolved-ct-var-drop-tracking.rs15
-rw-r--r--tests/ui/generator/unresolved-ct-var-drop-tracking.stderr78
-rw-r--r--tests/ui/generator/unresolved-ct-var.rs5
-rw-r--r--tests/ui/generator/unresolved-ct-var.stderr65
-rw-r--r--tests/ui/generator/unsized-capture-across-yield.rs22
-rw-r--r--tests/ui/generator/unsized-capture-across-yield.stderr23
-rw-r--r--tests/ui/generator/unsized-local-across-yield.rs21
-rw-r--r--tests/ui/generator/unsized-local-across-yield.stderr21
-rw-r--r--tests/ui/generic-associated-types/bugs/issue-100013.stderr30
-rw-r--r--tests/ui/generic-const-items/elided-lifetimes.stderr2
-rw-r--r--tests/ui/generics/issue-83556.rs4
-rw-r--r--tests/ui/generics/issue-83556.stderr8
-rw-r--r--tests/ui/impl-trait/bound-normalization-fail.rs3
-rw-r--r--tests/ui/impl-trait/bound-normalization-fail.stderr16
-rw-r--r--tests/ui/impl-trait/capture-lifetime-not-in-hir.rs21
-rw-r--r--tests/ui/impl-trait/capture-lifetime-not-in-hir.stderr14
-rw-r--r--tests/ui/impl-trait/feature-self-return-type.rs1
-rw-r--r--tests/ui/impl-trait/feature-self-return-type.stderr6
-rw-r--r--tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs13
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs26
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr16
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs23
-rw-r--r--tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr16
-rw-r--r--tests/ui/impl-trait/issue-55872-2.drop_tracking.stderr8
-rw-r--r--tests/ui/impl-trait/issue-55872-2.no_drop_tracking.stderr8
-rw-r--r--tests/ui/impl-trait/issue-55872-2.rs5
-rw-r--r--tests/ui/impl-trait/issue-55872-2.stderr (renamed from tests/ui/impl-trait/issue-55872-2.drop_tracking_mir.stderr)4
-rw-r--r--tests/ui/impl-trait/opaque-cast-field-access-in-future.rs27
-rw-r--r--tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr9
-rw-r--r--tests/ui/impl-trait/recursive-generator.rs1
-rw-r--r--tests/ui/impl-trait/recursive-generator.stderr15
-rw-r--r--tests/ui/impl-trait/recursive-impl-trait-type-indirect.drop_tracking.stderr152
-rw-r--r--tests/ui/impl-trait/recursive-impl-trait-type-indirect.no_drop_tracking.stderr152
-rw-r--r--tests/ui/impl-trait/recursive-impl-trait-type-indirect.rs4
-rw-r--r--tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr (renamed from tests/ui/impl-trait/recursive-impl-trait-type-indirect.drop_tracking_mir.stderr)38
-rw-r--r--tests/ui/intrinsics/feature-gate-safe-intrinsic.rs6
-rw-r--r--tests/ui/intrinsics/feature-gate-safe-intrinsic.stderr20
-rw-r--r--tests/ui/intrinsics/intrinsic-alignment.rs2
-rw-r--r--tests/ui/invalid_dispatch_from_dyn_impls.stderr4
-rw-r--r--tests/ui/issues/issue-27042.stderr15
-rw-r--r--tests/ui/lifetimes/unusual-rib-combinations.stderr4
-rw-r--r--tests/ui/lint/must_not_suspend/dedup.drop_tracking_mir.stderr21
-rw-r--r--tests/ui/lint/must_not_suspend/dedup.no_drop_tracking.stderr33
-rw-r--r--tests/ui/lint/must_not_suspend/dedup.rs8
-rw-r--r--tests/ui/lint/must_not_suspend/dedup.stderr (renamed from tests/ui/lint/must_not_suspend/dedup.drop_tracking.stderr)7
-rw-r--r--tests/ui/lint/must_not_suspend/ref-drop-tracking.rs30
-rw-r--r--tests/ui/lint/must_not_suspend/ref-drop-tracking.stderr27
-rw-r--r--tests/ui/lint/must_not_suspend/ref.drop_tracking.stderr27
-rw-r--r--tests/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr27
-rw-r--r--tests/ui/lint/must_not_suspend/ref.rs5
-rw-r--r--tests/ui/lint/must_not_suspend/ref.stderr (renamed from tests/ui/lint/must_not_suspend/ref.drop_tracking_mir.stderr)8
-rw-r--r--tests/ui/lint/must_not_suspend/trait.drop_tracking_mir.stderr37
-rw-r--r--tests/ui/lint/must_not_suspend/trait.no_drop_tracking.stderr37
-rw-r--r--tests/ui/lint/must_not_suspend/trait.rs6
-rw-r--r--tests/ui/lint/must_not_suspend/trait.stderr (renamed from tests/ui/lint/must_not_suspend/trait.drop_tracking.stderr)10
-rw-r--r--tests/ui/lint/must_not_suspend/unit.drop_tracking_mir.stderr26
-rw-r--r--tests/ui/lint/must_not_suspend/unit.no_drop_tracking.stderr26
-rw-r--r--tests/ui/lint/must_not_suspend/unit.rs4
-rw-r--r--tests/ui/lint/must_not_suspend/unit.stderr (renamed from tests/ui/lint/must_not_suspend/unit.drop_tracking.stderr)8
-rw-r--r--tests/ui/lint/must_not_suspend/warn.drop_tracking.stderr26
-rw-r--r--tests/ui/lint/must_not_suspend/warn.no_drop_tracking.stderr26
-rw-r--r--tests/ui/lint/must_not_suspend/warn.rs7
-rw-r--r--tests/ui/lint/must_not_suspend/warn.stderr (renamed from tests/ui/lint/must_not_suspend/warn.drop_tracking_mir.stderr)20
-rw-r--r--tests/ui/lint/noop-method-call.fixed13
-rw-r--r--tests/ui/lint/noop-method-call.rs13
-rw-r--r--tests/ui/lint/noop-method-call.stderr14
-rw-r--r--tests/ui/lint/reference_casting.rs23
-rw-r--r--tests/ui/lint/reference_casting.stderr101
-rw-r--r--tests/ui/loops/loop-break-value.rs63
-rw-r--r--tests/ui/loops/loop-break-value.stderr153
-rw-r--r--tests/ui/loops/loop-labeled-break-value.stderr39
-rw-r--r--tests/ui/loops/loop-properly-diverging-2.stderr13
-rw-r--r--tests/ui/match/issue-72896-non-partial-eq-const.rs (renamed from tests/ui/match/issue-72896.rs)3
-rw-r--r--tests/ui/match/issue-72896-non-partial-eq-const.stderr23
-rw-r--r--tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs11
-rw-r--r--tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr4
-rw-r--r--tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs8
-rw-r--r--tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr4
-rw-r--r--tests/ui/never_type/issue-52443.stderr10
-rw-r--r--tests/ui/nll/closure-requirements/escape-argument-callee.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/escape-argument.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr4
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-approximated-val.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr2
-rw-r--r--tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr2
-rw-r--r--tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr4
-rw-r--r--tests/ui/panic-handler/panic-handler-bad-signature-1.stderr4
-rw-r--r--tests/ui/panic-handler/panic-handler-bad-signature-2.stderr4
-rw-r--r--tests/ui/panic-handler/panic-handler-bad-signature-3.stderr2
-rw-r--r--tests/ui/panic-handler/panic-handler-bad-signature-5.stderr4
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames-2.rs1
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr2
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames.rs1
-rw-r--r--tests/ui/panics/short-ice-remove-middle-frames.run.stderr2
-rw-r--r--tests/ui/parser/issues/issue-89388.stderr7
-rw-r--r--tests/ui/proc-macro/auxiliary/api/mod.rs1
-rw-r--r--tests/ui/proc-macro/auxiliary/api/parse.rs4
-rw-r--r--tests/ui/proc-macro/auxiliary/print-tokens.rs16
-rw-r--r--tests/ui/proc-macro/literal-to-string.rs26
-rw-r--r--tests/ui/proc-macro/literal-to-string.stdout107
-rw-r--r--tests/ui/repr/16-bit-repr-c-enum.rs2
-rw-r--r--tests/ui/resolve/associated-fn-called-as-fn.stderr14
-rw-r--r--tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs18
-rw-r--r--tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr41
-rw-r--r--tests/ui/resolve/issue-103474.stderr2
-rw-r--r--tests/ui/resolve/issue-14254.stderr98
-rw-r--r--tests/ui/resolve/issue-2356.stderr42
-rw-r--r--tests/ui/resolve/issue-60057.stderr12
-rw-r--r--tests/ui/resolve/resolve-assoc-suggestions.stderr21
-rw-r--r--tests/ui/resolve/resolve-speculative-adjustment.stderr14
-rw-r--r--tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr26
-rw-r--r--tests/ui/resolve/unresolved_static_type_field.stderr5
-rw-r--r--tests/ui/self/class-missing-self.stderr9
-rw-r--r--tests/ui/simd/intrinsic/generic-elements.rs28
-rw-r--r--tests/ui/simd/intrinsic/generic-elements.stderr80
-rw-r--r--tests/ui/simd/monomorphize-shuffle-index.generic.stderr12
-rw-r--r--tests/ui/simd/monomorphize-shuffle-index.rs28
-rw-r--r--tests/ui/specialization/specialization-default-types.stderr2
-rw-r--r--tests/ui/structs-enums/rec-align-u32.rs2
-rw-r--r--tests/ui/structs-enums/rec-align-u64.rs2
-rw-r--r--tests/ui/suggestions/assoc-const-without-self.stderr2
-rw-r--r--tests/ui/suggestions/assoc-type-in-method-return.stderr7
-rw-r--r--tests/ui/suggestions/assoc_fn_without_self.rs8
-rw-r--r--tests/ui/suggestions/assoc_fn_without_self.stderr49
-rw-r--r--tests/ui/suggestions/auxiliary/extern-issue-98562.rs26
-rw-r--r--tests/ui/suggestions/issue-98562.rs12
-rw-r--r--tests/ui/suggestions/issue-98562.stderr11
-rw-r--r--tests/ui/suggestions/missing-assoc-fn.stderr2
-rw-r--r--tests/ui/symbol-names/basic.legacy.stderr4
-rw-r--r--tests/ui/symbol-names/issue-60925.legacy.stderr4
-rw-r--r--tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs2
-rw-r--r--tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs53
-rw-r--r--tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr10
-rw-r--r--tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs2
-rw-r--r--tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr15
-rw-r--r--tests/ui/traits/unsend-future.rs1
-rw-r--r--tests/ui/traits/unsend-future.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs19
-rw-r--r--tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs23
-rw-r--r--tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr18
-rw-r--r--tests/ui/type/type-error-break-tail.stderr13
-rw-r--r--triagebot.toml4
1196 files changed, 23701 insertions, 15897 deletions
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 618a26958ee..4dcc9556965 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -305,7 +305,7 @@ jobs:
               SCRIPT: "./x.py dist bootstrap --include-default-paths --host=x86_64-apple-darwin --target=x86_64-apple-darwin"
               RUST_CONFIGURE_ARGS: "--enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false --set rust.lto=thin"
               RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
-              MACOSX_DEPLOYMENT_TARGET: 10.7
+              MACOSX_DEPLOYMENT_TARGET: 10.12
               SELECT_XCODE: /Applications/Xcode_13.4.1.app
               NO_LLVM_ASSERTIONS: 1
               NO_DEBUG_ASSERTIONS: 1
@@ -317,7 +317,7 @@ jobs:
               SCRIPT: "./x.py dist bootstrap --include-default-paths --host='' --target=aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim"
               RUST_CONFIGURE_ARGS: "--enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false"
               RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
-              MACOSX_DEPLOYMENT_TARGET: 10.7
+              MACOSX_DEPLOYMENT_TARGET: 10.12
               SELECT_XCODE: /Applications/Xcode_13.4.1.app
               NO_LLVM_ASSERTIONS: 1
               NO_DEBUG_ASSERTIONS: 1
@@ -328,8 +328,8 @@ jobs:
               SCRIPT: "./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc --skip tests/run-make-fulldeps"
               RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false"
               RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
-              MACOSX_DEPLOYMENT_TARGET: 10.8
-              MACOSX_STD_DEPLOYMENT_TARGET: 10.7
+              MACOSX_DEPLOYMENT_TARGET: 10.12
+              MACOSX_STD_DEPLOYMENT_TARGET: 10.12
               NO_LLVM_ASSERTIONS: 1
               NO_DEBUG_ASSERTIONS: 1
               NO_OVERFLOW_CHECKS: 1
@@ -339,8 +339,8 @@ jobs:
               SCRIPT: "./x.py --stage 2 test tests/ui tests/rustdoc tests/run-make-fulldeps"
               RUST_CONFIGURE_ARGS: "--build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false"
               RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
-              MACOSX_DEPLOYMENT_TARGET: 10.8
-              MACOSX_STD_DEPLOYMENT_TARGET: 10.7
+              MACOSX_DEPLOYMENT_TARGET: 10.12
+              MACOSX_STD_DEPLOYMENT_TARGET: 10.12
               NO_LLVM_ASSERTIONS: 1
               NO_DEBUG_ASSERTIONS: 1
               NO_OVERFLOW_CHECKS: 1
diff --git a/.mailmap b/.mailmap
index 21e1adb43cf..26d6be9f0c6 100644
--- a/.mailmap
+++ b/.mailmap
@@ -429,6 +429,8 @@ Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> nils <48135649+Nilstrieb
 Nif Ward <nif.ward@gmail.com>
 Nika Layzell <nika@thelayzells.com> <michael@thelayzells.com>
 NODA Kai <nodakai@gmail.com>
+Oğuz Ağcayazı <oguz.agcayazi@gmail.com> <oguz.agcayazi@gmail.com>
+Oğuz Ağcayazı <oguz.agcayazi@gmail.com> <ouz.agz@gmail.com>
 oliver <16816606+o752d@users.noreply.github.com>
 Oliver Middleton <olliemail27@gmail.com> <ollie27@users.noreply.github.com>
 Oliver Scherer <oli-obk@users.noreply.github.com> <git-spam-no-reply9815368754983@oli-obk.de>
diff --git a/Cargo.lock b/Cargo.lock
index d9aaedb8544..476f5578187 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -118,16 +118,15 @@ dependencies = [
 
 [[package]]
 name = "anstream"
-version = "0.3.2"
+version = "0.5.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "0ca84f3628370c59db74ee214b3263d58f9aadd9b4fe7e711fd87dc452b7f163"
+checksum = "b1f58811cfac344940f1a400b6e6231ce35171f614f26439e80f8c1465c5cc0c"
 dependencies = [
  "anstyle",
  "anstyle-parse",
  "anstyle-query",
  "anstyle-wincon",
  "colorchoice",
- "is-terminal",
  "utf8parse",
 ]
 
@@ -157,9 +156,9 @@ dependencies = [
 
 [[package]]
 name = "anstyle-wincon"
-version = "1.0.1"
+version = "2.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "180abfa45703aebe0093f79badacc01b8fd4ea2e35118747e5811127f926e188"
+checksum = "58f54d10c6dfa51283a066ceab3ec1ab78d13fae00aa49243a45e4571fb79dfd"
 dependencies = [
  "anstyle",
  "windows-sys 0.48.0",
@@ -291,9 +290,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
 name = "bitflags"
-version = "2.3.3"
+version = "2.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "630be753d4e58660abd17930c71b647fe46c27ea6b63cc59e1e3851406972e42"
+checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
 
 [[package]]
 name = "block-buffer"
@@ -459,25 +458,23 @@ dependencies = [
 
 [[package]]
 name = "clap"
-version = "4.3.10"
+version = "4.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "384e169cc618c613d5e3ca6404dda77a8685a63e08660dcc64abaf7da7cb0c7a"
+checksum = "b1d7b8d5ec32af0fadc644bf1fd509a688c2103b185644bb1e29d164e0703136"
 dependencies = [
  "clap_builder",
  "clap_derive",
- "once_cell",
 ]
 
 [[package]]
 name = "clap_builder"
-version = "4.3.10"
+version = "4.4.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef137bbe35aab78bdb468ccfba75a5f4d8321ae011d34063770780545176af2d"
+checksum = "5179bb514e4d7c2051749d8fcefa2ed6d06a9f4e6d69faf3805f5d80b8cf8d56"
 dependencies = [
  "anstream",
  "anstyle",
  "clap_lex",
- "once_cell",
  "strsim",
  "terminal_size",
 ]
@@ -493,9 +490,9 @@ dependencies = [
 
 [[package]]
 name = "clap_derive"
-version = "4.3.2"
+version = "4.4.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b8cd2b2a819ad6eec39e8f1d6b53001af1e5469f8c177579cdaeb313115b825f"
+checksum = "0862016ff20d69b84ef8247369fabf5c008a7417002411897d40ee1f4532b873"
 dependencies = [
  "heck",
  "proc-macro2",
@@ -515,7 +512,6 @@ version = "0.1.74"
 dependencies = [
  "clippy_lints",
  "clippy_utils",
- "derive-new",
  "filetime",
  "futures",
  "if_chain",
@@ -945,17 +941,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "derive-new"
-version = "0.5.9"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "3418329ca0ad70234b9735dc4ceed10af4df60eff9c8e7b06cb5e520d92c3535"
-dependencies = [
- "proc-macro2",
- "quote",
- "syn 1.0.109",
-]
-
-[[package]]
 name = "derive_builder"
 version = "0.12.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1253,12 +1238,9 @@ checksum = "2acce4a10f12dc2fb14a218589d4f1f62ef011b2d0cc4b3cb1bba8e94da14649"
 
 [[package]]
 name = "fastrand"
-version = "1.9.0"
+version = "2.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "e51093e27b0797c359783294ca4f0a911c270184cb10f85783b118614a1501be"
-dependencies = [
- "instant",
-]
+checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764"
 
 [[package]]
 name = "field-offset"
@@ -1994,17 +1976,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "io-lifetimes"
-version = "1.0.11"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "eae7b9aee968036d54dce06cebaefd919e4472e753296daccd6d344e3e2df0c2"
-dependencies = [
- "hermit-abi 0.3.2",
- "libc",
- "windows-sys 0.48.0",
-]
-
-[[package]]
 name = "ipnet"
 version = "2.7.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2017,7 +1988,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "24fddda5af7e54bf7da53067d6e802dbcc381d0a8eef629df528e3ebf68755cb"
 dependencies = [
  "hermit-abi 0.3.2",
- "rustix 0.38.2",
+ "rustix",
  "windows-sys 0.48.0",
 ]
 
@@ -2214,15 +2185,9 @@ dependencies = [
 
 [[package]]
 name = "linux-raw-sys"
-version = "0.3.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519"
-
-[[package]]
-name = "linux-raw-sys"
-version = "0.4.3"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0"
+checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
 
 [[package]]
 name = "litemap"
@@ -2454,7 +2419,7 @@ dependencies = [
  "rustc_version",
  "serde",
  "smallvec",
- "ui_test 0.11.7",
+ "ui_test 0.21.2",
 ]
 
 [[package]]
@@ -3007,6 +2972,27 @@ dependencies = [
 ]
 
 [[package]]
+name = "r-efi"
+version = "4.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "575fc2d9b3da54adbdfaddf6eca48fec256d977c8630a1750b8991347d1ac911"
+dependencies = [
+ "compiler_builtins",
+ "rustc-std-workspace-core",
+]
+
+[[package]]
+name = "r-efi-alloc"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31d6f09fe2b6ad044bc3d2c34ce4979796581afd2f1ebc185837e02421e02fd7"
+dependencies = [
+ "compiler_builtins",
+ "r-efi",
+ "rustc-std-workspace-core",
+]
+
+[[package]]
 name = "rand"
 version = "0.8.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3259,6 +3245,7 @@ dependencies = [
  "rustc_driver",
  "rustc_driver_impl",
  "rustc_smir",
+ "stable_mir",
 ]
 
 [[package]]
@@ -4423,7 +4410,7 @@ dependencies = [
  "rustc_session",
  "rustc_span",
  "rustc_target",
- "scoped-tls",
+ "stable_mir",
  "tracing",
 ]
 
@@ -4690,28 +4677,14 @@ dependencies = [
 
 [[package]]
 name = "rustix"
-version = "0.37.22"
+version = "0.38.14"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8818fa822adcc98b18fedbb3632a6a33213c070556b5aa7c4c8cc21cff565c4c"
+checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f"
 dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.4.0",
  "errno",
- "io-lifetimes",
  "libc",
- "linux-raw-sys 0.3.8",
- "windows-sys 0.48.0",
-]
-
-[[package]]
-name = "rustix"
-version = "0.38.2"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "aabcb0461ebd01d6b79945797c27f8529082226cb630a9865a71870ff63532a4"
-dependencies = [
- "bitflags 2.3.3",
- "errno",
- "libc",
- "linux-raw-sys 0.4.3",
+ "linux-raw-sys",
  "windows-sys 0.48.0",
 ]
 
@@ -4975,6 +4948,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
 
 [[package]]
+name = "stable_mir"
+version = "0.1.0-preview"
+dependencies = [
+ "scoped-tls",
+ "tracing",
+]
+
+[[package]]
 name = "stacker"
 version = "0.1.15"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -5012,6 +4993,8 @@ dependencies = [
  "panic_abort",
  "panic_unwind",
  "profiler_builtins",
+ "r-efi",
+ "r-efi-alloc",
  "rand",
  "rand_xorshift",
  "rustc-demangle",
@@ -5173,15 +5156,14 @@ dependencies = [
 
 [[package]]
 name = "tempfile"
-version = "3.6.0"
+version = "3.8.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6"
+checksum = "cb94d2f3cc536af71caac6b6fcebf65860b347e7ce0cc9ebe8f70d3e521054ef"
 dependencies = [
- "autocfg",
  "cfg-if",
  "fastrand",
  "redox_syscall 0.3.5",
- "rustix 0.37.22",
+ "rustix",
  "windows-sys 0.48.0",
 ]
 
@@ -5218,11 +5200,11 @@ dependencies = [
 
 [[package]]
 name = "terminal_size"
-version = "0.2.6"
+version = "0.3.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "8e6bf6f19e9f8ed8d4048dc22981458ebcf406d67e94cd422e5ecd73d63b3237"
+checksum = "21bebf2b7c9e0a515f6e0f8c51dc0f8e4696391e6f1ff30379559f8365fb0df7"
 dependencies = [
- "rustix 0.37.22",
+ "rustix",
  "windows-sys 0.48.0",
 ]
 
@@ -5639,18 +5621,23 @@ checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81"
 
 [[package]]
 name = "ui_test"
-version = "0.11.7"
+version = "0.20.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c21899b59f53717dfad29e4f46e5b21a200a1b6888ab86532a07cfc8b48dd78c"
+checksum = "bfd8fb9b15c8332cf51bfc2dc4830063b2446a9c9d732421b56f2478024a3971"
 dependencies = [
+ "annotate-snippets",
+ "anyhow",
  "bstr",
  "cargo-platform",
  "cargo_metadata",
  "color-eyre",
  "colored",
+ "comma",
  "crossbeam-channel",
- "diff",
+ "indicatif",
  "lazy_static",
+ "levenshtein",
+ "prettydiff",
  "regex",
  "rustc_version",
  "rustfix",
@@ -5661,9 +5648,9 @@ dependencies = [
 
 [[package]]
 name = "ui_test"
-version = "0.20.0"
+version = "0.21.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "bfd8fb9b15c8332cf51bfc2dc4830063b2446a9c9d732421b56f2478024a3971"
+checksum = "aaf4bf7c184b8dfc7a4d3b90df789b1eb992ee42811cd115f32a7a1eb781058d"
 dependencies = [
  "annotate-snippets",
  "anyhow",
@@ -6043,19 +6030,21 @@ dependencies = [
 
 [[package]]
 name = "windows-bindgen"
-version = "0.49.0"
+version = "0.51.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b6935fb09b84ee57929ae92518b475f5dfdfbeb87c5334756acc28ee8e202b60"
+checksum = "bc1f16b778125675feee0d15d6dd9f6af0e3ac52b3233d63a10aa39230c1cd75"
 dependencies = [
+ "proc-macro2",
+ "rayon",
+ "syn 2.0.29",
  "windows-metadata",
- "windows-tokens",
 ]
 
 [[package]]
 name = "windows-metadata"
-version = "0.49.0"
+version = "0.51.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f5bca94a32bf1e6a376522b6601275a3b611ee885ec0f1b6a05f17e8cfd3385"
+checksum = "753135d996f9da437c0b31dbde3032489a61708361929bcc07d4fba0b161000e"
 
 [[package]]
 name = "windows-sys"
@@ -6106,12 +6095,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "windows-tokens"
-version = "0.48.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b34c9a3b28cb41db7385546f7f9a8179348dffc89923dde66857b1ba5312f6b4"
-
-[[package]]
 name = "windows_aarch64_gnullvm"
 version = "0.42.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/compiler/rustc/Cargo.toml b/compiler/rustc/Cargo.toml
index 41003ad83f3..dcb165f9fdb 100644
--- a/compiler/rustc/Cargo.toml
+++ b/compiler/rustc/Cargo.toml
@@ -13,6 +13,7 @@ rustc_codegen_ssa = { path = "../rustc_codegen_ssa" }
 # Make sure rustc_smir ends up in the sysroot, because this
 # crate is intended to be used by stable MIR consumers, which are not in-tree
 rustc_smir = { path = "../rustc_smir" }
+stable_mir = { path = "../stable_mir" }
 
 [dependencies.jemalloc-sys]
 version = "0.5.0"
diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs
index f14463fe940..23fdd272ffd 100644
--- a/compiler/rustc_arena/src/lib.rs
+++ b/compiler/rustc_arena/src/lib.rs
@@ -37,9 +37,10 @@ use std::ptr::{self, NonNull};
 use std::slice;
 use std::{cmp, intrinsics};
 
+/// This calls the passed function while ensuring it won't be inlined into the caller.
 #[inline(never)]
 #[cold]
-fn cold_path<F: FnOnce() -> R, R>(f: F) -> R {
+fn outline<F: FnOnce() -> R, R>(f: F) -> R {
     f()
 }
 
@@ -600,7 +601,7 @@ impl DroplessArena {
                 unsafe { self.write_from_iter(iter, len, mem) }
             }
             (_, _) => {
-                cold_path(move || -> &mut [T] {
+                outline(move || -> &mut [T] {
                     let mut vec: SmallVec<[_; 8]> = iter.collect();
                     if vec.is_empty() {
                         return &mut [];
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 5b172b863ab..85ab5e7223b 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -1664,7 +1664,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                     lifetime.ident,
                 ));
 
-                // Now make an arg that we can use for the substs of the opaque tykind.
+                // Now make an arg that we can use for the generic params of the opaque tykind.
                 let id = self.next_node_id();
                 let lifetime_arg = self.new_named_lifetime_with_res(id, lifetime.ident, res);
                 let duplicated_lifetime_def_id = self.local_def_id(duplicated_lifetime_node_id);
diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs
index 8405ae6ff8e..62dc7ae58a2 100644
--- a/compiler/rustc_ast_passes/src/feature_gate.rs
+++ b/compiler/rustc_ast_passes/src/feature_gate.rs
@@ -578,11 +578,11 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
         }
     }
 
-    // All uses of `gate_all!` below this point were added in #65742,
+    // All uses of `gate_all_legacy_dont_use!` below this point were added in #65742,
     // and subsequently disabled (with the non-early gating readded).
     // We emit an early future-incompatible warning for these.
     // New syntax gates should go above here to get a hard error gate.
-    macro_rules! gate_all {
+    macro_rules! gate_all_legacy_dont_use {
         ($gate:ident, $msg:literal) => {
             for span in spans.get(&sym::$gate).unwrap_or(&vec![]) {
                 gate_feature_post!(future_incompatible; &visitor, $gate, *span, $msg);
@@ -590,13 +590,19 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
         };
     }
 
-    gate_all!(trait_alias, "trait aliases are experimental");
-    gate_all!(associated_type_bounds, "associated type bounds are unstable");
-    gate_all!(return_type_notation, "return type notation is experimental");
-    gate_all!(decl_macro, "`macro` is experimental");
-    gate_all!(box_patterns, "box pattern syntax is experimental");
-    gate_all!(exclusive_range_pattern, "exclusive range pattern syntax is experimental");
-    gate_all!(try_blocks, "`try` blocks are unstable");
+    gate_all_legacy_dont_use!(trait_alias, "trait aliases are experimental");
+    gate_all_legacy_dont_use!(associated_type_bounds, "associated type bounds are unstable");
+    // Despite being a new feature, `where T: Trait<Assoc(): Sized>`, which is RTN syntax now,
+    // used to be gated under associated_type_bounds, which are right above, so RTN needs to
+    // be too.
+    gate_all_legacy_dont_use!(return_type_notation, "return type notation is experimental");
+    gate_all_legacy_dont_use!(decl_macro, "`macro` is experimental");
+    gate_all_legacy_dont_use!(box_patterns, "box pattern syntax is experimental");
+    gate_all_legacy_dont_use!(
+        exclusive_range_pattern,
+        "exclusive range pattern syntax is experimental"
+    );
+    gate_all_legacy_dont_use!(try_blocks, "`try` blocks are unstable");
 
     visit::walk_crate(&mut visitor, krate);
 }
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
index 2ea399789b9..27072a60f65 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_errors.rs
@@ -245,7 +245,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
             let Trait(PolyTraitRef { trait_ref, span: trait_span, .. }, _) = bound else { return; };
             diag.span_note(
                 *trait_span,
-                format!("due to current limitations in the borrow checker, this implies a `'static` lifetime")
+                "due to current limitations in the borrow checker, this implies a `'static` lifetime"
             );
             let Some(generics_fn) = hir.get_generics(self.body.source.def_id().expect_local()) else { return; };
             let Def(_, trait_res_defid) = trait_ref.path.res else { return; };
@@ -277,7 +277,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
         if suggestions.len() > 0 {
             suggestions.dedup();
             diag.multipart_suggestion_verbose(
-                format!("consider restricting the type parameter to the `'static` lifetime"),
+                "consider restricting the type parameter to the `'static` lifetime",
                 suggestions,
                 Applicability::MaybeIncorrect,
             );
diff --git a/compiler/rustc_borrowck/src/diagnostics/region_name.rs b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
index 096bf826cfb..55d581b3ab1 100644
--- a/compiler/rustc_borrowck/src/diagnostics/region_name.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/region_name.rs
@@ -27,7 +27,7 @@ pub(crate) struct RegionName {
 /// This helps to print the right kinds of diagnostics.
 #[derive(Debug, Clone)]
 pub(crate) enum RegionNameSource {
-    /// A bound (not free) region that was substituted at the def site (not an HRTB).
+    /// A bound (not free) region that was instantiated at the def site (not an HRTB).
     NamedEarlyBoundRegion(Span),
     /// A free region that the user has a name (`'a`) for.
     NamedFreeRegion(Span),
@@ -354,7 +354,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                     })
                 }
 
-                ty::BoundRegionKind::BrAnon(..) => None,
+                ty::BoundRegionKind::BrAnon => None,
             },
 
             ty::ReLateBound(..)
@@ -516,7 +516,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                         // be the same as those of the ADT.
                         // FIXME: We should be able to do something similar to
                         // match_adt_and_segment in this case.
-                        Res::Def(DefKind::TyAlias { .. }, _) => (),
+                        Res::Def(DefKind::TyAlias, _) => (),
                         _ => {
                             if let Some(last_segment) = path.segments.last() {
                                 if let Some(highlight) = self.match_adt_and_segment(
@@ -619,7 +619,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
                     // programs, so we need to use delay_span_bug here. See #82126.
                     self.infcx.tcx.sess.delay_span_bug(
                         hir_arg.span(),
-                        format!("unmatched subst and hir arg: found {kind:?} vs {hir_arg:?}"),
+                        format!("unmatched arg and hir arg: found {kind:?} vs {hir_arg:?}"),
                     );
                 }
             }
diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs
index 1049e7a8bbe..852935676b6 100644
--- a/compiler/rustc_borrowck/src/region_infer/mod.rs
+++ b/compiler/rustc_borrowck/src/region_infer/mod.rs
@@ -2250,7 +2250,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
     pub(crate) fn universe_info(&self, universe: ty::UniverseIndex) -> UniverseInfo<'tcx> {
         // Query canonicalization can create local superuniverses (for example in
-        // `InferCtx::query_response_substitution_guess`), but they don't have an associated
+        // `InferCtx::query_response_instantiation_guess`), but they don't have an associated
         // `UniverseInfo` explaining why they were created.
         // This can cause ICEs if these causes are accessed in diagnostics, for example in issue
         // #114907 where this happens via liveness and dropck outlives results.
diff --git a/compiler/rustc_borrowck/src/renumber.rs b/compiler/rustc_borrowck/src/renumber.rs
index 4c7c4982050..5d6f5cc8967 100644
--- a/compiler/rustc_borrowck/src/renumber.rs
+++ b/compiler/rustc_borrowck/src/renumber.rs
@@ -7,7 +7,7 @@ use rustc_middle::mir::visit::{MutVisitor, TyContext};
 use rustc_middle::mir::{Body, ConstOperand, Location, Promoted};
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
-use rustc_span::{Span, Symbol};
+use rustc_span::Symbol;
 
 /// Replaces all free regions appearing in the MIR with fresh
 /// inference variables, returning the number of variables created.
@@ -29,20 +29,14 @@ pub fn renumber_mir<'tcx>(
 }
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
-pub(crate) enum BoundRegionInfo {
-    Name(Symbol),
-    Span(Span),
-}
-
-#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
 pub(crate) enum RegionCtxt {
     Location(Location),
     TyContext(TyContext),
     Free(Symbol),
-    Bound(BoundRegionInfo),
-    LateBound(BoundRegionInfo),
+    Bound(Symbol),
+    LateBound(Symbol),
     Existential(Option<Symbol>),
-    Placeholder(BoundRegionInfo),
+    Placeholder(Symbol),
     Unknown,
 }
 
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 60e6dcaf0b8..9b952f3fe36 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1007,7 +1007,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
     }
 
     pub(super) fn register_predefined_opaques_in_new_solver(&mut self) {
-        // OK to use the identity substitutions for each opaque type key, since
+        // OK to use the identity arguments for each opaque type key, since
         // we remap opaques from HIR typeck back to their definition params.
         let opaques: Vec<_> = self
             .infcx
@@ -1367,14 +1367,13 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                     }
                 };
                 let (sig, map) = tcx.replace_late_bound_regions(sig, |br| {
-                    use crate::renumber::{BoundRegionInfo, RegionCtxt};
+                    use crate::renumber::RegionCtxt;
 
                     let region_ctxt_fn = || {
                         let reg_info = match br.kind {
-                            ty::BoundRegionKind::BrAnon(Some(span)) => BoundRegionInfo::Span(span),
-                            ty::BoundRegionKind::BrAnon(..) => BoundRegionInfo::Name(sym::anon),
-                            ty::BoundRegionKind::BrNamed(_, name) => BoundRegionInfo::Name(name),
-                            ty::BoundRegionKind::BrEnv => BoundRegionInfo::Name(sym::env),
+                            ty::BoundRegionKind::BrAnon => sym::anon,
+                            ty::BoundRegionKind::BrNamed(_, name) => name,
+                            ty::BoundRegionKind::BrEnv => sym::env,
                         };
 
                         RegionCtxt::LateBound(reg_info)
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index e0c6295627b..c1f82e19c02 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -11,7 +11,7 @@ use rustc_span::{Span, Symbol};
 
 use crate::constraints::OutlivesConstraint;
 use crate::diagnostics::UniverseInfo;
-use crate::renumber::{BoundRegionInfo, RegionCtxt};
+use crate::renumber::RegionCtxt;
 use crate::type_check::{InstantiateOpaqueType, Locations, TypeChecker};
 
 impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
@@ -126,10 +126,9 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
             .placeholder_region(self.type_checker.infcx, placeholder);
 
         let reg_info = match placeholder.bound.kind {
-            ty::BoundRegionKind::BrAnon(Some(span)) => BoundRegionInfo::Span(span),
-            ty::BoundRegionKind::BrAnon(..) => BoundRegionInfo::Name(sym::anon),
-            ty::BoundRegionKind::BrNamed(_, name) => BoundRegionInfo::Name(name),
-            ty::BoundRegionKind::BrEnv => BoundRegionInfo::Name(sym::env),
+            ty::BoundRegionKind::BrAnon => sym::anon,
+            ty::BoundRegionKind::BrNamed(_, name) => name,
+            ty::BoundRegionKind::BrEnv => sym::env,
         };
 
         if cfg!(debug_assertions) {
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 02b52784ede..af437f36b9f 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -28,7 +28,7 @@ use rustc_span::symbol::{kw, sym};
 use rustc_span::Symbol;
 use std::iter;
 
-use crate::renumber::{BoundRegionInfo, RegionCtxt};
+use crate::renumber::RegionCtxt;
 use crate::BorrowckInferCtxt;
 
 #[derive(Debug)]
@@ -446,9 +446,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                     if !indices.indices.contains_key(&r) {
                         let region_vid = {
                             let name = r.get_name_or_anon();
-                            self.infcx.next_nll_region_var(FR, || {
-                                RegionCtxt::LateBound(BoundRegionInfo::Name(name))
-                            })
+                            self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
                         };
 
                         debug!(?region_vid);
@@ -480,9 +478,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
             if !indices.indices.contains_key(&r) {
                 let region_vid = {
                     let name = r.get_name_or_anon();
-                    self.infcx.next_nll_region_var(FR, || {
-                        RegionCtxt::LateBound(BoundRegionInfo::Name(name))
-                    })
+                    self.infcx.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
                 };
 
                 debug!(?region_vid);
@@ -643,10 +639,9 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
         };
 
         let global_mapping = iter::once((tcx.lifetimes.re_static, fr_static));
-        let subst_mapping =
-            iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
+        let arg_mapping = iter::zip(identity_args.regions(), fr_args.regions().map(|r| r.as_var()));
 
-        UniversalRegionIndices { indices: global_mapping.chain(subst_mapping).collect(), fr_static }
+        UniversalRegionIndices { indices: global_mapping.chain(arg_mapping).collect(), fr_static }
     }
 
     fn compute_inputs_and_output(
@@ -796,7 +791,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
                     _ => sym::anon,
                 };
 
-                self.next_nll_region_var(origin, || RegionCtxt::Bound(BoundRegionInfo::Name(name)))
+                self.next_nll_region_var(origin, || RegionCtxt::Bound(name))
             };
 
             indices.insert_late_bound_region(liberated_region, region_vid.as_var());
@@ -826,9 +821,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
             if !indices.indices.contains_key(&r) {
                 let region_vid = {
                     let name = r.get_name_or_anon();
-                    self.next_nll_region_var(FR, || {
-                        RegionCtxt::LateBound(BoundRegionInfo::Name(name))
-                    })
+                    self.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
                 };
 
                 debug!(?region_vid);
@@ -848,9 +841,7 @@ impl<'cx, 'tcx> InferCtxtExt<'tcx> for BorrowckInferCtxt<'cx, 'tcx> {
             if !indices.indices.contains_key(&r) {
                 let region_vid = {
                     let name = r.get_name_or_anon();
-                    self.next_nll_region_var(FR, || {
-                        RegionCtxt::LateBound(BoundRegionInfo::Name(name))
-                    })
+                    self.next_nll_region_var(FR, || RegionCtxt::LateBound(name))
                 };
 
                 indices.insert_late_bound_region(r, region_vid.as_var());
diff --git a/compiler/rustc_builtin_macros/src/deriving/bounds.rs b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
index 2c8e6f99c67..8027ca2e7bb 100644
--- a/compiler/rustc_builtin_macros/src/deriving/bounds.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/bounds.rs
@@ -41,7 +41,7 @@ pub fn expand_deriving_const_param_ty(
         path: path_std!(marker::ConstParamTy),
         skip_path_as_bound: false,
         needs_copy_as_bound_if_packed: false,
-        additional_bounds: Vec::new(),
+        additional_bounds: vec![ty::Ty::Path(path_std!(cmp::Eq))],
         supports_unions: false,
         methods: Vec::new(),
         associated_types: Vec::new(),
diff --git a/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs b/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
index f782671fe36..03912b18ea5 100755
--- a/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
+++ b/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
@@ -100,9 +100,9 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
             stack = &stack[..index + ENCODE_METADATA.len()];
         }
 
-        const SUBST_AND_NORMALIZE_ERASING_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::subst_and_normalize_erasing_regions";
-        if let Some(index) = stack.find(SUBST_AND_NORMALIZE_ERASING_REGIONS) {
-            stack = &stack[..index + SUBST_AND_NORMALIZE_ERASING_REGIONS.len()];
+        const INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::instantiate_and_normalize_erasing_regions";
+        if let Some(index) = stack.find(INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS) {
+            stack = &stack[..index + INSTANTIATE_AND_NORMALIZE_ERASING_REGIONS.len()];
         }
 
         const NORMALIZE_ERASING_LATE_BOUND_REGIONS: &str = "rustc_middle::ty::normalize_erasing_regions::<impl rustc_middle::ty::context::TyCtxt>::normalize_erasing_late_bound_regions";
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 9b5a6b89191..6d55fdc3074 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -875,7 +875,7 @@ pub(crate) fn codegen_place<'tcx>(
             PlaceElem::Deref => {
                 cplace = cplace.place_deref(fx);
             }
-            PlaceElem::OpaqueCast(ty) => cplace = cplace.place_opaque_cast(fx, ty),
+            PlaceElem::OpaqueCast(ty) => bug!("encountered OpaqueCast({ty}) in codegen"),
             PlaceElem::Field(field, _ty) => {
                 cplace = cplace.place_field(fx, field);
             }
diff --git a/compiler/rustc_codegen_cranelift/src/common.rs b/compiler/rustc_codegen_cranelift/src/common.rs
index ec2da39398b..359b430b4e5 100644
--- a/compiler/rustc_codegen_cranelift/src/common.rs
+++ b/compiler/rustc_codegen_cranelift/src/common.rs
@@ -359,7 +359,7 @@ impl<'tcx> FunctionCx<'_, '_, 'tcx> {
     where
         T: TypeFoldable<TyCtxt<'tcx>> + Copy,
     {
-        self.instance.subst_mir_and_normalize_erasing_regions(
+        self.instance.instantiate_mir_and_normalize_erasing_regions(
             self.tcx,
             ty::ParamEnv::reveal_all(),
             ty::EarlyBinder::bind(value),
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index c64a4008996..6efbe149863 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -21,7 +21,7 @@ fn report_simd_type_validation_error(
 pub(super) fn codegen_simd_intrinsic_call<'tcx>(
     fx: &mut FunctionCx<'_, '_, 'tcx>,
     intrinsic: Symbol,
-    _args: GenericArgsRef<'tcx>,
+    generic_args: GenericArgsRef<'tcx>,
     args: &[mir::Operand<'tcx>],
     ret: CPlace<'tcx>,
     target: BasicBlock,
@@ -117,6 +117,54 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
             });
         }
 
+        // simd_shuffle_generic<T, U, const I: &[u32]>(x: T, y: T) -> U
+        sym::simd_shuffle_generic => {
+            let [x, y] = args else {
+                bug!("wrong number of args for intrinsic {intrinsic}");
+            };
+            let x = codegen_operand(fx, x);
+            let y = codegen_operand(fx, y);
+
+            if !x.layout().ty.is_simd() {
+                report_simd_type_validation_error(fx, intrinsic, span, x.layout().ty);
+                return;
+            }
+
+            let idx = generic_args[2]
+                .expect_const()
+                .eval(fx.tcx, ty::ParamEnv::reveal_all(), Some(span))
+                .unwrap()
+                .unwrap_branch();
+
+            assert_eq!(x.layout(), y.layout());
+            let layout = x.layout();
+
+            let (lane_count, lane_ty) = layout.ty.simd_size_and_type(fx.tcx);
+            let (ret_lane_count, ret_lane_ty) = ret.layout().ty.simd_size_and_type(fx.tcx);
+
+            assert_eq!(lane_ty, ret_lane_ty);
+            assert_eq!(idx.len() as u64, ret_lane_count);
+
+            let total_len = lane_count * 2;
+
+            let indexes =
+                idx.iter().map(|idx| idx.unwrap_leaf().try_to_u16().unwrap()).collect::<Vec<u16>>();
+
+            for &idx in &indexes {
+                assert!(u64::from(idx) < total_len, "idx {} out of range 0..{}", idx, total_len);
+            }
+
+            for (out_idx, in_idx) in indexes.into_iter().enumerate() {
+                let in_lane = if u64::from(in_idx) < lane_count {
+                    x.value_lane(fx, in_idx.into())
+                } else {
+                    y.value_lane(fx, u64::from(in_idx) - lane_count)
+                };
+                let out_lane = ret.place_lane(fx, u64::try_from(out_idx).unwrap());
+                out_lane.write_cvalue(fx, in_lane);
+            }
+        }
+
         // simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U
         sym::simd_shuffle => {
             let (x, y, idx) = match args {
diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
index ff95141ce90..d4273c0b593 100644
--- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs
+++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
@@ -674,14 +674,6 @@ impl<'tcx> CPlace<'tcx> {
         }
     }
 
-    pub(crate) fn place_opaque_cast(
-        self,
-        fx: &mut FunctionCx<'_, '_, 'tcx>,
-        ty: Ty<'tcx>,
-    ) -> CPlace<'tcx> {
-        CPlace { inner: self.inner, layout: fx.layout_of(ty) }
-    }
-
     pub(crate) fn place_field(
         self,
         fx: &mut FunctionCx<'_, '_, 'tcx>,
diff --git a/compiler/rustc_codegen_llvm/messages.ftl b/compiler/rustc_codegen_llvm/messages.ftl
index ddaff36f24b..c0cfe39f1e0 100644
--- a/compiler/rustc_codegen_llvm/messages.ftl
+++ b/compiler/rustc_codegen_llvm/messages.ftl
@@ -37,6 +37,8 @@ codegen_llvm_lto_disallowed = lto can only be run for executables, cdylibs and s
 
 codegen_llvm_lto_dylib = lto cannot be used for `dylib` crate type without `-Zdylib-lto`
 
+codegen_llvm_lto_proc_macro = lto cannot be used for `proc-macro` crate type without `-Zdylib-lto`
+
 codegen_llvm_missing_features =
     add the missing features in a `target_feature` attribute
 
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index ba263296bb4..cb5acf79135 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -2,7 +2,7 @@ use crate::back::write::{
     self, bitcode_section_name, save_temp_bitcode, CodegenDiagnosticsStage, DiagnosticHandlers,
 };
 use crate::errors::{
-    DynamicLinkingWithLTO, LlvmError, LtoBitcodeFromRlib, LtoDisallowed, LtoDylib,
+    DynamicLinkingWithLTO, LlvmError, LtoBitcodeFromRlib, LtoDisallowed, LtoDylib, LtoProcMacro,
 };
 use crate::llvm::{self, build_string};
 use crate::{LlvmCodegenBackend, ModuleLlvm};
@@ -36,8 +36,12 @@ pub const THIN_LTO_KEYS_INCR_COMP_FILE_NAME: &str = "thin-lto-past-keys.bin";
 
 pub fn crate_type_allows_lto(crate_type: CrateType) -> bool {
     match crate_type {
-        CrateType::Executable | CrateType::Dylib | CrateType::Staticlib | CrateType::Cdylib => true,
-        CrateType::Rlib | CrateType::ProcMacro => false,
+        CrateType::Executable
+        | CrateType::Dylib
+        | CrateType::Staticlib
+        | CrateType::Cdylib
+        | CrateType::ProcMacro => true,
+        CrateType::Rlib => false,
     }
 }
 
@@ -87,6 +91,11 @@ fn prepare_lto(
                     diag_handler.emit_err(LtoDylib);
                     return Err(FatalError);
                 }
+            } else if *crate_type == CrateType::ProcMacro {
+                if !cgcx.opts.unstable_opts.dylib_lto {
+                    diag_handler.emit_err(LtoProcMacro);
+                    return Err(FatalError);
+                }
             }
         }
 
diff --git a/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs
new file mode 100644
index 00000000000..36484c3c3fc
--- /dev/null
+++ b/compiler/rustc_codegen_llvm/src/back/owned_target_machine.rs
@@ -0,0 +1,103 @@
+use std::{
+    ffi::{c_char, CStr},
+    marker::PhantomData,
+    ops::Deref,
+    ptr::NonNull,
+};
+
+use rustc_data_structures::small_c_str::SmallCStr;
+
+use crate::{errors::LlvmError, llvm};
+
+/// Responsible for safely creating and disposing llvm::TargetMachine via ffi functions.
+/// Not cloneable as there is no clone function for llvm::TargetMachine.
+#[repr(transparent)]
+pub struct OwnedTargetMachine {
+    tm_unique: NonNull<llvm::TargetMachine>,
+    phantom: PhantomData<llvm::TargetMachine>,
+}
+
+impl OwnedTargetMachine {
+    pub fn new(
+        triple: &CStr,
+        cpu: &CStr,
+        features: &CStr,
+        abi: &CStr,
+        model: llvm::CodeModel,
+        reloc: llvm::RelocModel,
+        level: llvm::CodeGenOptLevel,
+        use_soft_fp: bool,
+        function_sections: bool,
+        data_sections: bool,
+        unique_section_names: bool,
+        trap_unreachable: bool,
+        singletree: bool,
+        asm_comments: bool,
+        emit_stack_size_section: bool,
+        relax_elf_relocations: bool,
+        use_init_array: bool,
+        split_dwarf_file: &CStr,
+        output_obj_file: &CStr,
+        debug_info_compression: &CStr,
+        force_emulated_tls: bool,
+        args_cstr_buff: &[u8],
+    ) -> Result<Self, LlvmError<'static>> {
+        assert!(args_cstr_buff.len() > 0);
+        assert!(
+            *args_cstr_buff.last().unwrap() == 0,
+            "The last character must be a null terminator."
+        );
+
+        // SAFETY: llvm::LLVMRustCreateTargetMachine copies pointed to data
+        let tm_ptr = unsafe {
+            llvm::LLVMRustCreateTargetMachine(
+                triple.as_ptr(),
+                cpu.as_ptr(),
+                features.as_ptr(),
+                abi.as_ptr(),
+                model,
+                reloc,
+                level,
+                use_soft_fp,
+                function_sections,
+                data_sections,
+                unique_section_names,
+                trap_unreachable,
+                singletree,
+                asm_comments,
+                emit_stack_size_section,
+                relax_elf_relocations,
+                use_init_array,
+                split_dwarf_file.as_ptr(),
+                output_obj_file.as_ptr(),
+                debug_info_compression.as_ptr(),
+                force_emulated_tls,
+                args_cstr_buff.as_ptr() as *const c_char,
+                args_cstr_buff.len(),
+            )
+        };
+
+        NonNull::new(tm_ptr)
+            .map(|tm_unique| Self { tm_unique, phantom: PhantomData })
+            .ok_or_else(|| LlvmError::CreateTargetMachine { triple: SmallCStr::from(triple) })
+    }
+}
+
+impl Deref for OwnedTargetMachine {
+    type Target = llvm::TargetMachine;
+
+    fn deref(&self) -> &Self::Target {
+        // SAFETY: constructing ensures we have a valid pointer created by llvm::LLVMRustCreateTargetMachine
+        unsafe { self.tm_unique.as_ref() }
+    }
+}
+
+impl Drop for OwnedTargetMachine {
+    fn drop(&mut self) {
+        // SAFETY: constructing ensures we have a valid pointer created by llvm::LLVMRustCreateTargetMachine
+        // OwnedTargetMachine is not copyable so there is no double free or use after free
+        unsafe {
+            llvm::LLVMRustDisposeTargetMachine(self.tm_unique.as_mut());
+        }
+    }
+}
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 1f394a7335c..c778a6e017f 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -1,4 +1,5 @@
 use crate::back::lto::ThinBuffer;
+use crate::back::owned_target_machine::OwnedTargetMachine;
 use crate::back::profiling::{
     selfprofile_after_pass_callback, selfprofile_before_pass_callback, LlvmSelfProfiler,
 };
@@ -98,8 +99,8 @@ pub fn write_output_file<'ll>(
     }
 }
 
-pub fn create_informational_target_machine(sess: &Session) -> &'static mut llvm::TargetMachine {
-    let config = TargetMachineFactoryConfig { split_dwarf_file: None };
+pub fn create_informational_target_machine(sess: &Session) -> OwnedTargetMachine {
+    let config = TargetMachineFactoryConfig { split_dwarf_file: None, output_obj_file: None };
     // Can't use query system here quite yet because this function is invoked before the query
     // system/tcx is set up.
     let features = llvm_util::global_llvm_features(sess, false);
@@ -107,7 +108,7 @@ pub fn create_informational_target_machine(sess: &Session) -> &'static mut llvm:
         .unwrap_or_else(|err| llvm_err(sess.diagnostic(), err).raise())
 }
 
-pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut llvm::TargetMachine {
+pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> OwnedTargetMachine {
     let split_dwarf_file = if tcx.sess.target_can_use_split_dwarf() {
         tcx.output_filenames(()).split_dwarf_path(
             tcx.sess.split_debuginfo(),
@@ -117,7 +118,11 @@ pub fn create_target_machine(tcx: TyCtxt<'_>, mod_name: &str) -> &'static mut ll
     } else {
         None
     };
-    let config = TargetMachineFactoryConfig { split_dwarf_file };
+
+    let output_obj_file =
+        Some(tcx.output_filenames(()).temp_path(OutputType::Object, Some(mod_name)));
+    let config = TargetMachineFactoryConfig { split_dwarf_file, output_obj_file };
+
     target_machine_factory(
         &tcx.sess,
         tcx.backend_optimization_level(()),
@@ -255,38 +260,38 @@ pub fn target_machine_factory(
     let debuginfo_compression = SmallCStr::new(&debuginfo_compression);
 
     Arc::new(move |config: TargetMachineFactoryConfig| {
-        let split_dwarf_file =
-            path_mapping.map_prefix(config.split_dwarf_file.unwrap_or_default()).0;
-        let split_dwarf_file = CString::new(split_dwarf_file.to_str().unwrap()).unwrap();
-
-        let tm = unsafe {
-            llvm::LLVMRustCreateTargetMachine(
-                triple.as_ptr(),
-                cpu.as_ptr(),
-                features.as_ptr(),
-                abi.as_ptr(),
-                code_model,
-                reloc_model,
-                opt_level,
-                use_softfp,
-                ffunction_sections,
-                fdata_sections,
-                funique_section_names,
-                trap_unreachable,
-                singlethread,
-                asm_comments,
-                emit_stack_size_section,
-                relax_elf_relocations,
-                use_init_array,
-                split_dwarf_file.as_ptr(),
-                debuginfo_compression.as_ptr(),
-                force_emulated_tls,
-                args_cstr_buff.as_ptr() as *const c_char,
-                args_cstr_buff.len(),
-            )
+        let path_to_cstring_helper = |path: Option<PathBuf>| -> CString {
+            let path = path_mapping.map_prefix(path.unwrap_or_default()).0;
+            CString::new(path.to_str().unwrap()).unwrap()
         };
 
-        tm.ok_or_else(|| LlvmError::CreateTargetMachine { triple: triple.clone() })
+        let split_dwarf_file = path_to_cstring_helper(config.split_dwarf_file);
+        let output_obj_file = path_to_cstring_helper(config.output_obj_file);
+
+        OwnedTargetMachine::new(
+            &triple,
+            &cpu,
+            &features,
+            &abi,
+            code_model,
+            reloc_model,
+            opt_level,
+            use_softfp,
+            ffunction_sections,
+            fdata_sections,
+            funique_section_names,
+            trap_unreachable,
+            singlethread,
+            asm_comments,
+            emit_stack_size_section,
+            relax_elf_relocations,
+            use_init_array,
+            &split_dwarf_file,
+            &output_obj_file,
+            &debuginfo_compression,
+            force_emulated_tls,
+            &args_cstr_buff,
+        )
     })
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 8e8290279ab..b4b2ab1e1f8 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -160,9 +160,9 @@ pub unsafe fn create_module<'ll>(
 
     // Ensure the data-layout values hardcoded remain the defaults.
     if sess.target.is_builtin {
+        // tm is disposed by its drop impl
         let tm = crate::back::write::create_informational_target_machine(tcx.sess);
-        llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, tm);
-        llvm::LLVMRustDisposeTargetMachine(tm);
+        llvm::LLVMRustSetDataLayoutFromTargetMachine(llmod, &tm);
 
         let llvm_data_layout = llvm::LLVMGetDataLayoutStr(llmod);
         let llvm_data_layout = str::from_utf8(CStr::from_ptr(llvm_data_layout).to_bytes())
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
index 5ca2942ac4e..aff764f0224 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/create_scope_map.rs
@@ -90,7 +90,7 @@ fn make_mir_scope<'ll, 'tcx>(
         Some((callee, _)) => {
             // FIXME(eddyb) this would be `self.monomorphize(&callee)`
             // if this is moved to `rustc_codegen_ssa::mir::debuginfo`.
-            let callee = cx.tcx.subst_and_normalize_erasing_regions(
+            let callee = cx.tcx.instantiate_and_normalize_erasing_regions(
                 instance.args,
                 ty::ParamEnv::reveal_all(),
                 ty::EarlyBinder::bind(callee),
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index c862acdc7de..30cc9ea9b82 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -529,7 +529,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             if let Some(impl_def_id) = cx.tcx.impl_of_method(instance.def_id()) {
                 // If the method does *not* belong to a trait, proceed
                 if cx.tcx.trait_id_of_impl(impl_def_id).is_none() {
-                    let impl_self_ty = cx.tcx.subst_and_normalize_erasing_regions(
+                    let impl_self_ty = cx.tcx.instantiate_and_normalize_erasing_regions(
                         instance.args,
                         ty::ParamEnv::reveal_all(),
                         cx.tcx.type_of(impl_def_id),
diff --git a/compiler/rustc_codegen_llvm/src/errors.rs b/compiler/rustc_codegen_llvm/src/errors.rs
index 264c273ba30..665d195790c 100644
--- a/compiler/rustc_codegen_llvm/src/errors.rs
+++ b/compiler/rustc_codegen_llvm/src/errors.rs
@@ -139,6 +139,10 @@ pub(crate) struct LtoDisallowed;
 pub(crate) struct LtoDylib;
 
 #[derive(Diagnostic)]
+#[diag(codegen_llvm_lto_proc_macro)]
+pub(crate) struct LtoProcMacro;
+
+#[derive(Diagnostic)]
 #[diag(codegen_llvm_lto_bitcode_from_rlib)]
 pub(crate) struct LtoBitcodeFromRlib {
     pub llvm_err: String,
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 9289c37d763..a97b803fc64 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -15,7 +15,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
 use rustc_codegen_ssa::traits::*;
 use rustc_hir as hir;
 use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf};
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::{self, GenericArgsRef, Ty};
 use rustc_middle::{bug, span_bug};
 use rustc_span::{sym, symbol::kw, Span, Symbol};
 use rustc_target::abi::{self, Align, HasDataLayout, Primitive};
@@ -376,7 +376,9 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
             }
 
             _ if name.as_str().starts_with("simd_") => {
-                match generic_simd_intrinsic(self, name, callee_ty, args, ret_ty, llret_ty, span) {
+                match generic_simd_intrinsic(
+                    self, name, callee_ty, fn_args, args, ret_ty, llret_ty, span,
+                ) {
                     Ok(llval) => llval,
                     Err(()) => return,
                 }
@@ -911,6 +913,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
     bx: &mut Builder<'_, 'll, 'tcx>,
     name: Symbol,
     callee_ty: Ty<'tcx>,
+    fn_args: GenericArgsRef<'tcx>,
     args: &[OperandRef<'tcx, &'ll Value>],
     ret_ty: Ty<'tcx>,
     llret_ty: &'ll Type,
@@ -1030,6 +1033,56 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         ));
     }
 
+    if name == sym::simd_shuffle_generic {
+        let idx = fn_args[2]
+            .expect_const()
+            .eval(tcx, ty::ParamEnv::reveal_all(), Some(span))
+            .unwrap()
+            .unwrap_branch();
+        let n = idx.len() as u64;
+
+        require_simd!(ret_ty, InvalidMonomorphization::SimdReturn { span, name, ty: ret_ty });
+        let (out_len, out_ty) = ret_ty.simd_size_and_type(bx.tcx());
+        require!(
+            out_len == n,
+            InvalidMonomorphization::ReturnLength { span, name, in_len: n, ret_ty, out_len }
+        );
+        require!(
+            in_elem == out_ty,
+            InvalidMonomorphization::ReturnElement { span, name, in_elem, in_ty, ret_ty, out_ty }
+        );
+
+        let total_len = in_len * 2;
+
+        let indices: Option<Vec<_>> = idx
+            .iter()
+            .enumerate()
+            .map(|(arg_idx, val)| {
+                let idx = val.unwrap_leaf().try_to_i32().unwrap();
+                if idx >= i32::try_from(total_len).unwrap() {
+                    bx.sess().emit_err(InvalidMonomorphization::ShuffleIndexOutOfBounds {
+                        span,
+                        name,
+                        arg_idx: arg_idx as u64,
+                        total_len: total_len.into(),
+                    });
+                    None
+                } else {
+                    Some(bx.const_i32(idx))
+                }
+            })
+            .collect();
+        let Some(indices) = indices else {
+            return Ok(bx.const_null(llret_ty));
+        };
+
+        return Ok(bx.shuffle_vector(
+            args[0].immediate(),
+            args[1].immediate(),
+            bx.const_vector(&indices),
+        ));
+    }
+
     if name == sym::simd_shuffle {
         // Make sure this is actually an array, since typeck only checks the length-suffixed
         // version of this intrinsic.
diff --git a/compiler/rustc_codegen_llvm/src/lib.rs b/compiler/rustc_codegen_llvm/src/lib.rs
index fe87446f5c3..59d1ea05d8a 100644
--- a/compiler/rustc_codegen_llvm/src/lib.rs
+++ b/compiler/rustc_codegen_llvm/src/lib.rs
@@ -22,6 +22,7 @@ extern crate rustc_macros;
 #[macro_use]
 extern crate tracing;
 
+use back::owned_target_machine::OwnedTargetMachine;
 use back::write::{create_informational_target_machine, create_target_machine};
 
 use errors::ParseTargetMachineConfig;
@@ -52,6 +53,7 @@ use std::io::Write;
 mod back {
     pub mod archive;
     pub mod lto;
+    pub mod owned_target_machine;
     mod profiling;
     pub mod write;
 }
@@ -162,7 +164,7 @@ impl ExtraBackendMethods for LlvmCodegenBackend {
 impl WriteBackendMethods for LlvmCodegenBackend {
     type Module = ModuleLlvm;
     type ModuleBuffer = back::lto::ModuleBuffer;
-    type TargetMachine = &'static mut llvm::TargetMachine;
+    type TargetMachine = OwnedTargetMachine;
     type TargetMachineError = crate::errors::LlvmError<'static>;
     type ThinData = back::lto::ThinData;
     type ThinBuffer = back::lto::ThinBuffer;
@@ -401,7 +403,9 @@ impl CodegenBackend for LlvmCodegenBackend {
 pub struct ModuleLlvm {
     llcx: &'static mut llvm::Context,
     llmod_raw: *const llvm::Module,
-    tm: &'static mut llvm::TargetMachine,
+
+    // independent from llcx and llmod_raw, resources get disposed by drop impl
+    tm: OwnedTargetMachine,
 }
 
 unsafe impl Send for ModuleLlvm {}
@@ -453,7 +457,6 @@ impl ModuleLlvm {
 impl Drop for ModuleLlvm {
     fn drop(&mut self) {
         unsafe {
-            llvm::LLVMRustDisposeTargetMachine(&mut *(self.tm as *mut _));
             llvm::LLVMContextDispose(&mut *(self.llcx as *mut _));
         }
     }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 2ebfdae39e8..a038b3af03d 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2112,6 +2112,8 @@ extern "C" {
     );
 
     pub fn LLVMRustGetHostCPUName(len: *mut usize) -> *const c_char;
+
+    // This function makes copies of pointed to data, so the data's lifetime may end after this function returns
     pub fn LLVMRustCreateTargetMachine(
         Triple: *const c_char,
         CPU: *const c_char,
@@ -2131,13 +2133,14 @@ extern "C" {
         RelaxELFRelocations: bool,
         UseInitArray: bool,
         SplitDwarfFile: *const c_char,
+        OutputObjFile: *const c_char,
         DebugInfoCompression: *const c_char,
         ForceEmulatedTls: bool,
         ArgsCstrBuff: *const c_char,
         ArgsCstrBuffLen: usize,
-    ) -> Option<&'static mut TargetMachine>;
+    ) -> *mut TargetMachine;
 
-    pub fn LLVMRustDisposeTargetMachine(T: &'static mut TargetMachine);
+    pub fn LLVMRustDisposeTargetMachine(T: *mut TargetMachine);
     pub fn LLVMRustAddLibraryInfo<'a>(
         PM: &PassManager<'a>,
         M: &'a Module,
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index a76c9c9b735..7c8ef67ffd1 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -303,7 +303,7 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
             // check that all features in a given smallvec are enabled
             for llvm_feature in to_llvm_features(sess, feature) {
                 let cstr = SmallCStr::new(llvm_feature);
-                if !unsafe { llvm::LLVMRustHasFeature(target_machine, cstr.as_ptr()) } {
+                if !unsafe { llvm::LLVMRustHasFeature(&target_machine, cstr.as_ptr()) } {
                     return false;
                 }
             }
@@ -422,14 +422,14 @@ pub(crate) fn print(req: &PrintRequest, mut out: &mut dyn PrintBackendInfo, sess
             }
             unsafe {
                 llvm::LLVMRustPrintTargetCPUs(
-                    tm,
+                    &tm,
                     cpu_cstring.as_ptr(),
                     callback,
                     &mut out as *mut &mut dyn PrintBackendInfo as *mut c_void,
                 );
             }
         }
-        PrintKind::TargetFeatures => print_target_features(out, sess, tm),
+        PrintKind::TargetFeatures => print_target_features(out, sess, &tm),
         _ => bug!("rustc_codegen_llvm can't handle print request: {:?}", req),
     }
 }
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index d0a078505d2..6f7d7482aea 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -46,8 +46,6 @@ codegen_ssa_ignoring_output = ignoring -o because multiple .{$extension} files w
 codegen_ssa_illegal_link_ordinal_format = illegal ordinal format in `link_ordinal`
     .note = an unsuffixed integer value, e.g., `1`, is expected
 
-codegen_ssa_incompatible_linking_modifiers = link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs
-
 codegen_ssa_insufficient_vs_code_product = VS Code is a different product, and is not sufficient.
 
 codegen_ssa_invalid_link_ordinal_nargs = incorrect number of arguments to `#[link_ordinal]`
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index a7ac728c59b..c4a0f6291e7 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -365,15 +365,9 @@ fn link_rlib<'a>(
     // loaded from the libraries found here and then encode that into the
     // metadata of the rlib we're generating somehow.
     for lib in codegen_results.crate_info.used_libraries.iter() {
-        let NativeLibKind::Static { bundle: None | Some(true), whole_archive } = lib.kind else {
+        let NativeLibKind::Static { bundle: None | Some(true), .. } = lib.kind else {
             continue;
         };
-        if whole_archive == Some(true)
-            && flavor == RlibFlavor::Normal
-            && !codegen_results.crate_info.feature_packed_bundled_libs
-        {
-            sess.emit_err(errors::IncompatibleLinkingModifiers);
-        }
         if flavor == RlibFlavor::Normal && let Some(filename) = lib.filename {
             let path = find_native_static_library(filename.as_str(), true, &lib_search_paths, sess);
             let src = read(path).map_err(|e| sess.emit_fatal(errors::ReadFileError {message: e }))?;
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 3bf98c46dea..f192747c8ab 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -286,6 +286,10 @@ pub struct TargetMachineFactoryConfig {
     /// so the path to the dwarf object has to be provided when we create the target machine.
     /// This can be ignored by backends which do not need it for their Split DWARF support.
     pub split_dwarf_file: Option<PathBuf>,
+
+    /// The name of the output object file. Used for setting OutputFilenames in target options
+    /// so that LLVM can emit the CodeView S_OBJNAME record in pdb files
+    pub output_obj_file: Option<PathBuf>,
 }
 
 impl TargetMachineFactoryConfig {
@@ -302,7 +306,10 @@ impl TargetMachineFactoryConfig {
         } else {
             None
         };
-        TargetMachineFactoryConfig { split_dwarf_file }
+
+        let output_obj_file =
+            Some(cgcx.output_filenames.temp_path(OutputType::Object, Some(module_name)));
+        TargetMachineFactoryConfig { split_dwarf_file, output_obj_file }
     }
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index cd19885faa0..1e4ea73a172 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -181,7 +181,7 @@ pub fn unsized_info<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 old_info
             }
         }
-        (_, &ty::Dynamic(ref data, _, _)) => meth::get_vtable(cx, source, data.principal()),
+        (_, ty::Dynamic(data, _, _)) => meth::get_vtable(cx, source, data.principal()),
         _ => bug!("unsized_info: invalid unsizing {:?} -> {:?}", source, target),
     }
 }
@@ -420,9 +420,11 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         rust_main_def_id: DefId,
         entry_type: EntryFnType,
     ) -> Bx::Function {
-        // The entry function is either `int main(void)` or `int main(int argc, char **argv)`,
-        // depending on whether the target needs `argc` and `argv` to be passed in.
-        let llfty = if cx.sess().target.main_needs_argc_argv {
+        // The entry function is either `int main(void)` or `int main(int argc, char **argv)`, or
+        // `usize efi_main(void *handle, void *system_table)` depending on the target.
+        let llfty = if cx.sess().target.os.contains("uefi") {
+            cx.type_func(&[cx.type_ptr(), cx.type_ptr()], cx.type_isize())
+        } else if cx.sess().target.main_needs_argc_argv {
             cx.type_func(&[cx.type_int(), cx.type_ptr()], cx.type_int())
         } else {
             cx.type_func(&[], cx.type_int())
@@ -485,8 +487,12 @@ pub fn maybe_create_entry_wrapper<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
         };
 
         let result = bx.call(start_ty, None, None, start_fn, &args, None);
-        let cast = bx.intcast(result, cx.type_int(), true);
-        bx.ret(cast);
+        if cx.sess().target.os.contains("uefi") {
+            bx.ret(result);
+        } else {
+            let cast = bx.intcast(result, cx.type_int(), true);
+            bx.ret(cast);
+        }
 
         llfn
     }
@@ -497,7 +503,17 @@ fn get_argc_argv<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
     cx: &'a Bx::CodegenCx,
     bx: &mut Bx,
 ) -> (Bx::Value, Bx::Value) {
-    if cx.sess().target.main_needs_argc_argv {
+    if cx.sess().target.os.contains("uefi") {
+        // Params for UEFI
+        let param_handle = bx.get_param(0);
+        let param_system_table = bx.get_param(1);
+        let arg_argc = bx.const_int(cx.type_isize(), 2);
+        let arg_argv = bx.alloca(cx.type_array(cx.type_ptr(), 2), Align::ONE);
+        bx.store(param_handle, arg_argv, Align::ONE);
+        let arg_argv_el1 = bx.gep(cx.type_ptr(), arg_argv, &[bx.const_int(cx.type_int(), 1)]);
+        bx.store(param_system_table, arg_argv_el1, Align::ONE);
+        (arg_argc, arg_argv)
+    } else if cx.sess().target.main_needs_argc_argv {
         // Params from native `main()` used as args for rust start function
         let param_argc = bx.get_param(0);
         let param_argv = bx.get_param(1);
@@ -841,7 +857,6 @@ impl CrateInfo {
             dependency_formats: tcx.dependency_formats(()).clone(),
             windows_subsystem,
             natvis_debugger_visualizers: Default::default(),
-            feature_packed_bundled_libs: tcx.features().packed_bundled_libs,
         };
         let crates = tcx.crates(());
 
diff --git a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
index a2190293c0b..989df448a31 100644
--- a/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
+++ b/compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs
@@ -426,7 +426,6 @@ fn push_debuginfo_type_name<'tcx>(
         | ty::Placeholder(..)
         | ty::Alias(..)
         | ty::Bound(..)
-        | ty::GeneratorWitnessMIR(..)
         | ty::GeneratorWitness(..) => {
             bug!(
                 "debuginfo: Trying to create type name for \
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index bfd572a2eea..14311ec08fd 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -108,10 +108,6 @@ pub struct CreateTempDir {
 }
 
 #[derive(Diagnostic)]
-#[diag(codegen_ssa_incompatible_linking_modifiers)]
-pub struct IncompatibleLinkingModifiers;
-
-#[derive(Diagnostic)]
 #[diag(codegen_ssa_add_native_library)]
 pub struct AddNativeLibrary {
     pub library_path: PathBuf,
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 7ebaca9b0bc..f6186a290f8 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -164,7 +164,6 @@ pub struct CrateInfo {
     pub dependency_formats: Lrc<Dependencies>,
     pub windows_subsystem: Option<String>,
     pub natvis_debugger_visualizers: BTreeSet<DebuggerVisualizerFile>,
-    pub feature_packed_bundled_libs: bool, // unstable feature flag.
 }
 
 #[derive(Encodable, Decodable)]
diff --git a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
index d1560114763..0dc30d21c5b 100644
--- a/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/debuginfo.rs
@@ -158,8 +158,7 @@ fn calculate_debuginfo_offset<
     L: DebugInfoOffsetLocation<'tcx, Bx>,
 >(
     bx: &mut Bx,
-    local: mir::Local,
-    var: &PerLocalVarDebugInfo<'tcx, Bx::DIVariable>,
+    projection: &[mir::PlaceElem<'tcx>],
     base: L,
 ) -> DebugInfoOffset<L> {
     let mut direct_offset = Size::ZERO;
@@ -167,7 +166,7 @@ fn calculate_debuginfo_offset<
     let mut indirect_offsets = vec![];
     let mut place = base;
 
-    for elem in &var.projection[..] {
+    for elem in projection {
         match *elem {
             mir::ProjectionElem::Deref => {
                 indirect_offsets.push(Size::ZERO);
@@ -188,11 +187,7 @@ fn calculate_debuginfo_offset<
             } => {
                 let offset = indirect_offsets.last_mut().unwrap_or(&mut direct_offset);
                 let FieldsShape::Array { stride, count: _ } = place.layout().fields else {
-                    span_bug!(
-                        var.source_info.span,
-                        "ConstantIndex on non-array type {:?}",
-                        place.layout()
-                    )
+                    bug!("ConstantIndex on non-array type {:?}", place.layout())
                 };
                 *offset += stride * index;
                 place = place.project_constant_index(bx, index);
@@ -200,11 +195,7 @@ fn calculate_debuginfo_offset<
             _ => {
                 // Sanity check for `can_use_in_debuginfo`.
                 debug_assert!(!elem.can_use_in_debuginfo());
-                span_bug!(
-                    var.source_info.span,
-                    "unsupported var debuginfo place `{:?}`",
-                    mir::Place { local, projection: var.projection },
-                )
+                bug!("unsupported var debuginfo projection `{:?}`", projection)
             }
         }
     }
@@ -407,7 +398,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let Some(dbg_loc) = self.dbg_loc(var.source_info) else { return };
 
         let DebugInfoOffset { direct_offset, indirect_offsets, result: _ } =
-            calculate_debuginfo_offset(bx, local, &var, base.layout);
+            calculate_debuginfo_offset(bx, &var.projection, base.layout);
 
         // When targeting MSVC, create extra allocas for arguments instead of pointing multiple
         // dbg_var_addr() calls into the same alloca with offsets. MSVC uses CodeView records
@@ -425,7 +416,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         if should_create_individual_allocas {
             let DebugInfoOffset { direct_offset: _, indirect_offsets: _, result: place } =
-                calculate_debuginfo_offset(bx, local, &var, base);
+                calculate_debuginfo_offset(bx, &var.projection, base);
 
             // Create a variable which will be a pointer to the actual value
             let ptr_ty = Ty::new_ptr(
@@ -532,23 +523,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             let fragment = if let Some(ref fragment) = var.composite {
                 let var_layout = self.cx.layout_of(var_ty);
 
-                let mut fragment_start = Size::ZERO;
-                let mut fragment_layout = var_layout;
-
-                for elem in &fragment.projection {
-                    match *elem {
-                        mir::ProjectionElem::Field(field, _) => {
-                            let i = field.index();
-                            fragment_start += fragment_layout.fields.offset(i);
-                            fragment_layout = fragment_layout.field(self.cx, i);
-                        }
-                        _ => span_bug!(
-                            var.source_info.span,
-                            "unsupported fragment projection `{:?}`",
-                            elem,
-                        ),
-                    }
-                }
+                let DebugInfoOffset { direct_offset, indirect_offsets, result: fragment_layout } =
+                    calculate_debuginfo_offset(bx, &fragment.projection, var_layout);
+                debug_assert!(indirect_offsets.is_empty());
 
                 if fragment_layout.size == Size::ZERO {
                     // Fragment is a ZST, so does not represent anything. Avoid generating anything
@@ -559,7 +536,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     // DWARF is concerned, it's not really a fragment.
                     None
                 } else {
-                    Some(fragment_start..fragment_start + fragment_layout.size)
+                    Some(direct_offset..direct_offset + fragment_layout.size)
                 }
             } else {
                 None
diff --git a/compiler/rustc_codegen_ssa/src/mir/mod.rs b/compiler/rustc_codegen_ssa/src/mir/mod.rs
index 1e905a7c78e..a61018f9870 100644
--- a/compiler/rustc_codegen_ssa/src/mir/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/mod.rs
@@ -118,7 +118,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         T: Copy + TypeFoldable<TyCtxt<'tcx>>,
     {
         debug!("monomorphize: self.instance={:?}", self.instance);
-        self.instance.subst_mir_and_normalize_erasing_regions(
+        self.instance.instantiate_mir_and_normalize_erasing_regions(
             self.cx.tcx(),
             ty::ParamEnv::reveal_all(),
             ty::EarlyBinder::bind(value),
diff --git a/compiler/rustc_codegen_ssa/src/mir/operand.rs b/compiler/rustc_codegen_ssa/src/mir/operand.rs
index 9205acc527e..0ab2b7ecd9c 100644
--- a/compiler/rustc_codegen_ssa/src/mir/operand.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/operand.rs
@@ -135,15 +135,14 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
         assert_eq!(alloc_align, layout.align.abi);
 
         let read_scalar = |start, size, s: abi::Scalar, ty| {
-            let val = alloc
-                .0
-                .read_scalar(
-                    bx,
-                    alloc_range(start, size),
-                    /*read_provenance*/ matches!(s.primitive(), abi::Pointer(_)),
-                )
-                .unwrap();
-            bx.scalar_to_backend(val, s, ty)
+            match alloc.0.read_scalar(
+                bx,
+                alloc_range(start, size),
+                /*read_provenance*/ matches!(s.primitive(), abi::Pointer(_)),
+            ) {
+                Ok(val) => bx.scalar_to_backend(val, s, ty),
+                Err(_) => bx.const_poison(ty),
+            }
         };
 
         // It may seem like all types with `Scalar` or `ScalarPair` ABI are fair game at this point.
@@ -156,7 +155,7 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
             Abi::Scalar(s @ abi::Scalar::Initialized { .. }) => {
                 let size = s.size(bx);
                 assert_eq!(size, layout.size, "abi::Scalar size does not match layout size");
-                let val = read_scalar(Size::ZERO, size, s, bx.type_ptr());
+                let val = read_scalar(offset, size, s, bx.backend_type(layout));
                 OperandRef { val: OperandValue::Immediate(val), layout }
             }
             Abi::ScalarPair(
@@ -164,10 +163,10 @@ impl<'a, 'tcx, V: CodegenObject> OperandRef<'tcx, V> {
                 b @ abi::Scalar::Initialized { .. },
             ) => {
                 let (a_size, b_size) = (a.size(bx), b.size(bx));
-                let b_offset = a_size.align_to(b.align(bx).abi);
+                let b_offset = (offset + a_size).align_to(b.align(bx).abi);
                 assert!(b_offset.bytes() > 0);
                 let a_val = read_scalar(
-                    Size::ZERO,
+                    offset,
                     a_size,
                     a,
                     bx.scalar_pair_element_backend_type(layout, 0, true),
diff --git a/compiler/rustc_codegen_ssa/src/mir/place.rs b/compiler/rustc_codegen_ssa/src/mir/place.rs
index a9ecbdc5f35..f775711f870 100644
--- a/compiler/rustc_codegen_ssa/src/mir/place.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/place.rs
@@ -463,7 +463,9 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 mir::ProjectionElem::Field(ref field, _) => {
                     cg_base.project_field(bx, field.index())
                 }
-                mir::ProjectionElem::OpaqueCast(ty) => cg_base.project_type(bx, ty),
+                mir::ProjectionElem::OpaqueCast(ty) => {
+                    bug!("encountered OpaqueCast({ty}) in codegen")
+                }
                 mir::ProjectionElem::Index(index) => {
                     let index = &mir::Operand::Copy(mir::Place::from(index));
                     let index = self.codegen_operand(bx, index);
diff --git a/compiler/rustc_const_eval/src/const_eval/valtrees.rs b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
index 2fba7455cb2..7436ea6ae57 100644
--- a/compiler/rustc_const_eval/src/const_eval/valtrees.rs
+++ b/compiler/rustc_const_eval/src/const_eval/valtrees.rs
@@ -152,7 +152,7 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
         // FIXME(oli-obk): we can probably encode closures just like structs
         | ty::Closure(..)
         | ty::Generator(..)
-        | ty::GeneratorWitness(..) |ty::GeneratorWitnessMIR(..)=> Err(ValTreeCreationError::NonSupportedType),
+        | ty::GeneratorWitness(..) => Err(ValTreeCreationError::NonSupportedType),
     }
 }
 
@@ -280,7 +280,6 @@ pub fn valtree_to_const_value<'tcx>(
         | ty::Closure(..)
         | ty::Generator(..)
         | ty::GeneratorWitness(..)
-        | ty::GeneratorWitnessMIR(..)
         | ty::FnPtr(_)
         | ty::RawPtr(_)
         | ty::Str
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 83f2052d0f8..94a5cc67d31 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -569,7 +569,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
     ) -> Result<T, ErrorHandled> {
         frame
             .instance
-            .try_subst_mir_and_normalize_erasing_regions(
+            .try_instantiate_mir_and_normalize_erasing_regions(
                 *self.tcx,
                 self.param_env,
                 ty::EarlyBinder::bind(value),
@@ -963,7 +963,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 | ty::Ref(..)
                 | ty::Generator(..)
                 | ty::GeneratorWitness(..)
-                | ty::GeneratorWitnessMIR(..)
                 | ty::Array(..)
                 | ty::Closure(..)
                 | ty::Never
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 2b26dbbba98..2c0ba9b2673 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -100,8 +100,7 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
             | ty::Dynamic(_, _, _)
             | ty::Closure(_, _)
             | ty::Generator(_, _, _)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(_, _)
+            | ty::GeneratorWitness(..)
             | ty::Never
             | ty::Tuple(_)
             | ty::Error(_) => ConstValue::from_target_usize(0u64, &tcx),
diff --git a/compiler/rustc_const_eval/src/interpret/projection.rs b/compiler/rustc_const_eval/src/interpret/projection.rs
index 6c720ac4a57..f462c13816e 100644
--- a/compiler/rustc_const_eval/src/interpret/projection.rs
+++ b/compiler/rustc_const_eval/src/interpret/projection.rs
@@ -316,7 +316,9 @@ where
     {
         use rustc_middle::mir::ProjectionElem::*;
         Ok(match proj_elem {
-            OpaqueCast(ty) => base.transmute(self.layout_of(ty)?, self)?,
+            OpaqueCast(ty) => {
+                span_bug!(self.cur_span(), "OpaqueCast({ty}) encountered after borrowck")
+            }
             Field(field, _) => self.project_field(base, field.index())?,
             Downcast(_, variant) => self.project_downcast(base, variant)?,
             Deref => self.deref_pointer(&base.to_op(self)?)?.into(),
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index b3319442388..eb639ded70f 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -4,7 +4,7 @@ use rustc_middle::ty::{
 };
 use std::ops::ControlFlow;
 
-/// Checks whether a type contains generic parameters which require substitution.
+/// Checks whether a type contains generic parameters which must be instantiated.
 ///
 /// In case it does, returns a `TooGeneric` const eval error. Note that due to polymorphization
 /// types may be "concrete enough" even though they still contain generic parameters in
@@ -43,7 +43,8 @@ where
                             .try_into()
                             .expect("more generic parameters than can fit into a `u32`");
                         // Only recurse when generic parameters in fns, closures and generators
-                        // are used and require substitution.
+                        // are used and have to be instantiated.
+                        //
                         // Just in case there are closures or generators within this subst,
                         // recurse.
                         if unused_params.is_used(index) && subst.has_param() {
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index 8e2b35fd5b6..3e023a89648 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -583,7 +583,6 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
             | ty::Bound(..)
             | ty::Param(..)
             | ty::Alias(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::GeneratorWitness(..) => bug!("Encountered invalid type {:?}", ty),
         }
     }
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 2f5f2ad6534..18b22882e7d 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -558,8 +558,8 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
     }
 }
 
-/// A faster version of the validation pass that only checks those things which may break when apply
-/// generic substitutions.
+/// A faster version of the validation pass that only checks those things which may break when
+/// instantiating any generic parameters.
 pub fn validate_types<'tcx>(
     tcx: TyCtxt<'tcx>,
     mir_phase: MirPhase,
@@ -633,6 +633,14 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
         location: Location,
     ) {
         match elem {
+            ProjectionElem::OpaqueCast(ty)
+                if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) =>
+            {
+                self.fail(
+                    location,
+                    format!("explicit opaque type cast to `{ty}` after `RevealAll`"),
+                )
+            }
             ProjectionElem::Index(index) => {
                 let index_ty = self.body.local_decls[index].ty;
                 if index_ty != self.tcx.types.usize {
diff --git a/compiler/rustc_const_eval/src/util/type_name.rs b/compiler/rustc_const_eval/src/util/type_name.rs
index 14a840ad1b1..a924afda6f0 100644
--- a/compiler/rustc_const_eval/src/util/type_name.rs
+++ b/compiler/rustc_const_eval/src/util/type_name.rs
@@ -64,8 +64,7 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
 
             ty::Alias(ty::Weak, _) => bug!("type_name: unexpected weak projection"),
             ty::Alias(ty::Inherent, _) => bug!("type_name: unexpected inherent projection"),
-            ty::GeneratorWitness(_) => bug!("type_name: unexpected `GeneratorWitness`"),
-            ty::GeneratorWitnessMIR(..) => bug!("type_name: unexpected `GeneratorWitnessMIR`"),
+            ty::GeneratorWitness(..) => bug!("type_name: unexpected `GeneratorWitness`"),
         }
     }
 
diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs
index 7d037ddfa98..461ec3a90ed 100644
--- a/compiler/rustc_data_structures/src/lib.rs
+++ b/compiler/rustc_data_structures/src/lib.rs
@@ -51,9 +51,10 @@ use std::fmt;
 
 pub use rustc_index::static_assert_size;
 
+/// This calls the passed function while ensuring it won't be inlined into the caller.
 #[inline(never)]
 #[cold]
-pub fn cold_path<F: FnOnce() -> R, R>(f: F) -> R {
+pub fn outline<F: FnOnce() -> R, R>(f: F) -> R {
     f()
 }
 
diff --git a/compiler/rustc_data_structures/src/profiling.rs b/compiler/rustc_data_structures/src/profiling.rs
index 3c76c2b7991..e688feb5fe1 100644
--- a/compiler/rustc_data_structures/src/profiling.rs
+++ b/compiler/rustc_data_structures/src/profiling.rs
@@ -81,8 +81,8 @@
 //!
 //! [mm]: https://github.com/rust-lang/measureme/
 
-use crate::cold_path;
 use crate::fx::FxHashMap;
+use crate::outline;
 
 use std::borrow::Borrow;
 use std::collections::hash_map::Entry;
@@ -697,7 +697,7 @@ impl<'a> TimingGuard<'a> {
     #[inline]
     pub fn finish_with_query_invocation_id(self, query_invocation_id: QueryInvocationId) {
         if let Some(guard) = self.0 {
-            cold_path(|| {
+            outline(|| {
                 let event_id = StringId::new_virtual(query_invocation_id.0);
                 let event_id = EventId::from_virtual(event_id);
                 guard.finish_with_override_event_id(event_id);
diff --git a/compiler/rustc_data_structures/src/small_c_str.rs b/compiler/rustc_data_structures/src/small_c_str.rs
index 719e4e3d974..349fd7f9769 100644
--- a/compiler/rustc_data_structures/src/small_c_str.rs
+++ b/compiler/rustc_data_structures/src/small_c_str.rs
@@ -79,3 +79,9 @@ impl<'a> FromIterator<&'a str> for SmallCStr {
         Self { data }
     }
 }
+
+impl From<&ffi::CStr> for SmallCStr {
+    fn from(s: &ffi::CStr) -> Self {
+        Self { data: SmallVec::from_slice(s.to_bytes()) }
+    }
+}
diff --git a/compiler/rustc_data_structures/src/sync/worker_local.rs b/compiler/rustc_data_structures/src/sync/worker_local.rs
index 1f838cc4648..ffafdba13ce 100644
--- a/compiler/rustc_data_structures/src/sync/worker_local.rs
+++ b/compiler/rustc_data_structures/src/sync/worker_local.rs
@@ -6,7 +6,7 @@ use std::ptr;
 use std::sync::Arc;
 
 #[cfg(parallel_compiler)]
-use {crate::cold_path, crate::sync::CacheAligned};
+use {crate::outline, crate::sync::CacheAligned};
 
 /// A pointer to the `RegistryData` which uniquely identifies a registry.
 /// This identifier can be reused if the registry gets freed.
@@ -25,11 +25,7 @@ impl RegistryId {
     fn verify(self) -> usize {
         let (id, index) = THREAD_DATA.with(|data| (data.registry_id.get(), data.index.get()));
 
-        if id == self {
-            index
-        } else {
-            cold_path(|| panic!("Unable to verify registry association"))
-        }
+        if id == self { index } else { outline(|| panic!("Unable to verify registry association")) }
     }
 }
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0038.md b/compiler/rustc_error_codes/src/error_codes/E0038.md
index 584b78554ef..8f8eabb1519 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0038.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0038.md
@@ -162,14 +162,13 @@ fn foo<T>(x: T) {
 ```
 
 The machine code for `foo::<u8>()`, `foo::<bool>()`, `foo::<String>()`, or any
-other type substitution is different. Hence the compiler generates the
+other instantiation is different. Hence the compiler generates the
 implementation on-demand. If you call `foo()` with a `bool` parameter, the
 compiler will only generate code for `foo::<bool>()`. When we have additional
 type parameters, the number of monomorphized implementations the compiler
 generates does not grow drastically, since the compiler will only generate an
-implementation if the function is called with unparameterized substitutions
-(i.e., substitutions where none of the substituted types are themselves
-parameterized).
+implementation if the function is called with fully concrete arguments
+(i.e., arguments which do not contain any generic parameters).
 
 However, with trait objects we have to make a table containing _every_ object
 that implements the trait. Now, if it has type parameters, we need to add
diff --git a/compiler/rustc_error_codes/src/error_codes/E0094.md b/compiler/rustc_error_codes/src/error_codes/E0094.md
index 67a8c3678c5..d8c1a3cb55c 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0094.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0094.md
@@ -3,7 +3,7 @@ An invalid number of generic parameters was passed to an intrinsic function.
 Erroneous code example:
 
 ```compile_fail,E0094
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 extern "rust-intrinsic" {
@@ -18,7 +18,7 @@ and verify with the function declaration in the Rust source code.
 Example:
 
 ```
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 extern "rust-intrinsic" {
diff --git a/compiler/rustc_error_codes/src/error_codes/E0211.md b/compiler/rustc_error_codes/src/error_codes/E0211.md
index 70f14fffae6..19a482f6c93 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0211.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0211.md
@@ -4,7 +4,7 @@ You used a function or type which doesn't fit the requirements for where it was
 used. Erroneous code examples:
 
 ```compile_fail
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 extern "rust-intrinsic" {
@@ -41,7 +41,7 @@ impl Foo {
 For the first code example, please check the function definition. Example:
 
 ```
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 #![allow(internal_features)]
 
 extern "rust-intrinsic" {
diff --git a/compiler/rustc_error_codes/src/error_codes/E0698.md b/compiler/rustc_error_codes/src/error_codes/E0698.md
index 3ba992a8476..9bc652e642f 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0698.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0698.md
@@ -1,9 +1,11 @@
+#### Note: this error code is no longer emitted by the compiler.
+
 When using generators (or async) all type variables must be bound so a
 generator can be constructed.
 
 Erroneous code example:
 
-```edition2018,compile_fail,E0698
+```edition2018,compile_fail,E0282
 async fn bar<T>() -> () {}
 
 async fn foo() {
diff --git a/compiler/rustc_error_codes/src/error_codes/E0760.md b/compiler/rustc_error_codes/src/error_codes/E0760.md
index 85e5faada22..9c4739f0df0 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0760.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0760.md
@@ -5,7 +5,7 @@ or `Self` that references lifetimes from a parent scope.
 
 Erroneous code example:
 
-```compile_fail,edition2018
+```ignore,edition2018
 struct S<'a>(&'a i32);
 
 impl<'a> S<'a> {
diff --git a/compiler/rustc_feature/src/accepted.rs b/compiler/rustc_feature/src/accepted.rs
index afcf30d0b29..32d8380abd3 100644
--- a/compiler/rustc_feature/src/accepted.rs
+++ b/compiler/rustc_feature/src/accepted.rs
@@ -197,6 +197,8 @@ declare_features! (
     /// + `impl<I:Iterator> Iterator for &mut Iterator`
     /// + `impl Debug for Foo<'_>`
     (accepted, impl_header_lifetime_elision, "1.31.0", Some(15872), None),
+    /// Allows referencing `Self` and projections in impl-trait.
+    (accepted, impl_trait_projections, "CURRENT_RUSTC_VERSION", Some(103532), None),
     /// Allows using `a..=b` and `..=b` as inclusive range syntaxes.
     (accepted, inclusive_range_syntax, "1.26.0", Some(28237), None),
     /// Allows inferring outlives requirements (RFC 2093).
@@ -267,6 +269,8 @@ declare_features! (
     (accepted, non_modrs_mods, "1.30.0", Some(44660), None),
     /// Allows the use of or-patterns (e.g., `0 | 1`).
     (accepted, or_patterns, "1.53.0", Some(54883), None),
+    /// Allows using `+bundle,+whole-archive` link modifiers with native libs.
+    (accepted, packed_bundled_libs, "CURRENT_RUSTC_VERSION", Some(108081), None),
     /// Allows annotating functions conforming to `fn(&PanicInfo) -> !` with `#[panic_handler]`.
     /// This defines the behavior of panics.
     (accepted, panic_handler, "1.30.0", Some(44489), None),
diff --git a/compiler/rustc_feature/src/active.rs b/compiler/rustc_feature/src/active.rs
index f3b88f46bae..a02c04ecd3e 100644
--- a/compiler/rustc_feature/src/active.rs
+++ b/compiler/rustc_feature/src/active.rs
@@ -236,15 +236,15 @@ declare_features! (
     /// Allows using the `#[fundamental]` attribute.
     (active, fundamental, "1.0.0", Some(29635), None),
     /// Allows using `#[link_name="llvm.*"]`.
-    (active, link_llvm_intrinsics, "1.0.0", Some(29602), None),
+    (internal, link_llvm_intrinsics, "1.0.0", Some(29602), None),
     /// Allows using the `#[linkage = ".."]` attribute.
     (active, linkage, "1.0.0", Some(29603), None),
     /// Allows declaring with `#![needs_panic_runtime]` that a panic runtime is needed.
     (internal, needs_panic_runtime, "1.10.0", Some(32837), None),
-    /// Allows using `+bundled,+whole-archive` native libs.
-    (active, packed_bundled_libs, "1.69.0", Some(108081), None),
     /// Allows using the `#![panic_runtime]` attribute.
     (internal, panic_runtime, "1.10.0", Some(32837), None),
+    /// Allows `extern "platform-intrinsic" { ... }`.
+    (internal, platform_intrinsics, "1.4.0", Some(27731), None),
     /// Allows using `#[rustc_allow_const_fn_unstable]`.
     /// This is an attribute on `const fn` for the same
     /// purpose as `#[allow_internal_unstable]`.
@@ -470,8 +470,6 @@ declare_features! (
     (active, impl_trait_in_assoc_type, "1.70.0", Some(63063), None),
     /// Allows `impl Trait` as output type in `Fn` traits in return position of functions.
     (active, impl_trait_in_fn_trait_return, "1.64.0", Some(99697), None),
-    /// Allows referencing `Self` and projections in impl-trait.
-    (active, impl_trait_projections, "1.67.0", Some(103532), None),
     /// Allows using imported `main` function
     (active, imported_main, "1.53.0", Some(28937), None),
     /// Allows associated types in inherent impls.
@@ -526,8 +524,6 @@ declare_features! (
     (active, object_safe_for_dispatch, "1.40.0", Some(43561), None),
     /// Allows using `#[optimize(X)]`.
     (active, optimize_attribute, "1.34.0", Some(54882), None),
-    /// Allows `extern "platform-intrinsic" { ... }`.
-    (active, platform_intrinsics, "1.4.0", Some(27731), None),
     /// Allows using `#![plugin(myplugin)]`.
     (active, plugin, "1.0.0", Some(29597), None),
     /// Allows exhaustive integer pattern matching on `usize` and `isize`.
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 04ebe22a9eb..18397af565f 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -537,7 +537,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         allow_internal_unsafe, Normal, template!(Word), WarnFollowing,
         "allow_internal_unsafe side-steps the unsafe_code lint",
     ),
-    ungated!(rustc_safe_intrinsic, Normal, template!(Word), DuplicatesOk),
     rustc_attr!(rustc_allowed_through_unstable_modules, Normal, template!(Word), WarnFollowing,
     "rustc_allowed_through_unstable_modules special cases accidental stabilizations of stable items \
     through unstable paths"),
@@ -806,6 +805,10 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         rustc_doc_primitive, Normal, template!(NameValueStr: "primitive name"), ErrorFollowing,
         r#"`rustc_doc_primitive` is a rustc internal attribute"#,
     ),
+    rustc_attr!(
+        rustc_safe_intrinsic, Normal, template!(Word), WarnFollowing,
+        "the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe"
+    ),
 
     // ==========================================================================
     // Internal attributes, Testing:
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index 64271309664..3a4eb90f7f9 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -61,9 +61,7 @@ pub enum DefKind {
     Variant,
     Trait,
     /// Type alias: `type Foo = Bar;`
-    TyAlias {
-        lazy: bool,
-    },
+    TyAlias,
     /// Type from an `extern` block.
     ForeignTy,
     /// Trait alias: `trait IntIterator = Iterator<Item = i32>;`
@@ -143,7 +141,7 @@ impl DefKind {
             DefKind::Ctor(CtorOf::Struct, CtorKind::Fn) => "tuple struct",
             DefKind::Ctor(CtorOf::Struct, CtorKind::Const) => "unit struct",
             DefKind::OpaqueTy => "opaque type",
-            DefKind::TyAlias { .. } => "type alias",
+            DefKind::TyAlias => "type alias",
             DefKind::TraitAlias => "trait alias",
             DefKind::AssocTy => "associated type",
             DefKind::Union => "union",
@@ -199,7 +197,7 @@ impl DefKind {
             | DefKind::Variant
             | DefKind::Trait
             | DefKind::OpaqueTy
-            | DefKind::TyAlias { .. }
+            | DefKind::TyAlias
             | DefKind::ForeignTy
             | DefKind::TraitAlias
             | DefKind::AssocTy
@@ -250,7 +248,7 @@ impl DefKind {
             | DefKind::Enum
             | DefKind::Variant
             | DefKind::Trait
-            | DefKind::TyAlias { .. }
+            | DefKind::TyAlias
             | DefKind::ForeignTy
             | DefKind::TraitAlias
             | DefKind::AssocTy
diff --git a/compiler/rustc_hir/src/target.rs b/compiler/rustc_hir/src/target.rs
index 644c4d8265d..0d65ddb5642 100644
--- a/compiler/rustc_hir/src/target.rs
+++ b/compiler/rustc_hir/src/target.rs
@@ -101,7 +101,7 @@ impl Target {
             DefKind::Mod => Target::Mod,
             DefKind::ForeignMod => Target::ForeignMod,
             DefKind::GlobalAsm => Target::GlobalAsm,
-            DefKind::TyAlias { .. } => Target::TyAlias,
+            DefKind::TyAlias => Target::TyAlias,
             DefKind::OpaqueTy => Target::OpaqueTy,
             DefKind::Enum => Target::Enum,
             DefKind::Struct => Target::Struct,
diff --git a/compiler/rustc_hir_analysis/messages.ftl b/compiler/rustc_hir_analysis/messages.ftl
index 2a68d745c76..1c926533a27 100644
--- a/compiler/rustc_hir_analysis/messages.ftl
+++ b/compiler/rustc_hir_analysis/messages.ftl
@@ -38,6 +38,17 @@ hir_analysis_cast_thin_pointer_to_fat_pointer = cannot cast thin pointer `{$expr
 hir_analysis_closure_implicit_hrtb = implicit types in closure signatures are forbidden when `for<...>` is present
     .label = `for<...>` is here
 
+hir_analysis_coerce_unsized_may = the trait `{$trait_name}` may only be implemented for a coercion between structures
+
+hir_analysis_coerce_unsized_multi = implementing the trait `CoerceUnsized` requires multiple coercions
+    .note = `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced
+    .coercions_note = currently, {$number} fields need coercions: {$coercions}
+    .label = requires multiple coercions
+
+hir_analysis_coercion_between_struct_same_note = expected coercion between the same definition; expected `{$source_path}`, found `{$target_path}`
+
+hir_analysis_coercion_between_struct_single_note = expected a single field to be coerced, none found
+
 hir_analysis_const_bound_for_non_const_trait =
     ~const can only be applied to `#[const_trait]` traits
 
@@ -61,6 +72,15 @@ hir_analysis_copy_impl_on_type_with_dtor =
     the trait `Copy` cannot be implemented for this type; the type has a destructor
     .label = `Copy` not allowed on types with destructors
 
+hir_analysis_dispatch_from_dyn_multi = implementing the `DispatchFromDyn` trait requires multiple coercions
+    .note = the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
+    .coercions_note = currently, {$number} fields need coercions: {$coercions}
+
+hir_analysis_dispatch_from_dyn_repr = structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]`
+
+hir_analysis_dispatch_from_dyn_zst = the trait `DispatchFromDyn` may only be implemented for structs containing the field being coerced, ZST fields with 1 byte alignment, and nothing else
+    .note = extra field `{$name}` of type `{$ty}` is not allowed
+
 hir_analysis_drop_impl_negative = negative `Drop` impls are not supported
 
 hir_analysis_drop_impl_on_wrong_item =
@@ -232,6 +252,8 @@ hir_analysis_pass_to_variadic_function = can't pass `{$ty}` to variadic function
 hir_analysis_placeholder_not_allowed_item_signatures = the placeholder `_` is not allowed within types on item signatures for {$kind}
     .label = not allowed in type signatures
 
+hir_analysis_requires_note = the `{$trait_name}` impl for `{$ty}` requires that `{$error_predicate}`
+
 hir_analysis_return_type_notation_conflicting_bound =
     ambiguous associated function `{$assoc_name}` for `{$ty_name}`
     .note = `{$assoc_name}` is declared in two supertraits: `{$first_bound}` and `{$second_bound}`
@@ -299,6 +321,9 @@ hir_analysis_too_large_static = extern static is too large for the current archi
 hir_analysis_track_caller_on_main = `main` function is not allowed to be `#[track_caller]`
     .suggestion = remove this annotation
 
+hir_analysis_trait_cannot_impl_for_ty = the trait `{$trait_name}` cannot be implemented for this type
+    .label = this field does not implement `{$trait_name}`
+
 hir_analysis_trait_object_declared_with_no_traits =
     at least one trait is required for an object type
     .alias_span = this alias does not contain a trait
diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
index ba152cd48de..21611e9c586 100644
--- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
@@ -427,7 +427,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
             let bound_vars = tcx.late_bound_vars(binding.hir_id);
             ty::Binder::bind_with_vars(subst_output, bound_vars)
         } else {
-            // Include substitutions for generic parameters of associated types
+            // Append the generic arguments of the associated type to the `trait_ref`.
             candidate.map_bound(|trait_ref| {
                 let ident = Ident::new(assoc_item.name, binding.item_name.span);
                 let item_segment = hir::PathSegment {
diff --git a/compiler/rustc_hir_analysis/src/astconv/generics.rs b/compiler/rustc_hir_analysis/src/astconv/generics.rs
index 1372cc896be..e3621ef933a 100644
--- a/compiler/rustc_hir_analysis/src/astconv/generics.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/generics.rs
@@ -139,22 +139,22 @@ fn generic_arg_mismatch_err(
     err.emit()
 }
 
-/// Creates the relevant generic argument substitutions
+/// Creates the relevant generic arguments
 /// corresponding to a set of generic parameters. This is a
 /// rather complex function. Let us try to explain the role
 /// of each of its parameters:
 ///
-/// To start, we are given the `def_id` of the thing we are
-/// creating the substitutions for, and a partial set of
-/// substitutions `parent_args`. In general, the substitutions
-/// for an item begin with substitutions for all the "parents" of
+/// To start, we are given the `def_id` of the thing whose generic
+/// parameters we are instantiating, and a partial set of
+/// arguments `parent_args`. In general, the generic arguments
+/// for an item begin with arguments for all the "parents" of
 /// that item -- e.g., for a method it might include the
 /// parameters from the impl.
 ///
 /// Therefore, the method begins by walking down these parents,
 /// starting with the outermost parent and proceed inwards until
 /// it reaches `def_id`. For each parent `P`, it will check `parent_args`
-/// first to see if the parent's substitutions are listed in there. If so,
+/// first to see if the parent's arguments are listed in there. If so,
 /// we can append those and move on. Otherwise, it invokes the
 /// three callback functions:
 ///
@@ -188,7 +188,7 @@ pub fn create_args_for_parent_generic_args<'tcx, 'a>(
         stack.push((def_id, parent_defs));
     }
 
-    // We manually build up the substitution, rather than using convenience
+    // We manually build up the generic arguments, rather than using convenience
     // methods in `subst.rs`, so that we can iterate over the arguments and
     // parameters in lock-step linearly, instead of trying to match each pair.
     let mut args: SmallVec<[ty::GenericArg<'tcx>; 8]> = SmallVec::with_capacity(count);
@@ -196,7 +196,8 @@ pub fn create_args_for_parent_generic_args<'tcx, 'a>(
     while let Some((def_id, defs)) = stack.pop() {
         let mut params = defs.params.iter().peekable();
 
-        // If we have already computed substitutions for parents, we can use those directly.
+        // If we have already computed the generic arguments for parents,
+        // we can use those directly.
         while let Some(&param) = params.peek() {
             if let Some(&kind) = parent_args.get(param.index as usize) {
                 args.push(kind);
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 3a97a383ee1..56b1fd36973 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -289,7 +289,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     }
 
     /// Given a path `path` that refers to an item `I` with the declared generics `decl_generics`,
-    /// returns an appropriate set of substitutions for this particular reference to `I`.
+    /// returns an appropriate set of generic arguments for this particular reference to `I`.
     pub fn ast_path_args_for_ty(
         &self,
         span: Span,
@@ -315,7 +315,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
     /// Given the type/lifetime/const arguments provided to some path (along with
     /// an implicit `Self`, if this is a trait reference), returns the complete
-    /// set of substitutions. This may involve applying defaulted type parameters.
+    /// set of generic arguments. This may involve applying defaulted type parameters.
     /// Constraints on associated types are created from `create_assoc_bindings_for_generic_args`.
     ///
     /// Example:
@@ -909,23 +909,16 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         let tcx = self.tcx();
         let args = self.ast_path_args_for_ty(span, did, item_segment);
 
-        if let DefKind::TyAlias { lazy: true } = tcx.def_kind(did) {
+        if let DefKind::TyAlias = tcx.def_kind(did)
+            && tcx.type_alias_is_lazy(did)
+        {
             // Type aliases defined in crates that have the
             // feature `lazy_type_alias` enabled get encoded as a type alias that normalization will
             // then actually instantiate the where bounds of.
             let alias_ty = tcx.mk_alias_ty(did, args);
             Ty::new_alias(tcx, ty::Weak, alias_ty)
         } else {
-            let ty = tcx.at(span).type_of(did);
-            if ty.skip_binder().has_opaque_types() {
-                // Type aliases referring to types that contain opaque types (but aren't just directly
-                // referencing a single opaque type) get encoded as a type alias that normalization will
-                // then actually instantiate the where bounds of.
-                let alias_ty = tcx.mk_alias_ty(did, args);
-                Ty::new_alias(tcx, ty::Weak, alias_ty)
-            } else {
-                ty.instantiate(tcx, args)
-            }
+            tcx.at(span).type_of(did).instantiate(tcx, args)
         }
     }
 
@@ -2164,7 +2157,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
             }
             Res::Def(
                 DefKind::Enum
-                | DefKind::TyAlias { .. }
+                | DefKind::TyAlias
                 | DefKind::Struct
                 | DefKind::Union
                 | DefKind::ForeignTy,
@@ -2781,7 +2774,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
     ) {
         for br in referenced_regions.difference(&constrained_regions) {
             let br_name = match *br {
-                ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) | ty::BrEnv => {
+                ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon | ty::BrEnv => {
                     "an anonymous lifetime".to_string()
                 }
                 ty::BrNamed(_, name) => format!("lifetime `{name}`"),
@@ -2789,7 +2782,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
 
             let mut err = generate_err(&br_name);
 
-            if let ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) = *br {
+            if let ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon = *br {
                 // The only way for an anonymous lifetime to wind up
                 // in the return type but **also** be unconstrained is
                 // if it only appears in "associated types" in the
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 13826264a22..44e1bdb8370 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -5,20 +5,17 @@ use super::compare_impl_item::check_type_bounds;
 use super::compare_impl_item::{compare_impl_method, compare_impl_ty};
 use super::*;
 use rustc_attr as attr;
-use rustc_errors::{Applicability, ErrorGuaranteed, MultiSpan};
+use rustc_errors::{ErrorGuaranteed, MultiSpan};
 use rustc_hir as hir;
-use rustc_hir::def::{CtorKind, DefKind, Res};
+use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId};
-use rustc_hir::intravisit::Visitor;
-use rustc_hir::{ItemKind, Node, PathSegment};
-use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor;
+use rustc_hir::Node;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{RegionVariableOrigin, TyCtxtInferExt};
 use rustc_infer::traits::{Obligation, TraitEngineExt as _};
 use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
-use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::stability::EvalResult;
-use rustc_middle::traits::DefiningAnchor;
+use rustc_middle::traits::{DefiningAnchor, ObligationCauseCode};
 use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
 use rustc_middle::ty::util::{Discr, IntTypeExt};
@@ -218,9 +215,6 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
     let args = GenericArgs::identity_for_item(tcx, item.owner_id);
     let span = tcx.def_span(item.owner_id.def_id);
 
-    if !tcx.features().impl_trait_projections {
-        check_opaque_for_inheriting_lifetimes(tcx, item.owner_id.def_id, span);
-    }
     if tcx.type_of(item.owner_id.def_id).instantiate_identity().references_error() {
         return;
     }
@@ -231,129 +225,6 @@ fn check_opaque(tcx: TyCtxt<'_>, id: hir::ItemId) {
     let _ = check_opaque_meets_bounds(tcx, item.owner_id.def_id, span, &origin);
 }
 
-/// Checks that an opaque type does not use `Self` or `T::Foo` projections that would result
-/// in "inheriting lifetimes".
-#[instrument(level = "debug", skip(tcx, span))]
-pub(super) fn check_opaque_for_inheriting_lifetimes(
-    tcx: TyCtxt<'_>,
-    def_id: LocalDefId,
-    span: Span,
-) {
-    let item = tcx.hir().expect_item(def_id);
-    debug!(?item, ?span);
-
-    struct ProhibitOpaqueVisitor<'tcx> {
-        tcx: TyCtxt<'tcx>,
-        opaque_identity_ty: Ty<'tcx>,
-        parent_count: u32,
-        references_parent_regions: bool,
-        selftys: Vec<(Span, Option<String>)>,
-    }
-
-    impl<'tcx> ty::visit::TypeVisitor<TyCtxt<'tcx>> for ProhibitOpaqueVisitor<'tcx> {
-        type BreakTy = Ty<'tcx>;
-
-        fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
-            debug!(?t, "root_visit_ty");
-            if t == self.opaque_identity_ty {
-                ControlFlow::Continue(())
-            } else {
-                t.visit_with(&mut ConstrainOpaqueTypeRegionVisitor {
-                    tcx: self.tcx,
-                    op: |region| {
-                        if let ty::ReEarlyBound(ty::EarlyBoundRegion { index, .. }) = *region
-                            && index < self.parent_count
-                        {
-                            self.references_parent_regions= true;
-                        }
-                    },
-                });
-                if self.references_parent_regions {
-                    ControlFlow::Break(t)
-                } else {
-                    ControlFlow::Continue(())
-                }
-            }
-        }
-    }
-
-    impl<'tcx> Visitor<'tcx> for ProhibitOpaqueVisitor<'tcx> {
-        type NestedFilter = nested_filter::OnlyBodies;
-
-        fn nested_visit_map(&mut self) -> Self::Map {
-            self.tcx.hir()
-        }
-
-        fn visit_ty(&mut self, arg: &'tcx hir::Ty<'tcx>) {
-            match arg.kind {
-                hir::TyKind::Path(hir::QPath::Resolved(None, path)) => match &path.segments {
-                    [PathSegment { res: Res::SelfTyParam { .. }, .. }] => {
-                        let impl_ty_name = None;
-                        self.selftys.push((path.span, impl_ty_name));
-                    }
-                    [PathSegment { res: Res::SelfTyAlias { alias_to: def_id, .. }, .. }] => {
-                        let impl_ty_name = Some(self.tcx.def_path_str(*def_id));
-                        self.selftys.push((path.span, impl_ty_name));
-                    }
-                    _ => {}
-                },
-                _ => {}
-            }
-            hir::intravisit::walk_ty(self, arg);
-        }
-    }
-
-    if let ItemKind::OpaqueTy(&hir::OpaqueTy {
-        origin: hir::OpaqueTyOrigin::AsyncFn(..) | hir::OpaqueTyOrigin::FnReturn(..),
-        ..
-    }) = item.kind
-    {
-        let args = GenericArgs::identity_for_item(tcx, def_id);
-        let opaque_identity_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
-        let mut visitor = ProhibitOpaqueVisitor {
-            opaque_identity_ty,
-            parent_count: tcx.generics_of(def_id).parent_count as u32,
-            references_parent_regions: false,
-            tcx,
-            selftys: vec![],
-        };
-        let prohibit_opaque = tcx
-            .explicit_item_bounds(def_id)
-            .instantiate_identity_iter_copied()
-            .try_for_each(|(predicate, _)| predicate.visit_with(&mut visitor));
-
-        if let Some(ty) = prohibit_opaque.break_value() {
-            visitor.visit_item(&item);
-            let is_async = match item.kind {
-                ItemKind::OpaqueTy(hir::OpaqueTy { origin, .. }) => {
-                    matches!(origin, hir::OpaqueTyOrigin::AsyncFn(..))
-                }
-                _ => unreachable!(),
-            };
-
-            let mut err = feature_err(
-                &tcx.sess.parse_sess,
-                sym::impl_trait_projections,
-                span,
-                format!(
-                    "`{}` return type cannot contain a projection or `Self` that references \
-                    lifetimes from a parent scope",
-                    if is_async { "async fn" } else { "impl Trait" },
-                ),
-            );
-            for (span, name) in visitor.selftys {
-                err.span_suggestion(
-                    span,
-                    "consider spelling out the type instead",
-                    name.unwrap_or_else(|| format!("{ty:?}")),
-                    Applicability::MaybeIncorrect,
-                );
-            }
-            err.emit();
-        }
-    }
-}
-
 /// Checks that an opaque type does not contain cycles.
 pub(super) fn check_opaque_for_cycles<'tcx>(
     tcx: TyCtxt<'tcx>,
@@ -640,7 +511,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
                 check_opaque(tcx, id);
             }
         }
-        DefKind::TyAlias { .. } => {
+        DefKind::TyAlias => {
             let pty_ty = tcx.type_of(id.owner_id).instantiate_identity();
             let generics = tcx.generics_of(id.owner_id);
             check_type_params_are_used(tcx, &generics, pty_ty);
@@ -1579,13 +1450,7 @@ fn opaque_type_cycle_error(
                         label_match(capture.place.ty(), capture.get_path_span(tcx));
                     }
                     // Label any generator locals that capture the opaque
-                    for interior_ty in
-                        typeck_results.generator_interior_types.as_ref().skip_binder()
-                    {
-                        label_match(interior_ty.ty, interior_ty.span);
-                    }
-                    if tcx.sess.opts.unstable_opts.drop_tracking_mir
-                        && let DefKind::Generator = tcx.def_kind(closure_def_id)
+                    if let DefKind::Generator = tcx.def_kind(closure_def_id)
                         && let Some(generator_layout) = tcx.mir_generator_witnesses(closure_def_id)
                     {
                         for interior_ty in &generator_layout.field_tys {
@@ -1603,7 +1468,6 @@ fn opaque_type_cycle_error(
 }
 
 pub(super) fn check_generator_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
-    debug_assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir);
     debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Generator));
 
     let typeck = tcx.typeck(def_id);
@@ -1626,6 +1490,25 @@ pub(super) fn check_generator_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
         let obligation = Obligation::new(tcx, cause.clone(), param_env, *predicate);
         fulfillment_cx.register_predicate_obligation(&infcx, obligation);
     }
+
+    if (tcx.features().unsized_locals || tcx.features().unsized_fn_params)
+        && let Some(generator) = tcx.mir_generator_witnesses(def_id)
+    {
+        for field_ty in generator.field_tys.iter() {
+            fulfillment_cx.register_bound(
+                &infcx,
+                param_env,
+                field_ty.ty,
+                tcx.require_lang_item(hir::LangItem::Sized, Some(field_ty.source_info.span)),
+                ObligationCause::new(
+                    field_ty.source_info.span,
+                    def_id,
+                    ObligationCauseCode::SizedGeneratorInterior(def_id),
+                ),
+            );
+        }
+    }
+
     let errors = fulfillment_cx.select_all_or_error(&infcx);
     debug!(?errors);
     if !errors.is_empty() {
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 7be18a36d63..d081b0e35c6 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -14,6 +14,7 @@ use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKi
 use rustc_infer::infer::{self, InferCtxt, TyCtxtInferExt};
 use rustc_infer::traits::util;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
+use rustc_middle::ty::fold::BottomUpFolder;
 use rustc_middle::ty::util::ExplicitSelf;
 use rustc_middle::ty::{
     self, GenericArgs, Ty, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitableExt,
@@ -661,8 +662,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
     let impl_trait_ref =
         tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap().instantiate_identity();
-    let param_env = tcx.param_env(impl_m_def_id);
-
     // First, check a few of the same things as `compare_impl_method`,
     // just so we don't ICE during substitution later.
     check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?;
@@ -688,13 +687,26 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     let trait_to_placeholder_args =
         impl_to_placeholder_args.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_args);
 
+    let hybrid_preds = tcx
+        .predicates_of(impl_m.container_id(tcx))
+        .instantiate_identity(tcx)
+        .into_iter()
+        .chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_placeholder_args))
+        .map(|(clause, _)| clause);
+    let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing);
+    let param_env = traits::normalize_param_env_or_error(
+        tcx,
+        param_env,
+        ObligationCause::misc(tcx.def_span(impl_m_def_id), impl_m_def_id),
+    );
+
     let infcx = &tcx.infer_ctxt().build();
     let ocx = ObligationCtxt::new(infcx);
 
     // Normalize the impl signature with fresh variables for lifetime inference.
-    let norm_cause = ObligationCause::misc(return_span, impl_m_def_id);
+    let misc_cause = ObligationCause::misc(return_span, impl_m_def_id);
     let impl_sig = ocx.normalize(
-        &norm_cause,
+        &misc_cause,
         param_env,
         tcx.liberate_late_bound_regions(
             impl_m.def_id,
@@ -725,12 +737,68 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
         );
     }
 
-    let trait_sig = ocx.normalize(&norm_cause, param_env, unnormalized_trait_sig);
+    let trait_sig = ocx.normalize(&misc_cause, param_env, unnormalized_trait_sig);
     trait_sig.error_reported()?;
     let trait_return_ty = trait_sig.output();
 
+    // RPITITs are allowed to use the implied predicates of the method that
+    // defines them. This is because we want code like:
+    // ```
+    // trait Foo {
+    //     fn test<'a, T>(_: &'a T) -> impl Sized;
+    // }
+    // impl Foo for () {
+    //     fn test<'a, T>(x: &'a T) -> &'a T { x }
+    // }
+    // ```
+    // .. to compile. However, since we use both the normalized and unnormalized
+    // inputs and outputs from the substituted trait signature, we will end up
+    // seeing the hidden type of an RPIT in the signature itself. Naively, this
+    // means that we will use the hidden type to imply the hidden type's own
+    // well-formedness.
+    //
+    // To avoid this, we replace the infer vars used for hidden type inference
+    // with placeholders, which imply nothing about outlives bounds, and then
+    // prove below that the hidden types are well formed.
+    let universe = infcx.create_next_universe();
+    let mut idx = 0;
+    let mapping: FxHashMap<_, _> = collector
+        .types
+        .iter()
+        .map(|(_, &(ty, _))| {
+            assert!(
+                infcx.resolve_vars_if_possible(ty) == ty && ty.is_ty_var(),
+                "{ty:?} should not have been constrained via normalization",
+                ty = infcx.resolve_vars_if_possible(ty)
+            );
+            idx += 1;
+            (
+                ty,
+                Ty::new_placeholder(
+                    tcx,
+                    ty::Placeholder {
+                        universe,
+                        bound: ty::BoundTy {
+                            var: ty::BoundVar::from_usize(idx),
+                            kind: ty::BoundTyKind::Anon,
+                        },
+                    },
+                ),
+            )
+        })
+        .collect();
+    let mut type_mapper = BottomUpFolder {
+        tcx,
+        ty_op: |ty| *mapping.get(&ty).unwrap_or(&ty),
+        lt_op: |lt| lt,
+        ct_op: |ct| ct,
+    };
     let wf_tys = FxIndexSet::from_iter(
-        unnormalized_trait_sig.inputs_and_output.iter().chain(trait_sig.inputs_and_output.iter()),
+        unnormalized_trait_sig
+            .inputs_and_output
+            .iter()
+            .chain(trait_sig.inputs_and_output.iter())
+            .map(|ty| ty.fold_with(&mut type_mapper)),
     );
 
     match ocx.eq(&cause, param_env, trait_return_ty, impl_return_ty) {
@@ -787,6 +855,20 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
         }
     }
 
+    // FIXME: This has the same issue as #108544, but since this isn't breaking
+    // existing code, I'm not particularly inclined to do the same hack as above
+    // where we process wf obligations manually. This can be fixed in a forward-
+    // compatible way later.
+    let collected_types = collector.types;
+    for (_, &(ty, _)) in &collected_types {
+        ocx.register_obligation(traits::Obligation::new(
+            tcx,
+            misc_cause.clone(),
+            param_env,
+            ty::ClauseKind::WellFormed(ty.into()),
+        ));
+    }
+
     // Check that all obligations are satisfied by the implementation's
     // RPITs.
     let errors = ocx.select_all_or_error();
@@ -795,8 +877,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
         return Err(reported);
     }
 
-    let collected_types = collector.types;
-
     // Finally, resolve all regions. This catches wily misuses of
     // lifetime parameters.
     let outlives_env = OutlivesEnvironment::with_bounds(
@@ -1134,7 +1214,10 @@ fn report_trait_method_mismatch<'tcx>(
         &mut diag,
         &cause,
         trait_err_span.map(|sp| (sp, Cow::from("type in trait"))),
-        Some(infer::ValuePairs::Sigs(ExpectedFound { expected: trait_sig, found: impl_sig })),
+        Some(infer::ValuePairs::PolySigs(ExpectedFound {
+            expected: ty::Binder::dummy(trait_sig),
+            found: ty::Binder::dummy(impl_sig),
+        })),
         terr,
         false,
         false,
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
index a8149b634ef..d9e0e87eb47 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item/refine.rs
@@ -5,7 +5,7 @@ use rustc_infer::infer::{outlives::env::OutlivesEnvironment, TyCtxtInferExt};
 use rustc_lint_defs::builtin::REFINING_IMPL_TRAIT;
 use rustc_middle::traits::{ObligationCause, Reveal};
 use rustc_middle::ty::{
-    self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitor,
+    self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperVisitable, TypeVisitable, TypeVisitor,
 };
 use rustc_span::{Span, DUMMY_SP};
 use rustc_trait_selection::traits::{
@@ -176,9 +176,13 @@ pub(super) fn check_refining_return_position_impl_trait_in_trait<'tcx>(
         return;
     };
 
-    // For quicker lookup, use an `IndexSet`
-    // (we don't use one earlier because it's not foldable..)
-    let trait_bounds = FxIndexSet::from_iter(trait_bounds);
+    // For quicker lookup, use an `IndexSet` (we don't use one earlier because
+    // it's not foldable..).
+    // Also, We have to anonymize binders in these types because they may contain
+    // `BrNamed` bound vars, which contain unique `DefId`s which correspond to syntax
+    // locations that we don't care about when checking bound equality.
+    let trait_bounds = FxIndexSet::from_iter(trait_bounds.fold_with(&mut Anonymize { tcx }));
+    let impl_bounds = impl_bounds.fold_with(&mut Anonymize { tcx });
 
     // Find any clauses that are present in the impl's RPITITs that are not
     // present in the trait's RPITITs. This will trigger on trivial predicates,
@@ -309,3 +313,20 @@ fn type_visibility<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Option<ty::Visibili
         _ => None,
     }
 }
+
+struct Anonymize<'tcx> {
+    tcx: TyCtxt<'tcx>,
+}
+
+impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Anonymize<'tcx> {
+    fn interner(&self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn fold_binder<T>(&mut self, t: ty::Binder<'tcx, T>) -> ty::Binder<'tcx, T>
+    where
+        T: TypeFoldable<TyCtxt<'tcx>>,
+    {
+        self.tcx.anonymize_bound_vars(t)
+    }
+}
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 444103ffe8f..c61719c1fd2 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -20,6 +20,7 @@ fn equate_intrinsic_type<'tcx>(
     it: &hir::ForeignItem<'_>,
     n_tps: usize,
     n_lts: usize,
+    n_cts: usize,
     sig: ty::PolyFnSig<'tcx>,
 ) {
     let (own_counts, span) = match &it.kind {
@@ -51,7 +52,7 @@ fn equate_intrinsic_type<'tcx>(
 
     if gen_count_ok(own_counts.lifetimes, n_lts, "lifetime")
         && gen_count_ok(own_counts.types, n_tps, "type")
-        && gen_count_ok(own_counts.consts, 0, "const")
+        && gen_count_ok(own_counts.consts, n_cts, "const")
     {
         let it_def_id = it.owner_id.def_id;
         check_function_signature(
@@ -137,7 +138,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
     let name_str = intrinsic_name.as_str();
 
     let bound_vars = tcx.mk_bound_variable_kinds(&[
-        ty::BoundVariableKind::Region(ty::BrAnon(None)),
+        ty::BoundVariableKind::Region(ty::BrAnon),
         ty::BoundVariableKind::Region(ty::BrEnv),
     ]);
     let mk_va_list_ty = |mutbl| {
@@ -145,7 +146,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             let region = ty::Region::new_late_bound(
                 tcx,
                 ty::INNERMOST,
-                ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) },
+                ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon },
             );
             let env_region = ty::Region::new_late_bound(
                 tcx,
@@ -405,7 +406,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
                 );
                 let discriminant_def_id = assoc_items[0];
 
-                let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) };
+                let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon };
                 (
                     1,
                     vec![Ty::new_imm_ref(
@@ -463,7 +464,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             }
 
             sym::raw_eq => {
-                let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) };
+                let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon };
                 let param_ty = Ty::new_imm_ref(
                     tcx,
                     ty::Region::new_late_bound(tcx, ty::INNERMOST, br),
@@ -489,7 +490,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
     };
     let sig = tcx.mk_fn_sig(inputs, output, false, unsafety, Abi::RustIntrinsic);
     let sig = ty::Binder::bind_with_vars(sig, bound_vars);
-    equate_intrinsic_type(tcx, it, n_tps, n_lts, sig)
+    equate_intrinsic_type(tcx, it, n_tps, n_lts, 0, sig)
 }
 
 /// Type-check `extern "platform-intrinsic" { ... }` functions.
@@ -501,9 +502,9 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
 
     let name = it.ident.name;
 
-    let (n_tps, inputs, output) = match name {
+    let (n_tps, n_cts, inputs, output) = match name {
         sym::simd_eq | sym::simd_ne | sym::simd_lt | sym::simd_le | sym::simd_gt | sym::simd_ge => {
-            (2, vec![param(0), param(0)], param(1))
+            (2, 0, vec![param(0), param(0)], param(1))
         }
         sym::simd_add
         | sym::simd_sub
@@ -519,8 +520,8 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
         | sym::simd_fmax
         | sym::simd_fpow
         | sym::simd_saturating_add
-        | sym::simd_saturating_sub => (1, vec![param(0), param(0)], param(0)),
-        sym::simd_arith_offset => (2, vec![param(0), param(1)], param(0)),
+        | sym::simd_saturating_sub => (1, 0, vec![param(0), param(0)], param(0)),
+        sym::simd_arith_offset => (2, 0, vec![param(0), param(1)], param(0)),
         sym::simd_neg
         | sym::simd_bswap
         | sym::simd_bitreverse
@@ -538,25 +539,25 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
         | sym::simd_ceil
         | sym::simd_floor
         | sym::simd_round
-        | sym::simd_trunc => (1, vec![param(0)], param(0)),
-        sym::simd_fpowi => (1, vec![param(0), tcx.types.i32], param(0)),
-        sym::simd_fma => (1, vec![param(0), param(0), param(0)], param(0)),
-        sym::simd_gather => (3, vec![param(0), param(1), param(2)], param(0)),
-        sym::simd_scatter => (3, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)),
-        sym::simd_insert => (2, vec![param(0), tcx.types.u32, param(1)], param(0)),
-        sym::simd_extract => (2, vec![param(0), tcx.types.u32], param(1)),
+        | sym::simd_trunc => (1, 0, vec![param(0)], param(0)),
+        sym::simd_fpowi => (1, 0, vec![param(0), tcx.types.i32], param(0)),
+        sym::simd_fma => (1, 0, vec![param(0), param(0), param(0)], param(0)),
+        sym::simd_gather => (3, 0, vec![param(0), param(1), param(2)], param(0)),
+        sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)),
+        sym::simd_insert => (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0)),
+        sym::simd_extract => (2, 0, vec![param(0), tcx.types.u32], param(1)),
         sym::simd_cast
         | sym::simd_as
         | sym::simd_cast_ptr
         | sym::simd_expose_addr
-        | sym::simd_from_exposed_addr => (2, vec![param(0)], param(1)),
-        sym::simd_bitmask => (2, vec![param(0)], param(1)),
+        | sym::simd_from_exposed_addr => (2, 0, vec![param(0)], param(1)),
+        sym::simd_bitmask => (2, 0, vec![param(0)], param(1)),
         sym::simd_select | sym::simd_select_bitmask => {
-            (2, vec![param(0), param(1), param(1)], param(1))
+            (2, 0, vec![param(0), param(1), param(1)], param(1))
         }
-        sym::simd_reduce_all | sym::simd_reduce_any => (1, vec![param(0)], tcx.types.bool),
+        sym::simd_reduce_all | sym::simd_reduce_any => (1, 0, vec![param(0)], tcx.types.bool),
         sym::simd_reduce_add_ordered | sym::simd_reduce_mul_ordered => {
-            (2, vec![param(0), param(1)], param(1))
+            (2, 0, vec![param(0), param(1)], param(1))
         }
         sym::simd_reduce_add_unordered
         | sym::simd_reduce_mul_unordered
@@ -566,8 +567,9 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
         | sym::simd_reduce_min
         | sym::simd_reduce_max
         | sym::simd_reduce_min_nanless
-        | sym::simd_reduce_max_nanless => (2, vec![param(0)], param(1)),
-        sym::simd_shuffle => (3, vec![param(0), param(0), param(1)], param(2)),
+        | sym::simd_reduce_max_nanless => (2, 0, vec![param(0)], param(1)),
+        sym::simd_shuffle => (3, 0, vec![param(0), param(0), param(1)], param(2)),
+        sym::simd_shuffle_generic => (2, 1, vec![param(0), param(0)], param(1)),
         _ => {
             let msg = format!("unrecognized platform-specific intrinsic function: `{name}`");
             tcx.sess.struct_span_err(it.span, msg).emit();
@@ -577,5 +579,5 @@ pub fn check_platform_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>)
 
     let sig = tcx.mk_fn_sig(inputs, output, false, hir::Unsafety::Unsafe, Abi::PlatformIntrinsic);
     let sig = ty::Binder::dummy(sig);
-    equate_intrinsic_type(tcx, it, n_tps, 0, sig)
+    equate_intrinsic_type(tcx, it, n_tps, 0, n_cts, sig)
 }
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 0cf3cee66b5..5fa65f33c76 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -329,41 +329,52 @@ fn bounds_from_generic_predicates<'tcx>(
             _ => {}
         }
     }
-    let generics = if types.is_empty() {
-        "".to_string()
-    } else {
-        format!(
-            "<{}>",
-            types
-                .keys()
-                .filter_map(|t| match t.kind() {
-                    ty::Param(_) => Some(t.to_string()),
-                    // Avoid suggesting the following:
-                    // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
-                    _ => None,
-                })
-                .collect::<Vec<_>>()
-                .join(", ")
-        )
-    };
+
     let mut where_clauses = vec![];
+    let mut types_str = vec![];
     for (ty, bounds) in types {
-        where_clauses
-            .extend(bounds.into_iter().map(|bound| format!("{}: {}", ty, tcx.def_path_str(bound))));
-    }
-    for projection in &projections {
-        let p = projection.skip_binder();
-        // FIXME: this is not currently supported syntax, we should be looking at the `types` and
-        // insert the associated types where they correspond, but for now let's be "lazy" and
-        // propose this instead of the following valid resugaring:
-        // `T: Trait, Trait::Assoc = K` → `T: Trait<Assoc = K>`
-        where_clauses.push(format!("{} = {}", tcx.def_path_str(p.projection_ty.def_id), p.term));
+        if let ty::Param(_) = ty.kind() {
+            let mut bounds_str = vec![];
+            for bound in bounds {
+                let mut projections_str = vec![];
+                for projection in &projections {
+                    let p = projection.skip_binder();
+                    let alias_ty = p.projection_ty;
+                    if bound == tcx.parent(alias_ty.def_id) && alias_ty.self_ty() == ty {
+                        let name = tcx.item_name(alias_ty.def_id);
+                        projections_str.push(format!("{} = {}", name, p.term));
+                    }
+                }
+                let bound_def_path = tcx.def_path_str(bound);
+                if projections_str.is_empty() {
+                    where_clauses.push(format!("{}: {}", ty, bound_def_path));
+                } else {
+                    bounds_str.push(format!("{}<{}>", bound_def_path, projections_str.join(", ")));
+                }
+            }
+            if bounds_str.is_empty() {
+                types_str.push(ty.to_string());
+            } else {
+                types_str.push(format!("{}: {}", ty, bounds_str.join(" + ")));
+            }
+        } else {
+            // Avoid suggesting the following:
+            // fn foo<T, <T as Trait>::Bar>(_: T) where T: Trait, <T as Trait>::Bar: Other {}
+            where_clauses.extend(
+                bounds.into_iter().map(|bound| format!("{}: {}", ty, tcx.def_path_str(bound))),
+            );
+        }
     }
+
+    let generics =
+        if types_str.is_empty() { "".to_string() } else { format!("<{}>", types_str.join(", ")) };
+
     let where_clauses = if where_clauses.is_empty() {
-        String::new()
+        "".to_string()
     } else {
         format!(" where {}", where_clauses.join(", "))
     };
+
     (generics, where_clauses)
 }
 
@@ -573,10 +584,7 @@ pub fn check_function_signature<'tcx>(
     let norm_cause = ObligationCause::misc(cause.span, local_id);
     let actual_sig = ocx.normalize(&norm_cause, param_env, actual_sig);
 
-    let expected_ty = Ty::new_fn_ptr(tcx, expected_sig);
-    let actual_ty = Ty::new_fn_ptr(tcx, actual_sig);
-
-    match ocx.eq(&cause, param_env, expected_ty, actual_ty) {
+    match ocx.eq(&cause, param_env, expected_sig, actual_sig) {
         Ok(()) => {
             let errors = ocx.select_all_or_error();
             if !errors.is_empty() {
@@ -595,9 +603,9 @@ pub fn check_function_signature<'tcx>(
                 &mut diag,
                 &cause,
                 None,
-                Some(infer::ValuePairs::Sigs(ExpectedFound {
-                    expected: tcx.liberate_late_bound_regions(fn_id, expected_sig),
-                    found: tcx.liberate_late_bound_regions(fn_id, actual_sig),
+                Some(infer::ValuePairs::PolySigs(ExpectedFound {
+                    expected: expected_sig,
+                    found: actual_sig,
                 })),
                 err,
                 false,
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index b97e0a80fe6..c4fdffb0261 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -24,6 +24,9 @@ use rustc_span::symbol::{sym, Ident, Symbol};
 use rustc_span::{Span, DUMMY_SP};
 use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt;
+use rustc_trait_selection::traits::misc::{
+    type_allowed_to_implement_const_param_ty, ConstParamTyImplementationError,
+};
 use rustc_trait_selection::traits::outlives_bounds::InferCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
 use rustc_trait_selection::traits::{
@@ -246,9 +249,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
         // `ForeignItem`s are handled separately.
         hir::ItemKind::ForeignMod { .. } => {}
         hir::ItemKind::TyAlias(hir_ty, ast_generics) => {
-            if tcx.features().lazy_type_alias
-                || tcx.type_of(item.owner_id).skip_binder().has_opaque_types()
-            {
+            if tcx.type_alias_is_lazy(item.owner_id) {
                 // Bounds of lazy type aliases and of eager ones that contain opaque types are respected.
                 // E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`.
                 check_item_type(tcx, def_id, hir_ty.span, UnsizedHandling::Allow);
@@ -867,43 +868,65 @@ fn check_param_wf(tcx: TyCtxt<'_>, param: &hir::GenericParam<'_>) {
                     );
                 });
             } else {
-                let err_ty_str;
-                let mut is_ptr = true;
-
-                let err = match ty.kind() {
+                let diag = match ty.kind() {
                     ty::Bool | ty::Char | ty::Int(_) | ty::Uint(_) | ty::Error(_) => None,
-                    ty::FnPtr(_) => Some("function pointers"),
-                    ty::RawPtr(_) => Some("raw pointers"),
-                    _ => {
-                        is_ptr = false;
-                        err_ty_str = format!("`{ty}`");
-                        Some(err_ty_str.as_str())
-                    }
+                    ty::FnPtr(_) => Some(tcx.sess.struct_span_err(
+                        hir_ty.span,
+                        "using function pointers as const generic parameters is forbidden",
+                    )),
+                    ty::RawPtr(_) => Some(tcx.sess.struct_span_err(
+                        hir_ty.span,
+                        "using raw pointers as const generic parameters is forbidden",
+                    )),
+                    _ => Some(tcx.sess.struct_span_err(
+                        hir_ty.span,
+                        format!("`{}` is forbidden as the type of a const generic parameter", ty),
+                    )),
                 };
 
-                if let Some(unsupported_type) = err {
-                    if is_ptr {
-                        tcx.sess.span_err(
-                            hir_ty.span,
-                            format!(
-                                "using {unsupported_type} as const generic parameters is forbidden",
-                            ),
-                        );
-                    } else {
-                        let mut err = tcx.sess.struct_span_err(
-                            hir_ty.span,
-                            format!(
-                                "{unsupported_type} is forbidden as the type of a const generic parameter",
-                            ),
-                        );
-                        err.note("the only supported types are integers, `bool` and `char`");
-                        if tcx.sess.is_nightly_build() {
-                            err.help(
-                            "more complex types are supported with `#![feature(adt_const_params)]`",
-                        );
+                if let Some(mut diag) = diag {
+                    diag.note("the only supported types are integers, `bool` and `char`");
+
+                    let cause = ObligationCause::misc(hir_ty.span, param.def_id);
+                    let may_suggest_feature = match type_allowed_to_implement_const_param_ty(
+                        tcx,
+                        tcx.param_env(param.def_id),
+                        ty,
+                        cause,
+                    ) {
+                        // Can never implement `ConstParamTy`, don't suggest anything.
+                        Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => false,
+                        // May be able to implement `ConstParamTy`. Only emit the feature help
+                        // if the type is local, since the user may be able to fix the local type.
+                        Err(ConstParamTyImplementationError::InfrigingFields(..)) => {
+                            fn ty_is_local(ty: Ty<'_>) -> bool {
+                                match ty.kind() {
+                                    ty::Adt(adt_def, ..) => adt_def.did().is_local(),
+                                    // Arrays and slices use the inner type's `ConstParamTy`.
+                                    ty::Array(ty, ..) => ty_is_local(*ty),
+                                    ty::Slice(ty) => ty_is_local(*ty),
+                                    // `&` references use the inner type's `ConstParamTy`.
+                                    // `&mut` are not supported.
+                                    ty::Ref(_, ty, ast::Mutability::Not) => ty_is_local(*ty),
+                                    // Say that a tuple is local if any of its components are local.
+                                    // This is not strictly correct, but it's likely that the user can fix the local component.
+                                    ty::Tuple(tys) => tys.iter().any(|ty| ty_is_local(ty)),
+                                    _ => false,
+                                }
+                            }
+
+                            ty_is_local(ty)
                         }
-                        err.emit();
+                        // Implments `ConstParamTy`, suggest adding the feature to enable.
+                        Ok(..) => true,
+                    };
+                    if may_suggest_feature && tcx.sess.is_nightly_build() {
+                        diag.help(
+                            "add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types",
+                        );
                     }
+
+                    diag.emit();
                 }
             }
         }
@@ -1711,10 +1734,8 @@ fn check_variances_for_type_defn<'tcx>(
             }
         }
         ItemKind::TyAlias(..) => {
-            let ty = tcx.type_of(item.owner_id).instantiate_identity();
-
-            if tcx.features().lazy_type_alias || ty.has_opaque_types() {
-                if ty.references_error() {
+            if tcx.type_alias_is_lazy(item.owner_id) {
+                if tcx.type_of(item.owner_id).skip_binder().references_error() {
                     return;
                 }
             } else {
@@ -1755,6 +1776,8 @@ fn check_variances_for_type_defn<'tcx>(
             .collect::<FxHashSet<_>>()
     });
 
+    let ty_generics = tcx.generics_of(item.owner_id);
+
     for (index, _) in variances.iter().enumerate() {
         let parameter = Parameter(index as u32);
 
@@ -1762,13 +1785,27 @@ fn check_variances_for_type_defn<'tcx>(
             continue;
         }
 
-        let param = &hir_generics.params[index];
+        let ty_param = &ty_generics.params[index];
+        let hir_param = &hir_generics.params[index];
+
+        if ty_param.def_id != hir_param.def_id.into() {
+            // valid programs always have lifetimes before types in the generic parameter list
+            // ty_generics are normalized to be in this required order, and variances are built
+            // from ty generics, not from hir generics. but we need hir generics to get
+            // a span out
+            //
+            // if they aren't in the same order, then the user has written invalid code, and already
+            // got an error about it (or I'm wrong about this)
+            tcx.sess
+                .delay_span_bug(hir_param.span, "hir generics and ty generics in different order");
+            continue;
+        }
 
-        match param.name {
+        match hir_param.name {
             hir::ParamName::Error => {}
             _ => {
                 let has_explicit_bounds = explicitly_bounded_params.contains(&parameter);
-                report_bivariance(tcx, param, has_explicit_bounds);
+                report_bivariance(tcx, hir_param, has_explicit_bounds);
             }
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 94f3e8706fc..be70acfc35d 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -1,11 +1,10 @@
 //! Check properties that are required by built-in traits and set
 //! up data structures required by type-checking/codegen.
 
-use crate::errors::{
-    ConstParamTyImplOnNonAdt, CopyImplOnNonAdt, CopyImplOnTypeWithDtor, DropImplOnWrongItem,
-};
+use crate::errors;
+
 use rustc_data_structures::fx::FxHashSet;
-use rustc_errors::{struct_span_err, ErrorGuaranteed, MultiSpan};
+use rustc_errors::{ErrorGuaranteed, MultiSpan};
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::lang_items::LangItem;
@@ -65,7 +64,7 @@ fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
 
     let impl_ = tcx.hir().expect_item(impl_did).expect_impl();
 
-    tcx.sess.emit_err(DropImplOnWrongItem { span: impl_.self_ty.span });
+    tcx.sess.emit_err(errors::DropImplOnWrongItem { span: impl_.self_ty.span });
 }
 
 fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
@@ -91,10 +90,10 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
             infringing_fields_error(tcx, fields, LangItem::Copy, impl_did, span);
         }
         Err(CopyImplementationError::NotAnAdt) => {
-            tcx.sess.emit_err(CopyImplOnNonAdt { span });
+            tcx.sess.emit_err(errors::CopyImplOnNonAdt { span });
         }
         Err(CopyImplementationError::HasDestructor) => {
-            tcx.sess.emit_err(CopyImplOnTypeWithDtor { span });
+            tcx.sess.emit_err(errors::CopyImplOnTypeWithDtor { span });
         }
     }
 }
@@ -117,7 +116,7 @@ fn visit_implementation_of_const_param_ty(tcx: TyCtxt<'_>, impl_did: LocalDefId)
             infringing_fields_error(tcx, fields, LangItem::ConstParamTy, impl_did, span);
         }
         Err(ConstParamTyImplementationError::NotAnAdtOrBuiltinAllowed) => {
-            tcx.sess.emit_err(ConstParamTyImplOnNonAdt { span });
+            tcx.sess.emit_err(errors::ConstParamTyImplOnNonAdt { span });
         }
     }
 }
@@ -152,8 +151,6 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
 
     let param_env = tcx.param_env(impl_did);
 
-    let create_err = |msg: &str| struct_span_err!(tcx.sess, span, E0378, "{}", msg);
-
     let infcx = tcx.infer_ctxt().build();
     let cause = ObligationCause::misc(span, impl_did);
 
@@ -176,22 +173,19 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
                 let source_path = tcx.def_path_str(def_a.did());
                 let target_path = tcx.def_path_str(def_b.did());
 
-                create_err(&format!(
-                    "the trait `DispatchFromDyn` may only be implemented \
-                            for a coercion between structures with the same \
-                            definition; expected `{source_path}`, found `{target_path}`",
-                ))
-                .emit();
+                tcx.sess.emit_err(errors::DispatchFromDynCoercion {
+                    span,
+                    trait_name: "DispatchFromDyn",
+                    note: true,
+                    source_path,
+                    target_path,
+                });
 
                 return;
             }
 
             if def_a.repr().c() || def_a.repr().packed() {
-                create_err(
-                    "structs implementing `DispatchFromDyn` may not have \
-                         `#[repr(packed)]` or `#[repr(C)]`",
-                )
-                .emit();
+                tcx.sess.emit_err(errors::DispatchFromDynRepr { span });
             }
 
             let fields = &def_a.non_enum_variant().fields;
@@ -213,16 +207,11 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
                         infcx.at(&cause, param_env).eq(DefineOpaqueTypes::No, ty_a, ty_b)
                     {
                         if ok.obligations.is_empty() {
-                            create_err(
-                                "the trait `DispatchFromDyn` may only be implemented \
-                                 for structs containing the field being coerced, \
-                                 ZST fields with 1 byte alignment, and nothing else",
-                            )
-                            .note(format!(
-                                "extra field `{}` of type `{}` is not allowed",
-                                field.name, ty_a,
-                            ))
-                            .emit();
+                            tcx.sess.emit_err(errors::DispatchFromDynZST {
+                                span,
+                                name: field.name,
+                                ty: ty_a,
+                            });
 
                             return false;
                         }
@@ -233,36 +222,29 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
                 .collect::<Vec<_>>();
 
             if coerced_fields.is_empty() {
-                create_err(
-                    "the trait `DispatchFromDyn` may only be implemented \
-                        for a coercion between structures with a single field \
-                        being coerced, none found",
-                )
-                .emit();
+                tcx.sess.emit_err(errors::DispatchFromDynSingle {
+                    span,
+                    trait_name: "DispatchFromDyn",
+                    note: true,
+                });
             } else if coerced_fields.len() > 1 {
-                create_err("implementing the `DispatchFromDyn` trait requires multiple coercions")
-                    .note(
-                        "the trait `DispatchFromDyn` may only be implemented \
-                            for a coercion between structures with a single field \
-                            being coerced",
-                    )
-                    .note(format!(
-                        "currently, {} fields need coercions: {}",
-                        coerced_fields.len(),
-                        coerced_fields
-                            .iter()
-                            .map(|field| {
-                                format!(
-                                    "`{}` (`{}` to `{}`)",
-                                    field.name,
-                                    field.ty(tcx, args_a),
-                                    field.ty(tcx, args_b),
-                                )
-                            })
-                            .collect::<Vec<_>>()
-                            .join(", ")
-                    ))
-                    .emit();
+                tcx.sess.emit_err(errors::DispatchFromDynMulti {
+                    span,
+                    coercions_note: true,
+                    number: coerced_fields.len(),
+                    coercions: coerced_fields
+                        .iter()
+                        .map(|field| {
+                            format!(
+                                "`{}` (`{}` to `{}`)",
+                                field.name,
+                                field.ty(tcx, args_a),
+                                field.ty(tcx, args_b),
+                            )
+                        })
+                        .collect::<Vec<_>>()
+                        .join(", "),
+                });
             } else {
                 let ocx = ObligationCtxt::new(&infcx);
                 for field in coerced_fields {
@@ -288,11 +270,7 @@ fn visit_implementation_of_dispatch_from_dyn(tcx: TyCtxt<'_>, impl_did: LocalDef
             }
         }
         _ => {
-            create_err(
-                "the trait `DispatchFromDyn` may only be implemented \
-                    for a coercion between structures",
-            )
-            .emit();
+            tcx.sess.emit_err(errors::CoerceUnsizedMay { span, trait_name: "DispatchFromDyn" });
         }
     }
 }
@@ -359,17 +337,13 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
             if def_a != def_b {
                 let source_path = tcx.def_path_str(def_a.did());
                 let target_path = tcx.def_path_str(def_b.did());
-                struct_span_err!(
-                    tcx.sess,
+                tcx.sess.emit_err(errors::DispatchFromDynSame {
                     span,
-                    E0377,
-                    "the trait `CoerceUnsized` may only be implemented \
-                           for a coercion between structures with the same \
-                           definition; expected `{}`, found `{}`",
+                    trait_name: "CoerceUnsized",
+                    note: true,
                     source_path,
-                    target_path
-                )
-                .emit();
+                    target_path,
+                });
                 return err_info;
             }
 
@@ -445,15 +419,11 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
                 .collect::<Vec<_>>();
 
             if diff_fields.is_empty() {
-                struct_span_err!(
-                    tcx.sess,
+                tcx.sess.emit_err(errors::CoerceUnsizedOneField {
                     span,
-                    E0374,
-                    "the trait `CoerceUnsized` may only be implemented \
-                           for a coercion between structures with one field \
-                           being coerced, none found"
-                )
-                .emit();
+                    trait_name: "CoerceUnsized",
+                    note: true,
+                });
                 return err_info;
             } else if diff_fields.len() > 1 {
                 let item = tcx.hir().expect_item(impl_did);
@@ -463,29 +433,17 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
                     tcx.def_span(impl_did)
                 };
 
-                struct_span_err!(
-                    tcx.sess,
+                tcx.sess.emit_err(errors::CoerceUnsizedMulti {
                     span,
-                    E0375,
-                    "implementing the trait \
-                                                `CoerceUnsized` requires multiple \
-                                                coercions"
-                )
-                .note(
-                    "`CoerceUnsized` may only be implemented for \
-                          a coercion between structures with one field being coerced",
-                )
-                .note(format!(
-                    "currently, {} fields need coercions: {}",
-                    diff_fields.len(),
-                    diff_fields
+                    coercions_note: true,
+                    number: diff_fields.len(),
+                    coercions: diff_fields
                         .iter()
-                        .map(|&(i, a, b)| { format!("`{}` (`{}` to `{}`)", fields[i].name, a, b) })
+                        .map(|&(i, a, b)| format!("`{}` (`{}` to `{}`)", fields[i].name, a, b))
                         .collect::<Vec<_>>()
-                        .join(", ")
-                ))
-                .span_label(span, "requires multiple coercions")
-                .emit();
+                        .join(", "),
+                });
+
                 return err_info;
             }
 
@@ -495,14 +453,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: LocalDefId) -> Coe
         }
 
         _ => {
-            struct_span_err!(
-                tcx.sess,
-                span,
-                E0376,
-                "the trait `CoerceUnsized` may only be implemented \
-                       for a coercion between structures"
-            )
-            .emit();
+            tcx.sess.emit_err(errors::DispatchFromDynStruct { span, trait_name: "CoerceUnsized" });
             return err_info;
         }
     };
@@ -540,13 +491,6 @@ fn infringing_fields_error(
 
     let trait_name = tcx.def_path_str(trait_did);
 
-    let mut err = struct_span_err!(
-        tcx.sess,
-        impl_span,
-        E0204,
-        "the trait `{trait_name}` cannot be implemented for this type"
-    );
-
     // We'll try to suggest constraining type parameters to fulfill the requirements of
     // their `Copy` implementation.
     let mut errors: BTreeMap<_, Vec<_>> = Default::default();
@@ -554,14 +498,15 @@ fn infringing_fields_error(
 
     let mut seen_tys = FxHashSet::default();
 
+    let mut label_spans = Vec::new();
+
     for (field, ty, reason) in fields {
         // Only report an error once per type.
         if !seen_tys.insert(ty) {
             continue;
         }
 
-        let field_span = tcx.def_span(field.did);
-        err.span_label(field_span, format!("this field does not implement `{trait_name}`"));
+        label_spans.push(tcx.def_span(field.did));
 
         match reason {
             InfringingFieldsReason::Fulfill(fulfillment_errors) => {
@@ -625,13 +570,24 @@ fn infringing_fields_error(
             }
         }
     }
+    let mut notes = Vec::new();
     for ((ty, error_predicate), spans) in errors {
         let span: MultiSpan = spans.into();
-        err.span_note(
+        notes.push(errors::ImplForTyRequires {
             span,
-            format!("the `{trait_name}` impl for `{ty}` requires that `{error_predicate}`"),
-        );
+            error_predicate,
+            trait_name: trait_name.clone(),
+            ty,
+        });
     }
+
+    let mut err = tcx.sess.create_err(errors::TraitCannotImplForTy {
+        span: impl_span,
+        trait_name,
+        label_spans,
+        notes,
+    });
+
     suggest_constraining_type_params(
         tcx,
         tcx.hir().get_generics(impl_did).expect("impls always have generics"),
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
index aa7c9e504c1..0042d683b19 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
@@ -157,7 +157,6 @@ impl<'tcx> InherentCollect<'tcx> {
             | ty::Closure(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Bound(..)
             | ty::Placeholder(_)
             | ty::Infer(_) => {
diff --git a/compiler/rustc_hir_analysis/src/coherence/orphan.rs b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
index bbdb108c59b..69020b1f11d 100644
--- a/compiler/rustc_hir_analysis/src/coherence/orphan.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/orphan.rs
@@ -245,7 +245,6 @@ fn do_orphan_check_impl<'tcx>(
             ty::Closure(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Bound(..)
             | ty::Placeholder(..)
             | ty::Infer(..) => {
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 01e40c62a8b..221df4e36b2 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -58,6 +58,7 @@ pub fn provide(providers: &mut Providers) {
     *providers = Providers {
         type_of: type_of::type_of,
         type_of_opaque: type_of::type_of_opaque,
+        type_alias_is_lazy: type_of::type_alias_is_lazy,
         item_bounds: item_bounds::item_bounds,
         explicit_item_bounds: item_bounds::explicit_item_bounds,
         generics_of: generics_of::generics_of,
@@ -1373,7 +1374,7 @@ fn impl_trait_ref(
                 // make astconv happy.
                 let mut path_segments = ast_trait_ref.path.segments.to_vec();
                 let last_segment = path_segments.len() - 1;
-                let mut args = path_segments[last_segment].args().clone();
+                let mut args = *path_segments[last_segment].args();
                 let last_arg = args.args.len() - 1;
                 assert!(matches!(args.args[last_arg], hir::GenericArg::Const(anon_const) if tcx.has_attr(anon_const.value.def_id, sym::rustc_host)));
                 args.args = &args.args[..args.args.len() - 1];
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index a39cfd7b6e1..eb4466449a0 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -856,22 +856,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
         let scope = Scope::TraitRefBoundary { s: self.scope };
         self.with(scope, |this| {
             walk_list!(this, visit_generic_param, generics.params);
-            for param in generics.params {
-                match param.kind {
-                    GenericParamKind::Lifetime { .. } => {}
-                    GenericParamKind::Type { default, .. } => {
-                        if let Some(ty) = default {
-                            this.visit_ty(ty);
-                        }
-                    }
-                    GenericParamKind::Const { ty, default } => {
-                        this.visit_ty(ty);
-                        if let Some(default) = default {
-                            this.visit_body(this.tcx.hir().body(default.body));
-                        }
-                    }
-                }
-            }
             walk_list!(this, visit_where_predicate, generics.predicates);
         })
     }
@@ -1000,6 +984,21 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
                 // like implicit `?Sized` or const-param-has-ty predicates.
             }
         }
+
+        match p.kind {
+            GenericParamKind::Lifetime { .. } => {}
+            GenericParamKind::Type { default, .. } => {
+                if let Some(ty) = default {
+                    self.visit_ty(ty);
+                }
+            }
+            GenericParamKind::Const { ty, default } => {
+                self.visit_ty(ty);
+                if let Some(default) = default {
+                    self.visit_body(self.tcx.hir().body(default.body));
+                }
+            }
+        }
     }
 }
 
@@ -1520,7 +1519,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
                 DefKind::Struct
                 | DefKind::Union
                 | DefKind::Enum
-                | DefKind::TyAlias { .. }
+                | DefKind::TyAlias
                 | DefKind::Trait,
                 def_id,
             ) if depth == 0 => Some(def_id),
@@ -2030,7 +2029,7 @@ fn is_late_bound_map(
 
                 hir::TyKind::Path(hir::QPath::Resolved(
                     None,
-                    hir::Path { res: Res::Def(DefKind::TyAlias { .. }, alias_def), segments, span },
+                    hir::Path { res: Res::Def(DefKind::TyAlias, alias_def), segments, span },
                 )) => {
                     // See comments on `ConstrainedCollectorPostAstConv` for why this arm does not just consider
                     // args to be unconstrained.
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index d12337687e2..ae62119b182 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -623,3 +623,25 @@ fn check_feature_inherent_assoc_ty(tcx: TyCtxt<'_>, span: Span) {
         .emit();
     }
 }
+
+pub fn type_alias_is_lazy<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> bool {
+    use hir::intravisit::Visitor;
+    if tcx.features().lazy_type_alias {
+        return true;
+    }
+    struct HasTait {
+        has_type_alias_impl_trait: bool,
+    }
+    impl<'tcx> Visitor<'tcx> for HasTait {
+        fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
+            if let hir::TyKind::OpaqueDef(..) = t.kind {
+                self.has_type_alias_impl_trait = true;
+            } else {
+                hir::intravisit::walk_ty(self, t);
+            }
+        }
+    }
+    let mut has_tait = HasTait { has_type_alias_impl_trait: false };
+    has_tait.visit_ty(tcx.hir().expect_item(def_id).expect_ty_alias().0);
+    has_tait.has_type_alias_impl_trait
+}
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index 4705e40988b..0efe82b20ee 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -964,6 +964,25 @@ pub struct InherentTyOutside {
 }
 
 #[derive(Diagnostic)]
+#[diag(hir_analysis_coerce_unsized_may, code = "E0378")]
+pub struct DispatchFromDynCoercion<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub trait_name: &'a str,
+    #[note(hir_analysis_coercion_between_struct_same_note)]
+    pub note: bool,
+    pub source_path: String,
+    pub target_path: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_dispatch_from_dyn_repr, code = "E0378")]
+pub struct DispatchFromDynRepr {
+    #[primary_span]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(hir_analysis_inherent_ty_outside_relevant, code = "E0390")]
 #[help]
 pub struct InherentTyOutsideRelevant {
@@ -1025,3 +1044,108 @@ pub struct InherentNominal {
     #[label]
     pub span: Span,
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_dispatch_from_dyn_zst, code = "E0378")]
+#[note]
+pub struct DispatchFromDynZST<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub name: Symbol,
+    pub ty: Ty<'a>,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_coerce_unsized_may, code = "E0378")]
+pub struct DispatchFromDynSingle<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub trait_name: &'a str,
+    #[note(hir_analysis_coercion_between_struct_single_note)]
+    pub note: bool,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_dispatch_from_dyn_multi, code = "E0378")]
+#[note]
+pub struct DispatchFromDynMulti {
+    #[primary_span]
+    pub span: Span,
+    #[note(hir_analysis_coercions_note)]
+    pub coercions_note: bool,
+    pub number: usize,
+    pub coercions: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_coerce_unsized_may, code = "E0376")]
+pub struct DispatchFromDynStruct<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub trait_name: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_coerce_unsized_may, code = "E0377")]
+pub struct DispatchFromDynSame<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub trait_name: &'a str,
+    #[note(hir_analysis_coercion_between_struct_same_note)]
+    pub note: bool,
+    pub source_path: String,
+    pub target_path: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_coerce_unsized_may, code = "E0374")]
+pub struct CoerceUnsizedOneField<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub trait_name: &'a str,
+    #[note(hir_analysis_coercion_between_struct_single_note)]
+    pub note: bool,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_coerce_unsized_multi, code = "E0375")]
+#[note]
+pub struct CoerceUnsizedMulti {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+    #[note(hir_analysis_coercions_note)]
+    pub coercions_note: bool,
+    pub number: usize,
+    pub coercions: String,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_coerce_unsized_may, code = "E0378")]
+pub struct CoerceUnsizedMay<'a> {
+    #[primary_span]
+    pub span: Span,
+    pub trait_name: &'a str,
+}
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_trait_cannot_impl_for_ty, code = "E0204")]
+pub struct TraitCannotImplForTy {
+    #[primary_span]
+    pub span: Span,
+    pub trait_name: String,
+    #[label]
+    pub label_spans: Vec<Span>,
+    #[subdiagnostic]
+    pub notes: Vec<ImplForTyRequires>,
+}
+
+#[derive(Subdiagnostic)]
+#[note(hir_analysis_requires_note)]
+pub struct ImplForTyRequires {
+    #[primary_span]
+    pub span: MultiSpan,
+    pub error_predicate: String,
+    pub trait_name: String,
+    pub ty: String,
+}
diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs
index 8a40509d7cc..61d9c989e2f 100644
--- a/compiler/rustc_hir_analysis/src/variance/constraints.rs
+++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs
@@ -6,7 +6,7 @@
 use hir::def_id::{DefId, LocalDefId};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
 
 use super::terms::VarianceTerm::*;
@@ -78,9 +78,7 @@ pub fn add_constraints_from_crate<'a, 'tcx>(
                 }
             }
             DefKind::Fn | DefKind::AssocFn => constraint_cx.build_constraints_for_item(def_id),
-            DefKind::TyAlias { lazy }
-                if lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types() =>
-            {
+            DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => {
                 constraint_cx.build_constraints_for_item(def_id)
             }
             _ => {}
@@ -110,8 +108,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
 
         // The type as returned by `type_of` is the underlying type and generally not a weak projection.
         // Therefore we need to check the `DefKind` first.
-        if let DefKind::TyAlias { lazy } = tcx.def_kind(def_id)
-            && (lazy || ty.has_opaque_types())
+        if let DefKind::TyAlias = tcx.def_kind(def_id)
+            && tcx.type_alias_is_lazy(def_id)
         {
             self.add_constraints_from_ty(current_item, ty, self.covariant);
             return;
@@ -314,11 +312,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                 // types, where we use Error as the Self type
             }
 
-            ty::Placeholder(..)
-            | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
-            | ty::Bound(..)
-            | ty::Infer(..) => {
+            ty::Placeholder(..) | ty::GeneratorWitness(..) | ty::Bound(..) | ty::Infer(..) => {
                 bug!("unexpected type encountered in variance inference: {}", ty);
             }
         }
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index d69d7ff904a..85e0000ab47 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -8,7 +8,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::query::Providers;
 use rustc_middle::ty::{self, CrateVariancesMap, GenericArgsRef, Ty, TyCtxt};
-use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
+use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable};
 use std::ops::ControlFlow;
 
 /// Defines the `TermsContext` basically houses an arena where we can
@@ -56,9 +56,7 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
             let crate_map = tcx.crate_variances(());
             return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
         }
-        DefKind::TyAlias { lazy }
-            if lazy || tcx.type_of(item_def_id).instantiate_identity().has_opaque_types() =>
-        {
+        DefKind::TyAlias if tcx.type_alias_is_lazy(item_def_id) => {
             // These are inferred.
             let crate_map = tcx.crate_variances(());
             return crate_map.variances.get(&item_def_id.to_def_id()).copied().unwrap_or(&[]);
diff --git a/compiler/rustc_hir_analysis/src/variance/terms.rs b/compiler/rustc_hir_analysis/src/variance/terms.rs
index 1a8ec5f0853..275df24956c 100644
--- a/compiler/rustc_hir_analysis/src/variance/terms.rs
+++ b/compiler/rustc_hir_analysis/src/variance/terms.rs
@@ -12,7 +12,7 @@
 use rustc_arena::DroplessArena;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{LocalDefId, LocalDefIdMap};
-use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, TyCtxt};
 use std::fmt;
 
 use self::VarianceTerm::*;
@@ -97,9 +97,7 @@ pub fn determine_parameters_to_be_inferred<'a, 'tcx>(
                 }
             }
             DefKind::Fn | DefKind::AssocFn => terms_cx.add_inferreds_for_item(def_id),
-            DefKind::TyAlias { lazy }
-                if lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types() =>
-            {
+            DefKind::TyAlias if tcx.type_alias_is_lazy(def_id) => {
                 terms_cx.add_inferreds_for_item(def_id)
             }
             _ => {}
diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index 3319b52e246..81fe0cc489e 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -2,6 +2,7 @@ use crate::coercion::{AsCoercionSite, CoerceMany};
 use crate::{Diverges, Expectation, FnCtxt, Needs};
 use rustc_errors::Diagnostic;
 use rustc_hir::{self as hir, ExprKind};
+use rustc_hir_pretty::ty_to_string;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::traits::Obligation;
 use rustc_middle::ty::{self, Ty};
@@ -252,7 +253,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     {
         // If this `if` expr is the parent's function return expr,
         // the cause of the type coercion is the return type, point at it. (#25228)
-        let ret_reason = self.maybe_get_coercion_reason(then_expr.hir_id, span);
+        let hir_id = self.tcx.hir().parent_id(self.tcx.hir().parent_id(then_expr.hir_id));
+        let ret_reason = self.maybe_get_coercion_reason(hir_id, span);
         let cause = self.cause(span, ObligationCauseCode::IfExpressionWithNoElse);
         let mut error = false;
         coercion.coerce_forced_unit(
@@ -275,11 +277,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         error
     }
 
-    fn maybe_get_coercion_reason(&self, hir_id: hir::HirId, sp: Span) -> Option<(Span, String)> {
-        let node = {
-            let rslt = self.tcx.hir().parent_id(self.tcx.hir().parent_id(hir_id));
-            self.tcx.hir().get(rslt)
-        };
+    pub fn maybe_get_coercion_reason(
+        &self,
+        hir_id: hir::HirId,
+        sp: Span,
+    ) -> Option<(Span, String)> {
+        let node = self.tcx.hir().get(hir_id);
         if let hir::Node::Block(block) = node {
             // check that the body's parent is an fn
             let parent = self.tcx.hir().get_parent(self.tcx.hir().parent_id(block.hir_id));
@@ -289,9 +292,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // check that the `if` expr without `else` is the fn body's expr
                 if expr.span == sp {
                     return self.get_fn_decl(hir_id).and_then(|(_, fn_decl, _)| {
-                        let span = fn_decl.output.span();
-                        let snippet = self.tcx.sess.source_map().span_to_snippet(span).ok()?;
-                        Some((span, format!("expected `{snippet}` because of this return type")))
+                        let (ty, span) = match fn_decl.output {
+                            hir::FnRetTy::DefaultReturn(span) => ("()".to_string(), span),
+                            hir::FnRetTy::Return(ty) => (ty_to_string(ty), ty.span),
+                        };
+                        Some((span, format!("expected `{ty}` because of this return type")))
                     });
                 }
             }
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 57cd88afcdc..2b1ac7f3537 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -129,7 +129,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             | ty::Float(_)
             | ty::Array(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::RawPtr(_)
             | ty::Ref(..)
             | ty::FnDef(..)
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index 041cc1abd54..1fa0ec173a7 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -204,7 +204,7 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
         &[ty::GenericArg::from(ty::Region::new_late_bound(
             tcx,
             ty::INNERMOST,
-            ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrAnon(None) },
+            ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrAnon },
         ))],
     );
     let panic_info_ref_ty = Ty::new_imm_ref(
@@ -212,14 +212,14 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
         ty::Region::new_late_bound(
             tcx,
             ty::INNERMOST,
-            ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon(None) },
+            ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon },
         ),
         panic_info_ty,
     );
 
     let bounds = tcx.mk_bound_variable_kinds(&[
-        ty::BoundVariableKind::Region(ty::BrAnon(None)),
-        ty::BoundVariableKind::Region(ty::BrAnon(None)),
+        ty::BoundVariableKind::Region(ty::BrAnon),
+        ty::BoundVariableKind::Region(ty::BrAnon),
     ]);
     let expected_sig = ty::Binder::bind_with_vars(
         tcx.mk_fn_sig([panic_info_ref_ty], tcx.types.never, false, fn_sig.unsafety, Abi::Rust),
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 2c16f21b491..d97691369c9 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -83,6 +83,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         self.annotate_expected_due_to_let_ty(err, expr, error);
+        self.annotate_loop_expected_due_to_inference(err, expr, error);
 
         // FIXME(#73154): For now, we do leak check when coercing function
         // pointers in typeck, instead of only during borrowck. This can lead
@@ -527,6 +528,136 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         false
     }
 
+    // When encountering a type error on the value of a `break`, try to point at the reason for the
+    // expected type.
+    pub fn annotate_loop_expected_due_to_inference(
+        &self,
+        err: &mut Diagnostic,
+        expr: &hir::Expr<'_>,
+        error: Option<TypeError<'tcx>>,
+    ) {
+        let Some(TypeError::Sorts(ExpectedFound { expected, .. })) = error else {
+            return;
+        };
+        let mut parent_id = self.tcx.hir().parent_id(expr.hir_id);
+        let mut parent;
+        'outer: loop {
+            // Climb the HIR tree to see if the current `Expr` is part of a `break;` statement.
+            let Some(
+                hir::Node::Stmt(hir::Stmt { kind: hir::StmtKind::Semi(&ref p), .. })
+                | hir::Node::Block(hir::Block { expr: Some(&ref p), .. })
+                | hir::Node::Expr(&ref p),
+            ) = self.tcx.hir().find(parent_id)
+            else {
+                break;
+            };
+            parent = p;
+            parent_id = self.tcx.hir().parent_id(parent_id);
+            let hir::ExprKind::Break(destination, _) = parent.kind else {
+                continue;
+            };
+            let mut parent_id = parent_id;
+            let mut direct = false;
+            loop {
+                // Climb the HIR tree to find the (desugared) `loop` this `break` corresponds to.
+                let parent = match self.tcx.hir().find(parent_id) {
+                    Some(hir::Node::Expr(&ref parent)) => {
+                        parent_id = self.tcx.hir().parent_id(parent.hir_id);
+                        parent
+                    }
+                    Some(hir::Node::Stmt(hir::Stmt {
+                        hir_id,
+                        kind: hir::StmtKind::Semi(&ref parent) | hir::StmtKind::Expr(&ref parent),
+                        ..
+                    })) => {
+                        parent_id = self.tcx.hir().parent_id(*hir_id);
+                        parent
+                    }
+                    Some(hir::Node::Block(_)) => {
+                        parent_id = self.tcx.hir().parent_id(parent_id);
+                        parent
+                    }
+                    _ => break,
+                };
+                if let hir::ExprKind::Loop(..) = parent.kind {
+                    // When you have `'a: loop { break; }`, the `break` corresponds to the labeled
+                    // loop, so we need to account for that.
+                    direct = !direct;
+                }
+                if let hir::ExprKind::Loop(block, label, _, span) = parent.kind
+                    && (destination.label == label || direct)
+                {
+                    if let Some((reason_span, message)) =
+                        self.maybe_get_coercion_reason(parent_id, parent.span)
+                    {
+                        err.span_label(reason_span, message);
+                        err.span_label(
+                            span,
+                            format!("this loop is expected to be of type `{expected}`"),
+                        );
+                        break 'outer;
+                    } else {
+                        // Locate all other `break` statements within the same `loop` that might
+                        // have affected inference.
+                        struct FindBreaks<'tcx> {
+                            label: Option<rustc_ast::Label>,
+                            uses: Vec<&'tcx hir::Expr<'tcx>>,
+                            nest_depth: usize,
+                        }
+                        impl<'tcx> Visitor<'tcx> for FindBreaks<'tcx> {
+                            fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
+                                let nest_depth = self.nest_depth;
+                                if let hir::ExprKind::Loop(_, label, _, _) = ex.kind {
+                                    if label == self.label {
+                                        // Account for `'a: loop { 'a: loop {...} }`.
+                                        return;
+                                    }
+                                    self.nest_depth += 1;
+                                }
+                                if let hir::ExprKind::Break(destination, _) = ex.kind
+                                    && (self.label == destination.label
+                                        // Account for `loop { 'a: loop { loop { break; } } }`.
+                                        || destination.label.is_none() && self.nest_depth == 0)
+                                {
+                                    self.uses.push(ex);
+                                }
+                                hir::intravisit::walk_expr(self, ex);
+                                self.nest_depth = nest_depth;
+                            }
+                        }
+                        let mut expr_finder = FindBreaks { label, uses: vec![], nest_depth: 0 };
+                        expr_finder.visit_block(block);
+                        let mut exit = false;
+                        for ex in expr_finder.uses {
+                            let hir::ExprKind::Break(_, val) = ex.kind else {
+                                continue;
+                            };
+                            let ty = match val {
+                                Some(val) => {
+                                    match self.typeck_results.borrow().expr_ty_adjusted_opt(val) {
+                                        None => continue,
+                                        Some(ty) => ty,
+                                    }
+                                }
+                                None => self.tcx.types.unit,
+                            };
+                            if self.can_eq(self.param_env, ty, expected) {
+                                err.span_label(
+                                    ex.span,
+                                    "expected because of this `break`",
+                                );
+                                exit = true;
+                            }
+                        }
+                        if exit {
+                            break 'outer;
+                        }
+                    }
+                }
+            }
+        }
+    }
+
     fn annotate_expected_due_to_let_ty(
         &self,
         err: &mut Diagnostic,
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 4ad14ce3059..eead4da5e3e 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -43,7 +43,10 @@ use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::middle::stability;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
-use rustc_middle::ty::error::TypeError::FieldMisMatch;
+use rustc_middle::ty::error::{
+    ExpectedFound,
+    TypeError::{FieldMisMatch, Sorts},
+};
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitableExt};
 use rustc_session::errors::ExprParenthesesNeeded;
@@ -664,15 +667,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             self.suggest_mismatched_types_on_tail(
                                 &mut err, expr, ty, e_ty, target_id,
                             );
+                            let error = Some(Sorts(ExpectedFound { expected: ty, found: e_ty }));
+                            self.annotate_loop_expected_due_to_inference(&mut err, expr, error);
                             if let Some(val) = ty_kind_suggestion(ty) {
-                                let label = destination
-                                    .label
-                                    .map(|l| format!(" {}", l.ident))
-                                    .unwrap_or_else(String::new);
-                                err.span_suggestion(
-                                    expr.span,
+                                err.span_suggestion_verbose(
+                                    expr.span.shrink_to_hi(),
                                     "give it a value of the expected type",
-                                    format!("break{label} {val}"),
+                                    format!(" {val}"),
                                     Applicability::HasPlaceholders,
                                 );
                             }
@@ -717,7 +718,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // ... except when we try to 'break rust;'.
                 // ICE this expression in particular (see #43162).
                 if let ExprKind::Path(QPath::Resolved(_, path)) = e.kind {
-                    if path.segments.len() == 1 && path.segments[0].ident.name == sym::rust {
+                    if let [segment] = path.segments && segment.ident.name == sym::rust {
                         fatally_break_rust(self.tcx);
                     }
                 }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index c94cfde0670..415920221f5 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -509,21 +509,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         typeck_results.rvalue_scopes = rvalue_scopes;
     }
 
-    pub(in super::super) fn resolve_generator_interiors(&self, def_id: DefId) {
-        if self.tcx.sess.opts.unstable_opts.drop_tracking_mir {
-            self.save_generator_interior_predicates(def_id);
-            return;
-        }
-
-        self.select_obligations_where_possible(|_| {});
-
-        let mut generators = self.deferred_generator_interiors.borrow_mut();
-        for (_, body_id, interior, kind) in generators.drain(..) {
-            crate::generator_interior::resolve_interior(self, def_id, body_id, interior, kind);
-            self.select_obligations_where_possible(|_| {});
-        }
-    }
-
     /// Unify the inference variables corresponding to generator witnesses, and save all the
     /// predicates that were stalled on those inference variables.
     ///
@@ -533,7 +518,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// We must not attempt to select obligations after this method has run, or risk query cycle
     /// ICE.
     #[instrument(level = "debug", skip(self))]
-    fn save_generator_interior_predicates(&self, def_id: DefId) {
+    pub(in super::super) fn resolve_generator_interiors(&self, def_id: DefId) {
         // Try selecting all obligations that are not blocked on inference variables.
         // Once we start unifying generator witnesses, trying to select obligations on them will
         // trigger query cycle ICEs, as doing so requires MIR.
@@ -550,7 +535,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.tcx,
                 self.tcx.typeck_root_def_id(expr_def_id.to_def_id()),
             );
-            let witness = Ty::new_generator_witness_mir(self.tcx, expr_def_id.to_def_id(), args);
+            let witness = Ty::new_generator_witness(self.tcx, expr_def_id.to_def_id(), args);
 
             // Unify `interior` with `witness` and collect all the resulting obligations.
             let span = self.tcx.hir().body(body_id).value.span;
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 37ea94d821e..c0332a48be3 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1370,10 +1370,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 }
                 _ => bug!("unexpected type: {:?}", ty.normalized),
             },
-            Res::Def(
-                DefKind::Struct | DefKind::Union | DefKind::TyAlias { .. } | DefKind::AssocTy,
-                _,
-            )
+            Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
             | Res::SelfTyParam { .. }
             | Res::SelfTyAlias { .. } => match ty.normalized.ty_adt_def() {
                 Some(adt) if !adt.is_enum() => {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
index 41f815a812a..abb68989218 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/suggestions.rs
@@ -65,6 +65,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let expr = expr.peel_drop_temps();
         self.suggest_missing_semicolon(err, expr, expected, false);
         let mut pointing_at_return_type = false;
+        if let hir::ExprKind::Break(..) = expr.kind {
+            // `break` type mismatches provide better context for tail `loop` expressions.
+            return false;
+        }
         if let Some((fn_id, fn_decl, can_suggest)) = self.get_fn_decl(blk_id) {
             pointing_at_return_type = self.suggest_missing_return_type(
                 err,
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs
deleted file mode 100644
index cfedcee9956..00000000000
--- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_build.rs
+++ /dev/null
@@ -1,601 +0,0 @@
-use super::{
-    for_each_consumable, record_consumed_borrow::ConsumedAndBorrowedPlaces, DropRangesBuilder,
-    NodeInfo, PostOrderId, TrackedValue, TrackedValueIndex,
-};
-use hir::{
-    intravisit::{self, Visitor},
-    Body, Expr, ExprKind, Guard, HirId, LoopIdError,
-};
-use rustc_data_structures::unord::{UnordMap, UnordSet};
-use rustc_hir as hir;
-use rustc_index::IndexVec;
-use rustc_infer::infer::InferCtxt;
-use rustc_middle::{
-    hir::map::Map,
-    ty::{ParamEnv, TyCtxt, TypeVisitableExt, TypeckResults},
-};
-use std::mem::swap;
-
-/// Traverses the body to find the control flow graph and locations for the
-/// relevant places are dropped or reinitialized.
-///
-/// The resulting structure still needs to be iterated to a fixed point, which
-/// can be done with propagate_to_fixpoint in cfg_propagate.
-pub(super) fn build_control_flow_graph<'tcx>(
-    infcx: &InferCtxt<'tcx>,
-    typeck_results: &TypeckResults<'tcx>,
-    param_env: ParamEnv<'tcx>,
-    consumed_borrowed_places: ConsumedAndBorrowedPlaces,
-    body: &'tcx Body<'tcx>,
-    num_exprs: usize,
-) -> (DropRangesBuilder, UnordSet<HirId>) {
-    let mut drop_range_visitor = DropRangeVisitor::new(
-        infcx,
-        typeck_results,
-        param_env,
-        consumed_borrowed_places,
-        num_exprs,
-    );
-    intravisit::walk_body(&mut drop_range_visitor, body);
-
-    drop_range_visitor.drop_ranges.process_deferred_edges();
-    if let Some(filename) = &infcx.tcx.sess.opts.unstable_opts.dump_drop_tracking_cfg {
-        super::cfg_visualize::write_graph_to_file(
-            &drop_range_visitor.drop_ranges,
-            filename,
-            infcx.tcx,
-        );
-    }
-
-    (drop_range_visitor.drop_ranges, drop_range_visitor.places.borrowed_temporaries)
-}
-
-/// This struct is used to gather the information for `DropRanges` to determine the regions of the
-/// HIR tree for which a value is dropped.
-///
-/// We are interested in points where a variables is dropped or initialized, and the control flow
-/// of the code. We identify locations in code by their post-order traversal index, so it is
-/// important for this traversal to match that in `RegionResolutionVisitor` and `InteriorVisitor`.
-///
-/// We make several simplifying assumptions, with the goal of being more conservative than
-/// necessary rather than less conservative (since being less conservative is unsound, but more
-/// conservative is still safe). These assumptions are:
-///
-/// 1. Moving a variable `a` counts as a move of the whole variable.
-/// 2. Moving a partial path like `a.b.c` is ignored.
-/// 3. Reinitializing through a field (e.g. `a.b.c = 5`) counts as a reinitialization of all of
-///    `a`.
-///
-/// Some examples:
-///
-/// Rule 1:
-/// ```rust
-/// let mut a = (vec![0], vec![0]);
-/// drop(a);
-/// // `a` is not considered initialized.
-/// ```
-///
-/// Rule 2:
-/// ```rust
-/// let mut a = (vec![0], vec![0]);
-/// drop(a.0);
-/// drop(a.1);
-/// // `a` is still considered initialized.
-/// ```
-///
-/// Rule 3:
-/// ```compile_fail,E0382
-/// let mut a = (vec![0], vec![0]);
-/// drop(a);
-/// a.1 = vec![1];
-/// // all of `a` is considered initialized
-/// ```
-
-struct DropRangeVisitor<'a, 'tcx> {
-    typeck_results: &'a TypeckResults<'tcx>,
-    infcx: &'a InferCtxt<'tcx>,
-    param_env: ParamEnv<'tcx>,
-    places: ConsumedAndBorrowedPlaces,
-    drop_ranges: DropRangesBuilder,
-    expr_index: PostOrderId,
-    label_stack: Vec<(Option<rustc_ast::Label>, PostOrderId)>,
-}
-
-impl<'a, 'tcx> DropRangeVisitor<'a, 'tcx> {
-    fn new(
-        infcx: &'a InferCtxt<'tcx>,
-        typeck_results: &'a TypeckResults<'tcx>,
-        param_env: ParamEnv<'tcx>,
-        places: ConsumedAndBorrowedPlaces,
-        num_exprs: usize,
-    ) -> Self {
-        debug!("consumed_places: {:?}", places.consumed);
-        let drop_ranges = DropRangesBuilder::new(
-            places.consumed.iter().flat_map(|(_, places)| places.iter().cloned()),
-            infcx.tcx.hir(),
-            num_exprs,
-        );
-        Self {
-            infcx,
-            typeck_results,
-            param_env,
-            places,
-            drop_ranges,
-            expr_index: PostOrderId::from_u32(0),
-            label_stack: vec![],
-        }
-    }
-
-    fn tcx(&self) -> TyCtxt<'tcx> {
-        self.infcx.tcx
-    }
-
-    fn record_drop(&mut self, value: TrackedValue) {
-        if self.places.borrowed.contains(&value) {
-            debug!("not marking {:?} as dropped because it is borrowed at some point", value);
-        } else {
-            debug!("marking {:?} as dropped at {:?}", value, self.expr_index);
-            let count = self.expr_index;
-            self.drop_ranges.drop_at(value, count);
-        }
-    }
-
-    /// ExprUseVisitor's consume callback doesn't go deep enough for our purposes in all
-    /// expressions. This method consumes a little deeper into the expression when needed.
-    fn consume_expr(&mut self, expr: &hir::Expr<'_>) {
-        debug!("consuming expr {:?}, count={:?}", expr.kind, self.expr_index);
-        let places = self
-            .places
-            .consumed
-            .get(&expr.hir_id)
-            .map_or(vec![], |places| places.iter().cloned().collect());
-        for place in places {
-            trace!(?place, "consuming place");
-            for_each_consumable(self.tcx().hir(), place, |value| self.record_drop(value));
-        }
-    }
-
-    /// Marks an expression as being reinitialized.
-    ///
-    /// Note that we always approximated on the side of things being more
-    /// initialized than they actually are, as opposed to less. In cases such
-    /// as `x.y = ...`, we would consider all of `x` as being initialized
-    /// instead of just the `y` field.
-    ///
-    /// This is because it is always safe to consider something initialized
-    /// even when it is not, but the other way around will cause problems.
-    ///
-    /// In the future, we will hopefully tighten up these rules to be more
-    /// precise.
-    fn reinit_expr(&mut self, expr: &hir::Expr<'_>) {
-        // Walk the expression to find the base. For example, in an expression
-        // like `*a[i].x`, we want to find the `a` and mark that as
-        // reinitialized.
-        match expr.kind {
-            ExprKind::Path(hir::QPath::Resolved(
-                _,
-                hir::Path { res: hir::def::Res::Local(hir_id), .. },
-            )) => {
-                // This is the base case, where we have found an actual named variable.
-
-                let location = self.expr_index;
-                debug!("reinitializing {:?} at {:?}", hir_id, location);
-                self.drop_ranges.reinit_at(TrackedValue::Variable(*hir_id), location);
-            }
-
-            ExprKind::Field(base, _) => self.reinit_expr(base),
-
-            // Most expressions do not refer to something where we need to track
-            // reinitializations.
-            //
-            // Some of these may be interesting in the future
-            ExprKind::Path(..)
-            | ExprKind::ConstBlock(..)
-            | ExprKind::Array(..)
-            | ExprKind::Call(..)
-            | ExprKind::MethodCall(..)
-            | ExprKind::Tup(..)
-            | ExprKind::Binary(..)
-            | ExprKind::Unary(..)
-            | ExprKind::Lit(..)
-            | ExprKind::Cast(..)
-            | ExprKind::Type(..)
-            | ExprKind::DropTemps(..)
-            | ExprKind::Let(..)
-            | ExprKind::If(..)
-            | ExprKind::Loop(..)
-            | ExprKind::Match(..)
-            | ExprKind::Closure { .. }
-            | ExprKind::Block(..)
-            | ExprKind::Assign(..)
-            | ExprKind::AssignOp(..)
-            | ExprKind::Index(..)
-            | ExprKind::AddrOf(..)
-            | ExprKind::Break(..)
-            | ExprKind::Continue(..)
-            | ExprKind::Ret(..)
-            | ExprKind::Become(..)
-            | ExprKind::InlineAsm(..)
-            | ExprKind::OffsetOf(..)
-            | ExprKind::Struct(..)
-            | ExprKind::Repeat(..)
-            | ExprKind::Yield(..)
-            | ExprKind::Err(_) => (),
-        }
-    }
-
-    /// For an expression with an uninhabited return type (e.g. a function that returns !),
-    /// this adds a self edge to the CFG to model the fact that the function does not
-    /// return.
-    fn handle_uninhabited_return(&mut self, expr: &Expr<'tcx>) {
-        let ty = self.typeck_results.expr_ty(expr);
-        let ty = self.infcx.resolve_vars_if_possible(ty);
-        if ty.has_non_region_infer() {
-            self.tcx()
-                .sess
-                .delay_span_bug(expr.span, format!("could not resolve infer vars in `{ty}`"));
-            return;
-        }
-        let ty = self.tcx().erase_regions(ty);
-        let m = self.tcx().parent_module(expr.hir_id).to_def_id();
-        if !ty.is_inhabited_from(self.tcx(), m, self.param_env) {
-            // This function will not return. We model this fact as an infinite loop.
-            self.drop_ranges.add_control_edge(self.expr_index + 1, self.expr_index + 1);
-        }
-    }
-
-    /// Map a Destination to an equivalent expression node
-    ///
-    /// The destination field of a Break or Continue expression can target either an
-    /// expression or a block. The drop range analysis, however, only deals in
-    /// expression nodes, so blocks that might be the destination of a Break or Continue
-    /// will not have a PostOrderId.
-    ///
-    /// If the destination is an expression, this function will simply return that expression's
-    /// hir_id. If the destination is a block, this function will return the hir_id of last
-    /// expression in the block.
-    fn find_target_expression_from_destination(
-        &self,
-        destination: hir::Destination,
-    ) -> Result<HirId, LoopIdError> {
-        destination.target_id.map(|target| {
-            let node = self.tcx().hir().get(target);
-            match node {
-                hir::Node::Expr(_) => target,
-                hir::Node::Block(b) => find_last_block_expression(b),
-                hir::Node::Param(..)
-                | hir::Node::Item(..)
-                | hir::Node::ForeignItem(..)
-                | hir::Node::TraitItem(..)
-                | hir::Node::ImplItem(..)
-                | hir::Node::Variant(..)
-                | hir::Node::Field(..)
-                | hir::Node::AnonConst(..)
-                | hir::Node::ConstBlock(..)
-                | hir::Node::Stmt(..)
-                | hir::Node::PathSegment(..)
-                | hir::Node::Ty(..)
-                | hir::Node::TypeBinding(..)
-                | hir::Node::TraitRef(..)
-                | hir::Node::Pat(..)
-                | hir::Node::PatField(..)
-                | hir::Node::ExprField(..)
-                | hir::Node::Arm(..)
-                | hir::Node::Local(..)
-                | hir::Node::Ctor(..)
-                | hir::Node::Lifetime(..)
-                | hir::Node::GenericParam(..)
-                | hir::Node::Crate(..)
-                | hir::Node::Infer(..) => bug!("Unsupported branch target: {:?}", node),
-            }
-        })
-    }
-}
-
-fn find_last_block_expression(block: &hir::Block<'_>) -> HirId {
-    block.expr.map_or_else(
-        // If there is no tail expression, there will be at least one statement in the
-        // block because the block contains a break or continue statement.
-        || block.stmts.last().unwrap().hir_id,
-        |expr| expr.hir_id,
-    )
-}
-
-impl<'a, 'tcx> Visitor<'tcx> for DropRangeVisitor<'a, 'tcx> {
-    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
-        let mut reinit = None;
-        match expr.kind {
-            ExprKind::Assign(lhs, rhs, _) => {
-                self.visit_expr(rhs);
-                self.visit_expr(lhs);
-
-                reinit = Some(lhs);
-            }
-
-            ExprKind::If(test, if_true, if_false) => {
-                self.visit_expr(test);
-
-                let fork = self.expr_index;
-
-                self.drop_ranges.add_control_edge(fork, self.expr_index + 1);
-                self.visit_expr(if_true);
-                let true_end = self.expr_index;
-
-                self.drop_ranges.add_control_edge(fork, self.expr_index + 1);
-                if let Some(if_false) = if_false {
-                    self.visit_expr(if_false);
-                }
-
-                self.drop_ranges.add_control_edge(true_end, self.expr_index + 1);
-            }
-            ExprKind::Match(scrutinee, arms, ..) => {
-                // We walk through the match expression almost like a chain of if expressions.
-                // Here's a diagram to follow along with:
-                //
-                //           ┌─┐
-                //     match │A│ {
-                //       ┌───┴─┘
-                //       │
-                //      ┌▼┌───►┌─┐   ┌─┐
-                //      │B│ if │C│ =>│D│,
-                //      └─┘    ├─┴──►└─┴──────┐
-                //          ┌──┘              │
-                //       ┌──┘                 │
-                //       │                    │
-                //      ┌▼┌───►┌─┐   ┌─┐      │
-                //      │E│ if │F│ =>│G│,     │
-                //      └─┘    ├─┴──►└─┴┐     │
-                //             │        │     │
-                //     }       ▼        ▼     │
-                //     ┌─┐◄───────────────────┘
-                //     │H│
-                //     └─┘
-                //
-                // The order we want is that the scrutinee (A) flows into the first pattern (B),
-                // which flows into the guard (C). Then the guard either flows into the arm body
-                // (D) or into the start of the next arm (E). Finally, the body flows to the end
-                // of the match block (H).
-                //
-                // The subsequent arms follow the same ordering. First we go to the pattern, then
-                // the guard (if present, otherwise it flows straight into the body), then into
-                // the body and then to the end of the match expression.
-                //
-                // The comments below show which edge is being added.
-                self.visit_expr(scrutinee);
-
-                let (guard_exit, arm_end_ids) = arms.iter().fold(
-                    (self.expr_index, vec![]),
-                    |(incoming_edge, mut arm_end_ids), hir::Arm { pat, body, guard, .. }| {
-                        // A -> B, or C -> E
-                        self.drop_ranges.add_control_edge(incoming_edge, self.expr_index + 1);
-                        self.visit_pat(pat);
-                        // B -> C and E -> F are added implicitly due to the traversal order.
-                        match guard {
-                            Some(Guard::If(expr)) => self.visit_expr(expr),
-                            Some(Guard::IfLet(let_expr)) => {
-                                self.visit_let_expr(let_expr);
-                            }
-                            None => (),
-                        }
-                        // Likewise, C -> D and F -> G are added implicitly.
-
-                        // Save C, F, so we can add the other outgoing edge.
-                        let to_next_arm = self.expr_index;
-
-                        // The default edge does not get added since we also have an explicit edge,
-                        // so we also need to add an edge to the next node as well.
-                        //
-                        // This adds C -> D, F -> G
-                        self.drop_ranges.add_control_edge(self.expr_index, self.expr_index + 1);
-                        self.visit_expr(body);
-
-                        // Save the end of the body so we can add the exit edge once we know where
-                        // the exit is.
-                        arm_end_ids.push(self.expr_index);
-
-                        // Pass C to the next iteration, as well as vec![D]
-                        //
-                        // On the last round through, we pass F and vec![D, G] so that we can
-                        // add all the exit edges.
-                        (to_next_arm, arm_end_ids)
-                    },
-                );
-                // F -> H
-                self.drop_ranges.add_control_edge(guard_exit, self.expr_index + 1);
-
-                arm_end_ids.into_iter().for_each(|arm_end| {
-                    // D -> H, G -> H
-                    self.drop_ranges.add_control_edge(arm_end, self.expr_index + 1)
-                });
-            }
-
-            ExprKind::Loop(body, label, ..) => {
-                let loop_begin = self.expr_index + 1;
-                self.label_stack.push((label, loop_begin));
-                if body.stmts.is_empty() && body.expr.is_none() {
-                    // For empty loops we won't have updated self.expr_index after visiting the
-                    // body, meaning we'd get an edge from expr_index to expr_index + 1, but
-                    // instead we want an edge from expr_index + 1 to expr_index + 1.
-                    self.drop_ranges.add_control_edge(loop_begin, loop_begin);
-                } else {
-                    self.visit_block(body);
-                    self.drop_ranges.add_control_edge(self.expr_index, loop_begin);
-                }
-                self.label_stack.pop();
-            }
-            // Find the loop entry by searching through the label stack for either the last entry
-            // (if label is none), or the first entry where the label matches this one. The Loop
-            // case maintains this stack mapping labels to the PostOrderId for the loop entry.
-            ExprKind::Continue(hir::Destination { label, .. }, ..) => self
-                .label_stack
-                .iter()
-                .rev()
-                .find(|(loop_label, _)| label.is_none() || *loop_label == label)
-                .map_or((), |(_, target)| {
-                    self.drop_ranges.add_control_edge(self.expr_index, *target)
-                }),
-
-            ExprKind::Break(destination, value) => {
-                // destination either points to an expression or to a block. We use
-                // find_target_expression_from_destination to use the last expression of the block
-                // if destination points to a block.
-                //
-                // We add an edge to the hir_id of the expression/block we are breaking out of, and
-                // then in process_deferred_edges we will map this hir_id to its PostOrderId, which
-                // will refer to the end of the block due to the post order traversal.
-                if let Ok(target) = self.find_target_expression_from_destination(destination) {
-                    self.drop_ranges.add_control_edge_hir_id(self.expr_index, target)
-                }
-
-                if let Some(value) = value {
-                    self.visit_expr(value);
-                }
-            }
-
-            ExprKind::Become(_call) => bug!("encountered a tail-call inside a generator"),
-
-            ExprKind::Call(f, args) => {
-                self.visit_expr(f);
-                for arg in args {
-                    self.visit_expr(arg);
-                }
-
-                self.handle_uninhabited_return(expr);
-            }
-            ExprKind::MethodCall(_, receiver, exprs, _) => {
-                self.visit_expr(receiver);
-                for expr in exprs {
-                    self.visit_expr(expr);
-                }
-
-                self.handle_uninhabited_return(expr);
-            }
-
-            ExprKind::AddrOf(..)
-            | ExprKind::Array(..)
-            // FIXME(eholk): We probably need special handling for AssignOps. The ScopeTree builder
-            // in region.rs runs both lhs then rhs and rhs then lhs and then sets all yields to be
-            // the latest they show up in either traversal. With the older scope-based
-            // approximation, this was fine, but it's probably not right now. What we probably want
-            // to do instead is still run both orders, but consider anything that showed up as a
-            // yield in either order.
-            | ExprKind::AssignOp(..)
-            | ExprKind::Binary(..)
-            | ExprKind::Block(..)
-            | ExprKind::Cast(..)
-            | ExprKind::Closure { .. }
-            | ExprKind::ConstBlock(..)
-            | ExprKind::DropTemps(..)
-            | ExprKind::Err(_)
-            | ExprKind::Field(..)
-            | ExprKind::Index(..)
-            | ExprKind::InlineAsm(..)
-            | ExprKind::OffsetOf(..)
-            | ExprKind::Let(..)
-            | ExprKind::Lit(..)
-            | ExprKind::Path(..)
-            | ExprKind::Repeat(..)
-            | ExprKind::Ret(..)
-            | ExprKind::Struct(..)
-            | ExprKind::Tup(..)
-            | ExprKind::Type(..)
-            | ExprKind::Unary(..)
-            | ExprKind::Yield(..) => intravisit::walk_expr(self, expr),
-        }
-
-        self.expr_index = self.expr_index + 1;
-        self.drop_ranges.add_node_mapping(expr.hir_id, self.expr_index);
-        self.consume_expr(expr);
-        if let Some(expr) = reinit {
-            self.reinit_expr(expr);
-        }
-    }
-
-    fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) {
-        intravisit::walk_pat(self, pat);
-
-        // Increment expr_count here to match what InteriorVisitor expects.
-        self.expr_index = self.expr_index + 1;
-
-        // Save a node mapping to get better CFG visualization
-        self.drop_ranges.add_node_mapping(pat.hir_id, self.expr_index);
-    }
-}
-
-impl DropRangesBuilder {
-    fn new(
-        tracked_values: impl Iterator<Item = TrackedValue>,
-        hir: Map<'_>,
-        num_exprs: usize,
-    ) -> Self {
-        let mut tracked_value_map = UnordMap::<_, TrackedValueIndex>::default();
-        let mut next = <_>::from(0u32);
-        for value in tracked_values {
-            for_each_consumable(hir, value, |value| {
-                if let std::collections::hash_map::Entry::Vacant(e) = tracked_value_map.entry(value)
-                {
-                    e.insert(next);
-                    next = next + 1;
-                }
-            });
-        }
-        debug!("hir_id_map: {:#?}", tracked_value_map);
-        let num_values = tracked_value_map.len();
-        Self {
-            tracked_value_map,
-            nodes: IndexVec::from_fn_n(|_| NodeInfo::new(num_values), num_exprs + 1),
-            deferred_edges: <_>::default(),
-            post_order_map: <_>::default(),
-        }
-    }
-
-    fn tracked_value_index(&self, tracked_value: TrackedValue) -> TrackedValueIndex {
-        *self.tracked_value_map.get(&tracked_value).unwrap()
-    }
-
-    /// Adds an entry in the mapping from HirIds to PostOrderIds
-    ///
-    /// Needed so that `add_control_edge_hir_id` can work.
-    fn add_node_mapping(&mut self, node_hir_id: HirId, post_order_id: PostOrderId) {
-        self.post_order_map.insert(node_hir_id, post_order_id);
-    }
-
-    /// Like add_control_edge, but uses a hir_id as the target.
-    ///
-    /// This can be used for branches where we do not know the PostOrderId of the target yet,
-    /// such as when handling `break` or `continue`.
-    fn add_control_edge_hir_id(&mut self, from: PostOrderId, to: HirId) {
-        self.deferred_edges.push((from, to));
-    }
-
-    fn drop_at(&mut self, value: TrackedValue, location: PostOrderId) {
-        let value = self.tracked_value_index(value);
-        self.node_mut(location).drops.push(value);
-    }
-
-    fn reinit_at(&mut self, value: TrackedValue, location: PostOrderId) {
-        let value = match self.tracked_value_map.get(&value) {
-            Some(value) => *value,
-            // If there's no value, this is never consumed and therefore is never dropped. We can
-            // ignore this.
-            None => return,
-        };
-        self.node_mut(location).reinits.push(value);
-    }
-
-    /// Looks up PostOrderId for any control edges added by HirId and adds a proper edge for them.
-    ///
-    /// Should be called after visiting the HIR but before solving the control flow, otherwise some
-    /// edges will be missed.
-    fn process_deferred_edges(&mut self) {
-        trace!("processing deferred edges. post_order_map={:#?}", self.post_order_map);
-        let mut edges = vec![];
-        swap(&mut edges, &mut self.deferred_edges);
-        edges.into_iter().for_each(|(from, to)| {
-            trace!("Adding deferred edge from {:?} to {:?}", from, to);
-            let to = *self.post_order_map.get(&to).expect("Expression ID not found");
-            trace!("target edge PostOrderId={:?}", to);
-            self.add_control_edge(from, to)
-        });
-    }
-}
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_propagate.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_propagate.rs
deleted file mode 100644
index 633b478895b..00000000000
--- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_propagate.rs
+++ /dev/null
@@ -1,92 +0,0 @@
-use super::{DropRangesBuilder, PostOrderId};
-use rustc_index::{bit_set::BitSet, IndexVec};
-use std::collections::BTreeMap;
-
-impl DropRangesBuilder {
-    pub fn propagate_to_fixpoint(&mut self) {
-        trace!("before fixpoint: {:#?}", self);
-        let preds = self.compute_predecessors();
-
-        trace!("predecessors: {:#?}", preds.iter_enumerated().collect::<BTreeMap<_, _>>());
-
-        let mut new_state = BitSet::new_empty(self.num_values());
-        let mut changed_nodes = BitSet::new_empty(self.nodes.len());
-        let mut unchanged_mask = BitSet::new_filled(self.nodes.len());
-        changed_nodes.insert(0u32.into());
-
-        let mut propagate = || {
-            let mut changed = false;
-            unchanged_mask.insert_all();
-            for id in self.nodes.indices() {
-                trace!("processing {:?}, changed_nodes: {:?}", id, changed_nodes);
-                // Check if any predecessor has changed, and if not then short-circuit.
-                //
-                // We handle the start node specially, since it doesn't have any predecessors,
-                // but we need to start somewhere.
-                if match id.index() {
-                    0 => !changed_nodes.contains(id),
-                    _ => !preds[id].iter().any(|pred| changed_nodes.contains(*pred)),
-                } {
-                    trace!("short-circuiting because none of {:?} have changed", preds[id]);
-                    unchanged_mask.remove(id);
-                    continue;
-                }
-
-                if id.index() == 0 {
-                    new_state.clear();
-                } else {
-                    // If we are not the start node and we have no predecessors, treat
-                    // everything as dropped because there's no way to get here anyway.
-                    new_state.insert_all();
-                };
-
-                for pred in &preds[id] {
-                    new_state.intersect(&self.nodes[*pred].drop_state);
-                }
-
-                for drop in &self.nodes[id].drops {
-                    new_state.insert(*drop);
-                }
-
-                for reinit in &self.nodes[id].reinits {
-                    new_state.remove(*reinit);
-                }
-
-                if self.nodes[id].drop_state.intersect(&new_state) {
-                    changed_nodes.insert(id);
-                    changed = true;
-                } else {
-                    unchanged_mask.remove(id);
-                }
-            }
-
-            changed_nodes.intersect(&unchanged_mask);
-            changed
-        };
-
-        while propagate() {
-            trace!("drop_state changed, re-running propagation");
-        }
-
-        trace!("after fixpoint: {:#?}", self);
-    }
-
-    fn compute_predecessors(&self) -> IndexVec<PostOrderId, Vec<PostOrderId>> {
-        let mut preds = IndexVec::from_fn_n(|_| vec![], self.nodes.len());
-        for (id, node) in self.nodes.iter_enumerated() {
-            // If the node has no explicit successors, we assume that control
-            // will from this node into the next one.
-            //
-            // If there are successors listed, then we assume that all
-            // possible successors are given and we do not include the default.
-            if node.successors.len() == 0 && id.index() != self.nodes.len() - 1 {
-                preds[id + 1].push(id);
-            } else {
-                for succ in &node.successors {
-                    preds[*succ].push(id);
-                }
-            }
-        }
-        preds
-    }
-}
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs
deleted file mode 100644
index e8d31be79d9..00000000000
--- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/cfg_visualize.rs
+++ /dev/null
@@ -1,96 +0,0 @@
-//! Implementation of GraphWalk for DropRanges so we can visualize the control
-//! flow graph when needed for debugging.
-
-use rustc_graphviz as dot;
-use rustc_hir::{Expr, ExprKind, Node};
-use rustc_middle::ty::TyCtxt;
-
-use super::{DropRangesBuilder, PostOrderId};
-
-/// Writes the CFG for DropRangesBuilder to a .dot file for visualization.
-///
-/// It is not normally called, but is kept around to easily add debugging
-/// code when needed.
-pub(super) fn write_graph_to_file(
-    drop_ranges: &DropRangesBuilder,
-    filename: &str,
-    tcx: TyCtxt<'_>,
-) {
-    dot::render(
-        &DropRangesGraph { drop_ranges, tcx },
-        &mut std::fs::File::create(filename).unwrap(),
-    )
-    .unwrap();
-}
-
-struct DropRangesGraph<'a, 'tcx> {
-    drop_ranges: &'a DropRangesBuilder,
-    tcx: TyCtxt<'tcx>,
-}
-
-impl<'a> dot::GraphWalk<'a> for DropRangesGraph<'_, '_> {
-    type Node = PostOrderId;
-
-    type Edge = (PostOrderId, PostOrderId);
-
-    fn nodes(&'a self) -> dot::Nodes<'a, Self::Node> {
-        self.drop_ranges.nodes.iter_enumerated().map(|(i, _)| i).collect()
-    }
-
-    fn edges(&'a self) -> dot::Edges<'a, Self::Edge> {
-        self.drop_ranges
-            .nodes
-            .iter_enumerated()
-            .flat_map(|(i, node)| {
-                if node.successors.len() == 0 {
-                    vec![(i, i + 1)]
-                } else {
-                    node.successors.iter().map(move |&s| (i, s)).collect()
-                }
-            })
-            .collect()
-    }
-
-    fn source(&'a self, edge: &Self::Edge) -> Self::Node {
-        edge.0
-    }
-
-    fn target(&'a self, edge: &Self::Edge) -> Self::Node {
-        edge.1
-    }
-}
-
-impl<'a> dot::Labeller<'a> for DropRangesGraph<'_, '_> {
-    type Node = PostOrderId;
-
-    type Edge = (PostOrderId, PostOrderId);
-
-    fn graph_id(&'a self) -> dot::Id<'a> {
-        dot::Id::new("drop_ranges").unwrap()
-    }
-
-    fn node_id(&'a self, n: &Self::Node) -> dot::Id<'a> {
-        dot::Id::new(format!("id{}", n.index())).unwrap()
-    }
-
-    fn node_label(&'a self, n: &Self::Node) -> dot::LabelText<'a> {
-        dot::LabelText::LabelStr(
-            format!(
-                "{n:?}: {}",
-                self.drop_ranges
-                    .post_order_map
-                    .iter()
-                    .find(|(_hir_id, &post_order_id)| post_order_id == *n)
-                    .map_or("<unknown>".into(), |(hir_id, _)| format!(
-                        "{}{}",
-                        self.tcx.hir().node_to_string(*hir_id),
-                        match self.tcx.hir().find(*hir_id) {
-                            Some(Node::Expr(Expr { kind: ExprKind::Yield(..), .. })) => " (yield)",
-                            _ => "",
-                        }
-                    ))
-            )
-            .into(),
-        )
-    }
-}
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs
deleted file mode 100644
index e563bd40b65..00000000000
--- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/mod.rs
+++ /dev/null
@@ -1,306 +0,0 @@
-//! Drop range analysis finds the portions of the tree where a value is guaranteed to be dropped
-//! (i.e. moved, uninitialized, etc.). This is used to exclude the types of those values from the
-//! generator type. See `InteriorVisitor::record` for where the results of this analysis are used.
-//!
-//! There are three phases to this analysis:
-//! 1. Use `ExprUseVisitor` to identify the interesting values that are consumed and borrowed.
-//! 2. Use `DropRangeVisitor` to find where the interesting values are dropped or reinitialized,
-//!    and also build a control flow graph.
-//! 3. Use `DropRanges::propagate_to_fixpoint` to flow the dropped/reinitialized information through
-//!    the CFG and find the exact points where we know a value is definitely dropped.
-//!
-//! The end result is a data structure that maps the post-order index of each node in the HIR tree
-//! to a set of values that are known to be dropped at that location.
-
-use self::cfg_build::build_control_flow_graph;
-use self::record_consumed_borrow::find_consumed_and_borrowed;
-use crate::FnCtxt;
-use hir::def_id::DefId;
-use hir::{Body, HirId, HirIdMap, Node};
-use rustc_data_structures::unord::{UnordMap, UnordSet};
-use rustc_hir as hir;
-use rustc_index::bit_set::BitSet;
-use rustc_index::IndexVec;
-use rustc_middle::hir::map::Map;
-use rustc_middle::hir::place::{PlaceBase, PlaceWithHirId};
-use rustc_middle::ty;
-use std::collections::BTreeMap;
-use std::fmt::Debug;
-
-mod cfg_build;
-mod cfg_propagate;
-mod cfg_visualize;
-mod record_consumed_borrow;
-
-pub fn compute_drop_ranges<'a, 'tcx>(
-    fcx: &'a FnCtxt<'a, 'tcx>,
-    def_id: DefId,
-    body: &'tcx Body<'tcx>,
-) -> DropRanges {
-    if fcx.sess().opts.unstable_opts.drop_tracking {
-        let consumed_borrowed_places = find_consumed_and_borrowed(fcx, def_id, body);
-
-        let typeck_results = &fcx.typeck_results.borrow();
-        let num_exprs = fcx.tcx.region_scope_tree(def_id).body_expr_count(body.id()).unwrap_or(0);
-        let (mut drop_ranges, borrowed_temporaries) = build_control_flow_graph(
-            &fcx,
-            typeck_results,
-            fcx.param_env,
-            consumed_borrowed_places,
-            body,
-            num_exprs,
-        );
-
-        drop_ranges.propagate_to_fixpoint();
-
-        debug!("borrowed_temporaries = {borrowed_temporaries:?}");
-        DropRanges {
-            tracked_value_map: drop_ranges.tracked_value_map,
-            nodes: drop_ranges.nodes,
-            borrowed_temporaries: Some(borrowed_temporaries),
-        }
-    } else {
-        // If drop range tracking is not enabled, skip all the analysis and produce an
-        // empty set of DropRanges.
-        DropRanges {
-            tracked_value_map: UnordMap::default(),
-            nodes: IndexVec::new(),
-            borrowed_temporaries: None,
-        }
-    }
-}
-
-/// Applies `f` to consumable node in the HIR subtree pointed to by `place`.
-///
-/// This includes the place itself, and if the place is a reference to a local
-/// variable then `f` is also called on the HIR node for that variable as well.
-///
-/// For example, if `place` points to `foo()`, then `f` is called once for the
-/// result of `foo`. On the other hand, if `place` points to `x` then `f` will
-/// be called both on the `ExprKind::Path` node that represents the expression
-/// as well as the HirId of the local `x` itself.
-fn for_each_consumable(hir: Map<'_>, place: TrackedValue, mut f: impl FnMut(TrackedValue)) {
-    f(place);
-    let node = hir.find(place.hir_id());
-    if let Some(Node::Expr(expr)) = node {
-        match expr.kind {
-            hir::ExprKind::Path(hir::QPath::Resolved(
-                _,
-                hir::Path { res: hir::def::Res::Local(hir_id), .. },
-            )) => {
-                f(TrackedValue::Variable(*hir_id));
-            }
-            _ => (),
-        }
-    }
-}
-
-rustc_index::newtype_index! {
-    #[debug_format = "id({})"]
-    pub struct PostOrderId {}
-}
-
-rustc_index::newtype_index! {
-    #[debug_format = "hidx({})"]
-    pub struct TrackedValueIndex {}
-}
-
-/// Identifies a value whose drop state we need to track.
-#[derive(PartialEq, Eq, Hash, Clone, Copy)]
-enum TrackedValue {
-    /// Represents a named variable, such as a let binding, parameter, or upvar.
-    ///
-    /// The HirId points to the variable's definition site.
-    Variable(HirId),
-    /// A value produced as a result of an expression.
-    ///
-    /// The HirId points to the expression that returns this value.
-    Temporary(HirId),
-}
-
-impl Debug for TrackedValue {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        ty::tls::with_opt(|opt_tcx| {
-            if let Some(tcx) = opt_tcx {
-                write!(f, "{}", tcx.hir().node_to_string(self.hir_id()))
-            } else {
-                match self {
-                    Self::Variable(hir_id) => write!(f, "Variable({hir_id:?})"),
-                    Self::Temporary(hir_id) => write!(f, "Temporary({hir_id:?})"),
-                }
-            }
-        })
-    }
-}
-
-impl TrackedValue {
-    fn hir_id(&self) -> HirId {
-        match self {
-            TrackedValue::Variable(hir_id) | TrackedValue::Temporary(hir_id) => *hir_id,
-        }
-    }
-
-    fn from_place_with_projections_allowed(place_with_id: &PlaceWithHirId<'_>) -> Self {
-        match place_with_id.place.base {
-            PlaceBase::Rvalue | PlaceBase::StaticItem => {
-                TrackedValue::Temporary(place_with_id.hir_id)
-            }
-            PlaceBase::Local(hir_id)
-            | PlaceBase::Upvar(ty::UpvarId { var_path: ty::UpvarPath { hir_id }, .. }) => {
-                TrackedValue::Variable(hir_id)
-            }
-        }
-    }
-}
-
-/// Represents a reason why we might not be able to convert a HirId or Place
-/// into a tracked value.
-#[derive(Debug)]
-enum TrackedValueConversionError {
-    /// Place projects are not currently supported.
-    ///
-    /// The reasoning around these is kind of subtle, so we choose to be more
-    /// conservative around these for now. There is no reason in theory we
-    /// cannot support these, we just have not implemented it yet.
-    PlaceProjectionsNotSupported,
-}
-
-impl TryFrom<&PlaceWithHirId<'_>> for TrackedValue {
-    type Error = TrackedValueConversionError;
-
-    fn try_from(place_with_id: &PlaceWithHirId<'_>) -> Result<Self, Self::Error> {
-        if !place_with_id.place.projections.is_empty() {
-            debug!(
-                "TrackedValue from PlaceWithHirId: {:?} has projections, which are not supported.",
-                place_with_id
-            );
-            return Err(TrackedValueConversionError::PlaceProjectionsNotSupported);
-        }
-
-        Ok(TrackedValue::from_place_with_projections_allowed(place_with_id))
-    }
-}
-
-pub struct DropRanges {
-    tracked_value_map: UnordMap<TrackedValue, TrackedValueIndex>,
-    nodes: IndexVec<PostOrderId, NodeInfo>,
-    borrowed_temporaries: Option<UnordSet<HirId>>,
-}
-
-impl DropRanges {
-    pub fn is_dropped_at(&self, hir_id: HirId, location: usize) -> bool {
-        self.tracked_value_map
-            .get(&TrackedValue::Temporary(hir_id))
-            .or(self.tracked_value_map.get(&TrackedValue::Variable(hir_id)))
-            .cloned()
-            .is_some_and(|tracked_value_id| {
-                self.expect_node(location.into()).drop_state.contains(tracked_value_id)
-            })
-    }
-
-    pub fn is_borrowed_temporary(&self, expr: &hir::Expr<'_>) -> bool {
-        if let Some(b) = &self.borrowed_temporaries { b.contains(&expr.hir_id) } else { true }
-    }
-
-    /// Returns a reference to the NodeInfo for a node, panicking if it does not exist
-    fn expect_node(&self, id: PostOrderId) -> &NodeInfo {
-        &self.nodes[id]
-    }
-}
-
-/// Tracks information needed to compute drop ranges.
-struct DropRangesBuilder {
-    /// The core of DropRangesBuilder is a set of nodes, which each represent
-    /// one expression. We primarily refer to them by their index in a
-    /// post-order traversal of the HIR tree,  since this is what
-    /// generator_interior uses to talk about yield positions.
-    ///
-    /// This IndexVec keeps the relevant details for each node. See the
-    /// NodeInfo struct for more details, but this information includes things
-    /// such as the set of control-flow successors, which variables are dropped
-    /// or reinitialized, and whether each variable has been inferred to be
-    /// known-dropped or potentially reinitialized at each point.
-    nodes: IndexVec<PostOrderId, NodeInfo>,
-    /// We refer to values whose drop state we are tracking by the HirId of
-    /// where they are defined. Within a NodeInfo, however, we store the
-    /// drop-state in a bit vector indexed by a HirIdIndex
-    /// (see NodeInfo::drop_state). The hir_id_map field stores the mapping
-    /// from HirIds to the HirIdIndex that is used to represent that value in
-    /// bitvector.
-    tracked_value_map: UnordMap<TrackedValue, TrackedValueIndex>,
-
-    /// When building the control flow graph, we don't always know the
-    /// post-order index of the target node at the point we encounter it.
-    /// For example, this happens with break and continue. In those cases,
-    /// we store a pair of the PostOrderId of the source and the HirId
-    /// of the target. Once we have gathered all of these edges, we make a
-    /// pass over the set of deferred edges (see process_deferred_edges in
-    /// cfg_build.rs), look up the PostOrderId for the target (since now the
-    /// post-order index for all nodes is known), and add missing control flow
-    /// edges.
-    deferred_edges: Vec<(PostOrderId, HirId)>,
-    /// This maps HirIds of expressions to their post-order index. It is
-    /// used in process_deferred_edges to correctly add back-edges.
-    post_order_map: HirIdMap<PostOrderId>,
-}
-
-impl Debug for DropRangesBuilder {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        f.debug_struct("DropRanges")
-            .field("hir_id_map", &self.tracked_value_map)
-            .field("post_order_maps", &self.post_order_map)
-            .field("nodes", &self.nodes.iter_enumerated().collect::<BTreeMap<_, _>>())
-            .finish()
-    }
-}
-
-/// DropRanges keeps track of what values are definitely dropped at each point in the code.
-///
-/// Values of interest are defined by the hir_id of their place. Locations in code are identified
-/// by their index in the post-order traversal. At its core, DropRanges maps
-/// (hir_id, post_order_id) -> bool, where a true value indicates that the value is definitely
-/// dropped at the point of the node identified by post_order_id.
-impl DropRangesBuilder {
-    /// Returns the number of values (hir_ids) that are tracked
-    fn num_values(&self) -> usize {
-        self.tracked_value_map.len()
-    }
-
-    fn node_mut(&mut self, id: PostOrderId) -> &mut NodeInfo {
-        let size = self.num_values();
-        self.nodes.ensure_contains_elem(id, || NodeInfo::new(size))
-    }
-
-    fn add_control_edge(&mut self, from: PostOrderId, to: PostOrderId) {
-        trace!("adding control edge from {:?} to {:?}", from, to);
-        self.node_mut(from).successors.push(to);
-    }
-}
-
-#[derive(Debug)]
-struct NodeInfo {
-    /// IDs of nodes that can follow this one in the control flow
-    ///
-    /// If the vec is empty, then control proceeds to the next node.
-    successors: Vec<PostOrderId>,
-
-    /// List of hir_ids that are dropped by this node.
-    drops: Vec<TrackedValueIndex>,
-
-    /// List of hir_ids that are reinitialized by this node.
-    reinits: Vec<TrackedValueIndex>,
-
-    /// Set of values that are definitely dropped at this point.
-    drop_state: BitSet<TrackedValueIndex>,
-}
-
-impl NodeInfo {
-    fn new(num_values: usize) -> Self {
-        Self {
-            successors: vec![],
-            drops: vec![],
-            reinits: vec![],
-            drop_state: BitSet::new_filled(num_values),
-        }
-    }
-}
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs b/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs
deleted file mode 100644
index 29413f08012..00000000000
--- a/compiler/rustc_hir_typeck/src/generator_interior/drop_ranges/record_consumed_borrow.rs
+++ /dev/null
@@ -1,242 +0,0 @@
-use super::TrackedValue;
-use crate::{
-    expr_use_visitor::{self, ExprUseVisitor},
-    FnCtxt,
-};
-use hir::{def_id::DefId, Body, HirId, HirIdMap};
-use rustc_data_structures::{fx::FxIndexSet, unord::UnordSet};
-use rustc_hir as hir;
-use rustc_middle::ty::{ParamEnv, TyCtxt};
-use rustc_middle::{
-    hir::place::{PlaceBase, Projection, ProjectionKind},
-    ty::TypeVisitableExt,
-};
-
-pub(super) fn find_consumed_and_borrowed<'a, 'tcx>(
-    fcx: &'a FnCtxt<'a, 'tcx>,
-    def_id: DefId,
-    body: &'tcx Body<'tcx>,
-) -> ConsumedAndBorrowedPlaces {
-    let mut expr_use_visitor = ExprUseDelegate::new(fcx.tcx, fcx.param_env);
-    expr_use_visitor.consume_body(fcx, def_id, body);
-    expr_use_visitor.places
-}
-
-pub(super) struct ConsumedAndBorrowedPlaces {
-    /// Records the variables/expressions that are dropped by a given expression.
-    ///
-    /// The key is the hir-id of the expression, and the value is a set or hir-ids for variables
-    /// or values that are consumed by that expression.
-    ///
-    /// Note that this set excludes "partial drops" -- for example, a statement like `drop(x.y)` is
-    /// not considered a drop of `x`, although it would be a drop of `x.y`.
-    pub(super) consumed: HirIdMap<FxIndexSet<TrackedValue>>,
-
-    /// A set of hir-ids of values or variables that are borrowed at some point within the body.
-    pub(super) borrowed: UnordSet<TrackedValue>,
-
-    /// A set of hir-ids of values or variables that are borrowed at some point within the body.
-    pub(super) borrowed_temporaries: UnordSet<HirId>,
-}
-
-/// Works with ExprUseVisitor to find interesting values for the drop range analysis.
-///
-/// Interesting values are those that are either dropped or borrowed. For dropped values, we also
-/// record the parent expression, which is the point where the drop actually takes place.
-struct ExprUseDelegate<'tcx> {
-    tcx: TyCtxt<'tcx>,
-    param_env: ParamEnv<'tcx>,
-    places: ConsumedAndBorrowedPlaces,
-}
-
-impl<'tcx> ExprUseDelegate<'tcx> {
-    fn new(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>) -> Self {
-        Self {
-            tcx,
-            param_env,
-            places: ConsumedAndBorrowedPlaces {
-                consumed: <_>::default(),
-                borrowed: <_>::default(),
-                borrowed_temporaries: <_>::default(),
-            },
-        }
-    }
-
-    fn consume_body(&mut self, fcx: &'_ FnCtxt<'_, 'tcx>, def_id: DefId, body: &'tcx Body<'tcx>) {
-        // Run ExprUseVisitor to find where values are consumed.
-        ExprUseVisitor::new(
-            self,
-            &fcx.infcx,
-            def_id.expect_local(),
-            fcx.param_env,
-            &fcx.typeck_results.borrow(),
-        )
-        .consume_body(body);
-    }
-
-    fn mark_consumed(&mut self, consumer: HirId, target: TrackedValue) {
-        self.places.consumed.entry(consumer).or_insert_with(|| <_>::default());
-
-        debug!(?consumer, ?target, "mark_consumed");
-        self.places.consumed.get_mut(&consumer).map(|places| places.insert(target));
-    }
-
-    fn borrow_place(&mut self, place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>) {
-        self.places
-            .borrowed
-            .insert(TrackedValue::from_place_with_projections_allowed(place_with_id));
-
-        // Ordinarily a value is consumed by it's parent, but in the special case of a
-        // borrowed RValue, we create a reference that lives as long as the temporary scope
-        // for that expression (typically, the innermost statement, but sometimes the enclosing
-        // block). We record this fact here so that later in generator_interior
-        // we can use the correct scope.
-        //
-        // We special case borrows through a dereference (`&*x`, `&mut *x` where `x` is
-        // some rvalue expression), since these are essentially a copy of a pointer.
-        // In other words, this borrow does not refer to the
-        // temporary (`*x`), but to the referent (whatever `x` is a borrow of).
-        //
-        // We were considering that we might encounter problems down the line if somehow,
-        // some part of the compiler were to look at this result and try to use it to
-        // drive a borrowck-like analysis (this does not currently happen, as of this writing).
-        // But even this should be fine, because the lifetime of the dereferenced reference
-        // found in the rvalue is only significant as an intermediate 'link' to the value we
-        // are producing, and we separately track whether that value is live over a yield.
-        // Example:
-        //
-        // ```notrust
-        // fn identity<T>(x: &mut T) -> &mut T { x }
-        // let a: A = ...;
-        // let y: &'y mut A = &mut *identity(&'a mut a);
-        //                    ^^^^^^^^^^^^^^^^^^^^^^^^^ the borrow we are talking about
-        // ```
-        //
-        // The expression `*identity(...)` is a deref of an rvalue,
-        // where the `identity(...)` (the rvalue) produces a return type
-        // of `&'rv mut A`, where `'a: 'rv`. We then assign this result to
-        // `'y`, resulting in (transitively) `'a: 'y` (i.e., while `y` is in use,
-        // `a` will be considered borrowed). Other parts of the code will ensure
-        // that if `y` is live over a yield, `&'y mut A` appears in the generator
-        // state. If `'y` is live, then any sound region analysis must conclude
-        // that `'a` is also live. So if this causes a bug, blame some other
-        // part of the code!
-        let is_deref = place_with_id
-            .place
-            .projections
-            .iter()
-            .any(|Projection { kind, .. }| *kind == ProjectionKind::Deref);
-
-        if let (false, PlaceBase::Rvalue) = (is_deref, place_with_id.place.base) {
-            self.places.borrowed_temporaries.insert(place_with_id.hir_id);
-        }
-    }
-}
-
-impl<'tcx> expr_use_visitor::Delegate<'tcx> for ExprUseDelegate<'tcx> {
-    fn consume(
-        &mut self,
-        place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
-        diag_expr_id: HirId,
-    ) {
-        let hir = self.tcx.hir();
-        let parent = match hir.opt_parent_id(place_with_id.hir_id) {
-            Some(parent) => parent,
-            None => place_with_id.hir_id,
-        };
-        debug!(
-            "consume {:?}; diag_expr_id={}, using parent {}",
-            place_with_id,
-            hir.node_to_string(diag_expr_id),
-            hir.node_to_string(parent)
-        );
-
-        if let Ok(tracked_value) = place_with_id.try_into() {
-            self.mark_consumed(parent, tracked_value)
-        }
-    }
-
-    fn borrow(
-        &mut self,
-        place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
-        diag_expr_id: HirId,
-        bk: rustc_middle::ty::BorrowKind,
-    ) {
-        debug!(
-            "borrow: place_with_id = {place_with_id:#?}, diag_expr_id={diag_expr_id:#?}, \
-            borrow_kind={bk:#?}"
-        );
-
-        self.borrow_place(place_with_id);
-    }
-
-    fn copy(
-        &mut self,
-        place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
-        _diag_expr_id: HirId,
-    ) {
-        debug!("copy: place_with_id = {place_with_id:?}");
-
-        self.places
-            .borrowed
-            .insert(TrackedValue::from_place_with_projections_allowed(place_with_id));
-
-        // For copied we treat this mostly like a borrow except that we don't add the place
-        // to borrowed_temporaries because the copy is consumed.
-    }
-
-    fn mutate(
-        &mut self,
-        assignee_place: &expr_use_visitor::PlaceWithHirId<'tcx>,
-        diag_expr_id: HirId,
-    ) {
-        debug!("mutate {assignee_place:?}; diag_expr_id={diag_expr_id:?}");
-
-        if assignee_place.place.base == PlaceBase::Rvalue
-            && assignee_place.place.projections.is_empty()
-        {
-            // Assigning to an Rvalue is illegal unless done through a dereference. We would have
-            // already gotten a type error, so we will just return here.
-            return;
-        }
-
-        // If the type being assigned needs dropped, then the mutation counts as a borrow
-        // since it is essentially doing `Drop::drop(&mut x); x = new_value;`.
-        let ty = self.tcx.erase_regions(assignee_place.place.base_ty);
-        if ty.has_infer() {
-            self.tcx.sess.delay_span_bug(
-                self.tcx.hir().span(assignee_place.hir_id),
-                format!("inference variables in {ty}"),
-            );
-        } else if ty.needs_drop(self.tcx, self.param_env) {
-            self.places
-                .borrowed
-                .insert(TrackedValue::from_place_with_projections_allowed(assignee_place));
-        }
-    }
-
-    fn bind(
-        &mut self,
-        binding_place: &expr_use_visitor::PlaceWithHirId<'tcx>,
-        diag_expr_id: HirId,
-    ) {
-        debug!("bind {binding_place:?}; diag_expr_id={diag_expr_id:?}");
-    }
-
-    fn fake_read(
-        &mut self,
-        place_with_id: &expr_use_visitor::PlaceWithHirId<'tcx>,
-        cause: rustc_middle::mir::FakeReadCause,
-        diag_expr_id: HirId,
-    ) {
-        debug!(
-            "fake_read place_with_id={place_with_id:?}; cause={cause:?}; diag_expr_id={diag_expr_id:?}"
-        );
-
-        // fake reads happen in places like the scrutinee of a match expression.
-        // we treat those as a borrow, much like a copy: the idea is that we are
-        // transiently creating a `&T` ref that we can read from to observe the current
-        // value (this `&T` is immediately dropped afterwards).
-        self.borrow_place(place_with_id);
-    }
-}
diff --git a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs b/compiler/rustc_hir_typeck/src/generator_interior/mod.rs
deleted file mode 100644
index 566dc09cdd2..00000000000
--- a/compiler/rustc_hir_typeck/src/generator_interior/mod.rs
+++ /dev/null
@@ -1,711 +0,0 @@
-//! This calculates the types which has storage which lives across a suspension point in a
-//! generator from the perspective of typeck. The actual types used at runtime
-//! is calculated in `rustc_mir_transform::generator` and may be a subset of the
-//! types computed here.
-
-use self::drop_ranges::DropRanges;
-use super::FnCtxt;
-use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
-use rustc_errors::{pluralize, DelayDm};
-use rustc_hir as hir;
-use rustc_hir::def::{CtorKind, DefKind, Res};
-use rustc_hir::def_id::DefId;
-use rustc_hir::hir_id::HirIdSet;
-use rustc_hir::intravisit::{self, Visitor};
-use rustc_hir::{Arm, Expr, ExprKind, Guard, HirId, Pat, PatKind};
-use rustc_infer::infer::{DefineOpaqueTypes, RegionVariableOrigin};
-use rustc_middle::middle::region::{self, Scope, ScopeData, YieldData};
-use rustc_middle::ty::fold::FnMutDelegate;
-use rustc_middle::ty::{self, BoundVariableKind, RvalueScopes, Ty, TyCtxt, TypeVisitableExt};
-use rustc_span::symbol::sym;
-use rustc_span::Span;
-use smallvec::{smallvec, SmallVec};
-
-mod drop_ranges;
-
-struct InteriorVisitor<'a, 'tcx> {
-    fcx: &'a FnCtxt<'a, 'tcx>,
-    region_scope_tree: &'a region::ScopeTree,
-    types: FxIndexSet<ty::GeneratorInteriorTypeCause<'tcx>>,
-    rvalue_scopes: &'a RvalueScopes,
-    expr_count: usize,
-    kind: hir::GeneratorKind,
-    prev_unresolved_span: Option<Span>,
-    linted_values: HirIdSet,
-    drop_ranges: DropRanges,
-}
-
-impl<'a, 'tcx> InteriorVisitor<'a, 'tcx> {
-    fn record(
-        &mut self,
-        ty: Ty<'tcx>,
-        hir_id: HirId,
-        scope: Option<region::Scope>,
-        expr: Option<&'tcx Expr<'tcx>>,
-        source_span: Span,
-    ) {
-        use rustc_span::DUMMY_SP;
-
-        let ty = self.fcx.resolve_vars_if_possible(ty);
-
-        debug!(
-            "attempting to record type ty={:?}; hir_id={:?}; scope={:?}; expr={:?}; source_span={:?}; expr_count={:?}",
-            ty, hir_id, scope, expr, source_span, self.expr_count,
-        );
-
-        let live_across_yield = scope
-            .map(|s| {
-                self.region_scope_tree.yield_in_scope(s).and_then(|yield_data| {
-                    // If we are recording an expression that is the last yield
-                    // in the scope, or that has a postorder CFG index larger
-                    // than the one of all of the yields, then its value can't
-                    // be storage-live (and therefore live) at any of the yields.
-                    //
-                    // See the mega-comment at `yield_in_scope` for a proof.
-
-                    yield_data
-                        .iter()
-                        .find(|yield_data| {
-                            debug!(
-                                "comparing counts yield: {} self: {}, source_span = {:?}",
-                                yield_data.expr_and_pat_count, self.expr_count, source_span
-                            );
-
-                            if self
-                                .is_dropped_at_yield_location(hir_id, yield_data.expr_and_pat_count)
-                            {
-                                debug!("value is dropped at yield point; not recording");
-                                return false;
-                            }
-
-                            // If it is a borrowing happening in the guard,
-                            // it needs to be recorded regardless because they
-                            // do live across this yield point.
-                            yield_data.expr_and_pat_count >= self.expr_count
-                        })
-                        .cloned()
-                })
-            })
-            .unwrap_or_else(|| {
-                Some(YieldData { span: DUMMY_SP, expr_and_pat_count: 0, source: self.kind.into() })
-            });
-
-        if let Some(yield_data) = live_across_yield {
-            debug!(
-                "type in expr = {:?}, scope = {:?}, type = {:?}, count = {}, yield_span = {:?}",
-                expr, scope, ty, self.expr_count, yield_data.span
-            );
-
-            if let Some((unresolved_term, unresolved_type_span)) =
-                self.fcx.first_unresolved_const_or_ty_var(&ty)
-            {
-                // If unresolved type isn't a ty_var then unresolved_type_span is None
-                let span = self
-                    .prev_unresolved_span
-                    .unwrap_or_else(|| unresolved_type_span.unwrap_or(source_span));
-
-                // If we encounter an int/float variable, then inference fallback didn't
-                // finish due to some other error. Don't emit spurious additional errors.
-                if let Some(unresolved_ty) = unresolved_term.ty()
-                    && let ty::Infer(ty::InferTy::IntVar(_) | ty::InferTy::FloatVar(_)) = unresolved_ty.kind()
-                {
-                    self.fcx
-                        .tcx
-                        .sess
-                        .delay_span_bug(span, format!("Encountered var {unresolved_term:?}"));
-                } else {
-                    let note = format!(
-                        "the type is part of the {} because of this {}",
-                        self.kind.descr(),
-                        yield_data.source
-                    );
-
-                    self.fcx
-                        .need_type_info_err_in_generator(self.kind, span, unresolved_term)
-                        .span_note(yield_data.span, note)
-                        .emit();
-                }
-            } else {
-                // Insert the type into the ordered set.
-                let scope_span = scope.map(|s| s.span(self.fcx.tcx, self.region_scope_tree));
-
-                if !self.linted_values.contains(&hir_id) {
-                    check_must_not_suspend_ty(
-                        self.fcx,
-                        ty,
-                        hir_id,
-                        SuspendCheckData {
-                            expr,
-                            source_span,
-                            yield_span: yield_data.span,
-                            plural_len: 1,
-                            ..Default::default()
-                        },
-                    );
-                    self.linted_values.insert(hir_id);
-                }
-
-                self.types.insert(ty::GeneratorInteriorTypeCause {
-                    span: source_span,
-                    ty,
-                    scope_span,
-                    yield_span: yield_data.span,
-                    expr: expr.map(|e| e.hir_id),
-                });
-            }
-        } else {
-            debug!(
-                "no type in expr = {:?}, count = {:?}, span = {:?}",
-                expr,
-                self.expr_count,
-                expr.map(|e| e.span)
-            );
-            if let Some((unresolved_type, unresolved_type_span)) =
-                self.fcx.first_unresolved_const_or_ty_var(&ty)
-            {
-                debug!(
-                    "remained unresolved_type = {:?}, unresolved_type_span: {:?}",
-                    unresolved_type, unresolved_type_span
-                );
-                self.prev_unresolved_span = unresolved_type_span;
-            }
-        }
-    }
-
-    /// If drop tracking is enabled, consult drop_ranges to see if a value is
-    /// known to be dropped at a yield point and therefore can be omitted from
-    /// the generator witness.
-    fn is_dropped_at_yield_location(&self, value_hir_id: HirId, yield_location: usize) -> bool {
-        // short-circuit if drop tracking is not enabled.
-        if !self.fcx.sess().opts.unstable_opts.drop_tracking {
-            return false;
-        }
-
-        self.drop_ranges.is_dropped_at(value_hir_id, yield_location)
-    }
-}
-
-pub fn resolve_interior<'a, 'tcx>(
-    fcx: &'a FnCtxt<'a, 'tcx>,
-    def_id: DefId,
-    body_id: hir::BodyId,
-    interior: Ty<'tcx>,
-    kind: hir::GeneratorKind,
-) {
-    let body = fcx.tcx.hir().body(body_id);
-    let typeck_results = fcx.inh.typeck_results.borrow();
-    let mut visitor = InteriorVisitor {
-        fcx,
-        types: FxIndexSet::default(),
-        region_scope_tree: fcx.tcx.region_scope_tree(def_id),
-        rvalue_scopes: &typeck_results.rvalue_scopes,
-        expr_count: 0,
-        kind,
-        prev_unresolved_span: None,
-        linted_values: <_>::default(),
-        drop_ranges: drop_ranges::compute_drop_ranges(fcx, def_id, body),
-    };
-    intravisit::walk_body(&mut visitor, body);
-
-    // Check that we visited the same amount of expressions as the RegionResolutionVisitor
-    let region_expr_count = fcx.tcx.region_scope_tree(def_id).body_expr_count(body_id).unwrap();
-    assert_eq!(region_expr_count, visitor.expr_count);
-
-    // The types are already kept in insertion order.
-    let types = visitor.types;
-
-    // The types in the generator interior contain lifetimes local to the generator itself,
-    // which should not be exposed outside of the generator. Therefore, we replace these
-    // lifetimes with existentially-bound lifetimes, which reflect the exact value of the
-    // lifetimes not being known by users.
-    //
-    // These lifetimes are used in auto trait impl checking (for example,
-    // if a Sync generator contains an &'α T, we need to check whether &'α T: Sync),
-    // so knowledge of the exact relationships between them isn't particularly important.
-
-    debug!("types in generator {:?}, span = {:?}", types, body.value.span);
-
-    // We want to deduplicate if the lifetimes are the same modulo some non-informative counter.
-    // So, we need to actually do two passes: first by type to anonymize (preserving information
-    // required for diagnostics), then a second pass over all captured types to reassign disjoint
-    // region indices.
-    let mut captured_tys = FxHashSet::default();
-    let type_causes: Vec<_> = types
-        .into_iter()
-        .filter_map(|mut cause| {
-            // Replace all regions inside the generator interior with late bound regions.
-            // Note that each region slot in the types gets a new fresh late bound region,
-            // which means that none of the regions inside relate to any other, even if
-            // typeck had previously found constraints that would cause them to be related.
-
-            let mut counter = 0;
-            let mut mk_bound_region = |kind| {
-                let var = ty::BoundVar::from_u32(counter);
-                counter += 1;
-                ty::BoundRegion { var, kind }
-            };
-            let ty = fcx.normalize(cause.span, cause.ty);
-            let ty = fcx.tcx.fold_regions(ty, |region, current_depth| {
-                let br = match region.kind() {
-                    ty::ReVar(vid) => {
-                        let origin = fcx.region_var_origin(vid);
-                        match origin {
-                            RegionVariableOrigin::EarlyBoundRegion(span, _) => {
-                                mk_bound_region(ty::BrAnon(Some(span)))
-                            }
-                            _ => mk_bound_region(ty::BrAnon(None)),
-                        }
-                    }
-                    ty::ReEarlyBound(region) => {
-                        mk_bound_region(ty::BrNamed(region.def_id, region.name))
-                    }
-                    ty::ReLateBound(_, ty::BoundRegion { kind, .. })
-                    | ty::ReFree(ty::FreeRegion { bound_region: kind, .. }) => match kind {
-                        ty::BoundRegionKind::BrAnon(span) => mk_bound_region(ty::BrAnon(span)),
-                        ty::BoundRegionKind::BrNamed(def_id, sym) => {
-                            mk_bound_region(ty::BrNamed(def_id, sym))
-                        }
-                        ty::BoundRegionKind::BrEnv => mk_bound_region(ty::BrAnon(None)),
-                    },
-                    _ => mk_bound_region(ty::BrAnon(None)),
-                };
-                let r = ty::Region::new_late_bound(fcx.tcx, current_depth, br);
-                r
-            });
-            captured_tys.insert(ty).then(|| {
-                cause.ty = ty;
-                cause
-            })
-        })
-        .collect();
-
-    let mut bound_vars: SmallVec<[BoundVariableKind; 4]> = smallvec![];
-    let mut counter = 0;
-    // Optimization: If there is only one captured type, then we don't actually
-    // need to fold and reindex (since the first type doesn't change).
-    let type_causes = if captured_tys.len() > 0 {
-        // Optimization: Use `replace_escaping_bound_vars_uncached` instead of
-        // `fold_regions`, since we only have late bound regions, and it skips
-        // types without bound regions.
-        fcx.tcx.replace_escaping_bound_vars_uncached(
-            type_causes,
-            FnMutDelegate {
-                regions: &mut |br| {
-                    let kind = br.kind;
-                    let var = ty::BoundVar::from_usize(bound_vars.len());
-                    bound_vars.push(ty::BoundVariableKind::Region(kind));
-                    counter += 1;
-                    ty::Region::new_late_bound(
-                        fcx.tcx,
-                        ty::INNERMOST,
-                        ty::BoundRegion { var, kind },
-                    )
-                },
-                types: &mut |b| bug!("unexpected bound ty in binder: {b:?}"),
-                consts: &mut |b, ty| bug!("unexpected bound ct in binder: {b:?} {ty}"),
-            },
-        )
-    } else {
-        type_causes
-    };
-
-    // Extract type components to build the witness type.
-    let type_list = fcx.tcx.mk_type_list_from_iter(type_causes.iter().map(|cause| cause.ty));
-    let bound_vars = fcx.tcx.mk_bound_variable_kinds(&bound_vars);
-    let witness =
-        Ty::new_generator_witness(fcx.tcx, ty::Binder::bind_with_vars(type_list, bound_vars));
-
-    drop(typeck_results);
-    // Store the generator types and spans into the typeck results for this generator.
-    fcx.inh.typeck_results.borrow_mut().generator_interior_types =
-        ty::Binder::bind_with_vars(type_causes, bound_vars);
-
-    debug!(
-        "types in generator after region replacement {:?}, span = {:?}",
-        witness, body.value.span
-    );
-
-    // Unify the type variable inside the generator with the new witness
-    match fcx.at(&fcx.misc(body.value.span), fcx.param_env).eq(
-        DefineOpaqueTypes::No,
-        interior,
-        witness,
-    ) {
-        Ok(ok) => fcx.register_infer_ok_obligations(ok),
-        _ => bug!("failed to relate {interior} and {witness}"),
-    }
-}
-
-// This visitor has to have the same visit_expr calls as RegionResolutionVisitor in
-// librustc_middle/middle/region.rs since `expr_count` is compared against the results
-// there.
-impl<'a, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'tcx> {
-    fn visit_arm(&mut self, arm: &'tcx Arm<'tcx>) {
-        let Arm { guard, pat, body, .. } = arm;
-        self.visit_pat(pat);
-        if let Some(ref g) = guard {
-            {
-                // If there is a guard, we need to count all variables bound in the pattern as
-                // borrowed for the entire guard body, regardless of whether they are accessed.
-                // We do this by walking the pattern bindings and recording `&T` for any `x: T`
-                // that is bound.
-
-                struct ArmPatCollector<'a, 'b, 'tcx> {
-                    interior_visitor: &'a mut InteriorVisitor<'b, 'tcx>,
-                    scope: Scope,
-                }
-
-                impl<'a, 'b, 'tcx> Visitor<'tcx> for ArmPatCollector<'a, 'b, 'tcx> {
-                    fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) {
-                        intravisit::walk_pat(self, pat);
-                        if let PatKind::Binding(_, id, ident, ..) = pat.kind {
-                            let ty =
-                                self.interior_visitor.fcx.typeck_results.borrow().node_type(id);
-                            let tcx = self.interior_visitor.fcx.tcx;
-                            let ty = Ty::new_ref(
-                                tcx,
-                                // Use `ReErased` as `resolve_interior` is going to replace all the
-                                // regions anyway.
-                                tcx.lifetimes.re_erased,
-                                ty::TypeAndMut { ty, mutbl: hir::Mutability::Not },
-                            );
-                            self.interior_visitor.record(
-                                ty,
-                                id,
-                                Some(self.scope),
-                                None,
-                                ident.span,
-                            );
-                        }
-                    }
-                }
-
-                ArmPatCollector {
-                    interior_visitor: self,
-                    scope: Scope { id: g.body().hir_id.local_id, data: ScopeData::Node },
-                }
-                .visit_pat(pat);
-            }
-
-            match g {
-                Guard::If(ref e) => {
-                    self.visit_expr(e);
-                }
-                Guard::IfLet(ref l) => {
-                    self.visit_let_expr(l);
-                }
-            }
-        }
-        self.visit_expr(body);
-    }
-
-    fn visit_pat(&mut self, pat: &'tcx Pat<'tcx>) {
-        intravisit::walk_pat(self, pat);
-
-        self.expr_count += 1;
-
-        if let PatKind::Binding(..) = pat.kind {
-            let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id).unwrap();
-            let ty = self.fcx.typeck_results.borrow().pat_ty(pat);
-            self.record(ty, pat.hir_id, Some(scope), None, pat.span);
-        }
-    }
-
-    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
-        match &expr.kind {
-            ExprKind::Call(callee, args) => match &callee.kind {
-                ExprKind::Path(qpath) => {
-                    let res = self.fcx.typeck_results.borrow().qpath_res(qpath, callee.hir_id);
-                    match res {
-                        // Direct calls never need to keep the callee `ty::FnDef`
-                        // ZST in a temporary, so skip its type, just in case it
-                        // can significantly complicate the generator type.
-                        Res::Def(
-                            DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(_, CtorKind::Fn),
-                            _,
-                        ) => {
-                            // NOTE(eddyb) this assumes a path expression has
-                            // no nested expressions to keep track of.
-                            self.expr_count += 1;
-
-                            // Record the rest of the call expression normally.
-                            for arg in *args {
-                                self.visit_expr(arg);
-                            }
-                        }
-                        _ => intravisit::walk_expr(self, expr),
-                    }
-                }
-                _ => intravisit::walk_expr(self, expr),
-            },
-            _ => intravisit::walk_expr(self, expr),
-        }
-
-        self.expr_count += 1;
-
-        debug!("is_borrowed_temporary: {:?}", self.drop_ranges.is_borrowed_temporary(expr));
-
-        let ty = self.fcx.typeck_results.borrow().expr_ty_adjusted_opt(expr);
-
-        // Typically, the value produced by an expression is consumed by its parent in some way,
-        // so we only have to check if the parent contains a yield (note that the parent may, for
-        // example, store the value into a local variable, but then we already consider local
-        // variables to be live across their scope).
-        //
-        // However, in the case of temporary values, we are going to store the value into a
-        // temporary on the stack that is live for the current temporary scope and then return a
-        // reference to it. That value may be live across the entire temporary scope.
-        //
-        // There's another subtlety: if the type has an observable drop, it must be dropped after
-        // the yield, even if it's not borrowed or referenced after the yield. Ideally this would
-        // *only* happen for types with observable drop, not all types which wrap them, but that
-        // doesn't match the behavior of MIR borrowck and causes ICEs. See the FIXME comment in
-        // tests/ui/generator/drop-tracking-parent-expression.rs.
-        let scope = if self.drop_ranges.is_borrowed_temporary(expr)
-            || ty.map_or(true, |ty| {
-                // Avoid ICEs in needs_drop.
-                let ty = self.fcx.resolve_vars_if_possible(ty);
-                let ty = self.fcx.tcx.erase_regions(ty);
-                if ty.has_infer() {
-                    self.fcx
-                        .tcx
-                        .sess
-                        .delay_span_bug(expr.span, format!("inference variables in {ty}"));
-                    true
-                } else {
-                    ty.needs_drop(self.fcx.tcx, self.fcx.param_env)
-                }
-            }) {
-            self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
-        } else {
-            let parent_expr = self
-                .fcx
-                .tcx
-                .hir()
-                .parent_iter(expr.hir_id)
-                .find(|(_, node)| matches!(node, hir::Node::Expr(_)))
-                .map(|(id, _)| id);
-            debug!("parent_expr: {:?}", parent_expr);
-            match parent_expr {
-                Some(parent) => Some(Scope { id: parent.local_id, data: ScopeData::Node }),
-                None => {
-                    self.rvalue_scopes.temporary_scope(self.region_scope_tree, expr.hir_id.local_id)
-                }
-            }
-        };
-
-        // If there are adjustments, then record the final type --
-        // this is the actual value that is being produced.
-        if let Some(adjusted_ty) = ty {
-            self.record(adjusted_ty, expr.hir_id, scope, Some(expr), expr.span);
-        }
-
-        // Also record the unadjusted type (which is the only type if
-        // there are no adjustments). The reason for this is that the
-        // unadjusted value is sometimes a "temporary" that would wind
-        // up in a MIR temporary.
-        //
-        // As an example, consider an expression like `vec![].push(x)`.
-        // Here, the `vec![]` would wind up MIR stored into a
-        // temporary variable `t` which we can borrow to invoke
-        // `<Vec<_>>::push(&mut t, x)`.
-        //
-        // Note that an expression can have many adjustments, and we
-        // are just ignoring those intermediate types. This is because
-        // those intermediate values are always linearly "consumed" by
-        // the other adjustments, and hence would never be directly
-        // captured in the MIR.
-        //
-        // (Note that this partly relies on the fact that the `Deref`
-        // traits always return references, which means their content
-        // can be reborrowed without needing to spill to a temporary.
-        // If this were not the case, then we could conceivably have
-        // to create intermediate temporaries.)
-        //
-        // The type table might not have information for this expression
-        // if it is in a malformed scope. (#66387)
-        if let Some(ty) = self.fcx.typeck_results.borrow().expr_ty_opt(expr) {
-            self.record(ty, expr.hir_id, scope, Some(expr), expr.span);
-        } else {
-            self.fcx.tcx.sess.delay_span_bug(expr.span, "no type for node");
-        }
-    }
-}
-
-#[derive(Default)]
-struct SuspendCheckData<'a, 'tcx> {
-    expr: Option<&'tcx Expr<'tcx>>,
-    source_span: Span,
-    yield_span: Span,
-    descr_pre: &'a str,
-    descr_post: &'a str,
-    plural_len: usize,
-}
-
-// Returns whether it emitted a diagnostic or not
-// Note that this fn and the proceeding one are based on the code
-// for creating must_use diagnostics
-//
-// Note that this technique was chosen over things like a `Suspend` marker trait
-// as it is simpler and has precedent in the compiler
-fn check_must_not_suspend_ty<'tcx>(
-    fcx: &FnCtxt<'_, 'tcx>,
-    ty: Ty<'tcx>,
-    hir_id: HirId,
-    data: SuspendCheckData<'_, 'tcx>,
-) -> bool {
-    if ty.is_unit()
-    // FIXME: should this check `Ty::is_inhabited_from`. This query is not available in this stage
-    // of typeck (before ReVar and RePlaceholder are removed), but may remove noise, like in
-    // `must_use`
-    // || !ty.is_inhabited_from(fcx.tcx, fcx.tcx.parent_module(hir_id).to_def_id(), fcx.param_env)
-    {
-        return false;
-    }
-
-    let plural_suffix = pluralize!(data.plural_len);
-
-    debug!("Checking must_not_suspend for {}", ty);
-
-    match *ty.kind() {
-        ty::Adt(..) if ty.is_box() => {
-            let boxed_ty = ty.boxed_ty();
-            let descr_pre = &format!("{}boxed ", data.descr_pre);
-            check_must_not_suspend_ty(fcx, boxed_ty, hir_id, SuspendCheckData { descr_pre, ..data })
-        }
-        ty::Adt(def, _) => check_must_not_suspend_def(fcx.tcx, def.did(), hir_id, data),
-        // FIXME: support adding the attribute to TAITs
-        ty::Alias(ty::Opaque, ty::AliasTy { def_id: def, .. }) => {
-            let mut has_emitted = false;
-            for &(predicate, _) in fcx.tcx.explicit_item_bounds(def).skip_binder() {
-                // We only look at the `DefId`, so it is safe to skip the binder here.
-                if let ty::ClauseKind::Trait(ref poly_trait_predicate) =
-                    predicate.kind().skip_binder()
-                {
-                    let def_id = poly_trait_predicate.trait_ref.def_id;
-                    let descr_pre = &format!("{}implementer{} of ", data.descr_pre, plural_suffix);
-                    if check_must_not_suspend_def(
-                        fcx.tcx,
-                        def_id,
-                        hir_id,
-                        SuspendCheckData { descr_pre, ..data },
-                    ) {
-                        has_emitted = true;
-                        break;
-                    }
-                }
-            }
-            has_emitted
-        }
-        ty::Dynamic(binder, _, _) => {
-            let mut has_emitted = false;
-            for predicate in binder.iter() {
-                if let ty::ExistentialPredicate::Trait(ref trait_ref) = predicate.skip_binder() {
-                    let def_id = trait_ref.def_id;
-                    let descr_post = &format!(" trait object{}{}", plural_suffix, data.descr_post);
-                    if check_must_not_suspend_def(
-                        fcx.tcx,
-                        def_id,
-                        hir_id,
-                        SuspendCheckData { descr_post, ..data },
-                    ) {
-                        has_emitted = true;
-                        break;
-                    }
-                }
-            }
-            has_emitted
-        }
-        ty::Tuple(fields) => {
-            let mut has_emitted = false;
-            let comps = match data.expr.map(|e| &e.kind) {
-                Some(hir::ExprKind::Tup(comps)) if comps.len() == fields.len() => Some(comps),
-                _ => None,
-            };
-            for (i, ty) in fields.iter().enumerate() {
-                let descr_post = &format!(" in tuple element {i}");
-                let span = comps.and_then(|c| c.get(i)).map(|e| e.span).unwrap_or(data.source_span);
-                if check_must_not_suspend_ty(
-                    fcx,
-                    ty,
-                    hir_id,
-                    SuspendCheckData {
-                        descr_post,
-                        expr: comps.and_then(|comps| comps.get(i)),
-                        source_span: span,
-                        ..data
-                    },
-                ) {
-                    has_emitted = true;
-                }
-            }
-            has_emitted
-        }
-        ty::Array(ty, len) => {
-            let descr_pre = &format!("{}array{} of ", data.descr_pre, plural_suffix);
-            let target_usize =
-                len.try_eval_target_usize(fcx.tcx, fcx.param_env).unwrap_or(0) as usize;
-            let plural_len = target_usize.saturating_add(1);
-            check_must_not_suspend_ty(
-                fcx,
-                ty,
-                hir_id,
-                SuspendCheckData { descr_pre, plural_len, ..data },
-            )
-        }
-        // If drop tracking is enabled, we want to look through references, since the referent
-        // may not be considered live across the await point.
-        ty::Ref(_region, ty, _mutability) if fcx.sess().opts.unstable_opts.drop_tracking => {
-            let descr_pre = &format!("{}reference{} to ", data.descr_pre, plural_suffix);
-            check_must_not_suspend_ty(fcx, ty, hir_id, SuspendCheckData { descr_pre, ..data })
-        }
-        _ => false,
-    }
-}
-
-fn check_must_not_suspend_def(
-    tcx: TyCtxt<'_>,
-    def_id: DefId,
-    hir_id: HirId,
-    data: SuspendCheckData<'_, '_>,
-) -> bool {
-    if let Some(attr) = tcx.get_attr(def_id, sym::must_not_suspend) {
-        tcx.struct_span_lint_hir(
-            rustc_session::lint::builtin::MUST_NOT_SUSPEND,
-            hir_id,
-            data.source_span,
-            DelayDm(|| {
-                format!(
-                    "{}`{}`{} held across a suspend point, but should not be",
-                    data.descr_pre,
-                    tcx.def_path_str(def_id),
-                    data.descr_post,
-                )
-            }),
-            |lint| {
-                // add span pointing to the offending yield/await
-                lint.span_label(data.yield_span, "the value is held across this suspend point");
-
-                // Add optional reason note
-                if let Some(note) = attr.value_str() {
-                    // FIXME(guswynn): consider formatting this better
-                    lint.span_note(data.source_span, note.to_string());
-                }
-
-                // Add some quick suggestions on what to do
-                // FIXME: can `drop` work as a suggestion here as well?
-                lint.span_help(
-                    data.source_span,
-                    "consider using a block (`{ ... }`) \
-                    to shrink the value's scope, ending before the suspend point",
-                );
-
-                lint
-            },
-        );
-
-        true
-    } else {
-        false
-    }
-}
diff --git a/compiler/rustc_hir_typeck/src/lib.rs b/compiler/rustc_hir_typeck/src/lib.rs
index f17f1d14bf3..6873382c4ac 100644
--- a/compiler/rustc_hir_typeck/src/lib.rs
+++ b/compiler/rustc_hir_typeck/src/lib.rs
@@ -32,7 +32,6 @@ pub mod expr_use_visitor;
 mod fallback;
 mod fn_ctxt;
 mod gather_locals;
-mod generator_interior;
 mod inherited;
 mod intrinsicck;
 mod mem_categorization;
diff --git a/compiler/rustc_hir_typeck/src/mem_categorization.rs b/compiler/rustc_hir_typeck/src/mem_categorization.rs
index 7fb1dc2347e..337d12b2d51 100644
--- a/compiler/rustc_hir_typeck/src/mem_categorization.rs
+++ b/compiler/rustc_hir_typeck/src/mem_categorization.rs
@@ -464,7 +464,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
         // Opaque types can't have field projections, but we can instead convert
         // the current place in-place (heh) to the hidden type, and then apply all
         // follow up projections on that.
-        if node_ty != place_ty && place_ty.has_opaque_types() {
+        if node_ty != place_ty && matches!(place_ty.kind(), ty::Alias(ty::Opaque, ..)) {
             projections.push(Projection { kind: ProjectionKind::OpaqueCast, ty: node_ty });
         }
         projections.push(Projection { kind, ty });
@@ -557,10 +557,7 @@ impl<'a, 'tcx> MemCategorizationContext<'a, 'tcx> {
                 Ok(adt_def.variant_index_with_ctor_id(variant_ctor_id))
             }
             Res::Def(DefKind::Ctor(CtorOf::Struct, ..), _)
-            | Res::Def(
-                DefKind::Struct | DefKind::Union | DefKind::TyAlias { .. } | DefKind::AssocTy,
-                _,
-            )
+            | Res::Def(DefKind::Struct | DefKind::Union | DefKind::TyAlias | DefKind::AssocTy, _)
             | Res::SelfCtor(..)
             | Res::SelfTyParam { .. }
             | Res::SelfTyAlias { .. } => {
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index ba469bd029d..4d641390368 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -41,6 +41,7 @@ use rustc_hir::intravisit::{self, Visitor};
 use rustc_infer::infer::UpvarRegion;
 use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection, ProjectionKind};
 use rustc_middle::mir::FakeReadCause;
+use rustc_middle::traits::ObligationCauseCode;
 use rustc_middle::ty::{
     self, ClosureSizeProfileData, Ty, TyCtxt, TypeckResults, UpvarArgs, UpvarCapture,
 };
@@ -295,6 +296,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let final_upvar_tys = self.final_upvar_tys(closure_def_id);
         debug!(?closure_hir_id, ?args, ?final_upvar_tys);
 
+        if self.tcx.features().unsized_locals || self.tcx.features().unsized_fn_params {
+            for capture in
+                self.typeck_results.borrow().closure_min_captures_flattened(closure_def_id)
+            {
+                if let UpvarCapture::ByValue = capture.info.capture_kind {
+                    self.require_type_is_sized(
+                        capture.place.ty(),
+                        capture.get_path_span(self.tcx),
+                        ObligationCauseCode::SizedClosureCapture(closure_def_id),
+                    );
+                }
+            }
+        }
+
         // Build a tuple (U0..Un) of the final upvar types U0..Un
         // and unify the upvar tuple type in the closure with it:
         let final_tupled_upvars_type = Ty::new_tup(self.tcx, &final_upvar_tys);
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 2fe41c1197f..9c16b486dbc 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -63,7 +63,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         wbcx.visit_coercion_casts();
         wbcx.visit_user_provided_tys();
         wbcx.visit_user_provided_sigs();
-        wbcx.visit_generator_interior_types();
+        wbcx.visit_generator_interior();
         wbcx.visit_offset_of_container_types();
 
         wbcx.typeck_results.rvalue_scopes =
@@ -538,11 +538,9 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         );
     }
 
-    fn visit_generator_interior_types(&mut self) {
+    fn visit_generator_interior(&mut self) {
         let fcx_typeck_results = self.fcx.typeck_results.borrow();
         assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
-        self.typeck_results.generator_interior_types =
-            fcx_typeck_results.generator_interior_types.clone();
         self.tcx().with_stable_hashing_context(move |ref hcx| {
             for (&expr_def_id, predicates) in
                 fcx_typeck_results.generator_interior_predicates.to_sorted(hcx, false).into_iter()
diff --git a/compiler/rustc_incremental/src/lib.rs b/compiler/rustc_incremental/src/lib.rs
index b9171fad55b..220ea194a6d 100644
--- a/compiler/rustc_incremental/src/lib.rs
+++ b/compiler/rustc_incremental/src/lib.rs
@@ -28,8 +28,8 @@ pub use persist::load_query_result_cache;
 pub use persist::prepare_session_directory;
 pub use persist::save_dep_graph;
 pub use persist::save_work_product_index;
+pub use persist::setup_dep_graph;
 pub use persist::LoadResult;
-pub use persist::{build_dep_graph, load_dep_graph, DepGraphFuture};
 
 use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_fluent_macro::fluent_messages;
diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs
index 25e694fa1c1..2310d0b12ef 100644
--- a/compiler/rustc_incremental/src/persist/load.rs
+++ b/compiler/rustc_incremental/src/persist/load.rs
@@ -3,17 +3,19 @@
 use crate::errors;
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::unord::UnordMap;
-use rustc_middle::dep_graph::{DepsType, SerializedDepGraph, WorkProductMap};
+use rustc_middle::dep_graph::{DepGraph, DepsType, SerializedDepGraph, WorkProductMap};
 use rustc_middle::query::on_disk_cache::OnDiskCache;
 use rustc_serialize::opaque::MemDecoder;
 use rustc_serialize::Decodable;
 use rustc_session::config::IncrementalStateAssertion;
-use rustc_session::Session;
+use rustc_session::{Session, StableCrateId};
+use rustc_span::{ErrorGuaranteed, Symbol};
 use std::path::{Path, PathBuf};
 
 use super::data::*;
 use super::file_format;
 use super::fs::*;
+use super::save::build_dep_graph;
 use super::work_product;
 
 #[derive(Debug)]
@@ -72,21 +74,12 @@ impl<T: Default> LoadResult<T> {
 }
 
 fn load_data(path: &Path, sess: &Session) -> LoadResult<(Mmap, usize)> {
-    load_data_no_sess(
+    match file_format::read_file(
         path,
         sess.opts.unstable_opts.incremental_info,
         sess.is_nightly_build(),
         sess.cfg_version,
-    )
-}
-
-fn load_data_no_sess(
-    path: &Path,
-    report_incremental_info: bool,
-    is_nightly_build: bool,
-    cfg_version: &'static str,
-) -> LoadResult<(Mmap, usize)> {
-    match file_format::read_file(path, report_incremental_info, is_nightly_build, cfg_version) {
+    ) {
         Ok(Some(data_and_pos)) => LoadResult::Ok { data: data_and_pos },
         Ok(None) => {
             // The file either didn't exist or was produced by an incompatible
@@ -102,39 +95,12 @@ fn delete_dirty_work_product(sess: &Session, swp: SerializedWorkProduct) {
     work_product::delete_workproduct_files(sess, &swp.work_product);
 }
 
-/// Either a result that has already be computed or a
-/// handle that will let us wait until it is computed
-/// by a background thread.
-pub enum MaybeAsync<T> {
-    Sync(T),
-    Async(std::thread::JoinHandle<T>),
-}
-
-impl<T> MaybeAsync<LoadResult<T>> {
-    /// Accesses the data returned in [`LoadResult::Ok`] in an asynchronous way if possible.
-    pub fn open(self) -> LoadResult<T> {
-        match self {
-            MaybeAsync::Sync(result) => result,
-            MaybeAsync::Async(handle) => {
-                handle.join().unwrap_or_else(|e| LoadResult::DecodeIncrCache(e))
-            }
-        }
-    }
-}
-
-/// An asynchronous type for computing the dependency graph.
-pub type DepGraphFuture = MaybeAsync<LoadResult<(SerializedDepGraph, WorkProductMap)>>;
-
-/// Launch a thread and load the dependency graph in the background.
-pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
-    // Since `sess` isn't `Sync`, we perform all accesses to `sess`
-    // before we fire the background thread.
-
+fn load_dep_graph(sess: &Session) -> LoadResult<(SerializedDepGraph, WorkProductMap)> {
     let prof = sess.prof.clone();
 
     if sess.opts.incremental.is_none() {
         // No incremental compilation.
-        return MaybeAsync::Sync(LoadResult::Ok { data: Default::default() });
+        return LoadResult::Ok { data: Default::default() };
     }
 
     let _timer = sess.prof.generic_activity("incr_comp_prepare_load_dep_graph");
@@ -142,7 +108,6 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
     // Calling `sess.incr_comp_session_dir()` will panic if `sess.opts.incremental.is_none()`.
     // Fortunately, we just checked that this isn't the case.
     let path = dep_graph_path(&sess);
-    let report_incremental_info = sess.opts.unstable_opts.incremental_info;
     let expected_hash = sess.opts.dep_tracking_hash(false);
 
     let mut prev_work_products = UnordMap::default();
@@ -180,40 +145,35 @@ pub fn load_dep_graph(sess: &Session) -> DepGraphFuture {
         }
     }
 
-    let is_nightly_build = sess.is_nightly_build();
-    let cfg_version = sess.cfg_version;
-
-    MaybeAsync::Async(std::thread::spawn(move || {
-        let _prof_timer = prof.generic_activity("incr_comp_load_dep_graph");
+    let _prof_timer = prof.generic_activity("incr_comp_load_dep_graph");
 
-        match load_data_no_sess(&path, report_incremental_info, is_nightly_build, cfg_version) {
-            LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
-            LoadResult::LoadDepGraph(path, err) => LoadResult::LoadDepGraph(path, err),
-            LoadResult::DecodeIncrCache(err) => LoadResult::DecodeIncrCache(err),
-            LoadResult::Ok { data: (bytes, start_pos) } => {
-                let mut decoder = MemDecoder::new(&bytes, start_pos);
-                let prev_commandline_args_hash = u64::decode(&mut decoder);
+    match load_data(&path, sess) {
+        LoadResult::DataOutOfDate => LoadResult::DataOutOfDate,
+        LoadResult::LoadDepGraph(path, err) => LoadResult::LoadDepGraph(path, err),
+        LoadResult::DecodeIncrCache(err) => LoadResult::DecodeIncrCache(err),
+        LoadResult::Ok { data: (bytes, start_pos) } => {
+            let mut decoder = MemDecoder::new(&bytes, start_pos);
+            let prev_commandline_args_hash = u64::decode(&mut decoder);
 
-                if prev_commandline_args_hash != expected_hash {
-                    if report_incremental_info {
-                        eprintln!(
-                            "[incremental] completely ignoring cache because of \
+            if prev_commandline_args_hash != expected_hash {
+                if sess.opts.unstable_opts.incremental_info {
+                    eprintln!(
+                        "[incremental] completely ignoring cache because of \
                                     differing commandline arguments"
-                        );
-                    }
-                    // We can't reuse the cache, purge it.
-                    debug!("load_dep_graph_new: differing commandline arg hashes");
-
-                    // No need to do any further work
-                    return LoadResult::DataOutOfDate;
+                    );
                 }
+                // We can't reuse the cache, purge it.
+                debug!("load_dep_graph_new: differing commandline arg hashes");
 
-                let dep_graph = SerializedDepGraph::decode::<DepsType>(&mut decoder);
-
-                LoadResult::Ok { data: (dep_graph, prev_work_products) }
+                // No need to do any further work
+                return LoadResult::DataOutOfDate;
             }
+
+            let dep_graph = SerializedDepGraph::decode::<DepsType>(&mut decoder);
+
+            LoadResult::Ok { data: (dep_graph, prev_work_products) }
         }
-    }))
+    }
 }
 
 /// Attempts to load the query result cache from disk
@@ -235,3 +195,35 @@ pub fn load_query_result_cache(sess: &Session) -> Option<OnDiskCache<'_>> {
         _ => Some(OnDiskCache::new_empty(sess.source_map())),
     }
 }
+
+/// Setups the dependency graph by loading an existing graph from disk and set up streaming of a
+/// new graph to an incremental session directory.
+pub fn setup_dep_graph(
+    sess: &Session,
+    crate_name: Symbol,
+    stable_crate_id: StableCrateId,
+) -> Result<DepGraph, ErrorGuaranteed> {
+    // `load_dep_graph` can only be called after `prepare_session_directory`.
+    prepare_session_directory(sess, crate_name, stable_crate_id)?;
+
+    let res = sess.opts.build_dep_graph().then(|| load_dep_graph(sess));
+
+    if sess.opts.incremental.is_some() {
+        sess.time("incr_comp_garbage_collect_session_directories", || {
+            if let Err(e) = garbage_collect_session_directories(sess) {
+                warn!(
+                    "Error while trying to garbage collect incremental \
+                     compilation cache directory: {}",
+                    e
+                );
+            }
+        });
+    }
+
+    Ok(res
+        .and_then(|result| {
+            let (prev_graph, prev_work_products) = result.open(sess);
+            build_dep_graph(sess, prev_graph, prev_work_products)
+        })
+        .unwrap_or_else(DepGraph::new_disabled))
+}
diff --git a/compiler/rustc_incremental/src/persist/mod.rs b/compiler/rustc_incremental/src/persist/mod.rs
index 1336189bc0d..fdecaca5a2d 100644
--- a/compiler/rustc_incremental/src/persist/mod.rs
+++ b/compiler/rustc_incremental/src/persist/mod.rs
@@ -16,9 +16,8 @@ pub use fs::in_incr_comp_dir;
 pub use fs::in_incr_comp_dir_sess;
 pub use fs::prepare_session_directory;
 pub use load::load_query_result_cache;
+pub use load::setup_dep_graph;
 pub use load::LoadResult;
-pub use load::{load_dep_graph, DepGraphFuture};
-pub use save::build_dep_graph;
 pub use save::save_dep_graph;
 pub use save::save_work_product_index;
 pub use work_product::copy_cgu_workproduct_to_incr_comp_cache_dir;
diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs
index 7719482890e..210da751d95 100644
--- a/compiler/rustc_incremental/src/persist/save.rs
+++ b/compiler/rustc_incremental/src/persist/save.rs
@@ -147,7 +147,7 @@ fn encode_query_cache(tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResult
 /// execution, the new dependency information is not kept in memory but directly
 /// output to this file. `save_dep_graph` then finalizes the staging dep-graph
 /// and moves it to the permanent dep-graph path
-pub fn build_dep_graph(
+pub(crate) fn build_dep_graph(
     sess: &Session,
     prev_graph: SerializedDepGraph,
     prev_work_products: WorkProductMap,
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index 38910e45ecc..ad4525c922b 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -14,8 +14,7 @@ use rustc_span::{symbol::Ident, BytePos, Span};
 
 use crate::fluent_generated as fluent;
 use crate::infer::error_reporting::{
-    need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind},
-    nice_region_error::placeholder_error::Highlighted,
+    need_type_info::UnderspecifiedArgKind, nice_region_error::placeholder_error::Highlighted,
     ObligationCauseAsDiagArg,
 };
 
@@ -86,16 +85,6 @@ pub struct AmbiguousReturn<'a> {
     pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
 }
 
-#[derive(Diagnostic)]
-#[diag(infer_need_type_info_in_generator, code = "E0698")]
-pub struct NeedTypeInfoInGenerator<'a> {
-    #[primary_span]
-    pub span: Span,
-    pub generator_kind: GeneratorKindAsDiagArg,
-    #[subdiagnostic]
-    pub bad_label: InferenceBadError<'a>,
-}
-
 // Used when a better one isn't available
 #[derive(Subdiagnostic)]
 #[label(infer_label_bad)]
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
index bd168f047fa..9276bb0a7b7 100644
--- a/compiler/rustc_infer/src/errors/note_and_explain.rs
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -56,11 +56,8 @@ impl<'a> DescriptionCtx<'a> {
                                 (Some(span), "as_defined", name.to_string())
                             }
                         }
-                        ty::BrAnon(span) => {
-                            let span = match span {
-                                Some(_) => span,
-                                None => Some(tcx.def_span(scope)),
-                            };
+                        ty::BrAnon => {
+                            let span = Some(tcx.def_span(scope));
                             (span, "defined_here", String::new())
                         }
                         _ => {
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 6d5db3336cf..2797d079761 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -478,7 +478,28 @@ impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
         a: Self,
         b: Self,
     ) -> TypeTrace<'tcx> {
-        TypeTrace { cause: cause.clone(), values: Sigs(ExpectedFound::new(a_is_expected, a, b)) }
+        TypeTrace {
+            cause: cause.clone(),
+            values: PolySigs(ExpectedFound::new(
+                a_is_expected,
+                ty::Binder::dummy(a),
+                ty::Binder::dummy(b),
+            )),
+        }
+    }
+}
+
+impl<'tcx> ToTrace<'tcx> for ty::PolyFnSig<'tcx> {
+    fn to_trace(
+        cause: &ObligationCause<'tcx>,
+        a_is_expected: bool,
+        a: Self,
+        b: Self,
+    ) -> TypeTrace<'tcx> {
+        TypeTrace {
+            cause: cause.clone(),
+            values: PolySigs(ExpectedFound::new(a_is_expected, a, b)),
+        }
     }
 }
 
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 99bd296d0d5..4124c9eada9 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -459,7 +459,6 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
             ty::Closure(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Bool
             | ty::Char
             | ty::Int(..)
@@ -776,7 +775,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
         r: ty::Region<'tcx>,
     ) -> ty::Region<'tcx> {
         let var = self.canonical_var(info, r.into());
-        let br = ty::BoundRegion { var, kind: ty::BrAnon(None) };
+        let br = ty::BoundRegion { var, kind: ty::BrAnon };
         ty::Region::new_late_bound(self.interner(), self.binder_index, br)
     }
 
diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs
index 1dbab48fd6c..665297da20f 100644
--- a/compiler/rustc_infer/src/infer/equate.rs
+++ b/compiler/rustc_infer/src/infer/equate.rs
@@ -119,26 +119,6 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
                         .obligations,
                 );
             }
-            // Optimization of GeneratorWitness relation since we know that all
-            // free regions are replaced with bound regions during construction.
-            // This greatly speeds up equating of GeneratorWitness.
-            (&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => {
-                let a_types = infcx.tcx.anonymize_bound_vars(a_types);
-                let b_types = infcx.tcx.anonymize_bound_vars(b_types);
-                if a_types.bound_vars() == b_types.bound_vars() {
-                    let (a_types, b_types) = infcx.instantiate_binder_with_placeholders(
-                        a_types.map_bound(|a_types| (a_types, b_types.skip_binder())),
-                    );
-                    for (a, b) in std::iter::zip(a_types, b_types) {
-                        self.relate(a, b)?;
-                    }
-                } else {
-                    return Err(ty::error::TypeError::Sorts(ty::relate::expected_found(
-                        self, a, b,
-                    )));
-                }
-            }
-
             _ => {
                 self.fields.infcx.super_combine_tys(self, a, b)?;
             }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index 1beb13cb94c..72cfc1337e2 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -242,12 +242,9 @@ fn msg_span_from_named_region<'tcx>(
                         };
                         (text, Some(span))
                     }
-                    ty::BrAnon(span) => (
+                    ty::BrAnon => (
                         "the anonymous lifetime as defined here".to_string(),
-                        Some(match span {
-                            Some(span) => span,
-                            None => tcx.def_span(scope)
-                        })
+                        Some(tcx.def_span(scope))
                     ),
                     _ => (
                         format!("the lifetime `{region}` as defined here"),
@@ -262,11 +259,7 @@ fn msg_span_from_named_region<'tcx>(
             ..
         }) => (format!("the lifetime `{name}` as defined here"), Some(tcx.def_span(def_id))),
         ty::RePlaceholder(ty::PlaceholderRegion {
-            bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(Some(span)), .. },
-            ..
-        }) => ("the anonymous lifetime defined here".to_owned(), Some(span)),
-        ty::RePlaceholder(ty::PlaceholderRegion {
-            bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(None), .. },
+            bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon, .. },
             ..
         }) => ("an anonymous lifetime".to_owned(), None),
         _ => bug!("{:?}", region),
@@ -1660,7 +1653,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                             _ => (false, Mismatch::Fixed("type")),
                         }
                     }
-                    ValuePairs::Sigs(infer::ExpectedFound { expected, found }) => {
+                    ValuePairs::PolySigs(infer::ExpectedFound { expected, found }) => {
                         OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span)
                             .report(diag);
                         (false, Mismatch::Fixed("signature"))
@@ -2232,15 +2225,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     ret => ret,
                 }
             }
-            infer::Sigs(exp_found) => {
+            infer::PolySigs(exp_found) => {
                 let exp_found = self.resolve_vars_if_possible(exp_found);
                 if exp_found.references_error() {
                     return None;
                 }
-                let (exp, fnd) = self.cmp_fn_sig(
-                    &ty::Binder::dummy(exp_found.expected),
-                    &ty::Binder::dummy(exp_found.found),
-                );
+                let (exp, fnd) = self.cmp_fn_sig(&exp_found.expected, &exp_found.found);
                 Some((exp, fnd, None, None))
             }
         }
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index f2a3c47bdfe..a9029a8cec0 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -1,5 +1,5 @@
 use crate::errors::{
-    AmbiguousImpl, AmbiguousReturn, AnnotationRequired, InferenceBadError, NeedTypeInfoInGenerator,
+    AmbiguousImpl, AmbiguousReturn, AnnotationRequired, InferenceBadError,
     SourceKindMultiSuggestion, SourceKindSubdiag,
 };
 use crate::infer::error_reporting::TypeErrCtxt;
@@ -595,39 +595,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     }
 }
 
-impl<'tcx> InferCtxt<'tcx> {
-    pub fn need_type_info_err_in_generator(
-        &self,
-        kind: hir::GeneratorKind,
-        span: Span,
-        ty: ty::Term<'tcx>,
-    ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
-        let ty = self.resolve_vars_if_possible(ty);
-        let data = self.extract_inference_diagnostics_data(ty.into(), None);
-
-        NeedTypeInfoInGenerator {
-            bad_label: data.make_bad_error(span),
-            span,
-            generator_kind: GeneratorKindAsDiagArg(kind),
-        }
-        .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic)
-    }
-}
-
-pub struct GeneratorKindAsDiagArg(pub hir::GeneratorKind);
-
-impl IntoDiagnosticArg for GeneratorKindAsDiagArg {
-    fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
-        let kind = match self.0 {
-            hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "async_block",
-            hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "async_closure",
-            hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "async_fn",
-            hir::GeneratorKind::Gen => "generator",
-        };
-        rustc_errors::DiagnosticArgValue::Str(kind.into())
-    }
-}
-
 #[derive(Debug)]
 struct InferSource<'tcx> {
     span: Span,
@@ -951,7 +918,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
             //
             // See the `need_type_info/issue-103053.rs` test for
             // a example.
-            if !matches!(path.res, Res::Def(DefKind::TyAlias { .. }, _)) => {
+            if !matches!(path.res, Res::Def(DefKind::TyAlias, _)) => {
                 if let Some(ty) = self.opt_node_type(expr.hir_id)
                     && let ty::Adt(_, args) = ty.kind()
                 {
@@ -1080,7 +1047,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
                         ) => {
                             if tcx.res_generics_def_id(path.res) != Some(def.did()) {
                                 match path.res {
-                                    Res::Def(DefKind::TyAlias { .. }, _) => {
+                                    Res::Def(DefKind::TyAlias, _) => {
                                         // FIXME: Ideally we should support this. For that
                                         // we have to map back from the self type to the
                                         // type alias though. That's difficult.
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index 07f04ec1e44..1b43022f8f7 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
@@ -61,7 +61,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
         let is_impl_item = region_info.is_impl_item;
 
         match br {
-            ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) => {}
+            ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon => {}
             _ => {
                 /* not an anonymous region */
                 debug!("try_report_named_anon_conflict: not an anonymous region");
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs
index 8a78a1956c9..f5b8912532b 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs
@@ -36,15 +36,13 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
                     ty::BrNamed(def_id, symbol) => {
                         (Some(self.tcx().def_span(def_id)), Some(symbol))
                     }
-                    ty::BrAnon(span) => (*span, None),
-                    ty::BrEnv => (None, None),
+                    ty::BrAnon | ty::BrEnv => (None, None),
                 };
                 let (sup_span, sup_symbol) = match sup_name {
                     ty::BrNamed(def_id, symbol) => {
                         (Some(self.tcx().def_span(def_id)), Some(symbol))
                     }
-                    ty::BrAnon(span) => (*span, None),
-                    ty::BrEnv => (None, None),
+                    ty::BrAnon | ty::BrEnv => (None, None),
                 };
                 let diag = match (sub_span, sup_span, sub_symbol, sup_symbol) {
                     (Some(sub_span), Some(sup_span), Some(&sub_symbol), Some(&sup_symbol)) => {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
index d2ba9966f03..cb51254a14b 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
@@ -35,14 +35,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
             && let (Subtype(sup_trace), Subtype(sub_trace)) = (&sup_origin, &sub_origin)
             && let CompareImplItemObligation { trait_item_def_id, .. } = sub_trace.cause.code()
             && sub_trace.values == sup_trace.values
-            && let ValuePairs::Sigs(ExpectedFound { expected, found }) = sub_trace.values
+            && let ValuePairs::PolySigs(ExpectedFound { expected, found }) = sub_trace.values
         {
             // FIXME(compiler-errors): Don't like that this needs `Ty`s, but
             // all of the region highlighting machinery only deals with those.
             let guar = self.emit_err(
                 var_origin.span(),
-                Ty::new_fn_ptr(self.cx.tcx,ty::Binder::dummy(expected)),
-                Ty::new_fn_ptr(self.cx.tcx,ty::Binder::dummy(found)),
+                Ty::new_fn_ptr(self.cx.tcx, expected),
+                Ty::new_fn_ptr(self.cx.tcx, found),
                 *trait_item_def_id,
             );
             return Some(guar);
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index 445f68160d2..5c3beee284f 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -616,9 +616,13 @@ fn foo(&self) -> Self::T { String::new() }
                 for item in &items[..] {
                     if let hir::AssocItemKind::Type = item.kind {
                         let assoc_ty = tcx.type_of(item.id.owner_id).instantiate_identity();
-
-                        if self.infcx.can_eq(param_env, assoc_ty, found) {
-                            diag.span_label(item.span, "expected this associated type");
+                        if let hir::Defaultness::Default { has_value: true } = tcx.defaultness(item.id.owner_id)
+                            && self.infcx.can_eq(param_env, assoc_ty, found)
+                        {
+                            diag.span_label(
+                                item.span,
+                                "associated type is `default` and may be overridden",
+                            );
                             return true;
                         }
                     }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 4cf9d44ed65..aeb3177af02 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -383,7 +383,7 @@ pub enum ValuePairs<'tcx> {
     Aliases(ExpectedFound<ty::AliasTy<'tcx>>),
     TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
     PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
-    Sigs(ExpectedFound<ty::FnSig<'tcx>>),
+    PolySigs(ExpectedFound<ty::PolyFnSig<'tcx>>),
     ExistentialTraitRef(ExpectedFound<ty::PolyExistentialTraitRef<'tcx>>),
     ExistentialProjection(ExpectedFound<ty::PolyExistentialProjection<'tcx>>),
 }
diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs
index 2ac9568f60b..6a9d40daab6 100644
--- a/compiler/rustc_infer/src/infer/outlives/components.rs
+++ b/compiler/rustc_infer/src/infer/outlives/components.rs
@@ -112,7 +112,7 @@ fn compute_components<'tcx>(
             }
 
             // All regions are bound inside a witness
-            ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => (),
+            ty::GeneratorWitness(..) => (),
 
             // OutlivesTypeParameterEnv -- the actual checking that `X:'a`
             // is implied by the environment is done in regionck.
diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs
index 27e1ed56f31..0c3bb633b53 100644
--- a/compiler/rustc_infer/src/infer/sub.rs
+++ b/compiler/rustc_infer/src/infer/sub.rs
@@ -147,25 +147,6 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
                 );
                 Ok(a)
             }
-            // Optimization of GeneratorWitness relation since we know that all
-            // free regions are replaced with bound regions during construction.
-            // This greatly speeds up subtyping of GeneratorWitness.
-            (&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => {
-                let a_types = infcx.tcx.anonymize_bound_vars(a_types);
-                let b_types = infcx.tcx.anonymize_bound_vars(b_types);
-                if a_types.bound_vars() == b_types.bound_vars() {
-                    let (a_types, b_types) = infcx.instantiate_binder_with_placeholders(
-                        a_types.map_bound(|a_types| (a_types, b_types.skip_binder())),
-                    );
-                    for (a, b) in std::iter::zip(a_types, b_types) {
-                        self.relate(a, b)?;
-                    }
-                    Ok(a)
-                } else {
-                    Err(ty::error::TypeError::Sorts(ty::relate::expected_found(self, a, b)))
-                }
-            }
-
             _ => {
                 self.fields.infcx.super_combine_tys(self, a, b)?;
                 Ok(a)
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index ce097922aef..0e8f93cef17 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -798,14 +798,12 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
         }
     });
 
-    if tcx.sess.opts.unstable_opts.drop_tracking_mir {
-        tcx.hir().par_body_owners(|def_id| {
-            if let rustc_hir::def::DefKind::Generator = tcx.def_kind(def_id) {
-                tcx.ensure().mir_generator_witnesses(def_id);
-                tcx.ensure().check_generator_obligations(def_id);
-            }
-        });
-    }
+    tcx.hir().par_body_owners(|def_id| {
+        if let rustc_hir::def::DefKind::Generator = tcx.def_kind(def_id) {
+            tcx.ensure().mir_generator_witnesses(def_id);
+            tcx.ensure().check_generator_obligations(def_id);
+        }
+    });
 
     sess.time("layout_testing", || layout_test::test_layout(tcx));
     sess.time("abi_testing", || abi_test::test_abi(tcx));
diff --git a/compiler/rustc_interface/src/queries.rs b/compiler/rustc_interface/src/queries.rs
index 449d7a29590..fe253febfc7 100644
--- a/compiler/rustc_interface/src/queries.rs
+++ b/compiler/rustc_interface/src/queries.rs
@@ -10,7 +10,7 @@ use rustc_data_structures::svh::Svh;
 use rustc_data_structures::sync::{AppendOnlyIndexVec, FreezeLock, Lrc, OnceLock, WorkerLocal};
 use rustc_hir::def_id::{StableCrateId, CRATE_DEF_ID, LOCAL_CRATE};
 use rustc_hir::definitions::Definitions;
-use rustc_incremental::DepGraphFuture;
+use rustc_incremental::setup_dep_graph;
 use rustc_metadata::creader::CStore;
 use rustc_middle::arena::Arena;
 use rustc_middle::dep_graph::DepGraph;
@@ -19,7 +19,6 @@ use rustc_session::config::{self, CrateType, OutputFilenames, OutputType};
 use rustc_session::cstore::Untracked;
 use rustc_session::{output::find_crate_name, Session};
 use rustc_span::symbol::sym;
-use rustc_span::Symbol;
 use std::any::Any;
 use std::cell::{RefCell, RefMut};
 use std::sync::Arc;
@@ -132,43 +131,6 @@ impl<'tcx> Queries<'tcx> {
         })
     }
 
-    fn dep_graph_future(
-        &self,
-        crate_name: Symbol,
-        stable_crate_id: StableCrateId,
-    ) -> Result<Option<DepGraphFuture>> {
-        let sess = self.session();
-
-        // `load_dep_graph` can only be called after `prepare_session_directory`.
-        rustc_incremental::prepare_session_directory(sess, crate_name, stable_crate_id)?;
-        let res = sess.opts.build_dep_graph().then(|| rustc_incremental::load_dep_graph(sess));
-
-        if sess.opts.incremental.is_some() {
-            sess.time("incr_comp_garbage_collect_session_directories", || {
-                if let Err(e) = rustc_incremental::garbage_collect_session_directories(sess) {
-                    warn!(
-                        "Error while trying to garbage collect incremental \
-                         compilation cache directory: {}",
-                        e
-                    );
-                }
-            });
-        }
-
-        Ok(res)
-    }
-
-    fn dep_graph(&self, dep_graph_future: Option<DepGraphFuture>) -> DepGraph {
-        dep_graph_future
-            .and_then(|future| {
-                let sess = self.session();
-                let (prev_graph, prev_work_products) =
-                    sess.time("blocked_on_dep_graph_loading", || future.open().open(sess));
-                rustc_incremental::build_dep_graph(sess, prev_graph, prev_work_products)
-            })
-            .unwrap_or_else(DepGraph::new_disabled)
-    }
-
     pub fn global_ctxt(&'tcx self) -> Result<QueryResult<'_, &'tcx GlobalCtxt<'tcx>>> {
         self.gcx.compute(|| {
             let sess = self.session();
@@ -184,10 +146,7 @@ impl<'tcx> Queries<'tcx> {
                 sess.opts.cg.metadata.clone(),
                 sess.cfg_version,
             );
-
-            // Compute the dependency graph (in the background). We want to do this as early as
-            // possible, to give the DepGraph maximum time to load before `dep_graph` is called.
-            let dep_graph_future = self.dep_graph_future(crate_name, stable_crate_id)?;
+            let dep_graph = setup_dep_graph(sess, crate_name, stable_crate_id)?;
 
             let lint_store = Lrc::new(passes::create_lint_store(
                 sess,
@@ -210,7 +169,7 @@ impl<'tcx> Queries<'tcx> {
                 crate_types,
                 stable_crate_id,
                 lint_store,
-                self.dep_graph(dep_graph_future),
+                dep_graph,
                 untracked,
                 &self.gcx_cell,
                 &self.arena,
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 1746cc8b719..2510ce71460 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -684,7 +684,6 @@ fn test_unstable_options_tracking_hash() {
     untracked!(dep_tasks, true);
     untracked!(dont_buffer_diagnostics, true);
     untracked!(dump_dep_graph, true);
-    untracked!(dump_drop_tracking_cfg, Some("cfg.dot".to_string()));
     untracked!(dump_mir, Some(String::from("abc")));
     untracked!(dump_mir_dataflow, true);
     untracked!(dump_mir_dir, String::from("abc"));
@@ -773,7 +772,6 @@ fn test_unstable_options_tracking_hash() {
     tracked!(debug_info_for_profiling, true);
     tracked!(debug_macros, true);
     tracked!(dep_info_omit_d_target, true);
-    tracked!(drop_tracking, true);
     tracked!(dual_proc_macros, true);
     tracked!(dwarf_version, Some(5));
     tracked!(emit_thin_lto, false);
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index 4f6b79d9aee..536f78a73ed 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1454,13 +1454,13 @@ impl<'tcx> LateLintPass<'tcx> for TypeAliasBounds {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
         let hir::ItemKind::TyAlias(hir_ty, type_alias_generics) = &item.kind else { return };
 
-        if cx.tcx.features().lazy_type_alias {
-            // Bounds of lazy type aliases are respected.
+        // Bounds of lazy type aliases and TAITs are respected.
+        if cx.tcx.type_alias_is_lazy(item.owner_id) {
             return;
         }
 
         let ty = cx.tcx.type_of(item.owner_id).skip_binder();
-        if ty.has_opaque_types() || ty.has_inherent_projections() {
+        if ty.has_inherent_projections() {
             // Bounds of type aliases that contain opaque types or inherent projections are respected.
             // E.g: `type X = impl Trait;`, `type X = (impl Trait, Y);`, `type X = Type::Inherent;`.
             return;
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 460d54739a2..3c5cde4309b 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -1317,6 +1317,40 @@ impl<'tcx> LateContext<'tcx> {
     }
 
     /// If the given expression is a local binding, find the initializer expression.
+    /// If that initializer expression is another local binding, find its initializer again.
+    ///
+    /// This process repeats as long as possible (but usually no more than once).
+    /// Type-check adjustments are not taken in account in this function.
+    ///
+    /// Examples:
+    /// ```
+    /// let abc = 1;
+    /// let def = abc + 2;
+    /// //        ^^^^^^^ output
+    /// let def = def;
+    /// dbg!(def);
+    /// //   ^^^ input
+    /// ```
+    pub fn expr_or_init<'a>(&self, mut expr: &'a hir::Expr<'tcx>) -> &'a hir::Expr<'tcx> {
+        expr = expr.peel_blocks();
+
+        while let hir::ExprKind::Path(ref qpath) = expr.kind
+            && let Some(parent_node) = match self.qpath_res(qpath, expr.hir_id) {
+                Res::Local(hir_id) => self.tcx.hir().find_parent(hir_id),
+                _ => None,
+            }
+            && let Some(init) = match parent_node {
+                hir::Node::Expr(expr) => Some(expr),
+                hir::Node::Local(hir::Local { init, .. }) => *init,
+                _ => None
+            }
+        {
+            expr = init.peel_blocks();
+        }
+        expr
+    }
+
+    /// If the given expression is a local binding, find the initializer expression.
     /// If that initializer expression is another local or **outside** (`const`/`static`)
     /// binding, find its initializer again.
     ///
@@ -1338,7 +1372,10 @@ impl<'tcx> LateContext<'tcx> {
     /// dbg!(def);
     /// //   ^^^ input
     /// ```
-    pub fn expr_or_init<'a>(&self, mut expr: &'a hir::Expr<'tcx>) -> &'a hir::Expr<'tcx> {
+    pub fn expr_or_init_with_outside_body<'a>(
+        &self,
+        mut expr: &'a hir::Expr<'tcx>,
+    ) -> &'a hir::Expr<'tcx> {
         expr = expr.peel_blocks();
 
         while let hir::ExprKind::Path(ref qpath) = expr.kind
diff --git a/compiler/rustc_lint/src/foreign_modules.rs b/compiler/rustc_lint/src/foreign_modules.rs
index 7b291d558e0..e1df69bdaf2 100644
--- a/compiler/rustc_lint/src/foreign_modules.rs
+++ b/compiler/rustc_lint/src/foreign_modules.rs
@@ -5,19 +5,18 @@ use rustc_hir::def::DefKind;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::layout::LayoutError;
 use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
-use rustc_session::lint::{lint_array, LintArray};
 use rustc_span::{sym, Span, Symbol};
 use rustc_target::abi::FIRST_VARIANT;
 
 use crate::lints::{BuiltinClashingExtern, BuiltinClashingExternSub};
-use crate::types;
+use crate::{types, LintVec};
 
 pub(crate) fn provide(providers: &mut Providers) {
     *providers = Providers { clashing_extern_declarations, ..*providers };
 }
 
-pub(crate) fn get_lints() -> LintArray {
-    lint_array!(CLASHING_EXTERN_DECLARATIONS)
+pub(crate) fn get_lints() -> LintVec {
+    vec![CLASHING_EXTERN_DECLARATIONS]
 }
 
 fn clashing_extern_declarations(tcx: TyCtxt<'_>, (): ()) {
diff --git a/compiler/rustc_lint/src/invalid_from_utf8.rs b/compiler/rustc_lint/src/invalid_from_utf8.rs
index 1841e7c85a8..e398059ade9 100644
--- a/compiler/rustc_lint/src/invalid_from_utf8.rs
+++ b/compiler/rustc_lint/src/invalid_from_utf8.rs
@@ -84,9 +84,9 @@ impl<'tcx> LateLintPass<'tcx> for InvalidFromUtf8 {
                 )
             };
 
-            let mut init = cx.expr_or_init(arg);
+            let mut init = cx.expr_or_init_with_outside_body(arg);
             while let ExprKind::AddrOf(.., inner) = init.kind {
-                init = cx.expr_or_init(inner);
+                init = cx.expr_or_init_with_outside_body(inner);
             }
             match init.kind {
                 ExprKind::Lit(Spanned { node: lit, .. }) => {
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 84434d585d3..72c103f2d4a 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -86,18 +86,14 @@ mod unused;
 
 pub use array_into_iter::ARRAY_INTO_ITER;
 
-use rustc_ast as ast;
 use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
 use rustc_fluent_macro::fluent_messages;
-use rustc_hir as hir;
-use rustc_hir::def_id::{LocalDefId, LocalModDefId};
+use rustc_hir::def_id::LocalModDefId;
 use rustc_middle::query::Providers;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::builtin::{
     BARE_TRAIT_OBJECTS, ELIDED_LIFETIMES_IN_PATHS, EXPLICIT_OUTLIVES_REQUIREMENTS,
 };
-use rustc_span::symbol::Ident;
-use rustc_span::Span;
 
 use array_into_iter::ArrayIntoIter;
 use builtin::*;
@@ -134,7 +130,7 @@ pub use late::{check_crate, late_lint_mod, unerased_lint_store};
 pub use passes::{EarlyLintPass, LateLintPass};
 pub use rustc_session::lint::Level::{self, *};
 pub use rustc_session::lint::{BufferedEarlyLint, FutureIncompatibleInfo, Lint, LintId};
-pub use rustc_session::lint::{LintArray, LintPass};
+pub use rustc_session::lint::{LintPass, LintVec};
 
 fluent_messages! { "../messages.ftl" }
 
@@ -200,7 +196,7 @@ late_lint_methods!(
             BoxPointers: BoxPointers,
             PathStatements: PathStatements,
             LetUnderscore: LetUnderscore,
-            InvalidReferenceCasting: InvalidReferenceCasting::default(),
+            InvalidReferenceCasting: InvalidReferenceCasting,
             // Depends on referenced function signatures in expressions
             UnusedResults: UnusedResults,
             NonUpperCaseGlobals: NonUpperCaseGlobals,
diff --git a/compiler/rustc_lint/src/noop_method_call.rs b/compiler/rustc_lint/src/noop_method_call.rs
index bc0b9d6d818..cfbca6efbfa 100644
--- a/compiler/rustc_lint/src/noop_method_call.rs
+++ b/compiler/rustc_lint/src/noop_method_call.rs
@@ -98,6 +98,12 @@ impl<'tcx> LateLintPass<'tcx> for NoopMethodCall {
         let Ok(Some(i)) = ty::Instance::resolve(cx.tcx, cx.param_env, did, args) else { return };
         // (Re)check that it implements the noop diagnostic.
         let Some(name) = cx.tcx.get_diagnostic_name(i.def_id()) else { return };
+        if !matches!(
+            name,
+            sym::noop_method_borrow | sym::noop_method_clone | sym::noop_method_deref
+        ) {
+            return;
+        }
 
         let receiver_ty = cx.typeck_results().expr_ty(receiver);
         let expr_ty = cx.typeck_results().expr_ty_adjusted(expr);
diff --git a/compiler/rustc_lint/src/passes.rs b/compiler/rustc_lint/src/passes.rs
index fca0eeeecc4..508f3e1ec31 100644
--- a/compiler/rustc_lint/src/passes.rs
+++ b/compiler/rustc_lint/src/passes.rs
@@ -1,58 +1,53 @@
 use crate::context::{EarlyContext, LateContext};
 
-use rustc_ast as ast;
-use rustc_hir as hir;
 use rustc_session::lint::builtin::HardwiredLints;
 use rustc_session::lint::LintPass;
-use rustc_span::def_id::LocalDefId;
-use rustc_span::symbol::Ident;
-use rustc_span::Span;
 
 #[macro_export]
 macro_rules! late_lint_methods {
     ($macro:path, $args:tt) => (
         $macro!($args, [
-            fn check_body(a: &'tcx hir::Body<'tcx>);
-            fn check_body_post(a: &'tcx hir::Body<'tcx>);
+            fn check_body(a: &'tcx rustc_hir::Body<'tcx>);
+            fn check_body_post(a: &'tcx rustc_hir::Body<'tcx>);
             fn check_crate();
             fn check_crate_post();
-            fn check_mod(a: &'tcx hir::Mod<'tcx>, b: hir::HirId);
-            fn check_foreign_item(a: &'tcx hir::ForeignItem<'tcx>);
-            fn check_item(a: &'tcx hir::Item<'tcx>);
-            fn check_item_post(a: &'tcx hir::Item<'tcx>);
-            fn check_local(a: &'tcx hir::Local<'tcx>);
-            fn check_block(a: &'tcx hir::Block<'tcx>);
-            fn check_block_post(a: &'tcx hir::Block<'tcx>);
-            fn check_stmt(a: &'tcx hir::Stmt<'tcx>);
-            fn check_arm(a: &'tcx hir::Arm<'tcx>);
-            fn check_pat(a: &'tcx hir::Pat<'tcx>);
-            fn check_expr(a: &'tcx hir::Expr<'tcx>);
-            fn check_expr_post(a: &'tcx hir::Expr<'tcx>);
-            fn check_ty(a: &'tcx hir::Ty<'tcx>);
-            fn check_generic_param(a: &'tcx hir::GenericParam<'tcx>);
-            fn check_generics(a: &'tcx hir::Generics<'tcx>);
-            fn check_poly_trait_ref(a: &'tcx hir::PolyTraitRef<'tcx>);
+            fn check_mod(a: &'tcx rustc_hir::Mod<'tcx>, b: rustc_hir::HirId);
+            fn check_foreign_item(a: &'tcx rustc_hir::ForeignItem<'tcx>);
+            fn check_item(a: &'tcx rustc_hir::Item<'tcx>);
+            fn check_item_post(a: &'tcx rustc_hir::Item<'tcx>);
+            fn check_local(a: &'tcx rustc_hir::Local<'tcx>);
+            fn check_block(a: &'tcx rustc_hir::Block<'tcx>);
+            fn check_block_post(a: &'tcx rustc_hir::Block<'tcx>);
+            fn check_stmt(a: &'tcx rustc_hir::Stmt<'tcx>);
+            fn check_arm(a: &'tcx rustc_hir::Arm<'tcx>);
+            fn check_pat(a: &'tcx rustc_hir::Pat<'tcx>);
+            fn check_expr(a: &'tcx rustc_hir::Expr<'tcx>);
+            fn check_expr_post(a: &'tcx rustc_hir::Expr<'tcx>);
+            fn check_ty(a: &'tcx rustc_hir::Ty<'tcx>);
+            fn check_generic_param(a: &'tcx rustc_hir::GenericParam<'tcx>);
+            fn check_generics(a: &'tcx rustc_hir::Generics<'tcx>);
+            fn check_poly_trait_ref(a: &'tcx rustc_hir::PolyTraitRef<'tcx>);
             fn check_fn(
                 a: rustc_hir::intravisit::FnKind<'tcx>,
-                b: &'tcx hir::FnDecl<'tcx>,
-                c: &'tcx hir::Body<'tcx>,
-                d: Span,
-                e: LocalDefId);
-            fn check_trait_item(a: &'tcx hir::TraitItem<'tcx>);
-            fn check_impl_item(a: &'tcx hir::ImplItem<'tcx>);
-            fn check_impl_item_post(a: &'tcx hir::ImplItem<'tcx>);
-            fn check_struct_def(a: &'tcx hir::VariantData<'tcx>);
-            fn check_field_def(a: &'tcx hir::FieldDef<'tcx>);
-            fn check_variant(a: &'tcx hir::Variant<'tcx>);
-            fn check_path(a: &hir::Path<'tcx>, b: hir::HirId);
-            fn check_attribute(a: &'tcx ast::Attribute);
+                b: &'tcx rustc_hir::FnDecl<'tcx>,
+                c: &'tcx rustc_hir::Body<'tcx>,
+                d: rustc_span::Span,
+                e: rustc_span::def_id::LocalDefId);
+            fn check_trait_item(a: &'tcx rustc_hir::TraitItem<'tcx>);
+            fn check_impl_item(a: &'tcx rustc_hir::ImplItem<'tcx>);
+            fn check_impl_item_post(a: &'tcx rustc_hir::ImplItem<'tcx>);
+            fn check_struct_def(a: &'tcx rustc_hir::VariantData<'tcx>);
+            fn check_field_def(a: &'tcx rustc_hir::FieldDef<'tcx>);
+            fn check_variant(a: &'tcx rustc_hir::Variant<'tcx>);
+            fn check_path(a: &rustc_hir::Path<'tcx>, b: rustc_hir::HirId);
+            fn check_attribute(a: &'tcx rustc_ast::Attribute);
 
             /// Called when entering a syntax node that can have lint attributes such
             /// as `#[allow(...)]`. Called with *all* the attributes of that node.
-            fn enter_lint_attrs(a: &'tcx [ast::Attribute]);
+            fn enter_lint_attrs(a: &'tcx [rustc_ast::Attribute]);
 
             /// Counterpart to `enter_lint_attrs`.
-            fn exit_lint_attrs(a: &'tcx [ast::Attribute]);
+            fn exit_lint_attrs(a: &'tcx [rustc_ast::Attribute]);
         ]);
     )
 }
@@ -90,8 +85,8 @@ macro_rules! expand_combined_late_lint_pass_method {
 #[macro_export]
 macro_rules! expand_combined_late_lint_pass_methods {
     ($passes:tt, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
-        $(fn $name(&mut self, context: &LateContext<'tcx>, $($param: $arg),*) {
-            expand_combined_late_lint_pass_method!($passes, self, $name, (context, $($param),*));
+        $(fn $name(&mut self, context: &$crate::LateContext<'tcx>, $($param: $arg),*) {
+            $crate::expand_combined_late_lint_pass_method!($passes, self, $name, (context, $($param),*));
         })*
     )
 }
@@ -116,19 +111,19 @@ macro_rules! declare_combined_late_lint_pass {
                 }
             }
 
-            $v fn get_lints() -> LintArray {
+            $v fn get_lints() -> $crate::LintVec {
                 let mut lints = Vec::new();
                 $(lints.extend_from_slice(&$pass::get_lints());)*
                 lints
             }
         }
 
-        impl<'tcx> LateLintPass<'tcx> for $name {
-            expand_combined_late_lint_pass_methods!([$($pass),*], $methods);
+        impl<'tcx> $crate::LateLintPass<'tcx> for $name {
+            $crate::expand_combined_late_lint_pass_methods!([$($pass),*], $methods);
         }
 
         #[allow(rustc::lint_pass_impl_without_macro)]
-        impl LintPass for $name {
+        impl $crate::LintPass for $name {
             fn name(&self) -> &'static str {
                 panic!()
             }
@@ -140,42 +135,45 @@ macro_rules! declare_combined_late_lint_pass {
 macro_rules! early_lint_methods {
     ($macro:path, $args:tt) => (
         $macro!($args, [
-            fn check_param(a: &ast::Param);
-            fn check_ident(a: Ident);
-            fn check_crate(a: &ast::Crate);
-            fn check_crate_post(a: &ast::Crate);
-            fn check_item(a: &ast::Item);
-            fn check_item_post(a: &ast::Item);
-            fn check_local(a: &ast::Local);
-            fn check_block(a: &ast::Block);
-            fn check_stmt(a: &ast::Stmt);
-            fn check_arm(a: &ast::Arm);
-            fn check_pat(a: &ast::Pat);
-            fn check_pat_post(a: &ast::Pat);
-            fn check_expr(a: &ast::Expr);
-            fn check_expr_post(a: &ast::Expr);
-            fn check_ty(a: &ast::Ty);
-            fn check_generic_arg(a: &ast::GenericArg);
-            fn check_generic_param(a: &ast::GenericParam);
-            fn check_generics(a: &ast::Generics);
-            fn check_poly_trait_ref(a: &ast::PolyTraitRef);
-            fn check_fn(a: rustc_ast::visit::FnKind<'_>, c: Span, d_: ast::NodeId);
-            fn check_trait_item(a: &ast::AssocItem);
-            fn check_impl_item(a: &ast::AssocItem);
-            fn check_variant(a: &ast::Variant);
-            fn check_attribute(a: &ast::Attribute);
-            fn check_mac_def(a: &ast::MacroDef);
-            fn check_mac(a: &ast::MacCall);
+            fn check_param(a: &rustc_ast::Param);
+            fn check_ident(a: rustc_span::symbol::Ident);
+            fn check_crate(a: &rustc_ast::Crate);
+            fn check_crate_post(a: &rustc_ast::Crate);
+            fn check_item(a: &rustc_ast::Item);
+            fn check_item_post(a: &rustc_ast::Item);
+            fn check_local(a: &rustc_ast::Local);
+            fn check_block(a: &rustc_ast::Block);
+            fn check_stmt(a: &rustc_ast::Stmt);
+            fn check_arm(a: &rustc_ast::Arm);
+            fn check_pat(a: &rustc_ast::Pat);
+            fn check_pat_post(a: &rustc_ast::Pat);
+            fn check_expr(a: &rustc_ast::Expr);
+            fn check_expr_post(a: &rustc_ast::Expr);
+            fn check_ty(a: &rustc_ast::Ty);
+            fn check_generic_arg(a: &rustc_ast::GenericArg);
+            fn check_generic_param(a: &rustc_ast::GenericParam);
+            fn check_generics(a: &rustc_ast::Generics);
+            fn check_poly_trait_ref(a: &rustc_ast::PolyTraitRef);
+            fn check_fn(
+                a: rustc_ast::visit::FnKind<'_>,
+                c: rustc_span::Span,
+                d_: rustc_ast::NodeId);
+            fn check_trait_item(a: &rustc_ast::AssocItem);
+            fn check_impl_item(a: &rustc_ast::AssocItem);
+            fn check_variant(a: &rustc_ast::Variant);
+            fn check_attribute(a: &rustc_ast::Attribute);
+            fn check_mac_def(a: &rustc_ast::MacroDef);
+            fn check_mac(a: &rustc_ast::MacCall);
 
             /// Called when entering a syntax node that can have lint attributes such
             /// as `#[allow(...)]`. Called with *all* the attributes of that node.
-            fn enter_lint_attrs(a: &[ast::Attribute]);
+            fn enter_lint_attrs(a: &[rustc_ast::Attribute]);
 
             /// Counterpart to `enter_lint_attrs`.
-            fn exit_lint_attrs(a: &[ast::Attribute]);
+            fn exit_lint_attrs(a: &[rustc_ast::Attribute]);
 
-            fn enter_where_predicate(a: &ast::WherePredicate);
-            fn exit_where_predicate(a: &ast::WherePredicate);
+            fn enter_where_predicate(a: &rustc_ast::WherePredicate);
+            fn exit_where_predicate(a: &rustc_ast::WherePredicate);
         ]);
     )
 }
@@ -202,8 +200,8 @@ macro_rules! expand_combined_early_lint_pass_method {
 #[macro_export]
 macro_rules! expand_combined_early_lint_pass_methods {
     ($passes:tt, [$($(#[$attr:meta])* fn $name:ident($($param:ident: $arg:ty),*);)*]) => (
-        $(fn $name(&mut self, context: &EarlyContext<'_>, $($param: $arg),*) {
-            expand_combined_early_lint_pass_method!($passes, self, $name, (context, $($param),*));
+        $(fn $name(&mut self, context: &$crate::EarlyContext<'_>, $($param: $arg),*) {
+            $crate::expand_combined_early_lint_pass_method!($passes, self, $name, (context, $($param),*));
         })*
     )
 }
@@ -228,19 +226,19 @@ macro_rules! declare_combined_early_lint_pass {
                 }
             }
 
-            $v fn get_lints() -> LintArray {
+            $v fn get_lints() -> $crate::LintVec {
                 let mut lints = Vec::new();
                 $(lints.extend_from_slice(&$pass::get_lints());)*
                 lints
             }
         }
 
-        impl EarlyLintPass for $name {
-            expand_combined_early_lint_pass_methods!([$($pass),*], $methods);
+        impl $crate::EarlyLintPass for $name {
+            $crate::expand_combined_early_lint_pass_methods!([$($pass),*], $methods);
         }
 
         #[allow(rustc::lint_pass_impl_without_macro)]
-        impl LintPass for $name {
+        impl $crate::LintPass for $name {
             fn name(&self) -> &'static str {
                 panic!()
             }
diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs
index d540f473ae8..39def599be8 100644
--- a/compiler/rustc_lint/src/reference_casting.rs
+++ b/compiler/rustc_lint/src/reference_casting.rs
@@ -1,8 +1,7 @@
 use rustc_ast::Mutability;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_hir::{def::Res, Expr, ExprKind, HirId, Local, QPath, StmtKind, UnOp};
+use rustc_hir::{Expr, ExprKind, UnOp};
 use rustc_middle::ty::{self, TypeAndMut};
-use rustc_span::{sym, Span};
+use rustc_span::sym;
 
 use crate::{lints::InvalidReferenceCastingDiag, LateContext, LateLintPass, LintContext};
 
@@ -34,38 +33,18 @@ declare_lint! {
     "casts of `&T` to `&mut T` without interior mutability"
 }
 
-#[derive(Default)]
-pub struct InvalidReferenceCasting {
-    casted: FxHashMap<HirId, Span>,
-}
-
-impl_lint_pass!(InvalidReferenceCasting => [INVALID_REFERENCE_CASTING]);
+declare_lint_pass!(InvalidReferenceCasting => [INVALID_REFERENCE_CASTING]);
 
 impl<'tcx> LateLintPass<'tcx> for InvalidReferenceCasting {
-    fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx rustc_hir::Stmt<'tcx>) {
-        let StmtKind::Local(local) = stmt.kind else {
-            return;
-        };
-        let Local { init: Some(init), els: None, .. } = local else {
-            return;
-        };
-
-        if is_cast_from_const_to_mut(cx, init) {
-            self.casted.insert(local.pat.hir_id, init.span);
-        }
-    }
-
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
         let Some((is_assignment, e)) = is_operation_we_care_about(cx, expr) else {
             return;
         };
 
-        let orig_cast = if is_cast_from_const_to_mut(cx, e) {
-            None
-        } else if let ExprKind::Path(QPath::Resolved(_, path)) = e.kind
-            && let Res::Local(hir_id) = &path.res
-            && let Some(orig_cast) = self.casted.get(hir_id) {
-            Some(*orig_cast)
+        let init = cx.expr_or_init(e);
+
+        let orig_cast = if is_cast_from_const_to_mut(cx, init) {
+            if init.span != e.span { Some(init.span) } else { None }
         } else {
             return;
         };
@@ -125,99 +104,51 @@ fn is_operation_we_care_about<'tcx>(
     deref_assign_or_addr_of(e).or_else(|| ptr_write(cx, e))
 }
 
-fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {
-    let e = e.peel_blocks();
+fn is_cast_from_const_to_mut<'tcx>(cx: &LateContext<'tcx>, orig_expr: &'tcx Expr<'tcx>) -> bool {
+    let mut need_check_freeze = false;
+    let mut e = orig_expr;
 
-    fn from_casts<'tcx>(
-        cx: &LateContext<'tcx>,
-        e: &'tcx Expr<'tcx>,
-        need_check_freeze: &mut bool,
-    ) -> Option<&'tcx Expr<'tcx>> {
-        // <expr> as *mut ...
-        let mut e = if let ExprKind::Cast(e, t) = e.kind
-            && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Mut, .. }) = cx.typeck_results().node_type(t.hir_id).kind() {
-            e
-        // <expr>.cast_mut()
+    let end_ty = cx.typeck_results().node_type(orig_expr.hir_id);
+
+    // Bail out early if the end type is **not** a mutable pointer.
+    if !matches!(end_ty.kind(), ty::RawPtr(TypeAndMut { ty: _, mutbl: Mutability::Mut })) {
+        return false;
+    }
+
+    loop {
+        e = e.peel_blocks();
+        // <expr> as ...
+        e = if let ExprKind::Cast(expr, _) = e.kind {
+            expr
+        // <expr>.cast(), <expr>.cast_mut() or <expr>.cast_const()
         } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind
             && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
-            && cx.tcx.is_diagnostic_item(sym::ptr_cast_mut, def_id) {
+            && matches!(
+                cx.tcx.get_diagnostic_name(def_id),
+                Some(sym::ptr_cast | sym::const_ptr_cast | sym::ptr_cast_mut | sym::ptr_cast_const)
+            )
+        {
             expr
-        // UnsafeCell::raw_get(<expr>)
+        // ptr::from_ref(<expr>), UnsafeCell::raw_get(<expr>) or mem::transmute<_, _>(<expr>)
         } else if let ExprKind::Call(path, [arg]) = e.kind
             && let ExprKind::Path(ref qpath) = path.kind
             && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
-            && cx.tcx.is_diagnostic_item(sym::unsafe_cell_raw_get, def_id)
+            && matches!(
+                cx.tcx.get_diagnostic_name(def_id),
+                Some(sym::ptr_from_ref | sym::unsafe_cell_raw_get | sym::transmute)
+            )
         {
-            *need_check_freeze = true;
+            if cx.tcx.is_diagnostic_item(sym::unsafe_cell_raw_get, def_id) {
+                need_check_freeze = true;
+            }
             arg
         } else {
-            return None;
+            break;
         };
-
-        let mut had_at_least_one_cast = false;
-        loop {
-            e = e.peel_blocks();
-            // <expr> as *mut/const ... or <expr> as <uint>
-            e = if let ExprKind::Cast(expr, t) = e.kind
-                && matches!(cx.typeck_results().node_type(t.hir_id).kind(), ty::RawPtr(_) | ty::Uint(_))  {
-                had_at_least_one_cast = true;
-                expr
-            // <expr>.cast(), <expr>.cast_mut() or <expr>.cast_const()
-            } else if let ExprKind::MethodCall(_, expr, [], _) = e.kind
-                && let Some(def_id) = cx.typeck_results().type_dependent_def_id(e.hir_id)
-                && matches!(
-                    cx.tcx.get_diagnostic_name(def_id),
-                    Some(sym::ptr_cast | sym::const_ptr_cast | sym::ptr_cast_mut | sym::ptr_cast_const)
-                )
-            {
-                had_at_least_one_cast = true;
-                expr
-            // ptr::from_ref(<expr>) or UnsafeCell::raw_get(<expr>)
-            } else if let ExprKind::Call(path, [arg]) = e.kind
-                && let ExprKind::Path(ref qpath) = path.kind
-                && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
-                && matches!(
-                    cx.tcx.get_diagnostic_name(def_id),
-                    Some(sym::ptr_from_ref | sym::unsafe_cell_raw_get)
-                )
-            {
-                if cx.tcx.is_diagnostic_item(sym::unsafe_cell_raw_get, def_id) {
-                    *need_check_freeze = true;
-                }
-                return Some(arg);
-            } else if had_at_least_one_cast {
-                return Some(e);
-            } else {
-                return None;
-            };
-        }
-    }
-
-    fn from_transmute<'tcx>(
-        cx: &LateContext<'tcx>,
-        e: &'tcx Expr<'tcx>,
-    ) -> Option<&'tcx Expr<'tcx>> {
-        // mem::transmute::<_, *mut _>(<expr>)
-        if let ExprKind::Call(path, [arg]) = e.kind
-            && let ExprKind::Path(ref qpath) = path.kind
-            && let Some(def_id) = cx.qpath_res(qpath, path.hir_id).opt_def_id()
-            && cx.tcx.is_diagnostic_item(sym::transmute, def_id)
-            && let ty::RawPtr(TypeAndMut { mutbl: Mutability::Mut, .. }) = cx.typeck_results().node_type(e.hir_id).kind() {
-            Some(arg)
-        } else {
-            None
-        }
     }
 
-    let mut need_check_freeze = false;
-    let Some(e) = from_casts(cx, e, &mut need_check_freeze).or_else(|| from_transmute(cx, e))
-    else {
-        return false;
-    };
-
-    let e = e.peel_blocks();
-    let node_type = cx.typeck_results().node_type(e.hir_id);
-    if let ty::Ref(_, inner_ty, Mutability::Not) = node_type.kind() {
+    let start_ty = cx.typeck_results().node_type(e.hir_id);
+    if let ty::Ref(_, inner_ty, Mutability::Not) = start_ty.kind() {
         // If an UnsafeCell method is involved we need to additionaly check the
         // inner type for the presence of the Freeze trait (ie does NOT contain
         // an UnsafeCell), since in that case we would incorrectly lint on valid casts.
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 57c2e289f20..44cf1591c7d 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1271,7 +1271,6 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
             | ty::Closure(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Placeholder(..)
             | ty::FnDef(..) => bug!("unexpected type in foreign function: {:?}", ty),
         }
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 1951db49e91..69b462d32bd 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -306,6 +306,7 @@ declare_lint! {
     /// pub async fn uhoh() {
     ///     let guard = SyncThing {};
     ///     yield_now().await;
+    ///     let _guard = guard;
     /// }
     /// ```
     ///
@@ -2311,6 +2312,57 @@ declare_lint! {
 }
 
 declare_lint! {
+    /// The `const_patterns_without_partial_eq` lint detects constants that are used in patterns,
+    /// whose type does not implement `PartialEq`.
+    ///
+    /// ### Example
+    ///
+    /// ```rust,compile_fail
+    /// #![deny(const_patterns_without_partial_eq)]
+    ///
+    /// trait EnumSetType {
+    ///    type Repr;
+    /// }
+    ///
+    /// enum Enum8 { }
+    /// impl EnumSetType for Enum8 {
+    ///     type Repr = u8;
+    /// }
+    ///
+    /// #[derive(PartialEq, Eq)]
+    /// struct EnumSet<T: EnumSetType> {
+    ///     __enumset_underlying: T::Repr,
+    /// }
+    ///
+    /// const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
+    ///
+    /// fn main() {
+    ///     match CONST_SET {
+    ///         CONST_SET => { /* ok */ }
+    ///         _ => panic!("match fell through?"),
+    ///     }
+    /// }
+    /// ```
+    ///
+    /// {{produces}}
+    ///
+    /// ### Explanation
+    ///
+    /// Previous versions of Rust accepted constants in patterns, even if those constants' types
+    /// did not have `PartialEq` implemented. The compiler falls back to comparing the value
+    /// field-by-field. In the future we'd like to ensure that pattern matching always
+    /// follows `PartialEq` semantics, so that trait bound will become a requirement for
+    /// matching on constants.
+    pub CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
+    Warn,
+    "constant in pattern does not implement `PartialEq`",
+    @future_incompatible = FutureIncompatibleInfo {
+        reason: FutureIncompatibilityReason::FutureReleaseErrorReportInDeps,
+        reference: "issue #116122 <https://github.com/rust-lang/rust/issues/116122>",
+    };
+}
+
+declare_lint! {
     /// The `ambiguous_associated_items` lint detects ambiguity between
     /// [associated items] and [enum variants].
     ///
@@ -3356,6 +3408,7 @@ declare_lint_pass! {
         CONFLICTING_REPR_HINTS,
         CONST_EVALUATABLE_UNCHECKED,
         CONST_ITEM_MUTATION,
+        CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
         DEAD_CODE,
         DEPRECATED,
         DEPRECATED_CFG_ATTR_CRATE_TYPE_NAME,
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 84e7ecb0b88..7ba589c3b5a 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -785,16 +785,7 @@ macro_rules! declare_tool_lint {
     );
 }
 
-/// Declares a static `LintArray` and return it as an expression.
-#[macro_export]
-macro_rules! lint_array {
-    ($( $lint:expr ),* ,) => { lint_array!( $($lint),* ) };
-    ($( $lint:expr ),*) => {{
-        vec![$($lint),*]
-    }}
-}
-
-pub type LintArray = Vec<&'static Lint>;
+pub type LintVec = Vec<&'static Lint>;
 
 pub trait LintPass {
     fn name(&self) -> &'static str;
@@ -808,7 +799,7 @@ macro_rules! impl_lint_pass {
             fn name(&self) -> &'static str { stringify!($ty) }
         }
         impl $ty {
-            pub fn get_lints() -> $crate::LintArray { $crate::lint_array!($($lint),*) }
+            pub fn get_lints() -> $crate::LintVec { vec![$($lint),*] }
         }
     };
 }
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 461b5290e69..b729c40228b 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -416,6 +416,7 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
     bool RelaxELFRelocations,
     bool UseInitArray,
     const char *SplitDwarfFile,
+    const char *OutputObjFile,
     const char *DebugInfoCompression,
     bool ForceEmulatedTls,
     const char *ArgsCstrBuff, size_t ArgsCstrBuffLen) {
@@ -448,6 +449,9 @@ extern "C" LLVMTargetMachineRef LLVMRustCreateTargetMachine(
   if (SplitDwarfFile) {
       Options.MCOptions.SplitDwarfFile = SplitDwarfFile;
   }
+  if (OutputObjFile) {
+      Options.ObjectFilenameForDebug = OutputObjFile;
+  }
 #if LLVM_VERSION_GE(16, 0)
   if (!strcmp("zlib", DebugInfoCompression) && llvm::compression::zlib::isAvailable()) {
     Options.CompressDebugSections = DebugCompressionType::Zlib;
diff --git a/compiler/rustc_metadata/src/rmeta/decoder.rs b/compiler/rustc_metadata/src/rmeta/decoder.rs
index 8ea9c60e4f2..b189e79df56 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder.rs
@@ -24,7 +24,6 @@ use rustc_middle::middle::exported_symbols::{ExportedSymbol, SymbolExportInfo};
 use rustc_middle::mir::interpret::{AllocDecodingSession, AllocDecodingState};
 use rustc_middle::ty::codec::TyDecoder;
 use rustc_middle::ty::fast_reject::SimplifiedType;
-use rustc_middle::ty::GeneratorDiagnosticData;
 use rustc_middle::ty::{self, ParameterizedOverTcx, Ty, TyCtxt, Visibility};
 use rustc_serialize::opaque::MemDecoder;
 use rustc_serialize::{Decodable, Decoder};
@@ -1750,24 +1749,6 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
             .clone()
     }
 
-    fn get_generator_diagnostic_data(
-        self,
-        tcx: TyCtxt<'tcx>,
-        id: DefIndex,
-    ) -> Option<GeneratorDiagnosticData<'tcx>> {
-        self.root
-            .tables
-            .generator_diagnostic_data
-            .get(self, id)
-            .map(|param| param.decode((self, tcx)))
-            .map(|generator_data| GeneratorDiagnosticData {
-                generator_interior_types: generator_data.generator_interior_types,
-                hir_owner: generator_data.hir_owner,
-                nodes_types: generator_data.nodes_types,
-                adjustments: generator_data.adjustments,
-            })
-    }
-
     fn get_attr_flags(self, index: DefIndex) -> AttrFlags {
         self.root.tables.attr_flags.get(self, index)
     }
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index b682a153c77..f27eee0d79a 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -210,6 +210,7 @@ provide! { tcx, def_id, other, cdata,
     inferred_outlives_of => { table_defaulted_array }
     super_predicates_of => { table }
     type_of => { table }
+    type_alias_is_lazy => { cdata.root.tables.type_alias_is_lazy.get(cdata, def_id.index) }
     variances_of => { table }
     fn_sig => { table }
     codegen_fn_attrs => { table }
@@ -374,7 +375,6 @@ provide! { tcx, def_id, other, cdata,
 
     crate_extern_paths => { cdata.source().paths().cloned().collect() }
     expn_that_defined => { cdata.get_expn_that_defined(def_id.index, tcx.sess) }
-    generator_diagnostic_data => { cdata.get_generator_diagnostic_data(tcx, def_id.index) }
     is_doc_hidden => { cdata.get_attr_flags(def_id.index).contains(AttrFlags::IS_DOC_HIDDEN) }
     doc_link_resolutions => { tcx.arena.alloc(cdata.get_doc_link_resolutions(def_id.index)) }
     doc_link_traits_in_scope => {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index cc7ae932e11..a4ba943275e 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -31,7 +31,6 @@ use rustc_middle::query::Providers;
 use rustc_middle::traits::specialization_graph;
 use rustc_middle::ty::codec::TyEncoder;
 use rustc_middle::ty::fast_reject::{self, SimplifiedType, TreatParams};
-use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{self, AssocItemContainer, SymbolName, Ty, TyCtxt};
 use rustc_middle::util::common::to_readable_str;
 use rustc_serialize::{opaque, Decodable, Decoder, Encodable, Encoder};
@@ -827,7 +826,7 @@ fn should_encode_span(def_kind: DefKind) -> bool {
         | DefKind::Enum
         | DefKind::Variant
         | DefKind::Trait
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::TraitAlias
         | DefKind::AssocTy
@@ -862,7 +861,7 @@ fn should_encode_attrs(def_kind: DefKind) -> bool {
         | DefKind::Enum
         | DefKind::Variant
         | DefKind::Trait
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::TraitAlias
         | DefKind::AssocTy
@@ -903,7 +902,7 @@ fn should_encode_expn_that_defined(def_kind: DefKind) -> bool {
         | DefKind::Variant
         | DefKind::Trait
         | DefKind::Impl { .. } => true,
-        DefKind::TyAlias { .. }
+        DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::TraitAlias
         | DefKind::AssocTy
@@ -938,7 +937,7 @@ fn should_encode_visibility(def_kind: DefKind) -> bool {
         | DefKind::Enum
         | DefKind::Variant
         | DefKind::Trait
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::TraitAlias
         | DefKind::AssocTy
@@ -982,7 +981,7 @@ fn should_encode_stability(def_kind: DefKind) -> bool {
         | DefKind::Const
         | DefKind::Fn
         | DefKind::ForeignMod
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::OpaqueTy
         | DefKind::Enum
         | DefKind::Union
@@ -1092,9 +1091,7 @@ fn should_encode_variances<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, def_kind: Def
         | DefKind::Closure
         | DefKind::Generator
         | DefKind::ExternCrate => false,
-        DefKind::TyAlias { lazy } => {
-            lazy || tcx.type_of(def_id).instantiate_identity().has_opaque_types()
-        }
+        DefKind::TyAlias => tcx.type_alias_is_lazy(def_id),
     }
 }
 
@@ -1105,7 +1102,7 @@ fn should_encode_generics(def_kind: DefKind) -> bool {
         | DefKind::Enum
         | DefKind::Variant
         | DefKind::Trait
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::TraitAlias
         | DefKind::AssocTy
@@ -1145,7 +1142,7 @@ fn should_encode_type(tcx: TyCtxt<'_>, def_id: LocalDefId, def_kind: DefKind) ->
         | DefKind::Fn
         | DefKind::Const
         | DefKind::Static(..)
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::Impl { .. }
         | DefKind::AssocFn
@@ -1205,7 +1202,7 @@ fn should_encode_fn_sig(def_kind: DefKind) -> bool {
         | DefKind::Const
         | DefKind::Static(..)
         | DefKind::Ctor(..)
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::OpaqueTy
         | DefKind::ForeignTy
         | DefKind::Impl { .. }
@@ -1246,7 +1243,7 @@ fn should_encode_constness(def_kind: DefKind) -> bool {
         | DefKind::AssocConst
         | DefKind::AnonConst
         | DefKind::Static(..)
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::OpaqueTy
         | DefKind::Impl { of_trait: false }
         | DefKind::ForeignTy
@@ -1279,7 +1276,7 @@ fn should_encode_const(def_kind: DefKind) -> bool {
         | DefKind::Field
         | DefKind::Fn
         | DefKind::Static(..)
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::OpaqueTy
         | DefKind::ForeignTy
         | DefKind::Impl { .. }
@@ -1439,7 +1436,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 }
             }
             if let DefKind::Generator = def_kind {
-                self.encode_info_for_generator(local_id);
+                let data = self.tcx.generator_kind(def_id).unwrap();
+                record!(self.tables.generator_kind[def_id] <- data);
             }
             if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind {
                 self.encode_info_for_adt(local_id);
@@ -1450,6 +1448,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             if let DefKind::Macro(_) = def_kind {
                 self.encode_info_for_macro(local_id);
             }
+            if let DefKind::TyAlias = def_kind {
+                self.tables
+                    .type_alias_is_lazy
+                    .set(def_id.index, self.tcx.type_alias_is_lazy(def_id));
+            }
             if let DefKind::OpaqueTy = def_kind {
                 self.encode_explicit_item_bounds(def_id);
                 self.tables
@@ -1612,8 +1615,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 record!(self.tables.closure_saved_names_of_captured_variables[def_id.to_def_id()]
                     <- tcx.closure_saved_names_of_captured_variables(def_id));
 
-                if tcx.sess.opts.unstable_opts.drop_tracking_mir
-                    && let DefKind::Generator = self.tcx.def_kind(def_id)
+                if let DefKind::Generator = self.tcx.def_kind(def_id)
                     && let Some(witnesses) = tcx.mir_generator_witnesses(def_id)
                 {
                     record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- witnesses);
@@ -1640,6 +1642,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             }
             record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id));
 
+            if let DefKind::Generator = self.tcx.def_kind(def_id)
+                && let Some(witnesses) = tcx.mir_generator_witnesses(def_id)
+            {
+                record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- witnesses);
+            }
+
             let instance = ty::InstanceDef::Item(def_id.to_def_id());
             let unused = tcx.unused_generic_params(instance);
             self.tables.unused_generic_params.set(def_id.local_def_index, unused);
@@ -1712,15 +1720,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         record!(self.tables.macro_definition[def_id.to_def_id()] <- &*macro_def.body);
     }
 
-    #[instrument(level = "debug", skip(self))]
-    fn encode_info_for_generator(&mut self, def_id: LocalDefId) {
-        let typeck_result: &'tcx ty::TypeckResults<'tcx> = self.tcx.typeck(def_id);
-        let data = self.tcx.generator_kind(def_id).unwrap();
-        let generator_diagnostic_data = typeck_result.get_generator_diagnostic_data();
-        record!(self.tables.generator_kind[def_id.to_def_id()] <- data);
-        record!(self.tables.generator_diagnostic_data[def_id.to_def_id()]  <- generator_diagnostic_data);
-    }
-
     fn encode_native_libraries(&mut self) -> LazyArray<NativeLib> {
         empty_proc_macro!(self);
         let used_libraries = self.tcx.native_libraries(LOCAL_CRATE);
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 43d5cf43a81..42764af52c4 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -23,7 +23,7 @@ use rustc_middle::middle::resolve_bound_vars::ObjectLifetimeDefault;
 use rustc_middle::mir;
 use rustc_middle::ty::fast_reject::SimplifiedType;
 use rustc_middle::ty::{self, ReprOptions, Ty, UnusedGenericParams};
-use rustc_middle::ty::{DeducedParamAttrs, GeneratorDiagnosticData, ParameterizedOverTcx, TyCtxt};
+use rustc_middle::ty::{DeducedParamAttrs, ParameterizedOverTcx, TyCtxt};
 use rustc_middle::util::Providers;
 use rustc_serialize::opaque::FileEncoder;
 use rustc_session::config::SymbolManglingVersion;
@@ -383,6 +383,7 @@ define_tables! {
     is_intrinsic: Table<DefIndex, bool>,
     is_macro_rules: Table<DefIndex, bool>,
     is_type_alias_impl_trait: Table<DefIndex, bool>,
+    type_alias_is_lazy: Table<DefIndex, bool>,
     attr_flags: Table<DefIndex, AttrFlags>,
     def_path_hashes: Table<DefIndex, DefPathHash>,
     explicit_item_bounds: Table<DefIndex, LazyArray<(ty::Clause<'static>, Span)>>,
@@ -452,7 +453,6 @@ define_tables! {
     // definitions from any given crate.
     def_keys: Table<DefIndex, LazyValue<DefKey>>,
     proc_macro_quoted_spans: Table<usize, LazyValue<Span>>,
-    generator_diagnostic_data: Table<DefIndex, LazyValue<GeneratorDiagnosticData<'static>>>,
     variant_data: Table<DefIndex, LazyValue<VariantData>>,
     assoc_container: Table<DefIndex, ty::AssocItemContainer>,
     macro_definition: Table<DefIndex, LazyValue<ast::DelimArgs>>,
diff --git a/compiler/rustc_metadata/src/rmeta/table.rs b/compiler/rustc_metadata/src/rmeta/table.rs
index d105dab4814..bb1320942b0 100644
--- a/compiler/rustc_metadata/src/rmeta/table.rs
+++ b/compiler/rustc_metadata/src/rmeta/table.rs
@@ -145,8 +145,7 @@ fixed_size_enum! {
         ( Enum                                     )
         ( Variant                                  )
         ( Trait                                    )
-        ( TyAlias { lazy: false }                  )
-        ( TyAlias { lazy: true }                   )
+        ( TyAlias                                  )
         ( ForeignTy                                )
         ( TraitAlias                               )
         ( AssocTy                                  )
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 3491c487f3e..4af2d83e9c7 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -196,9 +196,7 @@ impl<'hir> Map<'hir> {
                 ItemKind::Macro(_, macro_kind) => DefKind::Macro(macro_kind),
                 ItemKind::Mod(..) => DefKind::Mod,
                 ItemKind::OpaqueTy(..) => DefKind::OpaqueTy,
-                ItemKind::TyAlias(..) => {
-                    DefKind::TyAlias { lazy: self.tcx.features().lazy_type_alias }
-                }
+                ItemKind::TyAlias(..) => DefKind::TyAlias,
                 ItemKind::Enum(..) => DefKind::Enum,
                 ItemKind::Struct(..) => DefKind::Struct,
                 ItemKind::Union(..) => DefKind::Union,
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index 2f2597d6b22..41beca072bf 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -455,7 +455,7 @@ impl<'tcx> CanonicalVarValues<'tcx> {
                         CanonicalVarKind::Region(_) | CanonicalVarKind::PlaceholderRegion(_) => {
                             let br = ty::BoundRegion {
                                 var: ty::BoundVar::from_usize(i),
-                                kind: ty::BrAnon(None),
+                                kind: ty::BrAnon,
                             };
                             ty::Region::new_late_bound(tcx, ty::INNERMOST, br).into()
                         }
diff --git a/compiler/rustc_middle/src/mir/basic_blocks.rs b/compiler/rustc_middle/src/mir/basic_blocks.rs
index cd770c395e4..3ecd5b9cd34 100644
--- a/compiler/rustc_middle/src/mir/basic_blocks.rs
+++ b/compiler/rustc_middle/src/mir/basic_blocks.rs
@@ -63,11 +63,14 @@ impl<'tcx> BasicBlocks<'tcx> {
     }
 
     /// Returns basic blocks in a reverse postorder.
+    ///
+    /// See [`traversal::reverse_postorder`]'s docs to learn what is preorder traversal.
+    ///
+    /// [`traversal::reverse_postorder`]: crate::mir::traversal::reverse_postorder
     #[inline]
     pub fn reverse_postorder(&self) -> &[BasicBlock] {
         self.cache.reverse_postorder.get_or_init(|| {
-            let mut rpo: Vec<_> =
-                Postorder::new(&self.basic_blocks, START_BLOCK).map(|(bb, _)| bb).collect();
+            let mut rpo: Vec<_> = Postorder::new(&self.basic_blocks, START_BLOCK).collect();
             rpo.reverse();
             rpo
         })
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index 349b32c10fb..76567c3f6b0 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -1146,10 +1146,10 @@ fn post_fmt_projection(projection: &[PlaceElem<'_>], fmt: &mut Formatter<'_>) ->
             ProjectionElem::ConstantIndex { offset, min_length, from_end: true } => {
                 write!(fmt, "[-{offset:?} of {min_length:?}]")?;
             }
-            ProjectionElem::Subslice { from, to, from_end: true } if to == 0 => {
+            ProjectionElem::Subslice { from, to: 0, from_end: true } => {
                 write!(fmt, "[{from:?}:]")?;
             }
-            ProjectionElem::Subslice { from, to, from_end: true } if from == 0 => {
+            ProjectionElem::Subslice { from: 0, to, from_end: true } => {
                 write!(fmt, "[:-{to:?}]")?;
             }
             ProjectionElem::Subslice { from, to, from_end: true } => {
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index c157b7052ab..c74a9536b63 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -414,8 +414,7 @@ impl<'tcx> ClosureOutlivesSubjectTy<'tcx> {
     pub fn bind(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Self {
         let inner = tcx.fold_regions(ty, |r, depth| match r.kind() {
             ty::ReVar(vid) => {
-                let br =
-                    ty::BoundRegion { var: ty::BoundVar::new(vid.index()), kind: ty::BrAnon(None) };
+                let br = ty::BoundRegion { var: ty::BoundVar::new(vid.index()), kind: ty::BrAnon };
                 ty::Region::new_late_bound(tcx, depth, br)
             }
             _ => bug!("unexpected region in ClosureOutlivesSubjectTy: {r:?}"),
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 8f651b2a2db..55f895f73b4 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -139,6 +139,7 @@ pub enum RuntimePhase {
     /// * [`TerminatorKind::Yield`]
     /// * [`TerminatorKind::GeneratorDrop`]
     /// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array`
+    /// * [`PlaceElem::OpaqueCast`]
     ///
     /// And the following variants are allowed:
     /// * [`StatementKind::Retag`]
@@ -1333,7 +1334,7 @@ pub enum AggregateKind<'tcx> {
     Generator(DefId, GenericArgsRef<'tcx>, hir::Movability),
 }
 
-#[derive(Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
 pub enum NullOp<'tcx> {
     /// Returns the size of a value of that type
     SizeOf,
diff --git a/compiler/rustc_middle/src/mir/traversal.rs b/compiler/rustc_middle/src/mir/traversal.rs
index ec16a8470c4..a1ff8410eac 100644
--- a/compiler/rustc_middle/src/mir/traversal.rs
+++ b/compiler/rustc_middle/src/mir/traversal.rs
@@ -41,6 +41,12 @@ impl<'a, 'tcx> Preorder<'a, 'tcx> {
     }
 }
 
+/// Preorder traversal of a graph.
+///
+/// This function creates an iterator over the `Body`'s basic blocks, that
+/// returns basic blocks in a preorder.
+///
+/// See [`Preorder`]'s docs to learn what is preorder traversal.
 pub fn preorder<'a, 'tcx>(body: &'a Body<'tcx>) -> Preorder<'a, 'tcx> {
     Preorder::new(body, START_BLOCK)
 }
@@ -178,7 +184,7 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
         // When we yield `C` and call `traverse_successor`, we push `B` to the stack, but
         // since we've already visited `E`, that child isn't added to the stack. The last
         // two iterations yield `B` and finally `A` for a final traversal of [E, D, C, B, A]
-        while let Some(&mut (_, ref mut iter)) = self.visit_stack.last_mut() && let Some(bb) = iter.next_back() {
+        while let Some(bb) = self.visit_stack.last_mut().and_then(|(_, iter)| iter.next_back()) {
             if self.visited.insert(bb) {
                 if let Some(term) = &self.basic_blocks[bb].terminator {
                     self.visit_stack.push((bb, term.successors()));
@@ -188,16 +194,14 @@ impl<'a, 'tcx> Postorder<'a, 'tcx> {
     }
 }
 
-impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
-    type Item = (BasicBlock, &'a BasicBlockData<'tcx>);
+impl<'tcx> Iterator for Postorder<'_, 'tcx> {
+    type Item = BasicBlock;
 
-    fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> {
-        let next = self.visit_stack.pop();
-        if next.is_some() {
-            self.traverse_successor();
-        }
+    fn next(&mut self) -> Option<BasicBlock> {
+        let (bb, _) = self.visit_stack.pop()?;
+        self.traverse_successor();
 
-        next.map(|(bb, _)| (bb, &self.basic_blocks[bb]))
+        Some(bb)
     }
 
     fn size_hint(&self) -> (usize, Option<usize>) {
@@ -215,10 +219,14 @@ impl<'a, 'tcx> Iterator for Postorder<'a, 'tcx> {
     }
 }
 
-/// Creates an iterator over the `Body`'s basic blocks, that:
+/// Postorder traversal of a graph.
+///
+/// This function creates an iterator over the `Body`'s basic blocks, that:
 /// - returns basic blocks in a postorder,
 /// - traverses the `BasicBlocks` CFG cache's reverse postorder backwards, and does not cache the
 ///   postorder itself.
+///
+/// See [`Postorder`]'s docs to learn what is postorder traversal.
 pub fn postorder<'a, 'tcx>(
     body: &'a Body<'tcx>,
 ) -> impl Iterator<Item = (BasicBlock, &'a BasicBlockData<'tcx>)> + ExactSizeIterator + DoubleEndedIterator
@@ -226,7 +234,28 @@ pub fn postorder<'a, 'tcx>(
     reverse_postorder(body).rev()
 }
 
-/// Reverse postorder traversal of a graph
+/// Returns an iterator over all basic blocks reachable from the `START_BLOCK` in no particular
+/// order.
+///
+/// This is clearer than writing `preorder` in cases where the order doesn't matter.
+pub fn reachable<'a, 'tcx>(
+    body: &'a Body<'tcx>,
+) -> impl 'a + Iterator<Item = (BasicBlock, &'a BasicBlockData<'tcx>)> {
+    preorder(body)
+}
+
+/// Returns a `BitSet` containing all basic blocks reachable from the `START_BLOCK`.
+pub fn reachable_as_bitset(body: &Body<'_>) -> BitSet<BasicBlock> {
+    let mut iter = preorder(body);
+    iter.by_ref().for_each(drop);
+    iter.visited
+}
+
+/// Reverse postorder traversal of a graph.
+///
+/// This function creates an iterator over the `Body`'s basic blocks, that:
+/// - returns basic blocks in a reverse postorder,
+/// - makes use of the `BasicBlocks` CFG cache's reverse postorder.
 ///
 /// Reverse postorder is the reverse order of a postorder traversal.
 /// This is different to a preorder traversal and represents a natural
@@ -246,65 +275,6 @@ pub fn postorder<'a, 'tcx>(
 /// A reverse postorder traversal of this graph is either `A B C D` or `A C B D`
 /// Note that for a graph containing no loops (i.e., A DAG), this is equivalent to
 /// a topological sort.
-///
-/// Construction of a `ReversePostorder` traversal requires doing a full
-/// postorder traversal of the graph, therefore this traversal should be
-/// constructed as few times as possible. Use the `reset` method to be able
-/// to re-use the traversal
-#[derive(Clone)]
-pub struct ReversePostorder<'a, 'tcx> {
-    body: &'a Body<'tcx>,
-    blocks: Vec<BasicBlock>,
-    idx: usize,
-}
-
-impl<'a, 'tcx> ReversePostorder<'a, 'tcx> {
-    pub fn new(body: &'a Body<'tcx>, root: BasicBlock) -> ReversePostorder<'a, 'tcx> {
-        let blocks: Vec<_> = Postorder::new(&body.basic_blocks, root).map(|(bb, _)| bb).collect();
-        let len = blocks.len();
-        ReversePostorder { body, blocks, idx: len }
-    }
-}
-
-impl<'a, 'tcx> Iterator for ReversePostorder<'a, 'tcx> {
-    type Item = (BasicBlock, &'a BasicBlockData<'tcx>);
-
-    fn next(&mut self) -> Option<(BasicBlock, &'a BasicBlockData<'tcx>)> {
-        if self.idx == 0 {
-            return None;
-        }
-        self.idx -= 1;
-
-        self.blocks.get(self.idx).map(|&bb| (bb, &self.body[bb]))
-    }
-
-    fn size_hint(&self) -> (usize, Option<usize>) {
-        (self.idx, Some(self.idx))
-    }
-}
-
-impl<'a, 'tcx> ExactSizeIterator for ReversePostorder<'a, 'tcx> {}
-
-/// Returns an iterator over all basic blocks reachable from the `START_BLOCK` in no particular
-/// order.
-///
-/// This is clearer than writing `preorder` in cases where the order doesn't matter.
-pub fn reachable<'a, 'tcx>(
-    body: &'a Body<'tcx>,
-) -> impl 'a + Iterator<Item = (BasicBlock, &'a BasicBlockData<'tcx>)> {
-    preorder(body)
-}
-
-/// Returns a `BitSet` containing all basic blocks reachable from the `START_BLOCK`.
-pub fn reachable_as_bitset(body: &Body<'_>) -> BitSet<BasicBlock> {
-    let mut iter = preorder(body);
-    (&mut iter).for_each(drop);
-    iter.visited
-}
-
-/// Creates an iterator over the `Body`'s basic blocks, that:
-/// - returns basic blocks in a reverse postorder,
-/// - makes use of the `BasicBlocks` CFG cache's reverse postorder.
 pub fn reverse_postorder<'a, 'tcx>(
     body: &'a Body<'tcx>,
 ) -> impl Iterator<Item = (BasicBlock, &'a BasicBlockData<'tcx>)> + ExactSizeIterator + DoubleEndedIterator
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 6928f59c3fd..340c5a769db 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -44,7 +44,6 @@ use crate::traits::{
 use crate::ty::fast_reject::SimplifiedType;
 use crate::ty::layout::ValidityRequirement;
 use crate::ty::util::AlwaysRequiresDrop;
-use crate::ty::GeneratorDiagnosticData;
 use crate::ty::TyCtxtFeed;
 use crate::ty::{
     self, print::describe_as_module, CrateInherentImpls, ParamEnvAnd, Ty, TyCtxt,
@@ -230,7 +229,7 @@ rustc_queries! {
             action = {
                 use rustc_hir::def::DefKind;
                 match tcx.def_kind(key) {
-                    DefKind::TyAlias { .. } => "expanding type alias",
+                    DefKind::TyAlias => "expanding type alias",
                     DefKind::TraitAlias => "expanding trait alias",
                     _ => "computing type of",
                 }
@@ -252,6 +251,14 @@ rustc_queries! {
         }
     }
 
+    query type_alias_is_lazy(key: DefId) -> bool {
+        desc { |tcx|
+            "computing whether `{path}` is a lazy type alias",
+            path = tcx.def_path_str(key),
+        }
+        separate_provide_extern
+    }
+
     query collect_return_position_impl_trait_in_trait_tys(key: DefId)
         -> Result<&'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed>
     {
@@ -2149,12 +2156,6 @@ rustc_queries! {
         desc { "computing the backend features for CLI flags" }
     }
 
-    query generator_diagnostic_data(key: DefId) -> &'tcx Option<GeneratorDiagnosticData<'tcx>> {
-        arena_cache
-        desc { |tcx| "looking up generator diagnostic data of `{}`", tcx.def_path_str(key) }
-        separate_provide_extern
-    }
-
     query check_validity_requirement(key: (ValidityRequirement, ty::ParamEnvAnd<'tcx, Ty<'tcx>>)) -> Result<bool, &'tcx ty::layout::LayoutError<'tcx>> {
         desc { "checking validity requirement for `{}`: {}", key.1.value, key.0 }
     }
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 8c39614903c..89934e4350e 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -732,12 +732,16 @@ pub enum PatKind<'tcx> {
     },
 
     /// One of the following:
-    /// * `&str`, which will be handled as a string pattern and thus exhaustiveness
-    ///   checking will detect if you use the same string twice in different patterns.
-    /// * integer, bool, char or float, which will be handled by exhaustiveness to cover exactly
-    ///   its own value, similar to `&str`, but these values are much simpler.
-    /// * Opaque constants, that must not be matched structurally. So anything that does not derive
-    ///   `PartialEq` and `Eq`.
+    /// * `&str` (represented as a valtree), which will be handled as a string pattern and thus
+    ///   exhaustiveness checking will detect if you use the same string twice in different
+    ///   patterns.
+    /// * integer, bool, char or float (represented as a valtree), which will be handled by
+    ///   exhaustiveness to cover exactly its own value, similar to `&str`, but these values are
+    ///   much simpler.
+    /// * Opaque constants (represented as `mir::ConstValue`), that must not be matched
+    ///   structurally. So anything that does not derive `PartialEq` and `Eq`.
+    ///
+    /// These are always compared with the matched place using (the semantics of) `PartialEq`.
     Constant {
         value: mir::Const<'tcx>,
     },
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index eef193a657d..99b750c9afc 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -299,6 +299,10 @@ pub enum ObligationCauseCode<'tcx> {
     SizedYieldType,
     /// Inline asm operand type must be `Sized`.
     InlineAsmSized,
+    /// Captured closure type must be `Sized`.
+    SizedClosureCapture(LocalDefId),
+    /// Types live across generator yields must be `Sized`.
+    SizedGeneratorInterior(LocalDefId),
     /// `[expr; N]` requires `type_of(expr): Copy`.
     RepeatElementCopy {
         /// If element is a `const fn` we display a help message suggesting to move the
diff --git a/compiler/rustc_middle/src/ty/adt.rs b/compiler/rustc_middle/src/ty/adt.rs
index 219927f5ab4..f50969dd967 100644
--- a/compiler/rustc_middle/src/ty/adt.rs
+++ b/compiler/rustc_middle/src/ty/adt.rs
@@ -448,7 +448,7 @@ impl<'tcx> AdtDef<'tcx> {
             Res::Def(DefKind::Ctor(..), cid) => self.variant_with_ctor_id(cid),
             Res::Def(DefKind::Struct, _)
             | Res::Def(DefKind::Union, _)
-            | Res::Def(DefKind::TyAlias { .. }, _)
+            | Res::Def(DefKind::TyAlias, _)
             | Res::Def(DefKind::AssocTy, _)
             | Res::SelfTyParam { .. }
             | Res::SelfTyAlias { .. }
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index 7c05deae90a..dff7ff8c66b 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -566,6 +566,5 @@ impl_binder_encode_decode! {
     ty::TraitPredicate<'tcx>,
     ty::ExistentialPredicate<'tcx>,
     ty::TraitRef<'tcx>,
-    Vec<ty::GeneratorInteriorTypeCause<'tcx>>,
     ty::ExistentialTraitRef<'tcx>,
 }
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 25eafce0d9e..c06b8b2dfa0 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -318,7 +318,7 @@ pub struct CommonLifetimes<'tcx> {
     pub re_vars: Vec<Region<'tcx>>,
 
     /// Pre-interned values of the form:
-    /// `ReLateBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon(None) })`
+    /// `ReLateBound(DebruijnIndex(i), BoundRegion { var: v, kind: BrAnon })`
     /// for small values of `i` and `v`.
     pub re_late_bounds: Vec<Vec<Region<'tcx>>>,
 }
@@ -395,7 +395,7 @@ impl<'tcx> CommonLifetimes<'tcx> {
                     .map(|v| {
                         mk(ty::ReLateBound(
                             ty::DebruijnIndex::from(i),
-                            ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BrAnon(None) },
+                            ty::BoundRegion { var: ty::BoundVar::from(v), kind: ty::BrAnon },
                         ))
                     })
                     .collect()
@@ -1114,7 +1114,7 @@ impl<'tcx> TyCtxt<'tcx> {
         if let Some(hir::FnDecl { output: hir::FnRetTy::Return(hir_output), .. }) = self.hir().fn_decl_by_hir_id(hir_id)
             && let hir::TyKind::Path(hir::QPath::Resolved(
                 None,
-                hir::Path { res: hir::def::Res::Def(DefKind::TyAlias { .. }, def_id), .. }, )) = hir_output.kind
+                hir::Path { res: hir::def::Res::Def(DefKind::TyAlias, def_id), .. }, )) = hir_output.kind
             && let Some(local_id) = def_id.as_local()
             && let Some(alias_ty) = self.hir().get_by_def_id(local_id).alias_ty() // it is type alias
             && let Some(alias_generics) = self.hir().get_by_def_id(local_id).generics()
@@ -1384,7 +1384,6 @@ impl<'tcx> TyCtxt<'tcx> {
                     Placeholder,
                     Generator,
                     GeneratorWitness,
-                    GeneratorWitnessMIR,
                     Dynamic,
                     Closure,
                     Tuple,
diff --git a/compiler/rustc_middle/src/ty/diagnostics.rs b/compiler/rustc_middle/src/ty/diagnostics.rs
index e7ebb985ca4..f03813a459b 100644
--- a/compiler/rustc_middle/src/ty/diagnostics.rs
+++ b/compiler/rustc_middle/src/ty/diagnostics.rs
@@ -493,7 +493,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for IsSuggestableVisitor<'tcx> {
             Alias(Opaque, AliasTy { def_id, .. }) => {
                 let parent = self.tcx.parent(def_id);
                 let parent_ty = self.tcx.type_of(parent).instantiate_identity();
-                if let DefKind::TyAlias { .. } | DefKind::AssocTy = self.tcx.def_kind(parent)
+                if let DefKind::TyAlias | DefKind::AssocTy = self.tcx.def_kind(parent)
                     && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *parent_ty.kind()
                     && parent_opaque_def_id == def_id
                 {
@@ -577,7 +577,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for MakeSuggestableFolder<'tcx> {
             Alias(Opaque, AliasTy { def_id, .. }) => {
                 let parent = self.tcx.parent(def_id);
                 let parent_ty = self.tcx.type_of(parent).instantiate_identity();
-                if let hir::def::DefKind::TyAlias { .. } | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent)
+                if let hir::def::DefKind::TyAlias | hir::def::DefKind::AssocTy = self.tcx.def_kind(parent)
                     && let Alias(Opaque, AliasTy { def_id: parent_opaque_def_id, .. }) = *parent_ty.kind()
                     && parent_opaque_def_id == def_id
                 {
diff --git a/compiler/rustc_middle/src/ty/error.rs b/compiler/rustc_middle/src/ty/error.rs
index f939d466078..459c8dfb596 100644
--- a/compiler/rustc_middle/src/ty/error.rs
+++ b/compiler/rustc_middle/src/ty/error.rs
@@ -242,8 +242,7 @@ impl<'tcx> Ty<'tcx> {
             ty::Dynamic(..) => "trait object".into(),
             ty::Closure(..) => "closure".into(),
             ty::Generator(def_id, ..) => tcx.generator_kind(def_id).unwrap().descr().into(),
-            ty::GeneratorWitness(..) |
-            ty::GeneratorWitnessMIR(..) => "generator witness".into(),
+            ty::GeneratorWitness(..) => "generator witness".into(),
             ty::Infer(ty::TyVar(_)) => "inferred type".into(),
             ty::Infer(ty::IntVar(_)) => "integer".into(),
             ty::Infer(ty::FloatVar(_)) => "floating-point number".into(),
@@ -295,7 +294,7 @@ impl<'tcx> Ty<'tcx> {
             ty::Dynamic(..) => "trait object".into(),
             ty::Closure(..) => "closure".into(),
             ty::Generator(def_id, ..) => tcx.generator_kind(def_id).unwrap().descr().into(),
-            ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => "generator witness".into(),
+            ty::GeneratorWitness(..) => "generator witness".into(),
             ty::Tuple(..) => "tuple".into(),
             ty::Placeholder(..) => "higher-ranked type".into(),
             ty::Bound(..) => "bound type variable".into(),
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 668aa4521c1..16935d5b380 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -29,8 +29,7 @@ pub enum SimplifiedType {
     Trait(DefId),
     Closure(DefId),
     Generator(DefId),
-    GeneratorWitness(usize),
-    GeneratorWitnessMIR(DefId),
+    GeneratorWitness(DefId),
     Function(usize),
     Placeholder,
 }
@@ -130,10 +129,7 @@ pub fn simplify_type<'tcx>(
         ty::Ref(_, _, mutbl) => Some(SimplifiedType::Ref(mutbl)),
         ty::FnDef(def_id, _) | ty::Closure(def_id, _) => Some(SimplifiedType::Closure(def_id)),
         ty::Generator(def_id, _, _) => Some(SimplifiedType::Generator(def_id)),
-        ty::GeneratorWitness(tys) => {
-            Some(SimplifiedType::GeneratorWitness(tys.skip_binder().len()))
-        }
-        ty::GeneratorWitnessMIR(def_id, _) => Some(SimplifiedType::GeneratorWitnessMIR(def_id)),
+        ty::GeneratorWitness(def_id, _) => Some(SimplifiedType::GeneratorWitness(def_id)),
         ty::Never => Some(SimplifiedType::Never),
         ty::Tuple(tys) => Some(SimplifiedType::Tuple(tys.len())),
         ty::FnPtr(f) => Some(SimplifiedType::Function(f.skip_binder().inputs().len())),
@@ -169,7 +165,7 @@ impl SimplifiedType {
             | SimplifiedType::Trait(d)
             | SimplifiedType::Closure(d)
             | SimplifiedType::Generator(d)
-            | SimplifiedType::GeneratorWitnessMIR(d) => Some(d),
+            | SimplifiedType::GeneratorWitness(d) => Some(d),
             _ => None,
         }
     }
@@ -240,7 +236,6 @@ impl DeepRejectCtxt {
             | ty::Closure(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Placeholder(..)
             | ty::Bound(..)
             | ty::Infer(_) => bug!("unexpected impl_ty: {impl_ty}"),
@@ -342,7 +337,7 @@ impl DeepRejectCtxt {
 
             ty::Error(_) => true,
 
-            ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => {
+            ty::GeneratorWitness(..) => {
                 bug!("unexpected obligation type: {:?}", obligation_ty)
             }
         }
diff --git a/compiler/rustc_middle/src/ty/flags.rs b/compiler/rustc_middle/src/ty/flags.rs
index 231635c086e..7ed31fbbfd8 100644
--- a/compiler/rustc_middle/src/ty/flags.rs
+++ b/compiler/rustc_middle/src/ty/flags.rs
@@ -127,11 +127,7 @@ impl FlagComputation {
                 self.add_ty(args.tupled_upvars_ty());
             }
 
-            &ty::GeneratorWitness(ts) => {
-                self.bound_computation(ts, |flags, ts| flags.add_tys(ts));
-            }
-
-            ty::GeneratorWitnessMIR(_, args) => {
+            ty::GeneratorWitness(_, args) => {
                 let should_remove_further_specializable =
                     !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
                 self.add_args(args);
diff --git a/compiler/rustc_middle/src/ty/fold.rs b/compiler/rustc_middle/src/ty/fold.rs
index 77cf6bee79d..00529a1e066 100644
--- a/compiler/rustc_middle/src/ty/fold.rs
+++ b/compiler/rustc_middle/src/ty/fold.rs
@@ -385,7 +385,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 let index = entry.index();
                 let var = ty::BoundVar::from_usize(index);
                 let kind = entry
-                    .or_insert_with(|| ty::BoundVariableKind::Region(ty::BrAnon(None)))
+                    .or_insert_with(|| ty::BoundVariableKind::Region(ty::BrAnon))
                     .expect_region();
                 let br = ty::BoundRegion { var, kind };
                 ty::Region::new_late_bound(self.tcx, ty::INNERMOST, br)
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 2b75f6c4e8f..0b0a708e42b 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -118,7 +118,7 @@ impl<'tcx> Instance<'tcx> {
     /// lifetimes erased, allowing a `ParamEnv` to be specified for use during normalization.
     pub fn ty(&self, tcx: TyCtxt<'tcx>, param_env: ty::ParamEnv<'tcx>) -> Ty<'tcx> {
         let ty = tcx.type_of(self.def.def_id());
-        tcx.subst_and_normalize_erasing_regions(self.args, param_env, ty)
+        tcx.instantiate_and_normalize_erasing_regions(self.args, param_env, ty)
     }
 
     /// Finds a crate that contains a monomorphization of this instance that
@@ -580,7 +580,7 @@ impl<'tcx> Instance<'tcx> {
         self.def.has_polymorphic_mir_body().then_some(self.args)
     }
 
-    pub fn subst_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T
+    pub fn instantiate_mir<T>(&self, tcx: TyCtxt<'tcx>, v: EarlyBinder<&T>) -> T
     where
         T: TypeFoldable<TyCtxt<'tcx>> + Copy,
     {
@@ -593,7 +593,7 @@ impl<'tcx> Instance<'tcx> {
     }
 
     #[inline(always)]
-    pub fn subst_mir_and_normalize_erasing_regions<T>(
+    pub fn instantiate_mir_and_normalize_erasing_regions<T>(
         &self,
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
@@ -603,14 +603,14 @@ impl<'tcx> Instance<'tcx> {
         T: TypeFoldable<TyCtxt<'tcx>> + Clone,
     {
         if let Some(args) = self.args_for_mir_body() {
-            tcx.subst_and_normalize_erasing_regions(args, param_env, v)
+            tcx.instantiate_and_normalize_erasing_regions(args, param_env, v)
         } else {
             tcx.normalize_erasing_regions(param_env, v.skip_binder())
         }
     }
 
     #[inline(always)]
-    pub fn try_subst_mir_and_normalize_erasing_regions<T>(
+    pub fn try_instantiate_mir_and_normalize_erasing_regions<T>(
         &self,
         tcx: TyCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
@@ -620,7 +620,7 @@ impl<'tcx> Instance<'tcx> {
         T: TypeFoldable<TyCtxt<'tcx>> + Clone,
     {
         if let Some(args) = self.args_for_mir_body() {
-            tcx.try_subst_and_normalize_erasing_regions(args, param_env, v)
+            tcx.try_instantiate_and_normalize_erasing_regions(args, param_env, v)
         } else {
             tcx.try_normalize_erasing_regions(param_env, v.skip_binder())
         }
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index 8b425ce0267..bccf5e83987 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -810,7 +810,6 @@ where
                 | ty::Never
                 | ty::FnDef(..)
                 | ty::GeneratorWitness(..)
-                | ty::GeneratorWitnessMIR(..)
                 | ty::Foreign(..)
                 | ty::Dynamic(_, _, ty::Dyn) => {
                     bug!("TyAndLayout::field({:?}): not applicable", this)
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index b050208b4a6..aa1e7f216a0 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -106,9 +106,8 @@ pub use self::sty::{
 };
 pub use self::trait_def::TraitDef;
 pub use self::typeck_results::{
-    CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations,
-    GeneratorDiagnosticData, GeneratorInteriorTypeCause, TypeckResults, UserType,
-    UserTypeAnnotationIndex,
+    CanonicalUserType, CanonicalUserTypeAnnotation, CanonicalUserTypeAnnotations, TypeckResults,
+    UserType, UserTypeAnnotationIndex,
 };
 
 pub mod _match;
diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
index 2415d50b278..fd125af2074 100644
--- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
+++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
@@ -134,8 +134,9 @@ impl<'tcx> TyCtxt<'tcx> {
     /// in-scope substitutions and then normalizing any associated
     /// types.
     /// Panics if normalization fails. In case normalization might fail
-    /// use `try_subst_and_normalize_erasing_regions` instead.
-    pub fn subst_and_normalize_erasing_regions<T>(
+    /// use `try_instantiate_and_normalize_erasing_regions` instead.
+    #[instrument(level = "debug", skip(self))]
+    pub fn instantiate_and_normalize_erasing_regions<T>(
         self,
         param_args: GenericArgsRef<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
@@ -144,22 +145,16 @@ impl<'tcx> TyCtxt<'tcx> {
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
-        debug!(
-            "subst_and_normalize_erasing_regions(\
-             param_args={:?}, \
-             value={:?}, \
-             param_env={:?})",
-            param_args, value, param_env,
-        );
         let substituted = value.instantiate(self, param_args);
         self.normalize_erasing_regions(param_env, substituted)
     }
 
     /// Monomorphizes a type from the AST by first applying the
     /// in-scope substitutions and then trying to normalize any associated
-    /// types. Contrary to `subst_and_normalize_erasing_regions` this does
+    /// types. Contrary to `instantiate_and_normalize_erasing_regions` this does
     /// not assume that normalization succeeds.
-    pub fn try_subst_and_normalize_erasing_regions<T>(
+    #[instrument(level = "debug", skip(self))]
+    pub fn try_instantiate_and_normalize_erasing_regions<T>(
         self,
         param_args: GenericArgsRef<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
@@ -168,13 +163,6 @@ impl<'tcx> TyCtxt<'tcx> {
     where
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
-        debug!(
-            "subst_and_normalize_erasing_regions(\
-             param_args={:?}, \
-             value={:?}, \
-             param_env={:?})",
-            param_args, value, param_env,
-        );
         let substituted = value.instantiate(self, param_args);
         self.try_normalize_erasing_regions(param_env, substituted)
     }
diff --git a/compiler/rustc_middle/src/ty/opaque_types.rs b/compiler/rustc_middle/src/ty/opaque_types.rs
index 0ff5ac90304..6491936c219 100644
--- a/compiler/rustc_middle/src/ty/opaque_types.rs
+++ b/compiler/rustc_middle/src/ty/opaque_types.rs
@@ -157,9 +157,9 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ReverseMapper<'tcx> {
                 Ty::new_generator(self.tcx, def_id, args, movability)
             }
 
-            ty::GeneratorWitnessMIR(def_id, args) => {
+            ty::GeneratorWitness(def_id, args) => {
                 let args = self.fold_closure_args(def_id, args);
-                Ty::new_generator_witness_mir(self.tcx, def_id, args)
+                Ty::new_generator_witness(self.tcx, def_id, args)
             }
 
             ty::Param(param) => {
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index f1093e88312..9aa673e4418 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -132,5 +132,4 @@ parameterized_over_tcx! {
     ty::Predicate,
     ty::Clause,
     ty::ClauseKind,
-    ty::GeneratorDiagnosticData,
 }
diff --git a/compiler/rustc_middle/src/ty/print/mod.rs b/compiler/rustc_middle/src/ty/print/mod.rs
index 05871d0bc39..aa8e2e30715 100644
--- a/compiler/rustc_middle/src/ty/print/mod.rs
+++ b/compiler/rustc_middle/src/ty/print/mod.rs
@@ -271,7 +271,7 @@ fn characteristic_def_id_of_type_cached<'a>(
         ty::FnDef(def_id, _)
         | ty::Closure(def_id, _)
         | ty::Generator(def_id, _, _)
-        | ty::GeneratorWitnessMIR(def_id, _)
+        | ty::GeneratorWitness(def_id, _)
         | ty::Foreign(def_id) => Some(def_id),
 
         ty::Bool
@@ -286,7 +286,6 @@ fn characteristic_def_id_of_type_cached<'a>(
         | ty::Infer(_)
         | ty::Bound(..)
         | ty::Error(_)
-        | ty::GeneratorWitness(..)
         | ty::Never
         | ty::Float(_) => None,
     }
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 5b833dde92c..2d7350387ca 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -360,7 +360,7 @@ pub trait PrettyPrinter<'tcx>:
                 self.write_str(get_local_name(&self, symbol, parent, parent_key).as_str())?;
                 self.write_str("::")?;
             } else if let DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::Trait
-                | DefKind::TyAlias { .. } | DefKind::Fn | DefKind::Const | DefKind::Static(_) = kind
+                | DefKind::TyAlias | DefKind::Fn | DefKind::Const | DefKind::Static(_) = kind
             {
             } else {
                 // If not covered above, like for example items out of `impl` blocks, fallback.
@@ -766,7 +766,7 @@ pub trait PrettyPrinter<'tcx>:
 
                 let parent = self.tcx().parent(def_id);
                 match self.tcx().def_kind(parent) {
-                    DefKind::TyAlias { .. } | DefKind::AssocTy => {
+                    DefKind::TyAlias | DefKind::AssocTy => {
                         // NOTE: I know we should check for NO_QUERIES here, but it's alright.
                         // `type_of` on a type alias or assoc type should never cause a cycle.
                         if let ty::Alias(ty::Opaque, ty::AliasTy { def_id: d, .. }) =
@@ -838,10 +838,7 @@ pub trait PrettyPrinter<'tcx>:
 
                 p!("}}")
             }
-            ty::GeneratorWitness(types) => {
-                p!(in_binder(&types));
-            }
-            ty::GeneratorWitnessMIR(did, args) => {
+            ty::GeneratorWitness(did, args) => {
                 p!(write("{{"));
                 if !self.tcx().sess.verbose() {
                     p!("generator witness");
@@ -2333,7 +2330,7 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
                 // If this is an anonymous placeholder, don't rename. Otherwise, in some
                 // async fns, we get a `for<'r> Send` bound
                 match kind {
-                    ty::BrAnon(..) | ty::BrEnv => r,
+                    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 };
@@ -2454,7 +2451,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> {
                             binder_level_idx: ty::DebruijnIndex,
                             br: ty::BoundRegion| {
                 let (name, kind) = match br.kind {
-                    ty::BrAnon(..) | ty::BrEnv => {
+                    ty::BrAnon | ty::BrEnv => {
                         let name = next_name(&self);
 
                         if let Some(lt_idx) = lifetime_idx {
@@ -3001,7 +2998,7 @@ fn for_each_def(tcx: TyCtxt<'_>, mut collect_fn: impl for<'b> FnMut(&'b Ident, N
 
             match child.res {
                 def::Res::Def(DefKind::AssocTy, _) => {}
-                def::Res::Def(DefKind::TyAlias { .. }, _) => {}
+                def::Res::Def(DefKind::TyAlias, _) => {}
                 def::Res::Def(defkind, def_id) => {
                     if let Some(ns) = defkind.ns() {
                         collect_fn(&child.ident, ns, def_id);
diff --git a/compiler/rustc_middle/src/ty/relate.rs b/compiler/rustc_middle/src/ty/relate.rs
index 47512d350e5..e9d763afa68 100644
--- a/compiler/rustc_middle/src/ty/relate.rs
+++ b/compiler/rustc_middle/src/ty/relate.rs
@@ -453,24 +453,14 @@ pub fn structurally_relate_tys<'tcx, R: TypeRelation<'tcx>>(
             Ok(Ty::new_generator(tcx, a_id, args, movability))
         }
 
-        (&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => {
-            // Wrap our types with a temporary GeneratorWitness struct
-            // inside the binder so we can related them
-            let a_types = a_types.map_bound(GeneratorWitness);
-            let b_types = b_types.map_bound(GeneratorWitness);
-            // Then remove the GeneratorWitness for the result
-            let types = relation.relate(a_types, b_types)?.map_bound(|witness| witness.0);
-            Ok(Ty::new_generator_witness(tcx, types))
-        }
-
-        (&ty::GeneratorWitnessMIR(a_id, a_args), &ty::GeneratorWitnessMIR(b_id, b_args))
+        (&ty::GeneratorWitness(a_id, a_args), &ty::GeneratorWitness(b_id, b_args))
             if a_id == b_id =>
         {
             // All GeneratorWitness types with the same id represent
             // the (anonymous) type of the same generator expression. So
             // all of their regions should be equated.
             let args = relation.relate(a_args, b_args)?;
-            Ok(Ty::new_generator_witness_mir(tcx, a_id, args))
+            Ok(Ty::new_generator_witness(tcx, a_id, args))
         }
 
         (&ty::Closure(a_id, a_args), &ty::Closure(b_id, b_args)) if a_id == b_id => {
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index b66c0f20990..2adbe9e0309 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -68,7 +68,7 @@ impl<'tcx> fmt::Debug for ty::adjustment::Adjustment<'tcx> {
 impl fmt::Debug for ty::BoundRegionKind {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         match *self {
-            ty::BrAnon(span) => write!(f, "BrAnon({span:?})"),
+            ty::BrAnon => write!(f, "BrAnon"),
             ty::BrNamed(did, name) => {
                 if did.is_crate_root() {
                     write!(f, "BrNamed({name})")
@@ -657,9 +657,8 @@ impl<'tcx> TypeSuperFoldable<TyCtxt<'tcx>> for Ty<'tcx> {
             ty::Generator(did, args, movability) => {
                 ty::Generator(did, args.try_fold_with(folder)?, movability)
             }
-            ty::GeneratorWitness(types) => ty::GeneratorWitness(types.try_fold_with(folder)?),
-            ty::GeneratorWitnessMIR(did, args) => {
-                ty::GeneratorWitnessMIR(did, args.try_fold_with(folder)?)
+            ty::GeneratorWitness(did, args) => {
+                ty::GeneratorWitness(did, args.try_fold_with(folder)?)
             }
             ty::Closure(did, args) => ty::Closure(did, args.try_fold_with(folder)?),
             ty::Alias(kind, data) => ty::Alias(kind, data.try_fold_with(folder)?),
@@ -708,8 +707,7 @@ impl<'tcx> TypeSuperVisitable<TyCtxt<'tcx>> for Ty<'tcx> {
                 ty.visit_with(visitor)
             }
             ty::Generator(_did, ref args, _) => args.visit_with(visitor),
-            ty::GeneratorWitness(ref types) => types.visit_with(visitor),
-            ty::GeneratorWitnessMIR(_did, ref args) => args.visit_with(visitor),
+            ty::GeneratorWitness(_did, ref args) => args.visit_with(visitor),
             ty::Closure(_did, ref args) => args.visit_with(visitor),
             ty::Alias(_, ref data) => data.visit_with(visitor),
 
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index f0526a23714..1e57392e0e7 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -69,7 +69,7 @@ pub struct FreeRegion {
 #[derive(HashStable)]
 pub enum BoundRegionKind {
     /// An anonymous region parameter for a given fn (&T)
-    BrAnon(Option<Span>),
+    BrAnon,
 
     /// Named region parameters for functions (a in &'a T)
     ///
@@ -1223,7 +1223,7 @@ impl<'tcx> AliasTy<'tcx> {
             DefKind::AssocTy if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) => ty::Inherent,
             DefKind::AssocTy => ty::Projection,
             DefKind::OpaqueTy => ty::Opaque,
-            DefKind::TyAlias { .. } => ty::Weak,
+            DefKind::TyAlias => ty::Weak,
             kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
         }
     }
@@ -1465,7 +1465,7 @@ impl<'tcx> Region<'tcx> {
         bound_region: ty::BoundRegion,
     ) -> Region<'tcx> {
         // Use a pre-interned one when possible.
-        if let ty::BoundRegion { var, kind: ty::BrAnon(None) } = bound_region
+        if let ty::BoundRegion { var, kind: ty::BrAnon } = bound_region
             && let Some(inner) = tcx.lifetimes.re_late_bounds.get(debruijn.as_usize())
             && let Some(re) = inner.get(var.as_usize()).copied()
         {
@@ -1959,7 +1959,7 @@ impl<'tcx> Ty<'tcx> {
             (kind, tcx.def_kind(alias_ty.def_id)),
             (ty::Opaque, DefKind::OpaqueTy)
                 | (ty::Projection | ty::Inherent, DefKind::AssocTy)
-                | (ty::Weak, DefKind::TyAlias { .. })
+                | (ty::Weak, DefKind::TyAlias)
         );
         Ty::new(tcx, Alias(kind, alias_ty))
     }
@@ -2165,18 +2165,10 @@ impl<'tcx> Ty<'tcx> {
     #[inline]
     pub fn new_generator_witness(
         tcx: TyCtxt<'tcx>,
-        types: ty::Binder<'tcx, &'tcx List<Ty<'tcx>>>,
-    ) -> Ty<'tcx> {
-        Ty::new(tcx, GeneratorWitness(types))
-    }
-
-    #[inline]
-    pub fn new_generator_witness_mir(
-        tcx: TyCtxt<'tcx>,
         id: DefId,
         args: GenericArgsRef<'tcx>,
     ) -> Ty<'tcx> {
-        Ty::new(tcx, GeneratorWitnessMIR(id, args))
+        Ty::new(tcx, GeneratorWitness(id, args))
     }
 
     // misc
@@ -2706,7 +2698,6 @@ impl<'tcx> Ty<'tcx> {
             | ty::Dynamic(..)
             | ty::Closure(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Never
             | ty::Tuple(_)
             | ty::Error(_)
@@ -2742,7 +2733,6 @@ impl<'tcx> Ty<'tcx> {
             | ty::Ref(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Array(..)
             | ty::Closure(..)
             | ty::Never
@@ -2831,7 +2821,6 @@ impl<'tcx> Ty<'tcx> {
             | ty::Ref(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Array(..)
             | ty::Closure(..)
             | ty::Never
@@ -2894,7 +2883,7 @@ impl<'tcx> Ty<'tcx> {
             // anything with custom metadata it might be more complicated.
             ty::Ref(_, _, hir::Mutability::Not) | ty::RawPtr(..) => false,
 
-            ty::Generator(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => false,
+            ty::Generator(..) | ty::GeneratorWitness(..) => false,
 
             // Might be, but not "trivial" so just giving the safe answer.
             ty::Adt(..) | ty::Closure(..) => false,
@@ -2970,8 +2959,7 @@ impl<'tcx> Ty<'tcx> {
             | Dynamic(_, _, _)
             | Closure(_, _)
             | Generator(_, _, _)
-            | GeneratorWitness(_)
-            | GeneratorWitnessMIR(_, _)
+            | GeneratorWitness(..)
             | Never
             | Tuple(_) => true,
             Error(_) | Infer(_) | Alias(_, _) | Param(_) | Bound(_, _) | Placeholder(_) => false,
@@ -3022,7 +3010,7 @@ mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
     // tidy-alphabetical-start
-    static_assert_size!(RegionKind<'_>, 28);
+    static_assert_size!(RegionKind<'_>, 24);
     static_assert_size!(TyKind<'_>, 32);
     // tidy-alphabetical-end
 }
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index 69c4c588c44..a44224e4dc7 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -189,10 +189,6 @@ pub struct TypeckResults<'tcx> {
     /// Details may be find in `rustc_hir_analysis::check::rvalue_scopes`.
     pub rvalue_scopes: RvalueScopes,
 
-    /// Stores the type, expression, span and optional scope span of all types
-    /// that are live across the yield of this generator (if a generator).
-    pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>,
-
     /// Stores the predicates that apply on generator witness types.
     /// formatting modified file tests/ui/generator/retain-resume-ref.rs
     pub generator_interior_predicates:
@@ -212,49 +208,6 @@ pub struct TypeckResults<'tcx> {
     offset_of_data: ItemLocalMap<(Ty<'tcx>, Vec<FieldIdx>)>,
 }
 
-/// Whenever a value may be live across a generator yield, the type of that value winds up in the
-/// `GeneratorInteriorTypeCause` struct. This struct adds additional information about such
-/// captured types that can be useful for diagnostics. In particular, it stores the span that
-/// caused a given type to be recorded, along with the scope that enclosed the value (which can
-/// be used to find the await that the value is live across).
-///
-/// For example:
-///
-/// ```ignore (pseudo-Rust)
-/// async move {
-///     let x: T = expr;
-///     foo.await
-///     ...
-/// }
-/// ```
-///
-/// Here, we would store the type `T`, the span of the value `x`, the "scope-span" for
-/// the scope that contains `x`, the expr `T` evaluated from, and the span of `foo.await`.
-#[derive(TyEncodable, TyDecodable, Clone, Debug, Eq, Hash, PartialEq, HashStable)]
-#[derive(TypeFoldable, TypeVisitable)]
-pub struct GeneratorInteriorTypeCause<'tcx> {
-    /// Type of the captured binding.
-    pub ty: Ty<'tcx>,
-    /// Span of the binding that was captured.
-    pub span: Span,
-    /// Span of the scope of the captured binding.
-    pub scope_span: Option<Span>,
-    /// Span of `.await` or `yield` expression.
-    pub yield_span: Span,
-    /// Expr which the type evaluated from.
-    pub expr: Option<hir::HirId>,
-}
-
-// This type holds diagnostic information on generators and async functions across crate boundaries
-// and is used to provide better error messages
-#[derive(TyEncodable, TyDecodable, Clone, Debug, HashStable)]
-pub struct GeneratorDiagnosticData<'tcx> {
-    pub generator_interior_types: ty::Binder<'tcx, Vec<GeneratorInteriorTypeCause<'tcx>>>,
-    pub hir_owner: DefId,
-    pub nodes_types: ItemLocalMap<Ty<'tcx>>,
-    pub adjustments: ItemLocalMap<Vec<ty::adjustment::Adjustment<'tcx>>>,
-}
-
 impl<'tcx> TypeckResults<'tcx> {
     pub fn new(hir_owner: OwnerId) -> TypeckResults<'tcx> {
         TypeckResults {
@@ -278,7 +231,6 @@ impl<'tcx> TypeckResults<'tcx> {
             closure_min_captures: Default::default(),
             closure_fake_reads: Default::default(),
             rvalue_scopes: Default::default(),
-            generator_interior_types: ty::Binder::dummy(Default::default()),
             generator_interior_predicates: Default::default(),
             treat_byte_string_as_slice: Default::default(),
             closure_size_eval: Default::default(),
@@ -351,28 +303,6 @@ impl<'tcx> TypeckResults<'tcx> {
         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.node_types }
     }
 
-    pub fn get_generator_diagnostic_data(&self) -> GeneratorDiagnosticData<'tcx> {
-        let generator_interior_type = self.generator_interior_types.map_bound_ref(|vec| {
-            vec.iter()
-                .map(|item| {
-                    GeneratorInteriorTypeCause {
-                        ty: item.ty,
-                        span: item.span,
-                        scope_span: item.scope_span,
-                        yield_span: item.yield_span,
-                        expr: None, //FIXME: Passing expression over crate boundaries is impossible at the moment
-                    }
-                })
-                .collect::<Vec<_>>()
-        });
-        GeneratorDiagnosticData {
-            generator_interior_types: generator_interior_type,
-            hir_owner: self.hir_owner.to_def_id(),
-            nodes_types: self.node_types.clone(),
-            adjustments: self.adjustments.clone(),
-        }
-    }
-
     pub fn node_type(&self, id: hir::HirId) -> Ty<'tcx> {
         self.node_type_opt(id).unwrap_or_else(|| {
             bug!("node_type: no type for node {}", tls::with(|tcx| tcx.hir().node_to_string(id)))
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 564f982f842..31b52677b27 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -156,7 +156,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 | DefKind::Enum
                 | DefKind::Trait
                 | DefKind::OpaqueTy
-                | DefKind::TyAlias { .. }
+                | DefKind::TyAlias
                 | DefKind::ForeignTy
                 | DefKind::TraitAlias
                 | DefKind::AssocTy
@@ -855,7 +855,7 @@ impl<'tcx> OpaqueTypeExpander<'tcx> {
                         let hidden_ty = bty.instantiate(self.tcx, args);
                         self.fold_ty(hidden_ty);
                     }
-                    let expanded_ty = Ty::new_generator_witness_mir(self.tcx, def_id, args);
+                    let expanded_ty = Ty::new_generator_witness(self.tcx, def_id, args);
                     self.expanded_cache.insert((def_id, args), expanded_ty);
                     expanded_ty
                 }
@@ -888,7 +888,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for OpaqueTypeExpander<'tcx> {
             t
         };
         if self.expand_generators {
-            if let ty::GeneratorWitnessMIR(def_id, args) = *t.kind() {
+            if let ty::GeneratorWitness(def_id, args) = *t.kind() {
                 t = self.expand_generator(def_id, args).unwrap_or(t);
             }
         }
@@ -1025,8 +1025,7 @@ impl<'tcx> Ty<'tcx> {
             | ty::Dynamic(..)
             | ty::Foreign(_)
             | ty::Generator(..)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..)
+            | ty::GeneratorWitness(..)
             | ty::Infer(_)
             | ty::Alias(..)
             | ty::Param(_)
@@ -1065,8 +1064,7 @@ impl<'tcx> Ty<'tcx> {
             | ty::Dynamic(..)
             | ty::Foreign(_)
             | ty::Generator(..)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..)
+            | ty::GeneratorWitness(..)
             | ty::Infer(_)
             | ty::Alias(..)
             | ty::Param(_)
@@ -1194,10 +1192,7 @@ impl<'tcx> Ty<'tcx> {
                 false
             }
 
-            ty::Foreign(_)
-            | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
-            | ty::Error(_) => false,
+            ty::Foreign(_) | ty::GeneratorWitness(..) | ty::Error(_) => false,
         }
     }
 
@@ -1293,7 +1288,6 @@ pub fn needs_drop_components<'tcx>(
         | ty::FnPtr(_)
         | ty::Char
         | ty::GeneratorWitness(..)
-        | ty::GeneratorWitnessMIR(..)
         | ty::RawPtr(_)
         | ty::Ref(..)
         | ty::Str => Ok(SmallVec::new()),
@@ -1364,11 +1358,7 @@ pub fn is_trivially_const_drop(ty: Ty<'_>) -> bool {
 
         // Not trivial because they have components, and instead of looking inside,
         // we'll just perform trait selection.
-        ty::Closure(..)
-        | ty::Generator(..)
-        | ty::GeneratorWitness(_)
-        | ty::GeneratorWitnessMIR(..)
-        | ty::Adt(..) => false,
+        ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) | ty::Adt(..) => false,
 
         ty::Array(ty, _) | ty::Slice(ty) => is_trivially_const_drop(ty),
 
diff --git a/compiler/rustc_middle/src/ty/walk.rs b/compiler/rustc_middle/src/ty/walk.rs
index 7c3d9ed390a..a86ff64bd0c 100644
--- a/compiler/rustc_middle/src/ty/walk.rs
+++ b/compiler/rustc_middle/src/ty/walk.rs
@@ -190,14 +190,11 @@ fn push_inner<'tcx>(stack: &mut TypeWalkerStack<'tcx>, parent: GenericArg<'tcx>)
             ty::Adt(_, args)
             | ty::Closure(_, args)
             | ty::Generator(_, args, _)
-            | ty::GeneratorWitnessMIR(_, args)
+            | ty::GeneratorWitness(_, args)
             | ty::FnDef(_, args) => {
                 stack.extend(args.iter().rev());
             }
             ty::Tuple(ts) => stack.extend(ts.iter().rev().map(GenericArg::from)),
-            ty::GeneratorWitness(ts) => {
-                stack.extend(ts.skip_binder().iter().rev().map(|ty| ty.into()));
-            }
             ty::FnPtr(sig) => {
                 stack.push(sig.skip_binder().output().into());
                 stack.extend(sig.skip_binder().inputs().iter().copied().rev().map(|ty| ty.into()));
diff --git a/compiler/rustc_middle/src/values.rs b/compiler/rustc_middle/src/values.rs
index dec06363380..578d8e7a975 100644
--- a/compiler/rustc_middle/src/values.rs
+++ b/compiler/rustc_middle/src/values.rs
@@ -217,7 +217,7 @@ fn find_item_ty_spans(
     match ty.kind {
         hir::TyKind::Path(hir::QPath::Resolved(_, path)) => {
             if let Res::Def(kind, def_id) = path.res
-                && !matches!(kind, DefKind::TyAlias { .. }) {
+                && !matches!(kind, DefKind::TyAlias) {
                 let check_params = def_id.as_local().map_or(true, |def_id| {
                     if def_id == needle {
                         spans.push(ty.span);
diff --git a/compiler/rustc_mir_build/messages.ftl b/compiler/rustc_mir_build/messages.ftl
index 938f3edd31b..ce021923f64 100644
--- a/compiler/rustc_mir_build/messages.ftl
+++ b/compiler/rustc_mir_build/messages.ftl
@@ -229,6 +229,9 @@ mir_build_non_exhaustive_patterns_type_not_empty = non-exhaustive patterns: type
     .suggestion = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
     .help = ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
 
+mir_build_non_partial_eq_match =
+    to use a constant of type `{$non_peq_ty}` in a pattern, the type must implement `PartialEq`
+
 mir_build_nontrivial_structural_match =
     to use a constant of type `{$non_sm_ty}` in a pattern, the constant's initializer must be trivial or `{$non_sm_ty}` must be annotated with `#[derive(PartialEq, Eq)]`
 
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 3ff3387a781..bee5ac550dd 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -749,6 +749,12 @@ pub struct NontrivialStructuralMatch<'tcx> {
 }
 
 #[derive(LintDiagnostic)]
+#[diag(mir_build_non_partial_eq_match)]
+pub struct NonPartialEqMatch<'tcx> {
+    pub non_peq_ty: Ty<'tcx>,
+}
+
+#[derive(LintDiagnostic)]
 #[diag(mir_build_overlapping_range_endpoints)]
 #[note]
 pub struct OverlappingRangeEndpoints<'tcx> {
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 95dced644e1..d440ca31926 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -740,9 +740,7 @@ fn non_exhaustive_match<'p, 'tcx>(
                         ));
                 }
             } else if ty == cx.tcx.types.str_ {
-                err.note(format!(
-                    "`&str` cannot be matched exhaustively, so a wildcard `_` is necessary",
-                ));
+                err.note("`&str` cannot be matched exhaustively, so a wildcard `_` is necessary");
             } else if cx.is_foreign_non_exhaustive_enum(ty) {
                 err.note(format!("`{ty}` is marked as non-exhaustive, so a wildcard `_` is necessary to match exhaustively"));
             }
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index 00d9fe72cfc..ae442466029 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -16,14 +16,16 @@ use std::cell::Cell;
 
 use super::PatCtxt;
 use crate::errors::{
-    FloatPattern, IndirectStructuralMatch, InvalidPattern, NontrivialStructuralMatch,
-    PointerPattern, TypeNotStructural, UnionPattern, UnsizedPattern,
+    FloatPattern, IndirectStructuralMatch, InvalidPattern, NonPartialEqMatch,
+    NontrivialStructuralMatch, PointerPattern, TypeNotStructural, UnionPattern, UnsizedPattern,
 };
 
 impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
     /// Converts an evaluated constant to a pattern (if possible).
     /// This means aggregate values (like structs and enums) are converted
     /// to a pattern that matches the value (as if you'd compared via structural equality).
+    ///
+    /// `cv` must be a valtree or a `mir::ConstValue`.
     #[instrument(level = "debug", skip(self), ret)]
     pub(super) fn const_to_pat(
         &self,
@@ -64,12 +66,10 @@ struct ConstToPat<'tcx> {
 }
 
 /// This error type signals that we encountered a non-struct-eq situation.
-/// We bubble this up in order to get back to the reference destructuring and make that emit
-/// a const pattern instead of a deref pattern. This allows us to simply call `PartialEq::eq`
-/// on such patterns (since that function takes a reference) and not have to jump through any
-/// hoops to get a reference to the value.
+/// We will fall back to calling `PartialEq::eq` on such patterns,
+/// and exhaustiveness checking will consider them as matching nothing.
 #[derive(Debug)]
-struct FallbackToConstRef;
+struct FallbackToOpaqueConst;
 
 impl<'tcx> ConstToPat<'tcx> {
     fn new(
@@ -136,7 +136,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 }
                 ty::ConstKind::Value(valtree) => self
                     .recur(valtree, cv.ty(), mir_structural_match_violation.unwrap_or(false))
-                    .unwrap_or_else(|_| {
+                    .unwrap_or_else(|_: FallbackToOpaqueConst| {
                         Box::new(Pat {
                             span: self.span,
                             ty: cv.ty(),
@@ -155,8 +155,9 @@ impl<'tcx> ConstToPat<'tcx> {
         };
 
         if !self.saw_const_match_error.get() {
-            // If we were able to successfully convert the const to some pat,
-            // double-check that all types in the const implement `Structural`.
+            // If we were able to successfully convert the const to some pat (possibly with some
+            // lints, but no errors), double-check that all types in the const implement
+            // `Structural` and `PartialEq`.
 
             let structural =
                 traits::search_for_structural_match_violation(self.span, self.tcx(), cv.ty());
@@ -178,7 +179,7 @@ impl<'tcx> ConstToPat<'tcx> {
             }
 
             if let Some(non_sm_ty) = structural {
-                if !self.type_may_have_partial_eq_impl(cv.ty()) {
+                if !self.type_has_partial_eq_impl(cv.ty()) {
                     if let ty::Adt(def, ..) = non_sm_ty.kind() {
                         if def.is_union() {
                             let err = UnionPattern { span: self.span };
@@ -192,8 +193,10 @@ impl<'tcx> ConstToPat<'tcx> {
                     } else {
                         let err = InvalidPattern { span: self.span, non_sm_ty };
                         self.tcx().sess.emit_err(err);
-                        return Box::new(Pat { span: self.span, ty: cv.ty(), kind: PatKind::Wild });
                     }
+                    // All branches above emitted an error. Don't print any more lints.
+                    // The pattern we return is irrelevant since we errored.
+                    return Box::new(Pat { span: self.span, ty: cv.ty(), kind: PatKind::Wild });
                 } else if !self.saw_const_match_lint.get() {
                     if let Some(mir_structural_match_violation) = mir_structural_match_violation {
                         match non_sm_ty.kind() {
@@ -238,13 +241,24 @@ impl<'tcx> ConstToPat<'tcx> {
                     _ => {}
                 }
             }
+
+            // Always check for `PartialEq`, even if we emitted other lints. (But not if there were
+            // any errors.) This ensures it shows up in cargo's future-compat reports as well.
+            if !self.type_has_partial_eq_impl(cv.ty()) {
+                self.tcx().emit_spanned_lint(
+                    lint::builtin::CONST_PATTERNS_WITHOUT_PARTIAL_EQ,
+                    self.id,
+                    self.span,
+                    NonPartialEqMatch { non_peq_ty: cv.ty() },
+                );
+            }
         }
 
         inlined_const_as_pat
     }
 
     #[instrument(level = "trace", skip(self), ret)]
-    fn type_may_have_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
+    fn type_has_partial_eq_impl(&self, ty: Ty<'tcx>) -> bool {
         // double-check there even *is* a semantic `PartialEq` to dispatch to.
         //
         // (If there isn't, then we can safely issue a hard
@@ -259,14 +273,19 @@ impl<'tcx> ConstToPat<'tcx> {
             ty::TraitRef::new(self.tcx(), partial_eq_trait_id, [ty, ty]),
         );
 
-        // FIXME: should this call a `predicate_must_hold` variant instead?
-        self.infcx.predicate_may_hold(&partial_eq_obligation)
+        // This *could* accept a type that isn't actually `PartialEq`, because region bounds get
+        // ignored. However that should be pretty much impossible since consts that do not depend on
+        // generics can only mention the `'static` lifetime, and how would one have a type that's
+        // `PartialEq` for some lifetime but *not* for `'static`? If this ever becomes a problem
+        // we'll need to leave some sort of trace of this requirement in the MIR so that borrowck
+        // can ensure that the type really implements `PartialEq`.
+        self.infcx.predicate_must_hold_modulo_regions(&partial_eq_obligation)
     }
 
     fn field_pats(
         &self,
         vals: impl Iterator<Item = (ValTree<'tcx>, Ty<'tcx>)>,
-    ) -> Result<Vec<FieldPat<'tcx>>, FallbackToConstRef> {
+    ) -> Result<Vec<FieldPat<'tcx>>, FallbackToOpaqueConst> {
         vals.enumerate()
             .map(|(idx, (val, ty))| {
                 let field = FieldIdx::new(idx);
@@ -284,7 +303,7 @@ impl<'tcx> ConstToPat<'tcx> {
         cv: ValTree<'tcx>,
         ty: Ty<'tcx>,
         mir_structural_match_violation: bool,
-    ) -> Result<Box<Pat<'tcx>>, FallbackToConstRef> {
+    ) -> Result<Box<Pat<'tcx>>, FallbackToOpaqueConst> {
         let id = self.id;
         let span = self.span;
         let tcx = self.tcx();
@@ -299,7 +318,7 @@ impl<'tcx> ConstToPat<'tcx> {
                     span,
                     FloatPattern,
                 );
-                return Err(FallbackToConstRef);
+                return Err(FallbackToOpaqueConst);
             }
             // If the type is not structurally comparable, just emit the constant directly,
             // causing the pattern match code to treat it opaquely.
@@ -323,11 +342,12 @@ impl<'tcx> ConstToPat<'tcx> {
                 // Since we are behind a reference, we can just bubble the error up so we get a
                 // constant at reference type, making it easy to let the fallback call
                 // `PartialEq::eq` on it.
-                return Err(FallbackToConstRef);
+                return Err(FallbackToOpaqueConst);
             }
             ty::FnDef(..) => {
                 self.saw_const_match_error.set(true);
                 tcx.sess.emit_err(InvalidPattern { span, non_sm_ty: ty });
+                // We errored, so the pattern we generate is irrelevant.
                 PatKind::Wild
             }
             ty::Adt(adt_def, _) if !self.type_marked_structural(ty) => {
@@ -335,6 +355,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 self.saw_const_match_error.set(true);
                 let err = TypeNotStructural { span, non_sm_ty: ty };
                 tcx.sess.emit_err(err);
+                // We errored, so the pattern we generate is irrelevant.
                 PatKind::Wild
             }
             ty::Adt(adt_def, args) if adt_def.is_enum() => {
@@ -404,13 +425,15 @@ impl<'tcx> ConstToPat<'tcx> {
                                 IndirectStructuralMatch { non_sm_ty: *pointee_ty },
                             );
                         }
-                        return Err(FallbackToConstRef);
+                        return Err(FallbackToOpaqueConst);
                     } else {
                         if !self.saw_const_match_error.get() {
                             self.saw_const_match_error.set(true);
                             let err = TypeNotStructural { span, non_sm_ty: *pointee_ty };
                             tcx.sess.emit_err(err);
                         }
+                        tcx.sess.delay_span_bug(span, "`saw_const_match_error` set but no error?");
+                        // We errored, so the pattern we generate is irrelevant.
                         PatKind::Wild
                     }
                 }
@@ -423,6 +446,7 @@ impl<'tcx> ConstToPat<'tcx> {
                         tcx.sess.emit_err(err);
 
                         // FIXME: introduce PatKind::Error to silence follow up diagnostics due to unreachable patterns.
+                        // We errored, so the pattern we generate is irrelevant.
                         PatKind::Wild
                     } else {
                         let old = self.behind_reference.replace(true);
@@ -453,6 +477,7 @@ impl<'tcx> ConstToPat<'tcx> {
                 self.saw_const_match_error.set(true);
                 let err = InvalidPattern { span, non_sm_ty: ty };
                 tcx.sess.emit_err(err);
+                // We errored, so the pattern we generate is irrelevant.
                 PatKind::Wild
             }
         };
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index f1f75c26717..fe47a1cd78c 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -439,7 +439,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                 DefKind::Struct
                 | DefKind::Ctor(CtorOf::Struct, ..)
                 | DefKind::Union
-                | DefKind::TyAlias { .. }
+                | DefKind::TyAlias
                 | DefKind::AssocTy,
                 _,
             )
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index e24685cb90f..c9991e499b3 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -194,6 +194,7 @@ where
     D: DropElaborator<'b, 'tcx>,
     'tcx: 'b,
 {
+    #[instrument(level = "trace", skip(self), ret)]
     fn place_ty(&self, place: Place<'tcx>) -> Ty<'tcx> {
         place.ty(self.elaborator.body(), self.tcx()).ty
     }
@@ -220,11 +221,9 @@ where
     //
     // FIXME: I think we should just control the flags externally,
     // and then we do not need this machinery.
+    #[instrument(level = "debug")]
     pub fn elaborate_drop(&mut self, bb: BasicBlock) {
-        debug!("elaborate_drop({:?}, {:?})", bb, self);
-        let style = self.elaborator.drop_style(self.path, DropFlagMode::Deep);
-        debug!("elaborate_drop({:?}, {:?}): live - {:?}", bb, self, style);
-        match style {
+        match self.elaborator.drop_style(self.path, DropFlagMode::Deep) {
             DropStyle::Dead => {
                 self.elaborator
                     .patch()
diff --git a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
index 213b81eaac9..9ced3a7f3cd 100644
--- a/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
+++ b/compiler/rustc_mir_dataflow/src/move_paths/builder.rs
@@ -144,8 +144,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                     | ty::Dynamic(_, _, _)
                     | ty::Closure(_, _)
                     | ty::Generator(_, _, _)
-                    | ty::GeneratorWitness(_)
-                    | ty::GeneratorWitnessMIR(_, _)
+                    | ty::GeneratorWitness(..)
                     | ty::Never
                     | ty::Tuple(_)
                     | ty::Alias(_, _)
@@ -184,8 +183,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                     | ty::FnDef(_, _)
                     | ty::FnPtr(_)
                     | ty::Dynamic(_, _, _)
-                    | ty::GeneratorWitness(_)
-                    | ty::GeneratorWitnessMIR(_, _)
+                    | ty::GeneratorWitness(..)
                     | ty::Never
                     | ty::Alias(_, _)
                     | ty::Param(_)
diff --git a/compiler/rustc_mir_dataflow/src/value_analysis.rs b/compiler/rustc_mir_dataflow/src/value_analysis.rs
index dd20e5d7430..83766f31148 100644
--- a/compiler/rustc_mir_dataflow/src/value_analysis.rs
+++ b/compiler/rustc_mir_dataflow/src/value_analysis.rs
@@ -758,7 +758,9 @@ impl Map {
             self.value_count += 1;
         }
 
-        if let Some(ref_ty) = ty.builtin_deref(true) && let ty::Slice(..) = ref_ty.ty.kind() {
+        if let ty::Ref(_, ref_ty, _) | ty::RawPtr(ty::TypeAndMut { ty: ref_ty, .. }) = ty.kind()
+            && let ty::Slice(..) = ref_ty.kind()
+        {
             assert!(self.places[place].value_index.is_none(), "slices are not scalars");
 
             // Prepend new child to the linked list.
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index 5b24fa10bea..767f8e9f4fa 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -763,7 +763,7 @@ pub(super) fn filtered_statement_span(statement: &Statement<'_>) -> Option<Span>
         // and `_1` is the `Place` for `somenum`.
         //
         // If and when the Issue is resolved, remove this special case match pattern:
-        StatementKind::FakeRead(box (cause, _)) if cause == FakeReadCause::ForGuardBinding => None,
+        StatementKind::FakeRead(box (FakeReadCause::ForGuardBinding, _)) => None,
 
         // Retain spans from all other statements
         StatementKind::FakeRead(box (_, _)) // Not including `ForGuardBinding`
diff --git a/compiler/rustc_mir_transform/src/elaborate_drops.rs b/compiler/rustc_mir_transform/src/elaborate_drops.rs
index 6a89d067275..b62d7da2a4c 100644
--- a/compiler/rustc_mir_transform/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_drops.rs
@@ -170,6 +170,7 @@ impl<'a, 'tcx> DropElaborator<'a, 'tcx> for Elaborator<'a, '_, 'tcx> {
         self.ctxt.param_env()
     }
 
+    #[instrument(level = "debug", skip(self), ret)]
     fn drop_style(&self, path: Self::Path, mode: DropFlagMode) -> DropStyle {
         let ((maybe_live, maybe_dead), multipart) = match mode {
             DropFlagMode::Shallow => (self.ctxt.init_data.maybe_live_dead(path), false),
diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs
index 35373bcaa41..5879a803946 100644
--- a/compiler/rustc_mir_transform/src/errors.rs
+++ b/compiler/rustc_mir_transform/src/errors.rs
@@ -4,7 +4,9 @@ use rustc_errors::{
 };
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
 use rustc_middle::mir::{AssertKind, UnsafetyViolationDetails};
+use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::{self, Lint};
+use rustc_span::def_id::DefId;
 use rustc_span::Span;
 
 #[derive(LintDiagnostic)]
@@ -237,20 +239,38 @@ pub(crate) struct FnItemRef {
     pub ident: String,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(mir_transform_must_not_suspend)]
-pub(crate) struct MustNotSupend<'a> {
-    #[label]
+pub(crate) struct MustNotSupend<'tcx, 'a> {
+    pub tcx: TyCtxt<'tcx>,
     pub yield_sp: Span,
-    #[subdiagnostic]
     pub reason: Option<MustNotSuspendReason>,
-    #[help]
     pub src_sp: Span,
     pub pre: &'a str,
-    pub def_path: String,
+    pub def_id: DefId,
     pub post: &'a str,
 }
 
+// Needed for def_path_str
+impl<'a> DecorateLint<'a, ()> for MustNotSupend<'_, '_> {
+    fn decorate_lint<'b>(
+        self,
+        diag: &'b mut rustc_errors::DiagnosticBuilder<'a, ()>,
+    ) -> &'b mut rustc_errors::DiagnosticBuilder<'a, ()> {
+        diag.span_label(self.yield_sp, crate::fluent_generated::_subdiag::label);
+        if let Some(reason) = self.reason {
+            diag.subdiagnostic(reason);
+        }
+        diag.span_help(self.src_sp, crate::fluent_generated::_subdiag::help);
+        diag.set_arg("pre", self.pre);
+        diag.set_arg("def_path", self.tcx.def_path_str(self.def_id));
+        diag.set_arg("post", self.post);
+        diag
+    }
+
+    fn msg(&self) -> rustc_errors::DiagnosticMessage {
+        crate::fluent_generated::mir_transform_must_not_suspend
+    }
+}
+
 #[derive(Subdiagnostic)]
 #[note(mir_transform_note)]
 pub(crate) struct MustNotSuspendReason {
diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/generator.rs
index 96c60fdf41b..8a807d786a5 100644
--- a/compiler/rustc_mir_transform/src/generator.rs
+++ b/compiler/rustc_mir_transform/src/generator.rs
@@ -853,60 +853,7 @@ impl StorageConflictVisitor<'_, '_, '_> {
     }
 }
 
-/// Validates the typeck view of the generator against the actual set of types saved between
-/// yield points.
-fn sanitize_witness<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    body: &Body<'tcx>,
-    witness: Ty<'tcx>,
-    upvars: &'tcx ty::List<Ty<'tcx>>,
-    layout: &GeneratorLayout<'tcx>,
-) {
-    let did = body.source.def_id();
-    let param_env = tcx.param_env(did);
-
-    let allowed_upvars = tcx.normalize_erasing_regions(param_env, upvars);
-    let allowed = match witness.kind() {
-        &ty::GeneratorWitness(interior_tys) => {
-            tcx.normalize_erasing_late_bound_regions(param_env, interior_tys)
-        }
-        _ => {
-            tcx.sess.delay_span_bug(
-                body.span,
-                format!("unexpected generator witness type {:?}", witness.kind()),
-            );
-            return;
-        }
-    };
-
-    let mut mismatches = Vec::new();
-    for fty in &layout.field_tys {
-        if fty.ignore_for_traits {
-            continue;
-        }
-        let decl_ty = tcx.normalize_erasing_regions(param_env, fty.ty);
-
-        // Sanity check that typeck knows about the type of locals which are
-        // live across a suspension point
-        if !allowed.contains(&decl_ty) && !allowed_upvars.contains(&decl_ty) {
-            mismatches.push(decl_ty);
-        }
-    }
-
-    if !mismatches.is_empty() {
-        span_bug!(
-            body.span,
-            "Broken MIR: generator contains type {:?} in MIR, \
-                       but typeck only knows about {} and {:?}",
-            mismatches,
-            allowed,
-            allowed_upvars
-        );
-    }
-}
-
 fn compute_layout<'tcx>(
-    tcx: TyCtxt<'tcx>,
     liveness: LivenessInfo,
     body: &Body<'tcx>,
 ) -> (
@@ -932,27 +879,20 @@ fn compute_layout<'tcx>(
         let decl = &body.local_decls[local];
         debug!(?decl);
 
-        let ignore_for_traits = if tcx.sess.opts.unstable_opts.drop_tracking_mir {
-            // Do not `assert_crate_local` here, as post-borrowck cleanup may have already cleared
-            // the information. This is alright, since `ignore_for_traits` is only relevant when
-            // this code runs on pre-cleanup MIR, and `ignore_for_traits = false` is the safer
-            // default.
-            match decl.local_info {
-                // Do not include raw pointers created from accessing `static` items, as those could
-                // well be re-created by another access to the same static.
-                ClearCrossCrate::Set(box LocalInfo::StaticRef { is_thread_local, .. }) => {
-                    !is_thread_local
-                }
-                // Fake borrows are only read by fake reads, so do not have any reality in
-                // post-analysis MIR.
-                ClearCrossCrate::Set(box LocalInfo::FakeBorrow) => true,
-                _ => false,
+        // Do not `assert_crate_local` here, as post-borrowck cleanup may have already cleared
+        // the information. This is alright, since `ignore_for_traits` is only relevant when
+        // this code runs on pre-cleanup MIR, and `ignore_for_traits = false` is the safer
+        // default.
+        let ignore_for_traits = match decl.local_info {
+            // Do not include raw pointers created from accessing `static` items, as those could
+            // well be re-created by another access to the same static.
+            ClearCrossCrate::Set(box LocalInfo::StaticRef { is_thread_local, .. }) => {
+                !is_thread_local
             }
-        } else {
-            // FIXME(#105084) HIR-based drop tracking does not account for all the temporaries that
-            // MIR building may introduce. This leads to wrongly ignored types, but this is
-            // necessary for internal consistency and to avoid ICEs.
-            decl.internal
+            // Fake borrows are only read by fake reads, so do not have any reality in
+            // post-analysis MIR.
+            ClearCrossCrate::Set(box LocalInfo::FakeBorrow) => true,
+            _ => false,
         };
         let decl =
             GeneratorSavedTy { ty: decl.ty, source_info: decl.source_info, ignore_for_traits };
@@ -1445,8 +1385,6 @@ pub(crate) fn mir_generator_witnesses<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: LocalDefId,
 ) -> Option<GeneratorLayout<'tcx>> {
-    assert!(tcx.sess.opts.unstable_opts.drop_tracking_mir);
-
     let (body, _) = tcx.mir_promoted(def_id);
     let body = body.borrow();
     let body = &*body;
@@ -1469,7 +1407,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>(
     // Extract locals which are live across suspension point into `layout`
     // `remap` gives a mapping from local indices onto generator struct indices
     // `storage_liveness` tells us which locals have live storage at suspension points
-    let (_, generator_layout, _) = compute_layout(tcx, liveness_info, body);
+    let (_, generator_layout, _) = compute_layout(liveness_info, body);
 
     check_suspend_tys(tcx, &generator_layout, &body);
 
@@ -1489,15 +1427,10 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
         let gen_ty = body.local_decls.raw[1].ty;
 
         // Get the discriminant type and args which typeck computed
-        let (discr_ty, upvars, interior, movable) = match *gen_ty.kind() {
+        let (discr_ty, movable) = match *gen_ty.kind() {
             ty::Generator(_, args, movability) => {
                 let args = args.as_generator();
-                (
-                    args.discr_ty(tcx),
-                    args.upvar_tys(),
-                    args.witness(),
-                    movability == hir::Movability::Movable,
-                )
+                (args.discr_ty(tcx), movability == hir::Movability::Movable)
             }
             _ => {
                 tcx.sess.delay_span_bug(body.span, format!("unexpected generator type {gen_ty}"));
@@ -1574,13 +1507,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
         // Extract locals which are live across suspension point into `layout`
         // `remap` gives a mapping from local indices onto generator struct indices
         // `storage_liveness` tells us which locals have live storage at suspension points
-        let (remap, layout, storage_liveness) = compute_layout(tcx, liveness_info, body);
-
-        if tcx.sess.opts.unstable_opts.validate_mir
-            && !tcx.sess.opts.unstable_opts.drop_tracking_mir
-        {
-            sanitize_witness(tcx, body, interior, upvars, &layout);
-        }
+        let (remap, layout, storage_liveness) = compute_layout(liveness_info, body);
 
         let can_return = can_return(tcx, body, tcx.param_env(body.source.def_id()));
 
@@ -1954,11 +1881,12 @@ fn check_must_not_suspend_def(
             hir_id,
             data.source_span,
             errors::MustNotSupend {
+                tcx,
                 yield_sp: data.yield_span,
                 reason,
                 src_sp: data.source_span,
                 pre: data.descr_pre,
-                def_path: tcx.def_path_str(def_id),
+                def_id,
                 post: data.descr_post,
             },
         );
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
new file mode 100644
index 00000000000..449bade3322
--- /dev/null
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -0,0 +1,538 @@
+//! Global value numbering.
+//!
+//! MIR may contain repeated and/or redundant computations. The objective of this pass is to detect
+//! such redundancies and re-use the already-computed result when possible.
+//!
+//! In a first pass, we compute a symbolic representation of values that are assigned to SSA
+//! locals. This symbolic representation is defined by the `Value` enum. Each produced instance of
+//! `Value` is interned as a `VnIndex`, which allows us to cheaply compute identical values.
+//!
+//! From those assignments, we construct a mapping `VnIndex -> Vec<(Local, Location)>` of available
+//! values, the locals in which they are stored, and a the assignment location.
+//!
+//! In a second pass, we traverse all (non SSA) assignments `x = rvalue` and operands. For each
+//! one, we compute the `VnIndex` of the rvalue. If this `VnIndex` is associated to a constant, we
+//! replace the rvalue/operand by that constant. Otherwise, if there is an SSA local `y`
+//! associated to this `VnIndex`, and if its definition location strictly dominates the assignment
+//! to `x`, we replace the assignment by `x = y`.
+//!
+//! By opportunity, this pass simplifies some `Rvalue`s based on the accumulated knowledge.
+//!
+//! # Operational semantic
+//!
+//! Operationally, this pass attempts to prove bitwise equality between locals. Given this MIR:
+//! ```ignore (MIR)
+//! _a = some value // has VnIndex i
+//! // some MIR
+//! _b = some other value // also has VnIndex i
+//! ```
+//!
+//! We consider it to be replacable by:
+//! ```ignore (MIR)
+//! _a = some value // has VnIndex i
+//! // some MIR
+//! _c = some other value // also has VnIndex i
+//! assume(_a bitwise equal to _c) // follows from having the same VnIndex
+//! _b = _a // follows from the `assume`
+//! ```
+//!
+//! Which is simplifiable to:
+//! ```ignore (MIR)
+//! _a = some value // has VnIndex i
+//! // some MIR
+//! _b = _a
+//! ```
+//!
+//! # Handling of references
+//!
+//! We handle references by assigning a different "provenance" index to each Ref/AddressOf rvalue.
+//! This ensure that we do not spuriously merge borrows that should not be merged. Meanwhile, we
+//! consider all the derefs of an immutable reference to a freeze type to give the same value:
+//! ```ignore (MIR)
+//! _a = *_b // _b is &Freeze
+//! _c = *_b // replaced by _c = _a
+//! ```
+
+use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
+use rustc_data_structures::graph::dominators::Dominators;
+use rustc_index::bit_set::BitSet;
+use rustc_index::IndexVec;
+use rustc_macros::newtype_index;
+use rustc_middle::mir::visit::*;
+use rustc_middle::mir::*;
+use rustc_middle::ty::{self, Ty, TyCtxt};
+use rustc_target::abi::{VariantIdx, FIRST_VARIANT};
+
+use crate::ssa::SsaLocals;
+use crate::MirPass;
+
+pub struct GVN;
+
+impl<'tcx> MirPass<'tcx> for GVN {
+    fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
+        sess.mir_opt_level() >= 4
+    }
+
+    #[instrument(level = "trace", skip(self, tcx, body))]
+    fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+        debug!(def_id = ?body.source.def_id());
+        propagate_ssa(tcx, body);
+    }
+}
+
+fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
+    let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
+    let ssa = SsaLocals::new(body);
+    // Clone dominators as we need them while mutating the body.
+    let dominators = body.basic_blocks.dominators().clone();
+
+    let mut state = VnState::new(tcx, param_env, &ssa, &dominators, &body.local_decls);
+    for arg in body.args_iter() {
+        if ssa.is_ssa(arg) {
+            let value = state.new_opaque().unwrap();
+            state.assign(arg, value);
+        }
+    }
+
+    ssa.for_each_assignment_mut(&mut body.basic_blocks, |local, rvalue, location| {
+        let value = state.simplify_rvalue(rvalue, location).or_else(|| state.new_opaque()).unwrap();
+        // FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark `local` as
+        // reusable if we have an exact type match.
+        if state.local_decls[local].ty == rvalue.ty(state.local_decls, tcx) {
+            state.assign(local, value);
+        }
+    });
+
+    // Stop creating opaques during replacement as it is useless.
+    state.next_opaque = None;
+
+    let reverse_postorder = body.basic_blocks.reverse_postorder().to_vec();
+    for bb in reverse_postorder {
+        let data = &mut body.basic_blocks.as_mut_preserves_cfg()[bb];
+        state.visit_basic_block_data(bb, data);
+    }
+    let any_replacement = state.any_replacement;
+
+    // For each local that is reused (`y` above), we remove its storage statements do avoid any
+    // difficulty. Those locals are SSA, so should be easy to optimize by LLVM without storage
+    // statements.
+    StorageRemover { tcx, reused_locals: state.reused_locals }.visit_body_preserves_cfg(body);
+
+    if any_replacement {
+        crate::simplify::remove_unused_definitions(body);
+    }
+}
+
+newtype_index! {
+    struct VnIndex {}
+}
+
+#[derive(Debug, PartialEq, Eq, Hash)]
+enum Value<'tcx> {
+    // Root values.
+    /// Used to represent values we know nothing about.
+    /// The `usize` is a counter incremented by `new_opaque`.
+    Opaque(usize),
+    /// Evaluated or unevaluated constant value.
+    Constant(Const<'tcx>),
+    /// An aggregate value, either tuple/closure/struct/enum.
+    /// This does not contain unions, as we cannot reason with the value.
+    Aggregate(Ty<'tcx>, VariantIdx, Vec<VnIndex>),
+    /// This corresponds to a `[value; count]` expression.
+    Repeat(VnIndex, ty::Const<'tcx>),
+    /// The address of a place.
+    Address {
+        place: Place<'tcx>,
+        /// Give each borrow and pointer a different provenance, so we don't merge them.
+        provenance: usize,
+    },
+
+    // Extractions.
+    /// This is the *value* obtained by projecting another value.
+    Projection(VnIndex, ProjectionElem<VnIndex, Ty<'tcx>>),
+    /// Discriminant of the given value.
+    Discriminant(VnIndex),
+    /// Length of an array or slice.
+    Len(VnIndex),
+
+    // Operations.
+    NullaryOp(NullOp<'tcx>, Ty<'tcx>),
+    UnaryOp(UnOp, VnIndex),
+    BinaryOp(BinOp, VnIndex, VnIndex),
+    CheckedBinaryOp(BinOp, VnIndex, VnIndex),
+    Cast {
+        kind: CastKind,
+        value: VnIndex,
+        from: Ty<'tcx>,
+        to: Ty<'tcx>,
+    },
+}
+
+struct VnState<'body, 'tcx> {
+    tcx: TyCtxt<'tcx>,
+    param_env: ty::ParamEnv<'tcx>,
+    local_decls: &'body LocalDecls<'tcx>,
+    /// Value stored in each local.
+    locals: IndexVec<Local, Option<VnIndex>>,
+    /// First local to be assigned that value.
+    rev_locals: FxHashMap<VnIndex, Vec<Local>>,
+    values: FxIndexSet<Value<'tcx>>,
+    /// Counter to generate different values.
+    /// This is an option to stop creating opaques during replacement.
+    next_opaque: Option<usize>,
+    ssa: &'body SsaLocals,
+    dominators: &'body Dominators<BasicBlock>,
+    reused_locals: BitSet<Local>,
+    any_replacement: bool,
+}
+
+impl<'body, 'tcx> VnState<'body, 'tcx> {
+    fn new(
+        tcx: TyCtxt<'tcx>,
+        param_env: ty::ParamEnv<'tcx>,
+        ssa: &'body SsaLocals,
+        dominators: &'body Dominators<BasicBlock>,
+        local_decls: &'body LocalDecls<'tcx>,
+    ) -> Self {
+        VnState {
+            tcx,
+            param_env,
+            local_decls,
+            locals: IndexVec::from_elem(None, local_decls),
+            rev_locals: FxHashMap::default(),
+            values: FxIndexSet::default(),
+            next_opaque: Some(0),
+            ssa,
+            dominators,
+            reused_locals: BitSet::new_empty(local_decls.len()),
+            any_replacement: false,
+        }
+    }
+
+    #[instrument(level = "trace", skip(self), ret)]
+    fn insert(&mut self, value: Value<'tcx>) -> VnIndex {
+        let (index, _) = self.values.insert_full(value);
+        VnIndex::from_usize(index)
+    }
+
+    /// Create a new `Value` for which we have no information at all, except that it is distinct
+    /// from all the others.
+    #[instrument(level = "trace", skip(self), ret)]
+    fn new_opaque(&mut self) -> Option<VnIndex> {
+        let next_opaque = self.next_opaque.as_mut()?;
+        let value = Value::Opaque(*next_opaque);
+        *next_opaque += 1;
+        Some(self.insert(value))
+    }
+
+    /// Create a new `Value::Address` distinct from all the others.
+    #[instrument(level = "trace", skip(self), ret)]
+    fn new_pointer(&mut self, place: Place<'tcx>) -> Option<VnIndex> {
+        let next_opaque = self.next_opaque.as_mut()?;
+        let value = Value::Address { place, provenance: *next_opaque };
+        *next_opaque += 1;
+        Some(self.insert(value))
+    }
+
+    fn get(&self, index: VnIndex) -> &Value<'tcx> {
+        self.values.get_index(index.as_usize()).unwrap()
+    }
+
+    /// Record that `local` is assigned `value`. `local` must be SSA.
+    #[instrument(level = "trace", skip(self))]
+    fn assign(&mut self, local: Local, value: VnIndex) {
+        self.locals[local] = Some(value);
+
+        // Only register the value if its type is `Sized`, as we will emit copies of it.
+        let is_sized = !self.tcx.features().unsized_locals
+            || self.local_decls[local].ty.is_sized(self.tcx, self.param_env);
+        if is_sized {
+            self.rev_locals.entry(value).or_default().push(local);
+        }
+    }
+
+    /// Represent the *value* which would be read from `place`, and point `place` to a preexisting
+    /// place with the same value (if that already exists).
+    #[instrument(level = "trace", skip(self), ret)]
+    fn simplify_place_value(
+        &mut self,
+        place: &mut Place<'tcx>,
+        location: Location,
+    ) -> Option<VnIndex> {
+        // Invariant: `place` and `place_ref` point to the same value, even if they point to
+        // different memory locations.
+        let mut place_ref = place.as_ref();
+
+        // Invariant: `value` holds the value up-to the `index`th projection excluded.
+        let mut value = self.locals[place.local]?;
+        for (index, proj) in place.projection.iter().enumerate() {
+            if let Some(local) = self.try_as_local(value, location) {
+                // Both `local` and `Place { local: place.local, projection: projection[..index] }`
+                // hold the same value. Therefore, following place holds the value in the original
+                // `place`.
+                place_ref = PlaceRef { local, projection: &place.projection[index..] };
+            }
+
+            let proj = match proj {
+                ProjectionElem::Deref => {
+                    let ty = Place::ty_from(
+                        place.local,
+                        &place.projection[..index],
+                        self.local_decls,
+                        self.tcx,
+                    )
+                    .ty;
+                    if let Some(Mutability::Not) = ty.ref_mutability()
+                        && let Some(pointee_ty) = ty.builtin_deref(true)
+                        && pointee_ty.ty.is_freeze(self.tcx, self.param_env)
+                    {
+                        // An immutable borrow `_x` always points to the same value for the
+                        // lifetime of the borrow, so we can merge all instances of `*_x`.
+                        ProjectionElem::Deref
+                    } else {
+                        return None;
+                    }
+                }
+                ProjectionElem::Field(f, ty) => ProjectionElem::Field(f, ty),
+                ProjectionElem::Index(idx) => {
+                    let idx = self.locals[idx]?;
+                    ProjectionElem::Index(idx)
+                }
+                ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
+                    ProjectionElem::ConstantIndex { offset, min_length, from_end }
+                }
+                ProjectionElem::Subslice { from, to, from_end } => {
+                    ProjectionElem::Subslice { from, to, from_end }
+                }
+                ProjectionElem::Downcast(name, index) => ProjectionElem::Downcast(name, index),
+                ProjectionElem::OpaqueCast(ty) => ProjectionElem::OpaqueCast(ty),
+            };
+            value = self.insert(Value::Projection(value, proj));
+        }
+
+        if let Some(local) = self.try_as_local(value, location)
+            && local != place.local // in case we had no projection to begin with.
+        {
+            *place = local.into();
+            self.reused_locals.insert(local);
+            self.any_replacement = true;
+        } else if place_ref.local != place.local
+            || place_ref.projection.len() < place.projection.len()
+        {
+            // By the invariant on `place_ref`.
+            *place = place_ref.project_deeper(&[], self.tcx);
+            self.reused_locals.insert(place_ref.local);
+            self.any_replacement = true;
+        }
+
+        Some(value)
+    }
+
+    #[instrument(level = "trace", skip(self), ret)]
+    fn simplify_operand(
+        &mut self,
+        operand: &mut Operand<'tcx>,
+        location: Location,
+    ) -> Option<VnIndex> {
+        match *operand {
+            Operand::Constant(ref constant) => Some(self.insert(Value::Constant(constant.const_))),
+            Operand::Copy(ref mut place) | Operand::Move(ref mut place) => {
+                let value = self.simplify_place_value(place, location)?;
+                if let Some(const_) = self.try_as_constant(value) {
+                    *operand = Operand::Constant(Box::new(const_));
+                    self.any_replacement = true;
+                }
+                Some(value)
+            }
+        }
+    }
+
+    #[instrument(level = "trace", skip(self), ret)]
+    fn simplify_rvalue(
+        &mut self,
+        rvalue: &mut Rvalue<'tcx>,
+        location: Location,
+    ) -> Option<VnIndex> {
+        let value = match *rvalue {
+            // Forward values.
+            Rvalue::Use(ref mut operand) => return self.simplify_operand(operand, location),
+            Rvalue::CopyForDeref(place) => {
+                let mut operand = Operand::Copy(place);
+                let val = self.simplify_operand(&mut operand, location);
+                *rvalue = Rvalue::Use(operand);
+                return val;
+            }
+
+            // Roots.
+            Rvalue::Repeat(ref mut op, amount) => {
+                let op = self.simplify_operand(op, location)?;
+                Value::Repeat(op, amount)
+            }
+            Rvalue::NullaryOp(op, ty) => Value::NullaryOp(op, ty),
+            Rvalue::Aggregate(box ref kind, ref mut fields) => {
+                let variant_index = match *kind {
+                    AggregateKind::Array(..)
+                    | AggregateKind::Tuple
+                    | AggregateKind::Closure(..)
+                    | AggregateKind::Generator(..) => FIRST_VARIANT,
+                    AggregateKind::Adt(_, variant_index, _, _, None) => variant_index,
+                    // Do not track unions.
+                    AggregateKind::Adt(_, _, _, _, Some(_)) => return None,
+                };
+                let fields: Option<Vec<_>> = fields
+                    .iter_mut()
+                    .map(|op| self.simplify_operand(op, location).or_else(|| self.new_opaque()))
+                    .collect();
+                let ty = rvalue.ty(self.local_decls, self.tcx);
+                Value::Aggregate(ty, variant_index, fields?)
+            }
+            Rvalue::Ref(.., place) | Rvalue::AddressOf(_, place) => return self.new_pointer(place),
+
+            // Operations.
+            Rvalue::Len(ref mut place) => {
+                let place = self.simplify_place_value(place, location)?;
+                Value::Len(place)
+            }
+            Rvalue::Cast(kind, ref mut value, to) => {
+                let from = value.ty(self.local_decls, self.tcx);
+                let value = self.simplify_operand(value, location)?;
+                Value::Cast { kind, value, from, to }
+            }
+            Rvalue::BinaryOp(op, box (ref mut lhs, ref mut rhs)) => {
+                let lhs = self.simplify_operand(lhs, location);
+                let rhs = self.simplify_operand(rhs, location);
+                Value::BinaryOp(op, lhs?, rhs?)
+            }
+            Rvalue::CheckedBinaryOp(op, box (ref mut lhs, ref mut rhs)) => {
+                let lhs = self.simplify_operand(lhs, location);
+                let rhs = self.simplify_operand(rhs, location);
+                Value::CheckedBinaryOp(op, lhs?, rhs?)
+            }
+            Rvalue::UnaryOp(op, ref mut arg) => {
+                let arg = self.simplify_operand(arg, location)?;
+                Value::UnaryOp(op, arg)
+            }
+            Rvalue::Discriminant(ref mut place) => {
+                let place = self.simplify_place_value(place, location)?;
+                Value::Discriminant(place)
+            }
+
+            // Unsupported values.
+            Rvalue::ThreadLocalRef(..) | Rvalue::ShallowInitBox(..) => return None,
+        };
+        debug!(?value);
+        Some(self.insert(value))
+    }
+}
+
+impl<'tcx> VnState<'_, 'tcx> {
+    /// If `index` is a `Value::Constant`, return the `Constant` to be put in the MIR.
+    fn try_as_constant(&mut self, index: VnIndex) -> Option<ConstOperand<'tcx>> {
+        if let Value::Constant(const_) = *self.get(index) {
+            // Some constants may contain pointers. We need to preserve the provenance of these
+            // pointers, but not all constants guarantee this:
+            // - valtrees purposefully do not;
+            // - ConstValue::Slice does not either.
+            match const_ {
+                Const::Ty(c) => match c.kind() {
+                    ty::ConstKind::Value(valtree) => match valtree {
+                        // This is just an integer, keep it.
+                        ty::ValTree::Leaf(_) => {}
+                        ty::ValTree::Branch(_) => return None,
+                    },
+                    ty::ConstKind::Param(..)
+                    | ty::ConstKind::Unevaluated(..)
+                    | ty::ConstKind::Expr(..) => {}
+                    // Should not appear in runtime MIR.
+                    ty::ConstKind::Infer(..)
+                    | ty::ConstKind::Bound(..)
+                    | ty::ConstKind::Placeholder(..)
+                    | ty::ConstKind::Error(..) => bug!(),
+                },
+                Const::Unevaluated(..) => {}
+                // If the same slice appears twice in the MIR, we cannot guarantee that we will
+                // give the same `AllocId` to the data.
+                Const::Val(ConstValue::Slice { .. }, _) => return None,
+                Const::Val(
+                    ConstValue::ZeroSized | ConstValue::Scalar(_) | ConstValue::Indirect { .. },
+                    _,
+                ) => {}
+            }
+            Some(ConstOperand { span: rustc_span::DUMMY_SP, user_ty: None, const_ })
+        } else {
+            None
+        }
+    }
+
+    /// If there is a local which is assigned `index`, and its assignment strictly dominates `loc`,
+    /// return it.
+    fn try_as_local(&mut self, index: VnIndex, loc: Location) -> Option<Local> {
+        let other = self.rev_locals.get(&index)?;
+        other
+            .iter()
+            .copied()
+            .find(|&other| self.ssa.assignment_dominates(self.dominators, other, loc))
+    }
+}
+
+impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn visit_operand(&mut self, operand: &mut Operand<'tcx>, location: Location) {
+        self.simplify_operand(operand, location);
+    }
+
+    fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, location: Location) {
+        self.super_statement(stmt, location);
+        if let StatementKind::Assign(box (_, ref mut rvalue)) = stmt.kind
+            // Do not try to simplify a constant, it's already in canonical shape.
+            && !matches!(rvalue, Rvalue::Use(Operand::Constant(_)))
+            && let Some(value) = self.simplify_rvalue(rvalue, location)
+        {
+            if let Some(const_) = self.try_as_constant(value) {
+                *rvalue = Rvalue::Use(Operand::Constant(Box::new(const_)));
+                self.any_replacement = true;
+            } else if let Some(local) = self.try_as_local(value, location)
+                && *rvalue != Rvalue::Use(Operand::Move(local.into()))
+            {
+                *rvalue = Rvalue::Use(Operand::Copy(local.into()));
+                self.reused_locals.insert(local);
+                self.any_replacement = true;
+            }
+        }
+    }
+}
+
+struct StorageRemover<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    reused_locals: BitSet<Local>,
+}
+
+impl<'tcx> MutVisitor<'tcx> for StorageRemover<'tcx> {
+    fn tcx(&self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
+
+    fn visit_operand(&mut self, operand: &mut Operand<'tcx>, _: Location) {
+        if let Operand::Move(place) = *operand
+            && let Some(local) = place.as_local()
+            && self.reused_locals.contains(local)
+        {
+            *operand = Operand::Copy(place);
+        }
+    }
+
+    fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, loc: Location) {
+        match stmt.kind {
+            // When removing storage statements, we need to remove both (#107511).
+            StatementKind::StorageLive(l) | StatementKind::StorageDead(l)
+                if self.reused_locals.contains(l) =>
+            {
+                stmt.make_nop()
+            }
+            _ => self.super_statement(stmt, loc),
+        }
+    }
+}
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 1d9c89477cb..ebd61f8ad95 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -193,7 +193,7 @@ impl<'tcx> Inliner<'tcx> {
             return Err("optimization fuel exhausted");
         }
 
-        let Ok(callee_body) = callsite.callee.try_subst_mir_and_normalize_erasing_regions(
+        let Ok(callee_body) = callsite.callee.try_instantiate_mir_and_normalize_erasing_regions(
             self.tcx,
             self.param_env,
             ty::EarlyBinder::bind(callee_body.clone()),
@@ -481,9 +481,10 @@ impl<'tcx> Inliner<'tcx> {
                 work_list.push(target);
 
                 // If the place doesn't actually need dropping, treat it like a regular goto.
-                let ty = callsite
-                    .callee
-                    .subst_mir(self.tcx, ty::EarlyBinder::bind(&place.ty(callee_body, tcx).ty));
+                let ty = callsite.callee.instantiate_mir(
+                    self.tcx,
+                    ty::EarlyBinder::bind(&place.ty(callee_body, tcx).ty),
+                );
                 if ty.needs_drop(tcx, self.param_env) && let UnwindAction::Cleanup(unwind) = unwind {
                     work_list.push(unwind);
                 }
@@ -650,7 +651,7 @@ impl<'tcx> Inliner<'tcx> {
                 // Copy only unevaluated constants from the callee_body into the caller_body.
                 // Although we are only pushing `ConstKind::Unevaluated` consts to
                 // `required_consts`, here we may not only have `ConstKind::Unevaluated`
-                // because we are calling `subst_and_normalize_erasing_regions`.
+                // because we are calling `instantiate_and_normalize_erasing_regions`.
                 caller_body.required_consts.extend(
                     callee_body.required_consts.iter().copied().filter(|&ct| match ct.const_ {
                         Const::Ty(_) => {
@@ -811,9 +812,10 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
         match terminator.kind {
             TerminatorKind::Drop { ref place, unwind, .. } => {
                 // If the place doesn't actually need dropping, treat it like a regular goto.
-                let ty = self
-                    .instance
-                    .subst_mir(tcx, ty::EarlyBinder::bind(&place.ty(self.callee_body, tcx).ty));
+                let ty = self.instance.instantiate_mir(
+                    tcx,
+                    ty::EarlyBinder::bind(&place.ty(self.callee_body, tcx).ty),
+                );
                 if ty.needs_drop(tcx, self.param_env) {
                     self.cost += CALL_PENALTY;
                     if let UnwindAction::Cleanup(_) = unwind {
@@ -824,7 +826,8 @@ impl<'tcx> Visitor<'tcx> for CostChecker<'_, 'tcx> {
                 }
             }
             TerminatorKind::Call { func: Operand::Constant(ref f), unwind, .. } => {
-                let fn_ty = self.instance.subst_mir(tcx, ty::EarlyBinder::bind(&f.const_.ty()));
+                let fn_ty =
+                    self.instance.instantiate_mir(tcx, ty::EarlyBinder::bind(&f.const_.ty()));
                 self.cost += if let ty::FnDef(def_id, _) = *fn_ty.kind() && tcx.is_intrinsic(def_id) {
                     // Don't give intrinsics the extra penalty for calls
                     INSTR_COST
diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs
index 822634129fc..d30e0bad813 100644
--- a/compiler/rustc_mir_transform/src/inline/cycle.rs
+++ b/compiler/rustc_mir_transform/src/inline/cycle.rs
@@ -44,7 +44,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
     ) -> bool {
         trace!(%caller);
         for &(callee, args) in tcx.mir_inliner_callees(caller.def) {
-            let Ok(args) = caller.try_subst_mir_and_normalize_erasing_regions(
+            let Ok(args) = caller.try_instantiate_mir_and_normalize_erasing_regions(
                 tcx,
                 param_env,
                 ty::EarlyBinder::bind(args),
diff --git a/compiler/rustc_mir_transform/src/large_enums.rs b/compiler/rustc_mir_transform/src/large_enums.rs
index 4eee45f8d00..886ff760481 100644
--- a/compiler/rustc_mir_transform/src/large_enums.rs
+++ b/compiler/rustc_mir_transform/src/large_enums.rs
@@ -54,11 +54,8 @@ impl EnumSizeOpt {
         let layout = tcx.layout_of(param_env.and(ty)).ok()?;
         let variants = match &layout.variants {
             Variants::Single { .. } => return None,
-            Variants::Multiple { tag_encoding, .. }
-                if matches!(tag_encoding, TagEncoding::Niche { .. }) =>
-            {
-                return None;
-            }
+            Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, .. } => return None,
+
             Variants::Multiple { variants, .. } if variants.len() <= 1 => return None,
             Variants::Multiple { variants, .. } => variants,
         };
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index d55b0cbe635..754f2ee8376 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -76,6 +76,7 @@ mod errors;
 mod ffi_unwind_calls;
 mod function_item_references;
 mod generator;
+mod gvn;
 pub mod inline;
 mod instsimplify;
 mod large_enums;
@@ -358,9 +359,7 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
 /// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't
 /// end up missing the source MIR due to stealing happening.
 fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
-    if tcx.sess.opts.unstable_opts.drop_tracking_mir
-        && let DefKind::Generator = tcx.def_kind(def)
-    {
+    if let DefKind::Generator = tcx.def_kind(def) {
         tcx.ensure_with_value().mir_generator_witnesses(def);
     }
     let mir_borrowck = tcx.mir_borrowck(def);
@@ -481,6 +480,7 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
     let passes: &[&dyn MirPass<'tcx>] = &[
         // These next passes must be executed together
         &add_call_guards::CriticalCallEdges,
+        &reveal_all::RevealAll, // has to be done before drop elaboration, since we need to drop opaque types, too.
         &elaborate_drops::ElaborateDrops,
         // This will remove extraneous landing pads which are no longer
         // necessary as well as well as forcing any call in a non-unwinding
@@ -527,7 +527,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         body,
         &[
             &check_alignment::CheckAlignment,
-            &reveal_all::RevealAll, // has to be done before inlining, since inlined code is in RevealAll mode.
             &lower_slice_len::LowerSliceLenCalls, // has to be done before inlining, otherwise actual call will be almost always inlined. Also simple, so can just do first
             &unreachable_prop::UnreachablePropagation,
             &uninhabited_enum_branching::UninhabitedEnumBranching,
@@ -551,6 +550,7 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
             // latter pass will leverage the created opportunities.
             &separate_const_switch::SeparateConstSwitch,
             &const_prop::ConstProp,
+            &gvn::GVN,
             &dataflow_const_prop::DataflowConstProp,
             //
             // Const-prop runs unconditionally, but doesn't mutate the MIR at mir-opt-level=0.
diff --git a/compiler/rustc_mir_transform/src/ref_prop.rs b/compiler/rustc_mir_transform/src/ref_prop.rs
index 49a940b5779..67941cf4395 100644
--- a/compiler/rustc_mir_transform/src/ref_prop.rs
+++ b/compiler/rustc_mir_transform/src/ref_prop.rs
@@ -108,7 +108,7 @@ enum Value<'tcx> {
 }
 
 /// For each local, save the place corresponding to `*local`.
-#[instrument(level = "trace", skip(tcx, body))]
+#[instrument(level = "trace", skip(tcx, body, ssa))]
 fn compute_replacement<'tcx>(
     tcx: TyCtxt<'tcx>,
     body: &Body<'tcx>,
diff --git a/compiler/rustc_mir_transform/src/reveal_all.rs b/compiler/rustc_mir_transform/src/reveal_all.rs
index 065793348e4..55f1eac6f84 100644
--- a/compiler/rustc_mir_transform/src/reveal_all.rs
+++ b/compiler/rustc_mir_transform/src/reveal_all.rs
@@ -8,16 +8,7 @@ use rustc_middle::ty::{self, Ty, TyCtxt};
 pub struct RevealAll;
 
 impl<'tcx> MirPass<'tcx> for RevealAll {
-    fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
-        sess.mir_opt_level() >= 3 || super::inline::Inline.is_enabled(sess)
-    }
-
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
-        // Do not apply this transformation to generators.
-        if body.generator.is_some() {
-            return;
-        }
-
         let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id());
         RevealAllVisitor { tcx, param_env }.visit_body_preserves_cfg(body);
     }
@@ -35,6 +26,29 @@ impl<'tcx> MutVisitor<'tcx> for RevealAllVisitor<'tcx> {
     }
 
     #[inline]
+    fn visit_place(
+        &mut self,
+        place: &mut Place<'tcx>,
+        _context: PlaceContext,
+        _location: Location,
+    ) {
+        // Performance optimization: don't reintern if there is no `OpaqueCast` to remove.
+        if place.projection.iter().all(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_))) {
+            return;
+        }
+        // `OpaqueCast` projections are only needed if there are opaque types on which projections are performed.
+        // After the `RevealAll` pass, all opaque types are replaced with their hidden types, so we don't need these
+        // projections anymore.
+        place.projection = self.tcx.mk_place_elems(
+            &place
+                .projection
+                .into_iter()
+                .filter(|elem| !matches!(elem, ProjectionElem::OpaqueCast(_)))
+                .collect::<Vec<_>>(),
+        );
+    }
+
+    #[inline]
     fn visit_constant(&mut self, constant: &mut ConstOperand<'tcx>, _: Location) {
         // We have to use `try_normalize_erasing_regions` here, since it's
         // possible that we visit impossible-to-satisfy where clauses here,
diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs
index b7a51cfd619..2795cf15702 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -29,6 +29,7 @@
 
 use crate::MirPass;
 use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
+use rustc_index::bit_set::BitSet;
 use rustc_index::{Idx, IndexSlice, IndexVec};
 use rustc_middle::mir::coverage::*;
 use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
@@ -345,24 +346,22 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
 
     let basic_blocks = body.basic_blocks.as_mut();
     let source_scopes = &body.source_scopes;
-    let mut replacements: Vec<_> = (0..num_blocks).map(BasicBlock::new).collect();
-    let mut used_blocks = 0;
-    for alive_index in reachable.iter() {
-        let alive_index = alive_index.index();
-        replacements[alive_index] = BasicBlock::new(used_blocks);
-        if alive_index != used_blocks {
-            // Swap the next alive block data with the current available slot. Since
-            // alive_index is non-decreasing this is a valid operation.
-            basic_blocks.raw.swap(alive_index, used_blocks);
-        }
-        used_blocks += 1;
-    }
-
     if tcx.sess.instrument_coverage() {
-        save_unreachable_coverage(basic_blocks, source_scopes, used_blocks);
+        save_unreachable_coverage(basic_blocks, source_scopes, &reachable);
     }
 
-    basic_blocks.raw.truncate(used_blocks);
+    let mut replacements: Vec<_> = (0..num_blocks).map(BasicBlock::new).collect();
+    let mut orig_index = 0;
+    let mut used_index = 0;
+    basic_blocks.raw.retain(|_| {
+        let keep = reachable.contains(BasicBlock::new(orig_index));
+        if keep {
+            replacements[orig_index] = BasicBlock::new(used_index);
+            used_index += 1;
+        }
+        orig_index += 1;
+        keep
+    });
 
     for block in basic_blocks {
         for target in block.terminator_mut().successors_mut() {
@@ -404,11 +403,12 @@ pub fn remove_dead_blocks<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
 fn save_unreachable_coverage(
     basic_blocks: &mut IndexSlice<BasicBlock, BasicBlockData<'_>>,
     source_scopes: &IndexSlice<SourceScope, SourceScopeData<'_>>,
-    first_dead_block: usize,
+    reachable: &BitSet<BasicBlock>,
 ) {
     // Identify instances that still have some live coverage counters left.
     let mut live = FxHashSet::default();
-    for basic_block in &basic_blocks.raw[0..first_dead_block] {
+    for bb in reachable.iter() {
+        let basic_block = &basic_blocks[bb];
         for statement in &basic_block.statements {
             let StatementKind::Coverage(coverage) = &statement.kind else { continue };
             let CoverageKind::Counter { .. } = coverage.kind else { continue };
@@ -417,7 +417,8 @@ fn save_unreachable_coverage(
         }
     }
 
-    for block in &mut basic_blocks.raw[..first_dead_block] {
+    for bb in reachable.iter() {
+        let block = &mut basic_blocks[bb];
         for statement in &mut block.statements {
             let StatementKind::Coverage(_) = &statement.kind else { continue };
             let instance = statement.source_info.scope.inlined_instance(source_scopes);
@@ -433,7 +434,11 @@ fn save_unreachable_coverage(
 
     // Retain coverage for instances that still have some live counters left.
     let mut retained_coverage = Vec::new();
-    for dead_block in &basic_blocks.raw[first_dead_block..] {
+    for dead_block in basic_blocks.indices() {
+        if reachable.contains(dead_block) {
+            continue;
+        }
+        let dead_block = &basic_blocks[dead_block];
         for statement in &dead_block.statements {
             let StatementKind::Coverage(coverage) = &statement.kind else { continue };
             let Some(code_region) = &coverage.code_region else { continue };
diff --git a/compiler/rustc_mir_transform/src/ssa.rs b/compiler/rustc_mir_transform/src/ssa.rs
index 04bc461c815..af9514ed6bb 100644
--- a/compiler/rustc_mir_transform/src/ssa.rs
+++ b/compiler/rustc_mir_transform/src/ssa.rs
@@ -13,7 +13,6 @@ use rustc_middle::middle::resolve_bound_vars::Set1;
 use rustc_middle::mir::visit::*;
 use rustc_middle::mir::*;
 
-#[derive(Debug)]
 pub struct SsaLocals {
     /// Assignments to each local. This defines whether the local is SSA.
     assignments: IndexVec<Local, Set1<LocationExtended>>,
@@ -79,14 +78,10 @@ impl SsaLocals {
             visitor.assignments[local] = Set1::One(LocationExtended::Arg);
         }
 
-        if body.basic_blocks.len() > 2 {
-            for (bb, data) in traversal::reverse_postorder(body) {
-                visitor.visit_basic_block_data(bb, data);
-            }
-        } else {
-            for (bb, data) in body.basic_blocks.iter_enumerated() {
-                visitor.visit_basic_block_data(bb, data);
-            }
+        // For SSA assignments, a RPO visit will see the assignment before it sees any use.
+        // We only visit reachable nodes: computing `dominates` on an unreachable node ICEs.
+        for (bb, data) in traversal::reverse_postorder(body) {
+            visitor.visit_basic_block_data(bb, data);
         }
 
         for var_debug_info in &body.var_debug_info {
@@ -129,6 +124,25 @@ impl SsaLocals {
         self.direct_uses[local]
     }
 
+    pub fn assignment_dominates(
+        &self,
+        dominators: &Dominators<BasicBlock>,
+        local: Local,
+        location: Location,
+    ) -> bool {
+        match self.assignments[local] {
+            Set1::One(LocationExtended::Arg) => true,
+            Set1::One(LocationExtended::Plain(ass)) => {
+                if ass.block == location.block {
+                    ass.statement_index < location.statement_index
+                } else {
+                    dominators.dominates(ass.block, location.block)
+                }
+            }
+            _ => false,
+        }
+    }
+
     pub fn assignments<'a, 'tcx>(
         &'a self,
         body: &'a Body<'tcx>,
@@ -146,6 +160,24 @@ impl SsaLocals {
         })
     }
 
+    pub fn for_each_assignment_mut<'tcx>(
+        &self,
+        basic_blocks: &mut BasicBlocks<'tcx>,
+        mut f: impl FnMut(Local, &mut Rvalue<'tcx>, Location),
+    ) {
+        for &local in &self.assignment_order {
+            if let Set1::One(LocationExtended::Plain(loc)) = self.assignments[local] {
+                // `loc` must point to a direct assignment to `local`.
+                let bbs = basic_blocks.as_mut_preserves_cfg();
+                let bb = &mut bbs[loc.block];
+                let stmt = &mut bb.statements[loc.statement_index];
+                let StatementKind::Assign(box (target, ref mut rvalue)) = stmt.kind else { bug!() };
+                assert_eq!(target.as_local(), Some(local));
+                f(local, rvalue, loc)
+            }
+        }
+    }
+
     /// Compute the equivalence classes for locals, based on copy statements.
     ///
     /// The returned vector maps each local to the one it copies. In the following case:
diff --git a/compiler/rustc_mir_transform/src/unreachable_prop.rs b/compiler/rustc_mir_transform/src/unreachable_prop.rs
index bd1724bf842..0b9311a20ef 100644
--- a/compiler/rustc_mir_transform/src/unreachable_prop.rs
+++ b/compiler/rustc_mir_transform/src/unreachable_prop.rs
@@ -13,7 +13,11 @@ pub struct UnreachablePropagation;
 impl MirPass<'_> for UnreachablePropagation {
     fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
         // Enable only under -Zmir-opt-level=2 as this can make programs less debuggable.
-        sess.mir_opt_level() >= 2
+
+        // FIXME(#116171) Coverage gets confused by MIR passes that can remove all
+        // coverage statements from an instrumented function. This pass can be
+        // re-enabled when coverage codegen is robust against that happening.
+        sess.mir_opt_level() >= 2 && !sess.instrument_coverage()
     }
 
     fn run_pass<'tcx>(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 4afa4e597f7..1a9f0e8352e 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -606,7 +606,7 @@ impl<'a, 'tcx> MirUsedCollector<'a, 'tcx> {
         T: TypeFoldable<TyCtxt<'tcx>>,
     {
         debug!("monomorphize: self.instance={:?}", self.instance);
-        self.instance.subst_mir_and_normalize_erasing_regions(
+        self.instance.instantiate_mir_and_normalize_erasing_regions(
             self.tcx,
             ty::ParamEnv::reveal_all(),
             ty::EarlyBinder::bind(value),
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index c993e64477b..1d8cbe0e21b 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -647,7 +647,7 @@ fn characteristic_def_id_of_mono_item<'tcx>(
                 // parameters, but the self-type of their impl block do will fail to normalize.
                 if !tcx.sess.opts.unstable_opts.polymorphize || !instance.has_param() {
                     // This is a method within an impl, find out what the self-type is:
-                    let impl_self_ty = tcx.subst_and_normalize_erasing_regions(
+                    let impl_self_ty = tcx.instantiate_and_normalize_erasing_regions(
                         instance.args,
                         ty::ParamEnv::reveal_all(),
                         tcx.type_of(impl_def_id),
diff --git a/compiler/rustc_monomorphize/src/polymorphize.rs b/compiler/rustc_monomorphize/src/polymorphize.rs
index 0e85f35fc1b..6c206a6bac8 100644
--- a/compiler/rustc_monomorphize/src/polymorphize.rs
+++ b/compiler/rustc_monomorphize/src/polymorphize.rs
@@ -143,7 +143,7 @@ fn mark_used_by_default_parameters<'tcx>(
         | DefKind::Enum
         | DefKind::Variant
         | DefKind::Trait
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::TraitAlias
         | DefKind::AssocTy
diff --git a/compiler/rustc_monomorphize/src/util.rs b/compiler/rustc_monomorphize/src/util.rs
index a3433d3d13d..e25c5c9f27c 100644
--- a/compiler/rustc_monomorphize/src/util.rs
+++ b/compiler/rustc_monomorphize/src/util.rs
@@ -26,12 +26,12 @@ pub(crate) fn dump_closure_profile<'tcx>(tcx: TyCtxt<'tcx>, closure_instance: In
         let ClosureSizeProfileData { before_feature_tys, after_feature_tys } =
             typeck_results.closure_size_eval[&closure_def_id];
 
-        let before_feature_tys = tcx.subst_and_normalize_erasing_regions(
+        let before_feature_tys = tcx.instantiate_and_normalize_erasing_regions(
             closure_instance.args,
             param_env,
             ty::EarlyBinder::bind(before_feature_tys),
         );
-        let after_feature_tys = tcx.subst_and_normalize_erasing_regions(
+        let after_feature_tys = tcx.instantiate_and_normalize_erasing_regions(
             closure_instance.args,
             param_env,
             ty::EarlyBinder::bind(after_feature_tys),
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index 2c4bc7bb568..05b6c406206 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -509,7 +509,7 @@ parse_maybe_fn_typo_with_impl = you might have meant to write `impl` instead of
 
 parse_maybe_recover_from_bad_qpath_stage_2 =
     missing angle brackets in associated item path
-    .suggestion = try: `{$ty}`
+    .suggestion = types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
 
 parse_maybe_recover_from_bad_type_plus =
     expected a path on the left-hand side of `+`, not `{$ty}`
diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs
index 5d3ec683552..7c75e440aaa 100644
--- a/compiler/rustc_parse/src/errors.rs
+++ b/compiler/rustc_parse/src/errors.rs
@@ -59,9 +59,18 @@ pub(crate) enum BadTypePlusSub {
 #[diag(parse_maybe_recover_from_bad_qpath_stage_2)]
 pub(crate) struct BadQPathStage2 {
     #[primary_span]
-    #[suggestion(code = "", applicability = "maybe-incorrect")]
     pub span: Span,
-    pub ty: String,
+    #[subdiagnostic]
+    pub wrap: WrapType,
+}
+
+#[derive(Subdiagnostic)]
+#[multipart_suggestion(parse_suggestion, applicability = "machine-applicable")]
+pub(crate) struct WrapType {
+    #[suggestion_part(code = "<")]
+    pub lo: Span,
+    #[suggestion_part(code = ">")]
+    pub hi: Span,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 6c8ef34063f..06b1b1523ed 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -16,7 +16,7 @@ use crate::errors::{
     StructLiteralBodyWithoutPath, StructLiteralBodyWithoutPathSugg, StructLiteralNeedingParens,
     StructLiteralNeedingParensSugg, SuggAddMissingLetStmt, SuggEscapeIdentifier, SuggRemoveComma,
     TernaryOperator, UnexpectedConstInGenericParam, UnexpectedConstParamDeclaration,
-    UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead,
+    UnexpectedConstParamDeclarationSugg, UnmatchedAngleBrackets, UseEqInstead, WrapType,
 };
 
 use crate::fluent_generated as fluent;
@@ -1589,10 +1589,9 @@ impl<'a> Parser<'a> {
         self.parse_path_segments(&mut path.segments, T::PATH_STYLE, None)?;
         path.span = ty_span.to(self.prev_token.span);
 
-        let ty_str = self.span_to_snippet(ty_span).unwrap_or_else(|_| pprust::ty_to_string(&ty));
         self.sess.emit_err(BadQPathStage2 {
-            span: path.span,
-            ty: format!("<{}>::{}", ty_str, pprust::path_to_string(&path)),
+            span: ty_span,
+            wrap: WrapType { lo: ty_span.shrink_to_lo(), hi: ty_span.shrink_to_hi() },
         });
 
         let path_span = ty_span.shrink_to_hi(); // Use an empty path since `position == 0`.
diff --git a/compiler/rustc_passes/messages.ftl b/compiler/rustc_passes/messages.ftl
index dc0776c5dad..214c6d70960 100644
--- a/compiler/rustc_passes/messages.ftl
+++ b/compiler/rustc_passes/messages.ftl
@@ -648,6 +648,10 @@ passes_rustc_lint_opt_ty =
     `#[rustc_lint_opt_ty]` should be applied to a struct
     .label = not a struct
 
+passes_rustc_safe_intrinsic =
+    attribute should be applied to intrinsic functions
+    .label = not an intrinsic function
+
 passes_rustc_std_internal_symbol =
     attribute should be applied to functions or statics
     .label = not a function or static
diff --git a/compiler/rustc_passes/src/abi_test.rs b/compiler/rustc_passes/src/abi_test.rs
index 9e4d960af14..153c39977bb 100644
--- a/compiler/rustc_passes/src/abi_test.rs
+++ b/compiler/rustc_passes/src/abi_test.rs
@@ -21,7 +21,7 @@ pub fn test_abi(tcx: TyCtxt<'_>) {
                 DefKind::Fn | DefKind::AssocFn => {
                     dump_abi_of_fn_item(tcx, id, attr);
                 }
-                DefKind::TyAlias { .. } => {
+                DefKind::TyAlias => {
                     dump_abi_of_fn_type(tcx, id, attr);
                 }
                 _ => {
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 12118a0268b..9a7564cb213 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -195,6 +195,9 @@ impl CheckAttrVisitor<'_> {
                 | sym::rustc_promotable => self.check_stability_promotable(&attr, span, target),
                 sym::link_ordinal => self.check_link_ordinal(&attr, span, target),
                 sym::rustc_confusables => self.check_confusables(&attr, target),
+                sym::rustc_safe_intrinsic => {
+                    self.check_rustc_safe_intrinsic(hir_id, attr, span, target)
+                }
                 _ => true,
             };
 
@@ -2042,6 +2045,29 @@ impl CheckAttrVisitor<'_> {
         }
     }
 
+    fn check_rustc_safe_intrinsic(
+        &self,
+        hir_id: HirId,
+        attr: &Attribute,
+        span: Span,
+        target: Target,
+    ) -> bool {
+        let hir = self.tcx.hir();
+
+        if let Target::ForeignFn = target
+            && let Some(parent) = hir.opt_parent_id(hir_id)
+            && let hir::Node::Item(Item {
+                kind: ItemKind::ForeignMod { abi: Abi::RustIntrinsic | Abi::PlatformIntrinsic, .. },
+                ..
+            }) = hir.get(parent)
+        {
+            return true;
+        }
+
+        self.tcx.sess.emit_err(errors::RustcSafeIntrinsic { attr_span: attr.span, span });
+        false
+    }
+
     fn check_rustc_std_internal_symbol(
         &self,
         attr: &Attribute,
@@ -2333,7 +2359,10 @@ impl CheckAttrVisitor<'_> {
                 &mut diag,
                 &cause,
                 None,
-                Some(ValuePairs::Sigs(ExpectedFound { expected: expected_sig, found: sig })),
+                Some(ValuePairs::PolySigs(ExpectedFound {
+                    expected: ty::Binder::dummy(expected_sig),
+                    found: ty::Binder::dummy(sig),
+                })),
                 terr,
                 false,
                 false,
diff --git a/compiler/rustc_passes/src/dead.rs b/compiler/rustc_passes/src/dead.rs
index d1c3bcf3839..493daf314ce 100644
--- a/compiler/rustc_passes/src/dead.rs
+++ b/compiler/rustc_passes/src/dead.rs
@@ -96,7 +96,7 @@ impl<'tcx> MarkSymbolVisitor<'tcx> {
 
     fn handle_res(&mut self, res: Res) {
         match res {
-            Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::TyAlias { .. }, def_id) => {
+            Res::Def(DefKind::Const | DefKind::AssocConst | DefKind::TyAlias, def_id) => {
                 self.check_def_id(def_id);
             }
             _ if self.in_pat => {}
@@ -923,7 +923,7 @@ impl<'tcx> DeadVisitor<'tcx> {
             | DefKind::Fn
             | DefKind::Static(_)
             | DefKind::Const
-            | DefKind::TyAlias { .. }
+            | DefKind::TyAlias
             | DefKind::Enum
             | DefKind::Union
             | DefKind::ForeignTy => self.warn_dead_code(def_id, "used"),
diff --git a/compiler/rustc_passes/src/errors.rs b/compiler/rustc_passes/src/errors.rs
index 2ec6a0b9241..bcf5abbfe7d 100644
--- a/compiler/rustc_passes/src/errors.rs
+++ b/compiler/rustc_passes/src/errors.rs
@@ -621,6 +621,15 @@ pub struct RustcAllowConstFnUnstable {
 }
 
 #[derive(Diagnostic)]
+#[diag(passes_rustc_safe_intrinsic)]
+pub struct RustcSafeIntrinsic {
+    #[primary_span]
+    pub attr_span: Span,
+    #[label]
+    pub span: Span,
+}
+
+#[derive(Diagnostic)]
 #[diag(passes_rustc_std_internal_symbol)]
 pub struct RustcStdInternalSymbol {
     #[primary_span]
diff --git a/compiler/rustc_passes/src/layout_test.rs b/compiler/rustc_passes/src/layout_test.rs
index e3a63f2e004..e195f9ab6da 100644
--- a/compiler/rustc_passes/src/layout_test.rs
+++ b/compiler/rustc_passes/src/layout_test.rs
@@ -23,7 +23,7 @@ pub fn test_layout(tcx: TyCtxt<'_>) {
     for id in tcx.hir_crate_items(()).definitions() {
         for attr in tcx.get_attrs(id, sym::rustc_layout) {
             match tcx.def_kind(id) {
-                DefKind::TyAlias { .. } | DefKind::Enum | DefKind::Struct | DefKind::Union => {
+                DefKind::TyAlias | DefKind::Enum | DefKind::Struct | DefKind::Union => {
                     dump_layout_of(tcx, id, attr);
                 }
                 _ => {
diff --git a/compiler/rustc_privacy/src/lib.rs b/compiler/rustc_privacy/src/lib.rs
index 1c2303ae9e0..ab85f680fcf 100644
--- a/compiler/rustc_privacy/src/lib.rs
+++ b/compiler/rustc_privacy/src/lib.rs
@@ -291,8 +291,7 @@ where
             | ty::Param(..)
             | ty::Bound(..)
             | ty::Error(_)
-            | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..) => {}
+            | ty::GeneratorWitness(..) => {}
             ty::Placeholder(..) | ty::Infer(..) => {
                 bug!("unexpected type: {:?}", ty)
             }
@@ -589,7 +588,7 @@ impl<'tcx> EmbargoVisitor<'tcx> {
         self.update(def_id, macro_ev, Level::Reachable);
         match def_kind {
             // No type privacy, so can be directly marked as reachable.
-            DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias { .. } => {
+            DefKind::Const | DefKind::Static(_) | DefKind::TraitAlias | DefKind::TyAlias => {
                 if vis.is_accessible_from(module, self.tcx) {
                     self.update(def_id, macro_ev, Level::Reachable);
                 }
@@ -1638,8 +1637,8 @@ impl<'tcx> PrivateItemsInPublicInterfacesChecker<'tcx, '_> {
         let def_kind = tcx.def_kind(def_id);
 
         match def_kind {
-            DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias { .. } => {
-                if let DefKind::TyAlias { .. } = def_kind {
+            DefKind::Const | DefKind::Static(_) | DefKind::Fn | DefKind::TyAlias => {
+                if let DefKind::TyAlias = def_kind {
                     self.check_unnameable(def_id, effective_vis);
                 }
                 self.check(def_id, item_visibility, effective_vis).generics().predicates().ty();
diff --git a/compiler/rustc_query_system/src/query/job.rs b/compiler/rustc_query_system/src/query/job.rs
index 2e9ebde296c..f2c1f84fccc 100644
--- a/compiler/rustc_query_system/src/query/job.rs
+++ b/compiler/rustc_query_system/src/query/job.rs
@@ -580,9 +580,7 @@ pub(crate) fn report_cycle<'a>(
         });
     }
 
-    let alias = if stack
-        .iter()
-        .all(|entry| matches!(entry.query.def_kind, Some(DefKind::TyAlias { .. })))
+    let alias = if stack.iter().all(|entry| matches!(entry.query.def_kind, Some(DefKind::TyAlias)))
     {
         Some(crate::error::Alias::Ty)
     } else if stack.iter().all(|entry| entry.query.def_kind == Some(DefKind::TraitAlias)) {
diff --git a/compiler/rustc_query_system/src/query/plumbing.rs b/compiler/rustc_query_system/src/query/plumbing.rs
index f93edffca79..ae8414ebba6 100644
--- a/compiler/rustc_query_system/src/query/plumbing.rs
+++ b/compiler/rustc_query_system/src/query/plumbing.rs
@@ -18,7 +18,7 @@ use rustc_data_structures::sharded::Sharded;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_data_structures::sync::Lock;
 #[cfg(parallel_compiler)]
-use rustc_data_structures::{cold_path, sync};
+use rustc_data_structures::{outline, sync};
 use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed, FatalError};
 use rustc_span::{Span, DUMMY_SP};
 use std::cell::Cell;
@@ -265,7 +265,7 @@ where
     match result {
         Ok(()) => {
             let Some((v, index)) = query.query_cache(qcx).lookup(&key) else {
-                cold_path(|| {
+                outline(|| {
                     // We didn't find the query result in the query cache. Check if it was
                     // poisoned due to a panic instead.
                     let lock = query.query_state(qcx).active.get_shard_by_value(&key).lock();
diff --git a/compiler/rustc_resolve/src/build_reduced_graph.rs b/compiler/rustc_resolve/src/build_reduced_graph.rs
index 2c36c83ae72..a18109574fe 100644
--- a/compiler/rustc_resolve/src/build_reduced_graph.rs
+++ b/compiler/rustc_resolve/src/build_reduced_graph.rs
@@ -698,10 +698,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
 
             // These items live in the type namespace.
             ItemKind::TyAlias(..) => {
-                let res = Res::Def(
-                    DefKind::TyAlias { lazy: self.r.tcx.features().lazy_type_alias },
-                    def_id,
-                );
+                let res = Res::Def(DefKind::TyAlias, def_id);
                 self.r.define(parent, ident, TypeNS, (res, vis, sp, expansion));
             }
 
@@ -950,7 +947,7 @@ impl<'a, 'b, 'tcx> BuildReducedGraphVisitor<'a, 'b, 'tcx> {
                 DefKind::Struct
                 | DefKind::Union
                 | DefKind::Variant
-                | DefKind::TyAlias { .. }
+                | DefKind::TyAlias
                 | DefKind::ForeignTy
                 | DefKind::OpaqueTy
                 | DefKind::TraitAlias
diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs
index 9b7fd76d103..907a6b1c46c 100644
--- a/compiler/rustc_resolve/src/diagnostics.rs
+++ b/compiler/rustc_resolve/src/diagnostics.rs
@@ -2596,7 +2596,9 @@ fn show_candidates(
             );
             if let [first, .., last] = &path[..] {
                 let sp = first.ident.span.until(last.ident.span);
-                if sp.can_be_used_for_suggestions() {
+                // Our suggestion is empty, so make sure the span is not empty (or we'd ICE).
+                // Can happen for derive-generated spans.
+                if sp.can_be_used_for_suggestions() && !sp.is_empty() {
                     err.span_suggestion_verbose(
                         sp,
                         format!("if you import `{}`, refer to it directly", last.ident),
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 01f9f060594..15ec727e4c9 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -474,7 +474,7 @@ impl<'a> PathSource<'a> {
                         | DefKind::Enum
                         | DefKind::Trait
                         | DefKind::TraitAlias
-                        | DefKind::TyAlias { .. }
+                        | DefKind::TyAlias
                         | DefKind::AssocTy
                         | DefKind::TyParam
                         | DefKind::OpaqueTy
@@ -513,7 +513,7 @@ impl<'a> PathSource<'a> {
                     DefKind::Struct
                         | DefKind::Union
                         | DefKind::Variant
-                        | DefKind::TyAlias { .. }
+                        | DefKind::TyAlias
                         | DefKind::AssocTy,
                     _,
                 ) | Res::SelfTyParam { .. }
@@ -1766,7 +1766,7 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                 Res::Def(DefKind::Struct, def_id)
                 | Res::Def(DefKind::Union, def_id)
                 | Res::Def(DefKind::Enum, def_id)
-                | Res::Def(DefKind::TyAlias { .. }, def_id)
+                | Res::Def(DefKind::TyAlias, def_id)
                 | Res::Def(DefKind::Trait, def_id)
                     if i + 1 == proj_start =>
                 {
@@ -4140,6 +4140,12 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
         });
     }
 
+    fn resolve_expr_field(&mut self, f: &'ast ExprField, e: &'ast Expr) {
+        self.resolve_expr(&f.expr, Some(e));
+        self.visit_ident(f.ident);
+        walk_list!(self, visit_attribute, f.attrs.iter());
+    }
+
     fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) {
         // First, record candidate traits for this expression if it could
         // result in the invocation of a method call.
@@ -4155,7 +4161,19 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
 
             ExprKind::Struct(ref se) => {
                 self.smart_resolve_path(expr.id, &se.qself, &se.path, PathSource::Struct);
-                visit::walk_expr(self, expr);
+                // This is the same as `visit::walk_expr(self, expr);`, but we want to pass the
+                // parent in for accurate suggestions when encountering `Foo { bar }` that should
+                // have been `Foo { bar: self.bar }`.
+                if let Some(qself) = &se.qself {
+                    self.visit_ty(&qself.ty);
+                }
+                self.visit_path(&se.path, expr.id);
+                walk_list!(self, resolve_expr_field, &se.fields, expr);
+                match &se.rest {
+                    StructRest::Base(expr) => self.visit_expr(expr),
+                    StructRest::Rest(_span) => {}
+                    StructRest::None => {}
+                }
             }
 
             ExprKind::Break(Some(label), _) | ExprKind::Continue(Some(label)) => {
diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs
index c34b7df9b46..bc5f8a37b0f 100644
--- a/compiler/rustc_resolve/src/late/diagnostics.rs
+++ b/compiler/rustc_resolve/src/late/diagnostics.rs
@@ -41,7 +41,7 @@ type Res = def::Res<ast::NodeId>;
 
 /// A field or associated item from self type suggested in case of resolution failure.
 enum AssocSuggestion {
-    Field,
+    Field(Span),
     MethodWithSelf { called: bool },
     AssocFn { called: bool },
     AssocType,
@@ -51,7 +51,7 @@ enum AssocSuggestion {
 impl AssocSuggestion {
     fn action(&self) -> &'static str {
         match self {
-            AssocSuggestion::Field => "use the available field",
+            AssocSuggestion::Field(_) => "use the available field",
             AssocSuggestion::MethodWithSelf { called: true } => {
                 "call the method with the fully-qualified path"
             }
@@ -186,7 +186,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 fallback_label: format!("not a {expected}"),
                 span,
                 span_label: match res {
-                    Res::Def(kind, def_id) if kind == DefKind::TyParam => {
+                    Res::Def(DefKind::TyParam, def_id) => {
                         Some((self.r.def_span(def_id), "found this type parameter"))
                     }
                     _ => None,
@@ -214,7 +214,9 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 module: None,
             }
         } else {
-            let item_span = path.last().unwrap().ident.span;
+            let mut span_label = None;
+            let item_ident = path.last().unwrap().ident;
+            let item_span = item_ident.span;
             let (mod_prefix, mod_str, module, suggestion) = if path.len() == 1 {
                 debug!(?self.diagnostic_metadata.current_impl_items);
                 debug!(?self.diagnostic_metadata.current_function);
@@ -224,32 +226,75 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                     && let FnKind::Fn(_, _, sig, ..) = fn_kind
                     && let Some(items) = self.diagnostic_metadata.current_impl_items
                     && let Some(item) = items.iter().find(|i| {
-                        if let AssocItemKind::Fn(..) | AssocItemKind::Const(..) = &i.kind
-                            && i.ident.name == item_str.name
-                            // don't suggest if the item is in Fn signature arguments
-                            // issue #112590
+                        i.ident.name == item_str.name
+                            // Don't suggest if the item is in Fn signature arguments (#112590).
                             && !sig.span.contains(item_span)
-                        {
-                            debug!(?item_str.name);
-                            return true
-                        }
-                        false
                     })
                 {
-                    let self_sugg = match &item.kind {
-                        AssocItemKind::Fn(fn_) if fn_.sig.decl.has_self() => "self.",
-                        _ => "Self::",
+                    let sp = item_span.shrink_to_lo();
+
+                    // Account for `Foo { field }` when suggesting `self.field` so we result on
+                    // `Foo { field: self.field }`.
+                    let field = match source {
+                        PathSource::Expr(Some(Expr { kind: ExprKind::Struct(expr), .. })) => {
+                            expr.fields.iter().find(|f| f.ident == item_ident)
+                        }
+                        _ => None,
+                    };
+                    let pre = if let Some(field) = field && field.is_shorthand {
+                        format!("{item_ident}: ")
+                    } else {
+                        String::new()
+                    };
+                    // Ensure we provide a structured suggestion for an assoc fn only for
+                    // expressions that are actually a fn call.
+                    let is_call = match field {
+                        Some(ast::ExprField { expr, .. }) => {
+                            matches!(expr.kind, ExprKind::Call(..))
+                        }
+                        _ => matches!(
+                            source,
+                            PathSource::Expr(Some(Expr { kind: ExprKind::Call(..), ..})),
+                        ),
                     };
 
-                    Some((
-                        item_span.shrink_to_lo(),
-                        match &item.kind {
-                            AssocItemKind::Fn(..) => "consider using the associated function",
-                            AssocItemKind::Const(..) => "consider using the associated constant",
-                            _ => unreachable!("item kind was filtered above"),
-                        },
-                        self_sugg.to_string()
-                    ))
+                    match &item.kind {
+                        AssocItemKind::Fn(fn_)
+                        if (!sig.decl.has_self() || !is_call) && fn_.sig.decl.has_self() => {
+                            // Ensure that we only suggest `self.` if `self` is available,
+                            // you can't call `fn foo(&self)` from `fn bar()` (#115992).
+                            // We also want to mention that the method exists.
+                            span_label = Some((
+                                item.ident.span,
+                                "a method by that name is available on `Self` here",
+                            ));
+                            None
+                        }
+                        AssocItemKind::Fn(fn_)
+                        if !fn_.sig.decl.has_self() && !is_call => {
+                            span_label = Some((
+                                item.ident.span,
+                                "an associated function by that name is available on `Self` here",
+                            ));
+                            None
+                        }
+                        AssocItemKind::Fn(fn_) if fn_.sig.decl.has_self() => Some((
+                            sp,
+                            "consider using the method on `Self`",
+                            format!("{pre}self."),
+                        )),
+                        AssocItemKind::Fn(_) => Some((
+                            sp,
+                            "consider using the associated function on `Self`",
+                            format!("{pre}Self::"),
+                        )),
+                        AssocItemKind::Const(..) => Some((
+                            sp,
+                            "consider using the associated constant on `Self`",
+                            format!("{pre}Self::"),
+                        )),
+                        _ => None
+                    }
                 } else {
                     None
                 };
@@ -314,7 +359,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 msg: format!("cannot find {expected} `{item_str}` in {mod_prefix}{mod_str}"),
                 fallback_label,
                 span: item_span,
-                span_label: None,
+                span_label,
                 could_be_expr: false,
                 suggestion,
                 module,
@@ -611,17 +656,30 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 self.lookup_assoc_candidate(ident, ns, is_expected, source.is_call())
             {
                 let self_is_available = self.self_value_is_available(path[0].ident.span);
+                // Account for `Foo { field }` when suggesting `self.field` so we result on
+                // `Foo { field: self.field }`.
+                let pre = match source {
+                    PathSource::Expr(Some(Expr { kind: ExprKind::Struct(expr), .. }))
+                        if expr
+                            .fields
+                            .iter()
+                            .any(|f| f.ident == path[0].ident && f.is_shorthand) =>
+                    {
+                        format!("{path_str}: ")
+                    }
+                    _ => String::new(),
+                };
                 match candidate {
-                    AssocSuggestion::Field => {
+                    AssocSuggestion::Field(field_span) => {
                         if self_is_available {
-                            err.span_suggestion(
-                                span,
+                            err.span_suggestion_verbose(
+                                span.shrink_to_lo(),
                                 "you might have meant to use the available field",
-                                format!("self.{path_str}"),
+                                format!("{pre}self."),
                                 Applicability::MachineApplicable,
                             );
                         } else {
-                            err.span_label(span, "a field by this name exists in `Self`");
+                            err.span_label(field_span, "a field by that name exists in `Self`");
                         }
                     }
                     AssocSuggestion::MethodWithSelf { called } if self_is_available => {
@@ -630,10 +688,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                         } else {
                             "you might have meant to refer to the method"
                         };
-                        err.span_suggestion(
-                            span,
+                        err.span_suggestion_verbose(
+                            span.shrink_to_lo(),
                             msg,
-                            format!("self.{path_str}"),
+                            "self.".to_string(),
                             Applicability::MachineApplicable,
                         );
                     }
@@ -641,10 +699,10 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                     | AssocSuggestion::AssocFn { .. }
                     | AssocSuggestion::AssocConst
                     | AssocSuggestion::AssocType => {
-                        err.span_suggestion(
-                            span,
+                        err.span_suggestion_verbose(
+                            span.shrink_to_lo(),
                             format!("you might have meant to {}", candidate.action()),
-                            format!("Self::{path_str}"),
+                            "Self::".to_string(),
                             Applicability::MachineApplicable,
                         );
                     }
@@ -1419,7 +1477,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
             (Res::Def(DefKind::Macro(MacroKind::Bang), _), _) => {
                 err.span_label(span, fallback_label.to_string());
             }
-            (Res::Def(DefKind::TyAlias { .. }, def_id), PathSource::Trait(_)) => {
+            (Res::Def(DefKind::TyAlias, def_id), PathSource::Trait(_)) => {
                 err.span_label(span, "type aliases cannot be used as traits");
                 if self.r.tcx.sess.is_nightly_build() {
                     let msg = "you might have meant to use `#![feature(trait_alias)]` instead of a \
@@ -1588,7 +1646,7 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                 err.span_label(span, fallback_label.to_string());
                 err.note("can't use `Self` as a constructor, you must use the implemented struct");
             }
-            (Res::Def(DefKind::TyAlias { .. } | DefKind::AssocTy, _), _) if ns == ValueNS => {
+            (Res::Def(DefKind::TyAlias | DefKind::AssocTy, _), _) if ns == ValueNS => {
                 err.note("can't use a type alias as a constructor");
             }
             _ => return false,
@@ -1657,11 +1715,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> {
                         resolution.full_res()
                     {
                         if let Some(field_ids) = self.r.field_def_ids(did) {
-                            if field_ids
+                            if let Some(field_id) = field_ids
                                 .iter()
-                                .any(|&field_id| ident.name == self.r.tcx.item_name(field_id))
+                                .find(|&&field_id| ident.name == self.r.tcx.item_name(field_id))
                             {
-                                return Some(AssocSuggestion::Field);
+                                return Some(AssocSuggestion::Field(self.r.def_span(*field_id)));
                             }
                         }
                     }
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 23f2be632b2..c1424db600e 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1458,17 +1458,11 @@ options! {
     dont_buffer_diagnostics: bool = (false, parse_bool, [UNTRACKED],
         "emit diagnostics rather than buffering (breaks NLL error downgrading, sorting) \
         (default: no)"),
-    drop_tracking: bool = (false, parse_bool, [TRACKED],
-        "enables drop tracking in generators (default: no)"),
-    drop_tracking_mir: bool = (false, parse_bool, [TRACKED],
-        "enables drop tracking on MIR in generators (default: no)"),
     dual_proc_macros: bool = (false, parse_bool, [TRACKED],
         "load proc macros for both target and host, but only link to the target (default: no)"),
     dump_dep_graph: bool = (false, parse_bool, [UNTRACKED],
         "dump the dependency graph to $RUST_DEP_GRAPH (default: /tmp/dep_graph.gv) \
         (default: no)"),
-    dump_drop_tracking_cfg: Option<String> = (None, parse_opt_string, [UNTRACKED],
-        "dump drop-tracking control-flow graph as a `.dot` file (default: no)"),
     dump_mir: Option<String> = (None, parse_opt_string, [UNTRACKED],
         "dump MIR state to file.
         `val` is used to select which passes and functions to dump. For example:
diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml
index 21ec904e43c..4c29f743708 100644
--- a/compiler/rustc_smir/Cargo.toml
+++ b/compiler/rustc_smir/Cargo.toml
@@ -4,24 +4,14 @@ version = "0.0.0"
 edition = "2021"
 
 [dependencies]
-# Use optional dependencies for rustc_* in order to support building this crate separately.
-rustc_hir = { path = "../rustc_hir", optional = true }
-rustc_middle = { path = "../rustc_middle", optional = true }
-rustc_span = { path = "../rustc_span", optional = true }
-rustc_target = { path = "../rustc_target", optional = true }
-rustc_driver = { path = "../rustc_driver", optional = true }
-rustc_interface = { path = "../rustc_interface", optional = true}
-rustc_session = {path = "../rustc_session", optional = true}
+rustc_hir = { path = "../rustc_hir" }
+rustc_middle = { path = "../rustc_middle" }
+rustc_span = { path = "../rustc_span" }
+rustc_target = { path = "../rustc_target" }
+rustc_driver = { path = "../rustc_driver" }
+rustc_interface = { path = "../rustc_interface" }
+rustc_session = {path = "../rustc_session" }
 tracing = "0.1"
-scoped-tls = "1.0"
+stable_mir = {path = "../stable_mir" }
 
 [features]
-default = [
-    "rustc_hir",
-    "rustc_middle",
-    "rustc_span",
-    "rustc_target",
-    "rustc_driver",
-    "rustc_interface",
-    "rustc_session",
-]
diff --git a/compiler/rustc_smir/src/lib.rs b/compiler/rustc_smir/src/lib.rs
index 8cb533c8d67..b6c36678db5 100644
--- a/compiler/rustc_smir/src/lib.rs
+++ b/compiler/rustc_smir/src/lib.rs
@@ -10,26 +10,12 @@
     html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
     test(attr(allow(unused_variables), deny(warnings)))
 )]
-#![cfg_attr(not(feature = "default"), feature(rustc_private))]
+#![feature(rustc_private)]
 #![feature(ptr_metadata)]
 #![feature(type_alias_impl_trait)] // Used to define opaque types.
 #![feature(intra_doc_pointers)]
 
-// Declare extern rustc_* crates to enable building this crate separately from the compiler.
-#[cfg(not(feature = "default"))]
-extern crate rustc_hir;
-#[cfg(not(feature = "default"))]
-extern crate rustc_middle;
-#[cfg(not(feature = "default"))]
-extern crate rustc_span;
-#[cfg(not(feature = "default"))]
-extern crate rustc_target;
-
 pub mod rustc_internal;
-pub mod stable_mir;
 
 // Make this module private for now since external users should not call these directly.
 mod rustc_smir;
-
-#[macro_use]
-extern crate scoped_tls;
diff --git a/compiler/rustc_smir/src/rustc_internal/mod.rs b/compiler/rustc_smir/src/rustc_internal/mod.rs
index 10ee5af86c6..1a9dea99f64 100644
--- a/compiler/rustc_smir/src/rustc_internal/mod.rs
+++ b/compiler/rustc_smir/src/rustc_internal/mod.rs
@@ -3,75 +3,17 @@
 //! For that, we define APIs that will temporarily be public to 3P that exposes rustc internal APIs
 //! until stable MIR is complete.
 
-use std::fmt::Debug;
 use std::ops::{ControlFlow, Index};
 
 use crate::rustc_internal;
-use crate::stable_mir::CompilerError;
-use crate::{
-    rustc_smir::Tables,
-    stable_mir::{self, with},
-};
+use crate::rustc_smir::Tables;
 use rustc_driver::{Callbacks, Compilation, RunCompiler};
 use rustc_interface::{interface, Queries};
 use rustc_middle::mir::interpret::AllocId;
 use rustc_middle::ty::TyCtxt;
 pub use rustc_span::def_id::{CrateNum, DefId};
 use rustc_span::Span;
-
-fn with_tables<R>(mut f: impl FnMut(&mut Tables<'_>) -> R) -> R {
-    let mut ret = None;
-    with(|tables| tables.rustc_tables(&mut |t| ret = Some(f(t))));
-    ret.unwrap()
-}
-
-pub fn item_def_id(item: &stable_mir::CrateItem) -> DefId {
-    with_tables(|t| t[item.0])
-}
-
-pub fn crate_item(did: DefId) -> stable_mir::CrateItem {
-    with_tables(|t| t.crate_item(did))
-}
-
-pub fn adt_def(did: DefId) -> stable_mir::ty::AdtDef {
-    with_tables(|t| t.adt_def(did))
-}
-
-pub fn foreign_def(did: DefId) -> stable_mir::ty::ForeignDef {
-    with_tables(|t| t.foreign_def(did))
-}
-
-pub fn fn_def(did: DefId) -> stable_mir::ty::FnDef {
-    with_tables(|t| t.fn_def(did))
-}
-
-pub fn closure_def(did: DefId) -> stable_mir::ty::ClosureDef {
-    with_tables(|t| t.closure_def(did))
-}
-
-pub fn generator_def(did: DefId) -> stable_mir::ty::GeneratorDef {
-    with_tables(|t| t.generator_def(did))
-}
-
-pub fn alias_def(did: DefId) -> stable_mir::ty::AliasDef {
-    with_tables(|t| t.alias_def(did))
-}
-
-pub fn param_def(did: DefId) -> stable_mir::ty::ParamDef {
-    with_tables(|t| t.param_def(did))
-}
-
-pub fn br_named_def(did: DefId) -> stable_mir::ty::BrNamedDef {
-    with_tables(|t| t.br_named_def(did))
-}
-
-pub fn trait_def(did: DefId) -> stable_mir::ty::TraitDef {
-    with_tables(|t| t.trait_def(did))
-}
-
-pub fn impl_def(did: DefId) -> stable_mir::ty::ImplDef {
-    with_tables(|t| t.impl_def(did))
-}
+use stable_mir::CompilerError;
 
 impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
     type Output = DefId;
@@ -82,6 +24,15 @@ impl<'tcx> Index<stable_mir::DefId> for Tables<'tcx> {
     }
 }
 
+impl<'tcx> Index<stable_mir::ty::Span> for Tables<'tcx> {
+    type Output = Span;
+
+    #[inline(always)]
+    fn index(&self, index: stable_mir::ty::Span) -> &Self::Output {
+        &self.spans[index.0]
+    }
+}
+
 impl<'tcx> Tables<'tcx> {
     pub fn crate_item(&mut self, did: DefId) -> stable_mir::CrateItem {
         stable_mir::CrateItem(self.create_def_id(did))
@@ -135,6 +86,10 @@ impl<'tcx> Tables<'tcx> {
         stable_mir::ty::ImplDef(self.create_def_id(did))
     }
 
+    pub fn region_def(&mut self, did: DefId) -> stable_mir::ty::RegionDef {
+        stable_mir::ty::RegionDef(self.create_def_id(did))
+    }
+
     pub fn prov(&mut self, aid: AllocId) -> stable_mir::ty::Prov {
         stable_mir::ty::Prov(self.create_alloc_id(aid))
     }
@@ -178,32 +133,12 @@ pub fn crate_num(item: &stable_mir::Crate) -> CrateNum {
 }
 
 pub fn run(tcx: TyCtxt<'_>, f: impl FnOnce()) {
-    crate::stable_mir::run(
+    stable_mir::run(
         Tables { tcx, def_ids: vec![], alloc_ids: vec![], spans: vec![], types: vec![] },
         f,
     );
 }
 
-/// A type that provides internal information but that can still be used for debug purpose.
-#[derive(Clone)]
-pub struct Opaque(String);
-
-impl std::fmt::Display for Opaque {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{}", self.0)
-    }
-}
-
-impl std::fmt::Debug for Opaque {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
-        write!(f, "{:?}", self.0)
-    }
-}
-
-pub(crate) fn opaque<T: Debug>(value: &T) -> Opaque {
-    Opaque(format!("{value:?}"))
-}
-
 pub struct StableMir<B = (), C = ()>
 where
     B: Send,
diff --git a/compiler/rustc_smir/src/rustc_smir/alloc.rs b/compiler/rustc_smir/src/rustc_smir/alloc.rs
index d8766cf8ce2..63a2a145069 100644
--- a/compiler/rustc_smir/src/rustc_smir/alloc.rs
+++ b/compiler/rustc_smir/src/rustc_smir/alloc.rs
@@ -3,11 +3,9 @@ use rustc_middle::mir::{
     ConstValue,
 };
 
-use crate::{
-    rustc_smir::{Stable, Tables},
-    stable_mir::mir::Mutability,
-    stable_mir::ty::{Allocation, ProvenanceMap},
-};
+use crate::rustc_smir::{Stable, Tables};
+use stable_mir::mir::Mutability;
+use stable_mir::ty::{Allocation, ProvenanceMap};
 
 /// Creates new empty `Allocation` from given `Align`.
 fn new_empty_allocation(align: rustc_target::abi::Align) -> Allocation {
diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs
index ad5f17cab6c..c6c97ce35e8 100644
--- a/compiler/rustc_smir/src/rustc_smir/mod.rs
+++ b/compiler/rustc_smir/src/rustc_smir/mod.rs
@@ -7,19 +7,17 @@
 //!
 //! For now, we are developing everything inside `rustc`, thus, we keep this module private.
 
-use crate::rustc_internal::{self, opaque};
-use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
-use crate::stable_mir::ty::{
-    FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy,
-};
-use crate::stable_mir::{self, CompilerError, Context};
+use crate::rustc_smir::hir::def::DefKind;
+use crate::rustc_smir::stable_mir::ty::{BoundRegion, EarlyBoundRegion, Region};
 use rustc_hir as hir;
 use rustc_middle::mir;
 use rustc_middle::mir::interpret::{alloc_range, AllocId};
 use rustc_middle::ty::{self, Ty, TyCtxt, Variance};
 use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE};
-use rustc_span::ErrorGuaranteed;
 use rustc_target::abi::FieldIdx;
+use stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx};
+use stable_mir::ty::{FloatTy, GenericParamDef, IntTy, Movability, RigidTy, Span, TyKind, UintTy};
+use stable_mir::{self, opaque, Context};
 use tracing::debug;
 
 mod alloc;
@@ -44,6 +42,14 @@ impl<'tcx> Context for Tables<'tcx> {
         self.tcx.def_path_str(self[def_id])
     }
 
+    fn print_span(&self, span: stable_mir::ty::Span) -> String {
+        self.tcx.sess.source_map().span_to_diagnostic_string(self[span])
+    }
+
+    fn def_kind(&mut self, def_id: stable_mir::DefId) -> stable_mir::DefKind {
+        self.tcx.def_kind(self[def_id]).stable(self)
+    }
+
     fn span_of_an_item(&mut self, def_id: stable_mir::DefId) -> Span {
         self.tcx.def_span(self[def_id]).stable(self)
     }
@@ -104,11 +110,7 @@ impl<'tcx> Context for Tables<'tcx> {
         }
     }
 
-    fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>)) {
-        f(self)
-    }
-
-    fn ty_kind(&mut self, ty: crate::stable_mir::ty::Ty) -> TyKind {
+    fn ty_kind(&mut self, ty: stable_mir::ty::Ty) -> TyKind {
         self.types[ty.0].clone().stable(self)
     }
 
@@ -276,7 +278,7 @@ impl<'tcx> Stable<'tcx> for mir::Rvalue<'tcx> {
                 place.stable(tables),
             ),
             ThreadLocalRef(def_id) => {
-                stable_mir::mir::Rvalue::ThreadLocalRef(rustc_internal::crate_item(*def_id))
+                stable_mir::mir::Rvalue::ThreadLocalRef(tables.crate_item(*def_id))
             }
             AddressOf(mutability, place) => {
                 stable_mir::mir::Rvalue::AddressOf(mutability.stable(tables), place.stable(tables))
@@ -739,7 +741,7 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
             mir::AggregateKind::Tuple => stable_mir::mir::AggregateKind::Tuple,
             mir::AggregateKind::Adt(def_id, var_idx, generic_arg, user_ty_index, field_idx) => {
                 stable_mir::mir::AggregateKind::Adt(
-                    rustc_internal::adt_def(*def_id),
+                    tables.adt_def(*def_id),
                     var_idx.index(),
                     generic_arg.stable(tables),
                     user_ty_index.map(|idx| idx.index()),
@@ -748,13 +750,13 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
             }
             mir::AggregateKind::Closure(def_id, generic_arg) => {
                 stable_mir::mir::AggregateKind::Closure(
-                    rustc_internal::closure_def(*def_id),
+                    tables.closure_def(*def_id),
                     generic_arg.stable(tables),
                 )
             }
             mir::AggregateKind::Generator(def_id, generic_arg, movability) => {
                 stable_mir::mir::AggregateKind::Generator(
-                    rustc_internal::generator_def(*def_id),
+                    tables.generator_def(*def_id),
                     generic_arg.stable(tables),
                     movability.stable(tables),
                 )
@@ -964,13 +966,13 @@ impl<'tcx> Stable<'tcx> for ty::FnSig<'tcx> {
 impl<'tcx> Stable<'tcx> for ty::BoundTyKind {
     type T = stable_mir::ty::BoundTyKind;
 
-    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
         use stable_mir::ty::BoundTyKind;
 
         match self {
             ty::BoundTyKind::Anon => BoundTyKind::Anon,
             ty::BoundTyKind::Param(def_id, symbol) => {
-                BoundTyKind::Param(rustc_internal::param_def(*def_id), symbol.to_string())
+                BoundTyKind::Param(tables.param_def(*def_id), symbol.to_string())
             }
         }
     }
@@ -983,11 +985,9 @@ impl<'tcx> Stable<'tcx> for ty::BoundRegionKind {
         use stable_mir::ty::BoundRegionKind;
 
         match self {
-            ty::BoundRegionKind::BrAnon(option_span) => {
-                BoundRegionKind::BrAnon(option_span.map(|span| span.stable(tables)))
-            }
+            ty::BoundRegionKind::BrAnon => BoundRegionKind::BrAnon,
             ty::BoundRegionKind::BrNamed(def_id, symbol) => {
-                BoundRegionKind::BrNamed(rustc_internal::br_named_def(*def_id), symbol.to_string())
+                BoundRegionKind::BrNamed(tables.br_named_def(*def_id), symbol.to_string())
             }
             ty::BoundRegionKind::BrEnv => BoundRegionKind::BrEnv,
         }
@@ -1074,12 +1074,10 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
             ty::Uint(uint_ty) => TyKind::RigidTy(RigidTy::Uint(uint_ty.stable(tables))),
             ty::Float(float_ty) => TyKind::RigidTy(RigidTy::Float(float_ty.stable(tables))),
             ty::Adt(adt_def, generic_args) => TyKind::RigidTy(RigidTy::Adt(
-                rustc_internal::adt_def(adt_def.did()),
+                tables.adt_def(adt_def.did()),
                 generic_args.stable(tables),
             )),
-            ty::Foreign(def_id) => {
-                TyKind::RigidTy(RigidTy::Foreign(rustc_internal::foreign_def(*def_id)))
-            }
+            ty::Foreign(def_id) => TyKind::RigidTy(RigidTy::Foreign(tables.foreign_def(*def_id))),
             ty::Str => TyKind::RigidTy(RigidTy::Str),
             ty::Array(ty, constant) => {
                 TyKind::RigidTy(RigidTy::Array(tables.intern_ty(*ty), constant.stable(tables)))
@@ -1093,10 +1091,9 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
                 tables.intern_ty(*ty),
                 mutbl.stable(tables),
             )),
-            ty::FnDef(def_id, generic_args) => TyKind::RigidTy(RigidTy::FnDef(
-                rustc_internal::fn_def(*def_id),
-                generic_args.stable(tables),
-            )),
+            ty::FnDef(def_id, generic_args) => {
+                TyKind::RigidTy(RigidTy::FnDef(tables.fn_def(*def_id), generic_args.stable(tables)))
+            }
             ty::FnPtr(poly_fn_sig) => TyKind::RigidTy(RigidTy::FnPtr(poly_fn_sig.stable(tables))),
             ty::Dynamic(existential_predicates, region, dyn_kind) => {
                 TyKind::RigidTy(RigidTy::Dynamic(
@@ -1109,11 +1106,11 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
                 ))
             }
             ty::Closure(def_id, generic_args) => TyKind::RigidTy(RigidTy::Closure(
-                rustc_internal::closure_def(*def_id),
+                tables.closure_def(*def_id),
                 generic_args.stable(tables),
             )),
             ty::Generator(def_id, generic_args, movability) => TyKind::RigidTy(RigidTy::Generator(
-                rustc_internal::generator_def(*def_id),
+                tables.generator_def(*def_id),
                 generic_args.stable(tables),
                 movability.stable(tables),
             )),
@@ -1128,11 +1125,7 @@ impl<'tcx> Stable<'tcx> for Ty<'tcx> {
             ty::Bound(debruijn_idx, bound_ty) => {
                 TyKind::Bound(debruijn_idx.as_usize(), bound_ty.stable(tables))
             }
-            ty::Placeholder(..)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(_, _)
-            | ty::Infer(_)
-            | ty::Error(_) => {
+            ty::Placeholder(..) | ty::GeneratorWitness(..) | ty::Infer(_) | ty::Error(_) => {
                 unreachable!();
             }
         }
@@ -1229,7 +1222,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitDef {
         use stable_mir::ty::TraitDecl;
 
         TraitDecl {
-            def_id: rustc_internal::trait_def(self.def_id),
+            def_id: tables.trait_def(self.def_id),
             unsafety: self.unsafety.stable(tables),
             paren_sugar: self.paren_sugar,
             has_auto_impl: self.has_auto_impl,
@@ -1278,7 +1271,7 @@ impl<'tcx> Stable<'tcx> for ty::TraitRef<'tcx> {
     fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
         use stable_mir::ty::TraitRef;
 
-        TraitRef { def_id: rustc_internal::trait_def(self.def_id), args: self.args.stable(tables) }
+        TraitRef { def_id: tables.trait_def(self.def_id), args: self.args.stable(tables) }
     }
 }
 
@@ -1508,9 +1501,39 @@ impl<'tcx> Stable<'tcx> for ty::ImplPolarity {
 impl<'tcx> Stable<'tcx> for ty::Region<'tcx> {
     type T = stable_mir::ty::Region;
 
-    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
-        // FIXME: add a real implementation of stable regions
-        opaque(self)
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        Region { kind: self.kind().stable(tables) }
+    }
+}
+
+impl<'tcx> Stable<'tcx> for ty::RegionKind<'tcx> {
+    type T = stable_mir::ty::RegionKind;
+
+    fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
+        use stable_mir::ty::RegionKind;
+        match self {
+            ty::ReEarlyBound(early_reg) => RegionKind::ReEarlyBound(EarlyBoundRegion {
+                def_id: tables.region_def(early_reg.def_id),
+                index: early_reg.index,
+                name: early_reg.name.to_string(),
+            }),
+            ty::ReLateBound(db_index, bound_reg) => RegionKind::ReLateBound(
+                db_index.as_u32(),
+                BoundRegion { var: bound_reg.var.as_u32(), kind: bound_reg.kind.stable(tables) },
+            ),
+            ty::ReStatic => RegionKind::ReStatic,
+            ty::RePlaceholder(place_holder) => {
+                RegionKind::RePlaceholder(stable_mir::ty::Placeholder {
+                    universe: place_holder.universe.as_u32(),
+                    bound: BoundRegion {
+                        var: place_holder.bound.var.as_u32(),
+                        kind: place_holder.bound.kind.stable(tables),
+                    },
+                })
+            }
+            ty::ReErased => RegionKind::ReErased,
+            _ => unreachable!("{self:?}"),
+        }
     }
 }
 
@@ -1522,8 +1545,11 @@ impl<'tcx> Stable<'tcx> for rustc_span::Span {
     }
 }
 
-impl<T> From<ErrorGuaranteed> for CompilerError<T> {
-    fn from(_error: ErrorGuaranteed) -> Self {
-        CompilerError::CompilationFailed
+impl<'tcx> Stable<'tcx> for DefKind {
+    type T = stable_mir::DefKind;
+
+    fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
+        // FIXME: add a real implementation of stable DefKind
+        opaque(self)
     }
 }
diff --git a/compiler/rustc_span/src/lib.rs b/compiler/rustc_span/src/lib.rs
index 68724c48037..772e09291a1 100644
--- a/compiler/rustc_span/src/lib.rs
+++ b/compiler/rustc_span/src/lib.rs
@@ -33,7 +33,7 @@ extern crate rustc_macros;
 #[macro_use]
 extern crate tracing;
 
-use rustc_data_structures::{cold_path, AtomicRef};
+use rustc_data_structures::{outline, AtomicRef};
 use rustc_macros::HashStable_Generic;
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 
@@ -1592,7 +1592,7 @@ impl SourceFile {
             return &lines[..];
         }
 
-        cold_path(|| {
+        outline(|| {
             self.convert_diffs_to_lines_frozen();
             if let Some(SourceFileLines::Lines(lines)) = self.lines.get() {
                 return &lines[..];
@@ -1753,7 +1753,7 @@ impl SourceFile {
         // is recorded.
         let diff = match self.normalized_pos.binary_search_by(|np| np.pos.cmp(&pos)) {
             Ok(i) => self.normalized_pos[i].diff,
-            Err(i) if i == 0 => 0,
+            Err(0) => 0,
             Err(i) => self.normalized_pos[i - 1].diff,
         };
 
@@ -1775,7 +1775,7 @@ impl SourceFile {
             .binary_search_by(|np| (np.pos.0 + np.diff).cmp(&(self.start_pos.0 + offset)))
         {
             Ok(i) => self.normalized_pos[i].diff,
-            Err(i) if i == 0 => 0,
+            Err(0) => 0,
             Err(i) => self.normalized_pos[i - 1].diff,
         };
 
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 382754be2ca..4f46256626f 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1465,6 +1465,7 @@ symbols! {
         simd_shl,
         simd_shr,
         simd_shuffle,
+        simd_shuffle_generic,
         simd_sub,
         simd_trunc,
         simd_xor,
diff --git a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
index d1f2c1b27fd..6ad3e7155e8 100644
--- a/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs
@@ -720,7 +720,6 @@ fn encode_ty<'tcx>(
         | ty::Bound(..)
         | ty::Error(..)
         | ty::GeneratorWitness(..)
-        | ty::GeneratorWitnessMIR(..)
         | ty::Infer(..)
         | ty::Placeholder(..) => {
             bug!("encode_ty: unexpected `{:?}`", ty.kind());
@@ -973,12 +972,7 @@ fn transform_ty<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, options: TransformTyOptio
             );
         }
 
-        ty::Bound(..)
-        | ty::Error(..)
-        | ty::GeneratorWitnessMIR(..)
-        | ty::Infer(..)
-        | ty::Param(..)
-        | ty::Placeholder(..) => {
+        ty::Bound(..) | ty::Error(..) | ty::Infer(..) | ty::Param(..) | ty::Placeholder(..) => {
             bug!("transform_ty: unexpected `{:?}`", ty.kind());
         }
     }
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index e9a7d0be4b4..82b1a772e3d 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -329,7 +329,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
 
             // Late-bound lifetimes use indices starting at 1,
             // see `BinderLevel` for more details.
-            ty::ReLateBound(debruijn, ty::BoundRegion { var, kind: ty::BrAnon(_) }) => {
+            ty::ReLateBound(debruijn, ty::BoundRegion { var, kind: ty::BrAnon }) => {
                 let binder = &self.binders[self.binders.len() - 1 - debruijn.index()];
                 let depth = binder.lifetime_depths.start + var.as_u32();
 
@@ -484,8 +484,7 @@ impl<'tcx> Printer<'tcx> for &mut SymbolMangler<'tcx> {
 
             ty::Alias(ty::Inherent, _) => bug!("symbol_names: unexpected inherent projection"),
             ty::Alias(ty::Weak, _) => bug!("symbol_names: unexpected weak projection"),
-            ty::GeneratorWitness(_) => bug!("symbol_names: unexpected `GeneratorWitness`"),
-            ty::GeneratorWitnessMIR(..) => bug!("symbol_names: unexpected `GeneratorWitnessMIR`"),
+            ty::GeneratorWitness(..) => bug!("symbol_names: unexpected `GeneratorWitness`"),
         }
 
         // Only cache types that do not refer to an enclosing
diff --git a/compiler/rustc_target/src/spec/apple_base.rs b/compiler/rustc_target/src/spec/apple_base.rs
index f7dcec307dd..7a666eea437 100644
--- a/compiler/rustc_target/src/spec/apple_base.rs
+++ b/compiler/rustc_target/src/spec/apple_base.rs
@@ -11,7 +11,6 @@ use Arch::*;
 #[allow(non_camel_case_types)]
 #[derive(Copy, Clone)]
 pub enum Arch {
-    Armv7,
     Armv7k,
     Armv7s,
     Arm64,
@@ -29,7 +28,6 @@ pub enum Arch {
 impl Arch {
     pub fn target_name(self) -> &'static str {
         match self {
-            Armv7 => "armv7",
             Armv7k => "armv7k",
             Armv7s => "armv7s",
             Arm64 | Arm64_macabi | Arm64_sim => "arm64",
@@ -43,7 +41,7 @@ impl Arch {
 
     pub fn target_arch(self) -> Cow<'static, str> {
         Cow::Borrowed(match self {
-            Armv7 | Armv7k | Armv7s => "arm",
+            Armv7k | Armv7s => "arm",
             Arm64 | Arm64_32 | Arm64_macabi | Arm64_sim => "aarch64",
             I386 | I686 => "x86",
             X86_64 | X86_64_sim | X86_64_macabi | X86_64h => "x86_64",
@@ -52,7 +50,7 @@ impl Arch {
 
     fn target_abi(self) -> &'static str {
         match self {
-            Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "",
+            Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64h => "",
             X86_64_macabi | Arm64_macabi => "macabi",
             // x86_64-apple-ios is a simulator target, even though it isn't
             // declared that way in the target like the other ones...
@@ -62,18 +60,20 @@ impl Arch {
 
     fn target_cpu(self) -> &'static str {
         match self {
-            Armv7 => "cortex-a8", // iOS7 is supported on iPhone 4 and higher
             Armv7k => "cortex-a8",
-            Armv7s => "cortex-a9",
+            Armv7s => "swift", // iOS 10 is only supported on iPhone 5 or higher.
             Arm64 => "apple-a7",
             Arm64_32 => "apple-s4",
-            I386 | I686 => "yonah",
-            X86_64 | X86_64_sim => "core2",
+            // Only macOS 10.12+ is supported, which means
+            // all x86_64/x86 CPUs must be running at least penryn
+            // https://github.com/llvm/llvm-project/blob/01f924d0e37a5deae51df0d77e10a15b63aa0c0f/clang/lib/Driver/ToolChains/Arch/X86.cpp#L79-L82
+            I386 | I686 => "penryn",
+            X86_64 | X86_64_sim => "penryn",
+            X86_64_macabi => "penryn",
             // Note: `core-avx2` is slightly more advanced than `x86_64h`, see
             // comments (and disabled features) in `x86_64h_apple_darwin` for
-            // details.
+            // details. It is a higher baseline then `penryn` however.
             X86_64h => "core-avx2",
-            X86_64_macabi => "core2",
             Arm64_macabi => "apple-a12",
             Arm64_sim => "apple-a12",
         }
@@ -115,21 +115,6 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs {
 }
 
 pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
-    // Static TLS is only available in macOS 10.7+. If you try to compile for 10.6
-    // either the linker will complain if it is used or the binary will end up
-    // segfaulting at runtime when run on 10.6. Rust by default supports macOS
-    // 10.7+, but there is a standard environment variable,
-    // MACOSX_DEPLOYMENT_TARGET, which is used to signal targeting older
-    // versions of macOS. For example compiling on 10.10 with
-    // MACOSX_DEPLOYMENT_TARGET set to 10.6 will cause the linker to generate
-    // warnings about the usage of static TLS.
-    //
-    // Here we detect what version is being requested, defaulting to 10.7. Static
-    // TLS is flagged as enabled if it looks to be supported. The architecture
-    // only matters for default deployment target which is 11.0 for ARM64 and
-    // 10.7 for everything else.
-    let has_thread_local = os == "macos" && macos_deployment_target(Arch::X86_64) >= (10, 7);
-
     let abi = arch.target_abi();
 
     TargetOptions {
@@ -145,12 +130,17 @@ pub fn opts(os: &'static str, arch: Arch) -> TargetOptions {
         pre_link_args: pre_link_args(os, arch, abi),
         families: cvs!["unix"],
         is_like_osx: true,
-        default_dwarf_version: 2,
+        // LLVM notes that macOS 10.11+ and iOS 9+ default
+        // to v4, so we do the same.
+        // https://github.com/llvm/llvm-project/blob/378778a0d10c2f8d5df8ceff81f95b6002984a4b/clang/lib/Driver/ToolChains/Darwin.cpp#L1203
+        default_dwarf_version: 4,
         frame_pointer: FramePointer::Always,
         has_rpath: true,
         dll_suffix: ".dylib".into(),
         archive_format: "darwin".into(),
-        has_thread_local,
+        // Thread locals became available with iOS 8 and macOS 10.7,
+        // and both are far below our minimum.
+        has_thread_local: true,
         abi_return_struct_as_int: true,
         emit_debug_gdb_scripts: false,
         eh_frame_header: false,
@@ -239,9 +229,7 @@ fn macos_default_deployment_target(arch: Arch) -> (u32, u32) {
     match arch {
         // Note: Arm64_sim is not included since macOS has no simulator.
         Arm64 | Arm64_macabi => (11, 0),
-        // x86_64h-apple-darwin only supports macOS 10.8 and later
-        X86_64h => (10, 8),
-        _ => (10, 7),
+        _ => (10, 12),
     }
 }
 
@@ -292,8 +280,8 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow<str>]>
         // Otherwise if cross-compiling for a different OS/SDK, remove any part
         // of the linking environment that's wrong and reversed.
         match arch {
-            Armv7 | Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim
-            | X86_64h | Arm64_sim => {
+            Armv7k | Armv7s | Arm64 | Arm64_32 | I386 | I686 | X86_64 | X86_64_sim | X86_64h
+            | Arm64_sim => {
                 cvs!["MACOSX_DEPLOYMENT_TARGET"]
             }
             X86_64_macabi | Arm64_macabi => cvs!["IPHONEOS_DEPLOYMENT_TARGET"],
@@ -303,7 +291,7 @@ fn link_env_remove(arch: Arch, os: &'static str) -> StaticCow<[StaticCow<str>]>
 
 fn ios_deployment_target() -> (u32, u32) {
     // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
-    from_set_deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
+    from_set_deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((10, 0))
 }
 
 fn mac_catalyst_deployment_target() -> (u32, u32) {
@@ -334,7 +322,7 @@ pub fn ios_sim_llvm_target(arch: Arch) -> String {
 
 fn tvos_deployment_target() -> (u32, u32) {
     // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
-    from_set_deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((7, 0))
+    from_set_deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((10, 0))
 }
 
 fn tvos_lld_platform_version() -> String {
diff --git a/compiler/rustc_target/src/spec/armv7_apple_ios.rs b/compiler/rustc_target/src/spec/armv7_apple_ios.rs
deleted file mode 100644
index 3259c854791..00000000000
--- a/compiler/rustc_target/src/spec/armv7_apple_ios.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-use super::apple_base::{ios_llvm_target, opts, Arch};
-use crate::spec::{Target, TargetOptions};
-
-pub fn target() -> Target {
-    let arch = Arch::Armv7;
-    Target {
-        // Clang automatically chooses a more specific target based on
-        // IPHONEOS_DEPLOYMENT_TARGET.
-        // This is required for the target to pick the right
-        // MACH-O commands, so we do too.
-        llvm_target: ios_llvm_target(arch).into(),
-        pointer_width: 32,
-        data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".into(),
-        arch: arch.target_arch(),
-        options: TargetOptions {
-            features: "+v7,+vfp3,+neon".into(),
-            max_atomic_width: Some(64),
-            ..opts("ios", arch)
-        },
-    }
-}
diff --git a/compiler/rustc_target/src/spec/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs
index be4bc675844..be7f8542c9e 100644
--- a/compiler/rustc_target/src/spec/armv7s_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/armv7s_apple_ios.rs
@@ -1,10 +1,10 @@
-use super::apple_base::{opts, Arch};
+use super::apple_base::{ios_llvm_target, opts, Arch};
 use crate::spec::{Target, TargetOptions};
 
 pub fn target() -> Target {
     let arch = Arch::Armv7s;
     Target {
-        llvm_target: "armv7s-apple-ios".into(),
+        llvm_target: ios_llvm_target(arch).into(),
         pointer_width: 32,
         data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".into(),
         arch: arch.target_arch(),
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 60fe98e5045..1bcb1f35315 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1394,7 +1394,6 @@ supported_targets! {
     ("i386-apple-ios", i386_apple_ios),
     ("x86_64-apple-ios", x86_64_apple_ios),
     ("aarch64-apple-ios", aarch64_apple_ios),
-    ("armv7-apple-ios", armv7_apple_ios),
     ("armv7s-apple-ios", armv7s_apple_ios),
     ("x86_64-apple-ios-macabi", x86_64_apple_ios_macabi),
     ("aarch64-apple-ios-macabi", aarch64_apple_ios_macabi),
diff --git a/compiler/rustc_target/src/spec/riscv64_linux_android.rs b/compiler/rustc_target/src/spec/riscv64_linux_android.rs
index af0d6855494..91f5e562d8b 100644
--- a/compiler/rustc_target/src/spec/riscv64_linux_android.rs
+++ b/compiler/rustc_target/src/spec/riscv64_linux_android.rs
@@ -9,7 +9,7 @@ pub fn target() -> Target {
         options: TargetOptions {
             code_model: Some(CodeModel::Medium),
             cpu: "generic-rv64".into(),
-            features: "+m,+a,+f,+d,+c".into(),
+            features: "+m,+a,+f,+d,+c,+Zba,+Zbb,+Zbs".into(),
             llvm_abiname: "lp64d".into(),
             supported_sanitizers: SanitizerSet::ADDRESS,
             max_atomic_width: Some(64),
diff --git a/compiler/rustc_target/src/spec/uefi_msvc_base.rs b/compiler/rustc_target/src/spec/uefi_msvc_base.rs
index 8968d3c8fc1..a50a55ad7e0 100644
--- a/compiler/rustc_target/src/spec/uefi_msvc_base.rs
+++ b/compiler/rustc_target/src/spec/uefi_msvc_base.rs
@@ -46,6 +46,7 @@ pub fn opts() -> TargetOptions {
         stack_probes: StackProbeType::Call,
         singlethread: true,
         linker: Some("rust-lld".into()),
+        entry_name: "efi_main".into(),
         ..base
     }
 }
diff --git a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
index e90bda9c9a8..e3f5d7321d1 100644
--- a/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/x86_64_apple_darwin.rs
@@ -5,7 +5,7 @@ use crate::spec::{StackProbeType, Target, TargetOptions};
 pub fn target() -> Target {
     let arch = Arch::X86_64;
     let mut base = opts("macos", arch);
-    base.max_atomic_width = Some(128); // core2 supports cmpxchg16b
+    base.max_atomic_width = Some(128); // penryn+ supports cmpxchg16b
     base.frame_pointer = FramePointer::Always;
     base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
     base.stack_probes = StackProbeType::X86;
diff --git a/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs b/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs
index 67664a74710..41ba768068a 100644
--- a/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs
+++ b/compiler/rustc_target/src/spec/x86_64_unknown_uefi.rs
@@ -5,13 +5,14 @@
 // The win64 ABI is used. It differs from the sysv64 ABI, so we must use a windows target with
 // LLVM. "x86_64-unknown-windows" is used to get the minimal subset of windows-specific features.
 
-use crate::spec::Target;
+use crate::{abi::call::Conv, spec::Target};
 
 pub fn target() -> Target {
     let mut base = super::uefi_msvc_base::opts();
     base.cpu = "x86-64".into();
     base.plt_by_default = false;
     base.max_atomic_width = Some(64);
+    base.entry_abi = Conv::X86_64Win64;
 
     // We disable MMX and SSE for now, even though UEFI allows using them. Problem is, you have to
     // enable these CPU features explicitly before their first use, otherwise their instructions
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 128b9ad7e47..23d2c0c4ea0 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -469,7 +469,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             // FIXME: These should ideally not exist as a self type. It would be nice for
             // the builtin auto trait impls of generators to instead directly recurse
             // into the witness.
-            ty::GeneratorWitness(_) | ty::GeneratorWitnessMIR(_, _) => (),
+            ty::GeneratorWitness(..) => (),
 
             // These variants should not exist as a self type.
             ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
@@ -621,8 +621,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             | ty::Dynamic(..)
             | ty::Closure(..)
             | ty::Generator(..)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..)
+            | ty::GeneratorWitness(..)
             | ty::Never
             | ty::Tuple(_)
             | ty::Param(_)
@@ -778,8 +777,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             | ty::Alias(..)
             | ty::Closure(..)
             | ty::Generator(..)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..)
+            | ty::GeneratorWitness(..)
             | ty::Never
             | ty::Tuple(_)
             | ty::Param(_)
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
index b61e02ba761..26c68acddff 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/structural_traits.rs
@@ -61,9 +61,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_auto_trait<'tcx>(
             Ok(vec![generator_args.tupled_upvars_ty(), generator_args.witness()])
         }
 
-        ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
-
-        ty::GeneratorWitnessMIR(def_id, args) => Ok(ecx
+        ty::GeneratorWitness(def_id, args) => Ok(ecx
             .tcx()
             .generator_hidden_types(def_id)
             .map(|bty| {
@@ -96,8 +94,7 @@ pub(in crate::solve) fn replace_erased_lifetimes_with_bound_vars<'tcx>(
     let mut counter = 0;
     let ty = tcx.fold_regions(ty, |r, current_depth| match r.kind() {
         ty::ReErased => {
-            let br =
-                ty::BoundRegion { var: ty::BoundVar::from_u32(counter), kind: ty::BrAnon(None) };
+            let br = ty::BoundRegion { var: ty::BoundVar::from_u32(counter), kind: ty::BrAnon };
             counter += 1;
             ty::Region::new_late_bound(tcx, current_depth, br)
         }
@@ -105,7 +102,7 @@ pub(in crate::solve) fn replace_erased_lifetimes_with_bound_vars<'tcx>(
         r => bug!("unexpected region: {r:?}"),
     });
     let bound_vars = tcx.mk_bound_variable_kinds_from_iter(
-        (0..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon(None))),
+        (0..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon)),
     );
     ty::Binder::bind_with_vars(ty, bound_vars)
 }
@@ -127,7 +124,6 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_sized_trait<'tcx>(
         | ty::Ref(..)
         | ty::Generator(..)
         | ty::GeneratorWitness(..)
-        | ty::GeneratorWitnessMIR(..)
         | ty::Array(..)
         | ty::Closure(..)
         | ty::Never
@@ -204,9 +200,7 @@ pub(in crate::solve) fn instantiate_constituent_tys_for_copy_clone_trait<'tcx>(
             }
         }
 
-        ty::GeneratorWitness(types) => Ok(ecx.instantiate_binder_with_placeholders(types).to_vec()),
-
-        ty::GeneratorWitnessMIR(def_id, args) => Ok(ecx
+        ty::GeneratorWitness(def_id, args) => Ok(ecx
             .tcx()
             .generator_hidden_types(def_id)
             .map(|bty| {
@@ -282,8 +276,7 @@ pub(in crate::solve) fn extract_tupled_inputs_and_output_from_callable<'tcx>(
         | ty::Ref(_, _, _)
         | ty::Dynamic(_, _, _)
         | ty::Generator(_, _, _)
-        | ty::GeneratorWitness(_)
-        | ty::GeneratorWitnessMIR(..)
+        | ty::GeneratorWitness(..)
         | ty::Never
         | ty::Tuple(_)
         | ty::Alias(_, _)
diff --git a/compiler/rustc_trait_selection/src/solve/canonicalize.rs b/compiler/rustc_trait_selection/src/solve/canonicalize.rs
index f5901057a9d..aa92b924ef2 100644
--- a/compiler/rustc_trait_selection/src/solve/canonicalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/canonicalize.rs
@@ -269,7 +269,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
             self.primitive_var_infos.push(CanonicalVarInfo { kind });
             var
         });
-        let br = ty::BoundRegion { var, kind: BrAnon(None) };
+        let br = ty::BoundRegion { var, kind: BrAnon };
         ty::Region::new_late_bound(self.interner(), self.binder_index, br)
     }
 
@@ -330,8 +330,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'_, 'tcx> {
             | ty::Dynamic(_, _, _)
             | ty::Closure(_, _)
             | ty::Generator(_, _, _)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..)
+            | ty::GeneratorWitness(..)
             | ty::Never
             | ty::Tuple(_)
             | ty::Alias(_, _)
diff --git a/compiler/rustc_trait_selection/src/solve/project_goals.rs b/compiler/rustc_trait_selection/src/solve/project_goals.rs
index f6e781b87ba..0f9d36342ad 100644
--- a/compiler/rustc_trait_selection/src/solve/project_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/project_goals.rs
@@ -59,7 +59,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             }
             DefKind::AnonConst => self.normalize_anon_const(goal),
             DefKind::OpaqueTy => self.normalize_opaque_type(goal),
-            DefKind::TyAlias { .. } => self.normalize_weak_type(goal),
+            DefKind::TyAlias => self.normalize_weak_type(goal),
             kind => bug!("unknown DefKind {} in projection goal: {goal:#?}", kind.descr(def_id)),
         }
     }
@@ -388,7 +388,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
                 | ty::Infer(ty::IntVar(..) | ty::FloatVar(..))
                 | ty::Generator(..)
                 | ty::GeneratorWitness(..)
-                | ty::GeneratorWitnessMIR(..)
                 | ty::Never
                 | ty::Foreign(..) => tcx.types.unit,
 
@@ -556,7 +555,6 @@ impl<'tcx> assembly::GoalKind<'tcx> for ProjectionPredicate<'tcx> {
             | ty::Infer(ty::IntVar(..) | ty::FloatVar(..))
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Never
             | ty::Foreign(..)
             | ty::Adt(_, _)
diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/cache.rs b/compiler/rustc_trait_selection/src/solve/search_graph/cache.rs
deleted file mode 100644
index be48447e27c..00000000000
--- a/compiler/rustc_trait_selection/src/solve/search_graph/cache.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-//! This module both handles the global cache which stores "finished" goals,
-//! and the provisional cache which contains partially computed goals.
-//!
-//! The provisional cache is necessary when dealing with coinductive cycles.
-//!
-//! For more information about the provisional cache and coinduction in general,
-//! check out the relevant section of the rustc-dev-guide.
-//!
-//! FIXME(@lcnr): Write that section, feel free to ping me if you need help here
-//! before then or if I still haven't done that before January 2023.
-use super::StackDepth;
-use rustc_data_structures::fx::FxHashMap;
-use rustc_index::IndexVec;
-use rustc_middle::traits::solve::{CanonicalInput, QueryResult};
-
-rustc_index::newtype_index! {
-    pub struct EntryIndex {}
-}
-
-#[derive(Debug, Clone)]
-pub(super) struct ProvisionalEntry<'tcx> {
-    /// In case we have a coinductive cycle, this is the
-    /// the current provisional result of this goal.
-    ///
-    /// This starts out as `None` for all goals and gets to some
-    /// when the goal gets popped from the stack or we rerun evaluation
-    /// for this goal to reach a fixpoint.
-    pub(super) response: Option<QueryResult<'tcx>>,
-    /// In case of a cycle, the position of deepest stack entry involved
-    /// in that cycle. This is monotonically decreasing in the stack as all
-    /// elements between the current stack element in the deepest stack entry
-    /// involved have to also be involved in that cycle.
-    ///
-    /// We can only move entries to the global cache once we're complete done
-    /// with the cycle. If this entry has not been involved in a cycle,
-    /// this is just its own depth.
-    pub(super) depth: StackDepth,
-
-    /// The goal for this entry. Should always be equal to the corresponding goal
-    /// in the lookup table.
-    pub(super) input: CanonicalInput<'tcx>,
-}
-
-pub(super) struct ProvisionalCache<'tcx> {
-    pub(super) entries: IndexVec<EntryIndex, ProvisionalEntry<'tcx>>,
-    // FIXME: This is only used to quickly check whether a given goal
-    // is in the cache. We should experiment with using something like
-    // `SsoHashSet` here because in most cases there are only a few entries.
-    pub(super) lookup_table: FxHashMap<CanonicalInput<'tcx>, EntryIndex>,
-}
-
-impl<'tcx> ProvisionalCache<'tcx> {
-    pub(super) fn empty() -> ProvisionalCache<'tcx> {
-        ProvisionalCache { entries: Default::default(), lookup_table: Default::default() }
-    }
-
-    pub(super) fn is_empty(&self) -> bool {
-        self.entries.is_empty() && self.lookup_table.is_empty()
-    }
-
-    /// Adds a dependency from the current leaf to `target` in the cache
-    /// to prevent us from moving any goals which depend on the current leaf
-    /// to the global cache while we're still computing `target`.
-    ///
-    /// Its important to note that `target` may already be part of a different cycle.
-    /// In this case we have to ensure that we also depend on all other goals
-    /// in the existing cycle in addition to the potentially direct cycle with `target`.
-    pub(super) fn add_dependency_of_leaf_on(&mut self, target: EntryIndex) {
-        let depth = self.entries[target].depth;
-        for provisional_entry in &mut self.entries.raw[target.index()..] {
-            // The depth of `target` is the position of the deepest goal in the stack
-            // on which `target` depends. That goal is the `root` of this cycle.
-            //
-            // Any entry which was added after `target` is either on the stack itself
-            // at which point its depth is definitely at least as high as the depth of
-            // `root`. If it's not on the stack itself it has to depend on a goal
-            // between `root` and `leaf`. If it were to depend on a goal deeper in the
-            // stack than `root`, then `root` would also depend on that goal, at which
-            // point `root` wouldn't be the root anymore.
-            debug_assert!(provisional_entry.depth >= depth);
-            provisional_entry.depth = depth;
-        }
-
-        // We only update entries which were added after `target` as no other
-        // entry should have a higher depth.
-        //
-        // Any entry which previously had a higher depth than target has to
-        // be between `target` and `root`. Because of this we would have updated
-        // its depth when calling `add_dependency_of_leaf_on(root)` for `target`.
-        if cfg!(debug_assertions) {
-            self.entries.iter().all(|e| e.depth <= depth);
-        }
-    }
-
-    pub(super) fn depth(&self, entry_index: EntryIndex) -> StackDepth {
-        self.entries[entry_index].depth
-    }
-
-    pub(super) fn provisional_result(&self, entry_index: EntryIndex) -> Option<QueryResult<'tcx>> {
-        self.entries[entry_index].response
-    }
-}
diff --git a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs
index 728d0fc1ae7..33513f6bd43 100644
--- a/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/search_graph/mod.rs
@@ -1,10 +1,7 @@
-mod cache;
-
-use self::cache::ProvisionalEntry;
 use super::inspect;
 use super::inspect::ProofTreeBuilder;
 use super::SolverMode;
-use cache::ProvisionalCache;
+use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_index::Idx;
 use rustc_index::IndexVec;
@@ -27,8 +24,14 @@ struct StackEntry<'tcx> {
     // The maximum depth reached by this stack entry, only up-to date
     // for the top of the stack and lazily updated for the rest.
     reached_depth: StackDepth,
+    // In case of a cycle, the depth of the root.
+    cycle_root_depth: StackDepth,
+
     encountered_overflow: bool,
     has_been_used: bool,
+    /// Starts out as `None` and gets set when rerunning this
+    /// goal in case we encounter a cycle.
+    provisional_result: Option<QueryResult<'tcx>>,
 
     /// We put only the root goal of a coinductive cycle into the global cache.
     ///
@@ -47,7 +50,7 @@ pub(super) struct SearchGraph<'tcx> {
     ///
     /// An element is *deeper* in the stack if its index is *lower*.
     stack: IndexVec<StackDepth, StackEntry<'tcx>>,
-    provisional_cache: ProvisionalCache<'tcx>,
+    stack_entries: FxHashMap<CanonicalInput<'tcx>, StackDepth>,
 }
 
 impl<'tcx> SearchGraph<'tcx> {
@@ -56,7 +59,7 @@ impl<'tcx> SearchGraph<'tcx> {
             mode,
             local_overflow_limit: tcx.recursion_limit().0.checked_ilog2().unwrap_or(0) as usize,
             stack: Default::default(),
-            provisional_cache: ProvisionalCache::empty(),
+            stack_entries: Default::default(),
         }
     }
 
@@ -85,6 +88,7 @@ impl<'tcx> SearchGraph<'tcx> {
     /// would cause us to not track overflow and recursion depth correctly.
     fn pop_stack(&mut self) -> StackEntry<'tcx> {
         let elem = self.stack.pop().unwrap();
+        assert!(self.stack_entries.remove(&elem.input).is_some());
         if let Some(last) = self.stack.raw.last_mut() {
             last.reached_depth = last.reached_depth.max(elem.reached_depth);
             last.encountered_overflow |= elem.encountered_overflow;
@@ -104,22 +108,17 @@ impl<'tcx> SearchGraph<'tcx> {
     }
 
     pub(super) fn is_empty(&self) -> bool {
-        self.stack.is_empty() && self.provisional_cache.is_empty()
+        self.stack.is_empty()
     }
 
     /// Whether we're currently in a cycle. This should only be used
     /// for debug assertions.
     pub(super) fn in_cycle(&self) -> bool {
         if let Some(stack_depth) = self.stack.last_index() {
-            // Either the current goal on the stack is the root of a cycle...
-            if self.stack[stack_depth].has_been_used {
-                return true;
-            }
-
-            // ...or it depends on a goal with a lower depth.
-            let current_goal = self.stack[stack_depth].input;
-            let entry_index = self.provisional_cache.lookup_table[&current_goal];
-            self.provisional_cache.entries[entry_index].depth != stack_depth
+            // Either the current goal on the stack is the root of a cycle
+            // or it depends on a goal with a lower depth.
+            self.stack[stack_depth].has_been_used
+                || self.stack[stack_depth].cycle_root_depth != stack_depth
         } else {
             false
         }
@@ -211,9 +210,8 @@ impl<'tcx> SearchGraph<'tcx> {
             }
         }
 
-        // Look at the provisional cache to detect cycles.
-        let cache = &mut self.provisional_cache;
-        match cache.lookup_table.entry(input) {
+        // Check whether we're in a cycle.
+        match self.stack_entries.entry(input) {
             // No entry, we push this goal on the stack and try to prove it.
             Entry::Vacant(v) => {
                 let depth = self.stack.next_index();
@@ -221,14 +219,14 @@ impl<'tcx> SearchGraph<'tcx> {
                     input,
                     available_depth,
                     reached_depth: depth,
+                    cycle_root_depth: depth,
                     encountered_overflow: false,
                     has_been_used: false,
+                    provisional_result: None,
                     cycle_participants: Default::default(),
                 };
                 assert_eq!(self.stack.push(entry), depth);
-                let entry_index =
-                    cache.entries.push(ProvisionalEntry { response: None, depth, input });
-                v.insert(entry_index);
+                v.insert(depth);
             }
             // We have a nested goal which relies on a goal `root` deeper in the stack.
             //
@@ -239,41 +237,50 @@ impl<'tcx> SearchGraph<'tcx> {
             //
             // Finally we can return either the provisional response for that goal if we have a
             // coinductive cycle or an ambiguous result if the cycle is inductive.
-            Entry::Occupied(entry_index) => {
+            Entry::Occupied(entry) => {
                 inspect.goal_evaluation_kind(inspect::WipCanonicalGoalEvaluationKind::CacheHit(
                     CacheHit::Provisional,
                 ));
 
-                let entry_index = *entry_index.get();
-                let stack_depth = cache.depth(entry_index);
+                let stack_depth = *entry.get();
                 debug!("encountered cycle with depth {stack_depth:?}");
-
-                cache.add_dependency_of_leaf_on(entry_index);
-                let mut iter = self.stack.iter_mut();
-                let root = iter.nth(stack_depth.as_usize()).unwrap();
-                for e in iter {
-                    root.cycle_participants.insert(e.input);
+                // We start by updating the root depth of all cycle participants, and
+                // add all cycle participants to the root.
+                let root_depth = self.stack[stack_depth].cycle_root_depth;
+                let (prev, participants) = self.stack.raw.split_at_mut(stack_depth.as_usize() + 1);
+                let root = &mut prev[root_depth.as_usize()];
+                for entry in participants {
+                    debug_assert!(entry.cycle_root_depth >= root_depth);
+                    entry.cycle_root_depth = root_depth;
+                    root.cycle_participants.insert(entry.input);
+                    // FIXME(@lcnr): I believe that this line is needed as we could
+                    // otherwise access a cache entry for the root of a cycle while
+                    // computing the result for a cycle participant. This can result
+                    // in unstable results due to incompleteness.
+                    //
+                    // However, a test for this would be an even more complex version of
+                    // tests/ui/traits/new-solver/coinduction/incompleteness-unstable-result.rs.
+                    // I did not bother to write such a test and we have no regression test
+                    // for this. It would be good to have such a test :)
+                    #[allow(rustc::potential_query_instability)]
+                    root.cycle_participants.extend(entry.cycle_participants.drain());
                 }
 
-                // If we're in a cycle, we have to retry proving the current goal
-                // until we reach a fixpoint.
+                // If we're in a cycle, we have to retry proving the cycle head
+                // until we reach a fixpoint. It is not enough to simply retry the
+                // `root` goal of this cycle.
+                //
+                // See tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs
+                // for an example.
                 self.stack[stack_depth].has_been_used = true;
-                return if let Some(result) = cache.provisional_result(entry_index) {
+                return if let Some(result) = self.stack[stack_depth].provisional_result {
                     result
                 } else {
-                    // If we don't have a provisional result yet, the goal has to
-                    // still be on the stack.
-                    let mut goal_on_stack = false;
-                    let mut is_coinductive = true;
-                    for entry in self.stack.raw[stack_depth.index()..]
+                    // If we don't have a provisional result yet we're in the first iteration,
+                    // so we start with no constraints.
+                    let is_coinductive = self.stack.raw[stack_depth.index()..]
                         .iter()
-                        .skip_while(|entry| entry.input != input)
-                    {
-                        goal_on_stack = true;
-                        is_coinductive &= entry.input.value.goal.predicate.is_coinductive(tcx);
-                    }
-                    debug_assert!(goal_on_stack);
-
+                        .all(|entry| entry.input.value.goal.predicate.is_coinductive(tcx));
                     if is_coinductive {
                         Self::response_no_constraints(tcx, input, Certainty::Yes)
                     } else {
@@ -294,40 +301,25 @@ impl<'tcx> SearchGraph<'tcx> {
                 // of the previous iteration is equal to the final result, at which
                 // point we are done.
                 for _ in 0..self.local_overflow_limit() {
-                    let response = prove_goal(self, inspect);
+                    let result = prove_goal(self, inspect);
 
                     // Check whether the current goal is the root of a cycle and whether
                     // we have to rerun because its provisional result differed from the
                     // final result.
-                    //
-                    // Also update the response for this goal stored in the provisional
-                    // cache.
                     let stack_entry = self.pop_stack();
                     debug_assert_eq!(stack_entry.input, input);
-                    let cache = &mut self.provisional_cache;
-                    let provisional_entry_index =
-                        *cache.lookup_table.get(&stack_entry.input).unwrap();
-                    let provisional_entry = &mut cache.entries[provisional_entry_index];
                     if stack_entry.has_been_used
-                        && provisional_entry.response.map_or(true, |r| r != response)
+                        && stack_entry.provisional_result.map_or(true, |r| r != result)
                     {
-                        // If so, update the provisional result for this goal and remove
-                        // all entries whose result depends on this goal from the provisional
-                        // cache...
-                        //
-                        // That's not completely correct, as a nested goal can also only
-                        // depend on a goal which is lower in the stack so it doesn't
-                        // actually depend on the current goal. This should be fairly
-                        // rare and is hopefully not relevant for performance.
-                        provisional_entry.response = Some(response);
-                        #[allow(rustc::potential_query_instability)]
-                        cache.lookup_table.retain(|_key, index| *index <= provisional_entry_index);
-                        cache.entries.truncate(provisional_entry_index.index() + 1);
-
-                        // ...and finally push our goal back on the stack and reevaluate it.
-                        self.stack.push(StackEntry { has_been_used: false, ..stack_entry });
+                        // If so, update its provisional result and reevaluate it.
+                        let depth = self.stack.push(StackEntry {
+                            has_been_used: false,
+                            provisional_result: Some(result),
+                            ..stack_entry
+                        });
+                        assert_eq!(self.stack_entries.insert(input, depth), None);
                     } else {
-                        return (stack_entry, response);
+                        return (stack_entry, result);
                     }
                 }
 
@@ -343,17 +335,7 @@ impl<'tcx> SearchGraph<'tcx> {
         //
         // It is not possible for any nested goal to depend on something deeper on the
         // stack, as this would have also updated the depth of the current goal.
-        let cache = &mut self.provisional_cache;
-        let provisional_entry_index = *cache.lookup_table.get(&input).unwrap();
-        let provisional_entry = &mut cache.entries[provisional_entry_index];
-        let depth = provisional_entry.depth;
-        if depth == self.stack.next_index() {
-            for (i, entry) in cache.entries.drain_enumerated(provisional_entry_index.index()..) {
-                let actual_index = cache.lookup_table.remove(&entry.input);
-                debug_assert_eq!(Some(i), actual_index);
-                debug_assert!(entry.depth == depth);
-            }
-
+        if final_entry.cycle_root_depth == self.stack.next_index() {
             // When encountering a cycle, both inductive and coinductive, we only
             // move the root into the global cache. We also store all other cycle
             // participants involved.
@@ -371,8 +353,6 @@ impl<'tcx> SearchGraph<'tcx> {
                 dep_node,
                 result,
             )
-        } else {
-            provisional_entry.response = Some(result);
         }
 
         result
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index f18eed94a68..8055c63b9f3 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -879,8 +879,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             | ty::FnPtr(_)
             | ty::Closure(_, _)
             | ty::Generator(_, _, _)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(_, _)
+            | ty::GeneratorWitness(..)
             | ty::Never
             | ty::Tuple(_)
             | ty::Adt(_, _)
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 59f712721fb..acab4498a09 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -827,9 +827,7 @@ where
             // This should only be created when checking whether we have to check whether some
             // auto trait impl applies. There will never be multiple impls, so we can just
             // act as if it were a local type here.
-            ty::GeneratorWitness(_) | ty::GeneratorWitnessMIR(..) => {
-                ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty))
-            }
+            ty::GeneratorWitness(..) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)),
             ty::Alias(ty::Opaque, ..) => {
                 // This merits some explanation.
                 // Normally, opaque types are not involved when performing
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
index d3e0d3b8b18..2a586f810d6 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1847,7 +1847,6 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 ty::Generator(..) => Some(18),
                 ty::Foreign(..) => Some(19),
                 ty::GeneratorWitness(..) => Some(20),
-                ty::GeneratorWitnessMIR(..) => Some(21),
                 ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) | ty::Error(_) => None,
             }
         }
@@ -3212,7 +3211,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
         let name = match self.tcx.opaque_type_origin(def_id.expect_local()) {
             hir::OpaqueTyOrigin::FnReturn(_) | hir::OpaqueTyOrigin::AsyncFn(_) => {
-                format!("opaque type")
+                "opaque type".to_string()
             }
             hir::OpaqueTyOrigin::TyAlias { .. } => {
                 format!("`{}`", self.tcx.def_path_debug_str(def_id))
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
index cd1dadde1ba..15f2ba809a4 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -30,10 +30,9 @@ use rustc_infer::infer::{DefineOpaqueTypes, InferOk, LateBoundRegionConversionTi
 use rustc_middle::hir::map;
 use rustc_middle::ty::error::TypeError::{self, Sorts};
 use rustc_middle::ty::{
-    self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind,
-    GeneratorDiagnosticData, GeneratorInteriorTypeCause, GenericArgs, InferTy, IsSuggestable,
-    ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeFolder, TypeSuperFoldable,
-    TypeVisitableExt, TypeckResults,
+    self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind, GenericArgs,
+    InferTy, IsSuggestable, ToPredicate, Ty, TyCtxt, TypeAndMut, TypeFoldable, TypeFolder,
+    TypeSuperFoldable, TypeVisitableExt, TypeckResults,
 };
 use rustc_span::def_id::LocalDefId;
 use rustc_span::symbol::{sym, Ident, Symbol};
@@ -50,7 +49,7 @@ use rustc_middle::ty::print::{with_forced_trimmed_paths, with_no_trimmed_paths};
 #[derive(Debug)]
 pub enum GeneratorInteriorOrUpvar {
     // span of interior type
-    Interior(Span, Option<(Option<Span>, Span, Option<hir::HirId>, Option<Span>)>),
+    Interior(Span, Option<(Span, Option<Span>)>),
     // span of upvar
     Upvar(Span),
 }
@@ -58,15 +57,12 @@ pub enum GeneratorInteriorOrUpvar {
 // This type provides a uniform interface to retrieve data on generators, whether it originated from
 // the local crate being compiled or from a foreign crate.
 #[derive(Debug)]
-pub enum GeneratorData<'tcx, 'a> {
-    Local(&'a TypeckResults<'tcx>),
-    Foreign(&'tcx GeneratorDiagnosticData<'tcx>),
-}
+struct GeneratorData<'tcx, 'a>(&'a TypeckResults<'tcx>);
 
 impl<'tcx, 'a> GeneratorData<'tcx, 'a> {
-    // Try to get information about variables captured by the generator that matches a type we are
-    // looking for with `ty_matches` function. We uses it to find upvar which causes a failure to
-    // meet an obligation
+    /// Try to get information about variables captured by the generator that matches a type we are
+    /// looking for with `ty_matches` function. We uses it to find upvar which causes a failure to
+    /// meet an obligation
     fn try_get_upvar_span<F>(
         &self,
         infer_context: &InferCtxt<'tcx>,
@@ -76,27 +72,21 @@ impl<'tcx, 'a> GeneratorData<'tcx, 'a> {
     where
         F: Fn(ty::Binder<'tcx, Ty<'tcx>>) -> bool,
     {
-        match self {
-            GeneratorData::Local(typeck_results) => {
-                infer_context.tcx.upvars_mentioned(generator_did).and_then(|upvars| {
-                    upvars.iter().find_map(|(upvar_id, upvar)| {
-                        let upvar_ty = typeck_results.node_type(*upvar_id);
-                        let upvar_ty = infer_context.resolve_vars_if_possible(upvar_ty);
-                        ty_matches(ty::Binder::dummy(upvar_ty))
-                            .then(|| GeneratorInteriorOrUpvar::Upvar(upvar.span))
-                    })
-                })
-            }
-            GeneratorData::Foreign(_) => None,
-        }
+        infer_context.tcx.upvars_mentioned(generator_did).and_then(|upvars| {
+            upvars.iter().find_map(|(upvar_id, upvar)| {
+                let upvar_ty = self.0.node_type(*upvar_id);
+                let upvar_ty = infer_context.resolve_vars_if_possible(upvar_ty);
+                ty_matches(ty::Binder::dummy(upvar_ty))
+                    .then(|| GeneratorInteriorOrUpvar::Upvar(upvar.span))
+            })
+        })
     }
 
-    // Try to get the span of a type being awaited on that matches the type we are looking with the
-    // `ty_matches` function. We uses it to find awaited type which causes a failure to meet an
-    // obligation
+    /// Try to get the span of a type being awaited on that matches the type we are looking with the
+    /// `ty_matches` function. We uses it to find awaited type which causes a failure to meet an
+    /// obligation
     fn get_from_await_ty<F>(
         &self,
-        tcx: TyCtxt<'tcx>,
         visitor: AwaitsVisitor,
         hir: map::Map<'tcx>,
         ty_matches: F,
@@ -104,69 +94,12 @@ impl<'tcx, 'a> GeneratorData<'tcx, 'a> {
     where
         F: Fn(ty::Binder<'tcx, Ty<'tcx>>) -> bool,
     {
-        match self {
-            GeneratorData::Local(typeck_results) => visitor
-                .awaits
-                .into_iter()
-                .map(|id| hir.expect_expr(id))
-                .find(|await_expr| {
-                    ty_matches(ty::Binder::dummy(typeck_results.expr_ty_adjusted(&await_expr)))
-                })
-                .map(|expr| expr.span),
-            GeneratorData::Foreign(generator_diagnostic_data) => visitor
-                .awaits
-                .into_iter()
-                .map(|id| hir.expect_expr(id))
-                .find(|await_expr| {
-                    ty_matches(ty::Binder::dummy(
-                        generator_diagnostic_data
-                            .adjustments
-                            .get(&await_expr.hir_id.local_id)
-                            .map_or::<&[ty::adjustment::Adjustment<'tcx>], _>(&[], |a| &a[..])
-                            .last()
-                            .map_or_else::<Ty<'tcx>, _, _>(
-                                || {
-                                    generator_diagnostic_data
-                                        .nodes_types
-                                        .get(&await_expr.hir_id.local_id)
-                                        .cloned()
-                                        .unwrap_or_else(|| {
-                                            bug!(
-                                                "node_type: no type for node {}",
-                                                tcx.hir().node_to_string(await_expr.hir_id)
-                                            )
-                                        })
-                                },
-                                |adj| adj.target,
-                            ),
-                    ))
-                })
-                .map(|expr| expr.span),
-        }
-    }
-
-    /// Get the type, expression, span and optional scope span of all types
-    /// that are live across the yield of this generator
-    fn get_generator_interior_types(
-        &self,
-    ) -> ty::Binder<'tcx, &[GeneratorInteriorTypeCause<'tcx>]> {
-        match self {
-            GeneratorData::Local(typeck_result) => {
-                typeck_result.generator_interior_types.as_deref()
-            }
-            GeneratorData::Foreign(generator_diagnostic_data) => {
-                generator_diagnostic_data.generator_interior_types.as_deref()
-            }
-        }
-    }
-
-    // Used to get the source of the data, note we don't have as much information for generators
-    // originated from foreign crates
-    fn is_foreign(&self) -> bool {
-        match self {
-            GeneratorData::Local(_) => false,
-            GeneratorData::Foreign(_) => true,
-        }
+        visitor
+            .awaits
+            .into_iter()
+            .map(|id| hir.expect_expr(id))
+            .find(|await_expr| ty_matches(ty::Binder::dummy(self.0.expr_ty_adjusted(&await_expr))))
+            .map(|expr| expr.span)
     }
 }
 
@@ -316,7 +249,6 @@ pub trait TypeErrCtxtExt<'tcx> {
         outer_generator: Option<DefId>,
         trait_pred: ty::TraitPredicate<'tcx>,
         target_ty: Ty<'tcx>,
-        typeck_results: Option<&ty::TypeckResults<'tcx>>,
         obligation: &PredicateObligation<'tcx>,
         next_code: Option<&ObligationCauseCode<'tcx>>,
     );
@@ -2240,11 +2172,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     );
 
                     match *ty.kind() {
-                        ty::Generator(did, ..) | ty::GeneratorWitnessMIR(did, _) => {
+                        ty::Generator(did, ..) | ty::GeneratorWitness(did, _) => {
                             generator = generator.or(Some(did));
                             outer_generator = Some(did);
                         }
-                        ty::GeneratorWitness(..) => {}
                         ty::Tuple(_) if !seen_upvar_tys_infer_tuple => {
                             // By introducing a tuple of upvar types into the chain of obligations
                             // of a generator, the first non-generator item is now the tuple itself,
@@ -2270,11 +2201,10 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     );
 
                     match *ty.kind() {
-                        ty::Generator(did, ..) | ty::GeneratorWitnessMIR(did, ..) => {
+                        ty::Generator(did, ..) | ty::GeneratorWitness(did, ..) => {
                             generator = generator.or(Some(did));
                             outer_generator = Some(did);
                         }
-                        ty::GeneratorWitness(..) => {}
                         ty::Tuple(_) if !seen_upvar_tys_infer_tuple => {
                             // By introducing a tuple of upvar types into the chain of obligations
                             // of a generator, the first non-generator item is now the tuple itself,
@@ -2351,12 +2281,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         // cycles. If we can't use resolved types because the generator comes from another crate,
         // we still provide a targeted error but without all the relevant spans.
         let generator_data = match &self.typeck_results {
-            Some(t) if t.hir_owner.to_def_id() == generator_did_root => GeneratorData::Local(&t),
+            Some(t) if t.hir_owner.to_def_id() == generator_did_root => GeneratorData(&t),
             _ if generator_did.is_local() => {
-                GeneratorData::Local(self.tcx.typeck(generator_did.expect_local()))
-            }
-            _ if let Some(generator_diag_data) = self.tcx.generator_diagnostic_data(generator_did) => {
-                GeneratorData::Foreign(generator_diag_data)
+                GeneratorData(self.tcx.typeck(generator_did.expect_local()))
             }
             _ => return false,
         };
@@ -2368,30 +2295,11 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
 
         let mut interior_or_upvar_span = None;
 
-        let from_awaited_ty = generator_data.get_from_await_ty(self.tcx, visitor, hir, ty_matches);
+        let from_awaited_ty = generator_data.get_from_await_ty(visitor, hir, ty_matches);
         debug!(?from_awaited_ty);
 
-        // The generator interior types share the same binders
-        if let Some(cause) =
-            generator_data.get_generator_interior_types().skip_binder().iter().find(
-                |ty::GeneratorInteriorTypeCause { ty, .. }| {
-                    ty_matches(generator_data.get_generator_interior_types().rebind(*ty))
-                },
-            )
-        {
-            let ty::GeneratorInteriorTypeCause { span, scope_span, yield_span, expr, .. } = cause;
-
-            interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(
-                *span,
-                Some((*scope_span, *yield_span, *expr, from_awaited_ty)),
-            ));
-
-            if interior_or_upvar_span.is_none() && generator_data.is_foreign() {
-                interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(*span, None));
-            }
-        } else if self.tcx.sess.opts.unstable_opts.drop_tracking_mir
-            // Avoid disclosing internal information to downstream crates.
-            && generator_did.is_local()
+        // Avoid disclosing internal information to downstream crates.
+        if generator_did.is_local()
             // Try to avoid cycles.
             && !generator_within_in_progress_typeck
             && let Some(generator_info) = self.tcx.mir_generator_witnesses(generator_did)
@@ -2407,7 +2315,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                     if ty_matches(ty::Binder::dummy(decl.ty)) && !decl.ignore_for_traits {
                         interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(
                             decl.source_info.span,
-                            Some((None, source_info.span, None, from_awaited_ty)),
+                            Some((source_info.span, from_awaited_ty)),
                         ));
                         break 'find_source;
                     }
@@ -2420,17 +2328,13 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 generator_data.try_get_upvar_span(&self, generator_did, ty_matches);
         }
 
-        if interior_or_upvar_span.is_none() && generator_data.is_foreign() {
+        if interior_or_upvar_span.is_none() && !generator_did.is_local() {
             interior_or_upvar_span = Some(GeneratorInteriorOrUpvar::Interior(span, None));
         }
 
         debug!(?interior_or_upvar_span);
         if let Some(interior_or_upvar_span) = interior_or_upvar_span {
             let is_async = self.tcx.generator_is_async(generator_did);
-            let typeck_results = match generator_data {
-                GeneratorData::Local(typeck_results) => Some(typeck_results),
-                GeneratorData::Foreign(_) => None,
-            };
             self.note_obligation_cause_for_async_await(
                 err,
                 interior_or_upvar_span,
@@ -2438,7 +2342,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 outer_generator,
                 trait_ref,
                 target_ty,
-                typeck_results,
                 obligation,
                 next_code,
             );
@@ -2459,7 +2362,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         outer_generator: Option<DefId>,
         trait_pred: ty::TraitPredicate<'tcx>,
         target_ty: Ty<'tcx>,
-        typeck_results: Option<&ty::TypeckResults<'tcx>>,
         obligation: &PredicateObligation<'tcx>,
         next_code: Option<&ObligationCauseCode<'tcx>>,
     ) {
@@ -2517,9 +2419,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             format!("does not implement `{}`", trait_pred.print_modifiers_and_trait_path())
         };
 
-        let mut explain_yield = |interior_span: Span,
-                                 yield_span: Span,
-                                 scope_span: Option<Span>| {
+        let mut explain_yield = |interior_span: Span, yield_span: Span| {
             let mut span = MultiSpan::from_span(yield_span);
             let snippet = match source_map.span_to_snippet(interior_span) {
                 // #70935: If snippet contains newlines, display "the value" instead
@@ -2551,22 +2451,14 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                 interior_span,
                 format!("has type `{target_ty}` which {trait_explanation}"),
             );
-            if let Some(scope_span) = scope_span {
-                let scope_span = source_map.end_point(scope_span);
-
-                let msg = format!("{snippet} is later dropped here");
-                span.push_span_label(scope_span, msg);
-            }
             err.span_note(
-                    span,
-                    format!(
-                        "{future_or_generator} {trait_explanation} as this value is used across {an_await_or_yield}"
-                    ),
-                );
+                span,
+                format!("{future_or_generator} {trait_explanation} as this value is used across {an_await_or_yield}"),
+            );
         };
         match interior_or_upvar_span {
             GeneratorInteriorOrUpvar::Interior(interior_span, interior_extra_info) => {
-                if let Some((scope_span, yield_span, expr, from_awaited_ty)) = interior_extra_info {
+                if let Some((yield_span, from_awaited_ty)) = interior_extra_info {
                     if let Some(await_span) = from_awaited_ty {
                         // The type causing this obligation is one being awaited at await_span.
                         let mut span = MultiSpan::from_span(await_span);
@@ -2584,62 +2476,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                         );
                     } else {
                         // Look at the last interior type to get a span for the `.await`.
-                        debug!(
-                            generator_interior_types = ?format_args!(
-                                "{:#?}", typeck_results.as_ref().map(|t| &t.generator_interior_types)
-                            ),
-                        );
-                        explain_yield(interior_span, yield_span, scope_span);
-                    }
-
-                    if let Some(expr_id) = expr {
-                        let expr = hir.expect_expr(expr_id);
-                        debug!("target_ty evaluated from {:?}", expr);
-
-                        let parent = hir.parent_id(expr_id);
-                        if let Some(hir::Node::Expr(e)) = hir.find(parent) {
-                            let parent_span = hir.span(parent);
-                            let parent_did = parent.owner.to_def_id();
-                            // ```rust
-                            // impl T {
-                            //     fn foo(&self) -> i32 {}
-                            // }
-                            // T.foo();
-                            // ^^^^^^^ a temporary `&T` created inside this method call due to `&self`
-                            // ```
-                            //
-                            let is_region_borrow = if let Some(typeck_results) = typeck_results {
-                                typeck_results
-                                    .expr_adjustments(expr)
-                                    .iter()
-                                    .any(|adj| adj.is_region_borrow())
-                            } else {
-                                false
-                            };
-
-                            // ```rust
-                            // struct Foo(*const u8);
-                            // bar(Foo(std::ptr::null())).await;
-                            //     ^^^^^^^^^^^^^^^^^^^^^ raw-ptr `*T` created inside this struct ctor.
-                            // ```
-                            debug!(parent_def_kind = ?self.tcx.def_kind(parent_did));
-                            let is_raw_borrow_inside_fn_like_call =
-                                match self.tcx.def_kind(parent_did) {
-                                    DefKind::Fn | DefKind::Ctor(..) => target_ty.is_unsafe_ptr(),
-                                    _ => false,
-                                };
-                            if let Some(typeck_results) = typeck_results {
-                                if (typeck_results.is_method_call(e) && is_region_borrow)
-                                    || is_raw_borrow_inside_fn_like_call
-                                {
-                                    err.span_help(
-                                        parent_span,
-                                        "consider moving this into a `let` \
-                        binding to create a shorter lived borrow",
-                                    );
-                                }
-                            }
-                        }
+                        explain_yield(interior_span, yield_span);
                     }
                 }
             }
@@ -3007,6 +2844,24 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             ObligationCauseCode::InlineAsmSized => {
                 err.note("all inline asm arguments must have a statically known size");
             }
+            ObligationCauseCode::SizedClosureCapture(closure_def_id) => {
+                err.note("all values captured by value by a closure must have a statically known size");
+                let hir::ExprKind::Closure(closure) = self.tcx.hir().get_by_def_id(closure_def_id).expect_expr().kind else {
+                    bug!("expected closure in SizedClosureCapture obligation");
+                };
+                if let hir::CaptureBy::Value = closure.capture_clause
+                    && let Some(span) = closure.fn_arg_span
+                {
+                    err.span_label(span, "this closure captures all values by move");
+                }
+            }
+            ObligationCauseCode::SizedGeneratorInterior(generator_def_id) => {
+                let what = match self.tcx.generator_kind(generator_def_id) {
+                    None | Some(hir::GeneratorKind::Gen) => "yield",
+                    Some(hir::GeneratorKind::Async(..)) => "await",
+                };
+                err.note(format!("all values live across `{what}` must have a statically known size"));
+            }
             ObligationCauseCode::ConstPatternStructural => {
                 err.note("constants used for pattern-matching must derive `PartialEq` and `Eq`");
             }
@@ -3072,20 +2927,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
                                 }
                                 err.span_note(self.tcx.def_span(def_id), msg)
                             }
-                            ty::GeneratorWitness(bound_tys) => {
-                                use std::fmt::Write;
-
-                                // FIXME: this is kind of an unusual format for rustc, can we make it more clear?
-                                // Maybe we should just remove this note altogether?
-                                // FIXME: only print types which don't meet the trait requirement
-                                let mut msg =
-                                    "required because it captures the following types: ".to_owned();
-                                for ty in bound_tys.skip_binder() {
-                                    with_forced_trimmed_paths!(write!(msg, "`{ty}`, ").unwrap());
-                                }
-                                err.note(msg.trim_end_matches(", ").to_string())
-                            }
-                            ty::GeneratorWitnessMIR(def_id, args) => {
+                            ty::GeneratorWitness(def_id, args) => {
                                 use std::fmt::Write;
 
                                 // FIXME: this is kind of an unusual format for rustc, can we make it more clear?
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 93e8e1f4bb1..154cc7a7141 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -1813,7 +1813,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                         | ty::Closure(..)
                         | ty::Generator(..)
                         | ty::GeneratorWitness(..)
-                        | ty::GeneratorWitnessMIR(..)
                         | ty::Never
                         | ty::Tuple(..)
                         // Integers and floats always have `u8` as their discriminant.
@@ -1863,7 +1862,6 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                         | ty::Closure(..)
                         | ty::Generator(..)
                         | ty::GeneratorWitness(..)
-                        | ty::GeneratorWitnessMIR(..)
                         | ty::Never
                         // Extern types have unit metadata, according to RFC 2850
                         | ty::Foreign(_)
diff --git a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
index 9484a50e3a9..86ea7a2bf83 100644
--- a/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/dropck_outlives.rs
@@ -36,7 +36,6 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> bool {
         | ty::FnPtr(_)
         | ty::Char
         | ty::GeneratorWitness(..)
-        | ty::GeneratorWitnessMIR(..)
         | ty::RawPtr(_)
         | ty::Ref(..)
         | ty::Str
@@ -218,8 +217,7 @@ pub fn dtorck_constraint_for_ty_inner<'tcx>(
         | ty::Ref(..)
         | ty::FnDef(..)
         | ty::FnPtr(_)
-        | ty::GeneratorWitness(..)
-        | ty::GeneratorWitnessMIR(..) => {
+        | ty::GeneratorWitness(..) => {
             // these types never have a destructor
         }
 
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index e3da87a2210..bead8758ad6 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -436,8 +436,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 | ty::Ref(_, _, _)
                 | ty::Closure(_, _)
                 | ty::Generator(_, _, _)
-                | ty::GeneratorWitness(_)
-                | ty::GeneratorWitnessMIR(_, _)
+                | ty::GeneratorWitness(..)
                 | ty::Never
                 | ty::Tuple(_)
                 | ty::Error(_) => return true,
@@ -569,8 +568,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 | ty::Generator(..)
                 | ty::Never
                 | ty::Tuple(_)
-                | ty::GeneratorWitness(_)
-                | ty::GeneratorWitnessMIR(..) => {
+                | ty::GeneratorWitness(..) => {
                     // Only consider auto impls if there are no manual impls for the root of `self_ty`.
                     //
                     // For example, we only consider auto candidates for `&i32: Auto` if no explicit impl
@@ -946,8 +944,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::Closure(..)
             | ty::Generator(..)
             | ty::Tuple(_)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..) => {
+            | ty::GeneratorWitness(..) => {
                 // These are built-in, and cannot have a custom `impl const Destruct`.
                 candidates.vec.push(ConstDestructCandidate(None));
             }
@@ -1020,8 +1017,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::Dynamic(_, _, _)
             | ty::Closure(_, _)
             | ty::Generator(_, _, _)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..)
+            | ty::GeneratorWitness(..)
             | ty::Never
             | ty::Alias(..)
             | ty::Param(_)
@@ -1083,7 +1079,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             | ty::Closure(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Never
             | ty::Tuple(..)
             | ty::Alias(..)
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index eadac70057c..08ee9c73bf8 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -1238,10 +1238,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     let generator = args.as_generator();
                     stack.extend([generator.tupled_upvars_ty(), generator.witness()]);
                 }
-                ty::GeneratorWitness(tys) => {
-                    stack.extend(tcx.erase_late_bound_regions(tys).to_vec());
-                }
-                ty::GeneratorWitnessMIR(def_id, args) => {
+                ty::GeneratorWitness(def_id, args) => {
                     let tcx = self.tcx();
                     stack.extend(tcx.generator_hidden_types(def_id).map(|bty| {
                         let ty = bty.instantiate(tcx, args);
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index dcf41c3774f..bc9ba85fc9f 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2131,7 +2131,6 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
             | ty::Ref(..)
             | ty::Generator(..)
             | ty::GeneratorWitness(..)
-            | ty::GeneratorWitnessMIR(..)
             | ty::Array(..)
             | ty::Closure(..)
             | ty::Never
@@ -2230,22 +2229,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 }
             }
 
-            ty::GeneratorWitness(binder) => {
-                let witness_tys = binder.skip_binder();
-                for witness_ty in witness_tys.iter() {
-                    let resolved = self.infcx.shallow_resolve(witness_ty);
-                    if resolved.is_ty_var() {
-                        return Ambiguous;
-                    }
-                }
-                // (*) binder moved here
-                let all_vars = self.tcx().mk_bound_variable_kinds_from_iter(
-                    obligation.predicate.bound_vars().iter().chain(binder.bound_vars().iter()),
-                );
-                Where(ty::Binder::bind_with_vars(witness_tys.to_vec(), all_vars))
-            }
-
-            ty::GeneratorWitnessMIR(def_id, ref args) => {
+            ty::GeneratorWitness(def_id, ref args) => {
                 let hidden_types = bind_generator_hidden_types_above(
                     self.infcx,
                     def_id,
@@ -2350,12 +2334,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 t.rebind([ty].into_iter().chain(iter::once(witness)).collect())
             }
 
-            ty::GeneratorWitness(types) => {
-                debug_assert!(!types.has_escaping_bound_vars());
-                types.map_bound(|types| types.to_vec())
-            }
-
-            ty::GeneratorWitnessMIR(def_id, ref args) => {
+            ty::GeneratorWitness(def_id, ref args) => {
                 bind_generator_hidden_types_above(self.infcx, def_id, args, t.bound_vars())
             }
 
@@ -3115,32 +3094,33 @@ fn bind_generator_hidden_types_above<'tcx>(
         .generator_hidden_types(def_id)
         // Deduplicate tys to avoid repeated work.
         .filter(|bty| seen_tys.insert(*bty))
-        .map(|bty| {
-            let mut ty = bty.instantiate(tcx, args);
-
+        .map(|mut bty| {
             // Only remap erased regions if we use them.
             if considering_regions {
-                ty = tcx.fold_regions(ty, |r, current_depth| match r.kind() {
-                    ty::ReErased => {
-                        let br = ty::BoundRegion {
-                            var: ty::BoundVar::from_u32(counter),
-                            kind: ty::BrAnon(None),
-                        };
-                        counter += 1;
-                        ty::Region::new_late_bound(tcx, current_depth, br)
-                    }
-                    r => bug!("unexpected region: {r:?}"),
+                bty = bty.map_bound(|ty| {
+                    tcx.fold_regions(ty, |r, current_depth| match r.kind() {
+                        ty::ReErased => {
+                            let br = ty::BoundRegion {
+                                var: ty::BoundVar::from_u32(counter),
+                                kind: ty::BrAnon,
+                            };
+                            counter += 1;
+                            ty::Region::new_late_bound(tcx, current_depth, br)
+                        }
+                        r => bug!("unexpected region: {r:?}"),
+                    })
                 })
             }
 
-            ty
+            bty.instantiate(tcx, args)
         })
         .collect();
     if considering_regions {
         debug_assert!(!hidden_types.has_erased_regions());
     }
-    let bound_vars = tcx.mk_bound_variable_kinds_from_iter(bound_vars.iter().chain(
-        (num_bound_variables..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon(None))),
-    ));
+    let bound_vars =
+        tcx.mk_bound_variable_kinds_from_iter(bound_vars.iter().chain(
+            (num_bound_variables..counter).map(|_| ty::BoundVariableKind::Region(ty::BrAnon)),
+        ));
     ty::Binder::bind_with_vars(hidden_types, bound_vars)
 }
diff --git a/compiler/rustc_trait_selection/src/traits/structural_match.rs b/compiler/rustc_trait_selection/src/traits/structural_match.rs
index 0864e4dc841..fc9b424369a 100644
--- a/compiler/rustc_trait_selection/src/traits/structural_match.rs
+++ b/compiler/rustc_trait_selection/src/traits/structural_match.rs
@@ -79,7 +79,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for Search<'tcx> {
             ty::Closure(..) => {
                 return ControlFlow::Break(ty);
             }
-            ty::Generator(..) | ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => {
+            ty::Generator(..) | ty::GeneratorWitness(..) => {
                 return ControlFlow::Break(ty);
             }
             ty::FnDef(..) => {
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index f26310665f9..b04008d9ee5 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -609,7 +609,6 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> {
                 | ty::Error(_)
                 | ty::Str
                 | ty::GeneratorWitness(..)
-                | ty::GeneratorWitnessMIR(..)
                 | ty::Never
                 | ty::Param(_)
                 | ty::Bound(..)
diff --git a/compiler/rustc_ty_utils/src/implied_bounds.rs b/compiler/rustc_ty_utils/src/implied_bounds.rs
index 436f10a4f7b..ec2e0daaf88 100644
--- a/compiler/rustc_ty_utils/src/implied_bounds.rs
+++ b/compiler/rustc_ty_utils/src/implied_bounds.rs
@@ -119,7 +119,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
         },
         DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)),
         DefKind::OpaqueTy => match tcx.def_kind(tcx.local_parent(def_id)) {
-            DefKind::TyAlias { .. } => ty::List::empty(),
+            DefKind::TyAlias => ty::List::empty(),
             DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)),
             // Nested opaque types only occur in associated types:
             // ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
@@ -136,7 +136,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
         | DefKind::Enum
         | DefKind::Variant
         | DefKind::Trait
-        | DefKind::TyAlias { .. }
+        | DefKind::TyAlias
         | DefKind::ForeignTy
         | DefKind::TraitAlias
         | DefKind::TyParam
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index a03b82305f0..5bd68d7ccaa 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -577,11 +577,7 @@ fn layout_of_uncached<'tcx>(
             return Err(error(cx, LayoutError::Unknown(ty)));
         }
 
-        ty::Bound(..)
-        | ty::GeneratorWitness(..)
-        | ty::GeneratorWitnessMIR(..)
-        | ty::Infer(_)
-        | ty::Error(_) => {
+        ty::Bound(..) | ty::GeneratorWitness(..) | ty::Infer(_) | ty::Error(_) => {
             bug!("Layout::compute: unexpected type `{}`", ty)
         }
 
diff --git a/compiler/rustc_ty_utils/src/needs_drop.rs b/compiler/rustc_ty_utils/src/needs_drop.rs
index 1fc5d9359a4..6dcbc4470e6 100644
--- a/compiler/rustc_ty_utils/src/needs_drop.rs
+++ b/compiler/rustc_ty_utils/src/needs_drop.rs
@@ -7,7 +7,7 @@ use rustc_middle::ty::util::{needs_drop_components, AlwaysRequiresDrop};
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{self, EarlyBinder, Ty, TyCtxt};
 use rustc_session::Limit;
-use rustc_span::{sym, DUMMY_SP};
+use rustc_span::sym;
 
 use crate::errors::NeedsDropOverflow;
 
@@ -133,7 +133,7 @@ where
                     // The information required to determine whether a generator has drop is
                     // computed on MIR, while this very method is used to build MIR.
                     // To avoid cycles, we consider that generators always require drop.
-                    ty::Generator(..) if tcx.sess.opts.unstable_opts.drop_tracking_mir => {
+                    ty::Generator(..) => {
                         return Some(Err(AlwaysRequiresDrop));
                     }
 
@@ -145,29 +145,6 @@ where
                         }
                     }
 
-                    ty::Generator(def_id, args, _) => {
-                        let args = args.as_generator();
-                        for upvar in args.upvar_tys() {
-                            queue_type(self, upvar);
-                        }
-
-                        let witness = args.witness();
-                        let interior_tys = match witness.kind() {
-                            &ty::GeneratorWitness(tys) => tcx.erase_late_bound_regions(tys),
-                            _ => {
-                                tcx.sess.delay_span_bug(
-                                    tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP),
-                                    format!("unexpected generator witness type {witness:?}"),
-                                );
-                                return Some(Err(AlwaysRequiresDrop));
-                            }
-                        };
-
-                        for interior_ty in interior_tys {
-                            queue_type(self, interior_ty);
-                        }
-                    }
-
                     // Check for a `Drop` impl and whether this is a union or
                     // `ManuallyDrop`. If it's a struct or enum without a `Drop`
                     // impl then check whether the field types need `Drop`.
@@ -215,7 +192,6 @@ where
                     | ty::Tuple(_)
                     | ty::Bound(..)
                     | ty::GeneratorWitness(..)
-                    | ty::GeneratorWitnessMIR(..)
                     | ty::Never
                     | ty::Infer(_)
                     | ty::Error(_) => {
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index 38768f0a05b..06a30677d20 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -53,9 +53,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
 
     fn parent(&self) -> Option<LocalDefId> {
         match self.tcx.def_kind(self.item) {
-            DefKind::AnonConst | DefKind::InlineConst | DefKind::Fn | DefKind::TyAlias { .. } => {
-                None
-            }
+            DefKind::AnonConst | DefKind::InlineConst | DefKind::Fn | DefKind::TyAlias => None,
             DefKind::AssocFn | DefKind::AssocTy | DefKind::AssocConst => {
                 Some(self.tcx.local_parent(self.item))
             }
@@ -118,7 +116,7 @@ impl<'tcx> OpaqueTypeCollector<'tcx> {
             #[instrument(level = "trace", skip(self))]
             fn visit_nested_item(&mut self, id: rustc_hir::ItemId) {
                 let id = id.owner_id.def_id;
-                if let DefKind::TyAlias { .. } = self.collector.tcx.def_kind(id) {
+                if let DefKind::TyAlias = self.collector.tcx.def_kind(id) {
                     let items = self.collector.tcx.opaque_types_defined_by(id);
                     self.collector.opaques.extend(items);
                 }
@@ -297,7 +295,7 @@ fn opaque_types_defined_by<'tcx>(tcx: TyCtxt<'tcx>, item: LocalDefId) -> &'tcx [
             collector.collect_body_and_predicate_taits();
         }
         // We're also doing this for `AssocTy` for the wf checks in `check_opaque_meets_bounds`
-        DefKind::TyAlias { .. } | DefKind::AssocTy => {
+        DefKind::TyAlias | DefKind::AssocTy => {
             tcx.type_of(item).instantiate_identity().visit_with(&mut collector);
         }
         DefKind::OpaqueTy => {
diff --git a/compiler/rustc_ty_utils/src/ty.rs b/compiler/rustc_ty_utils/src/ty.rs
index 6c23589b39a..4234e69e854 100644
--- a/compiler/rustc_ty_utils/src/ty.rs
+++ b/compiler/rustc_ty_utils/src/ty.rs
@@ -21,13 +21,7 @@ fn sized_constraint_for_ty<'tcx>(
         Bool | Char | Int(..) | Uint(..) | Float(..) | RawPtr(..) | Ref(..) | FnDef(..)
         | FnPtr(_) | Array(..) | Closure(..) | Generator(..) | Never => vec![],
 
-        Str
-        | Dynamic(..)
-        | Slice(_)
-        | Foreign(..)
-        | Error(_)
-        | GeneratorWitness(..)
-        | GeneratorWitnessMIR(..) => {
+        Str | Dynamic(..) | Slice(_) | Foreign(..) | Error(_) | GeneratorWitness(..) => {
             // these are never sized - return the target type
             vec![ty]
         }
diff --git a/compiler/rustc_type_ir/src/sty.rs b/compiler/rustc_type_ir/src/sty.rs
index b574cdcc879..091b51440a6 100644
--- a/compiler/rustc_type_ir/src/sty.rs
+++ b/compiler/rustc_type_ir/src/sty.rs
@@ -146,31 +146,6 @@ pub enum TyKind<I: Interner> {
     /// A type representing the types stored inside a generator.
     /// This should only appear as part of the `GeneratorArgs`.
     ///
-    /// Note that the captured variables for generators are stored separately
-    /// using a tuple in the same way as for closures.
-    ///
-    /// Unlike upvars, the witness can reference lifetimes from
-    /// inside of the generator itself. To deal with them in
-    /// the type of the generator, we convert them to higher ranked
-    /// lifetimes bound by the witness itself.
-    ///
-    /// Looking at the following example, the witness for this generator
-    /// may end up as something like `for<'a> [Vec<i32>, &'a Vec<i32>]`:
-    ///
-    /// ```ignore UNSOLVED (ask @compiler-errors, should this error? can we just swap the yields?)
-    /// #![feature(generators)]
-    /// |a| {
-    ///     let x = &vec![3];
-    ///     yield a;
-    ///     yield x[0];
-    /// }
-    /// # ;
-    /// ```
-    GeneratorWitness(I::BinderListTy),
-
-    /// A type representing the types stored inside a generator.
-    /// This should only appear as part of the `GeneratorArgs`.
-    ///
     /// Unlike upvars, the witness can reference lifetimes from
     /// inside of the generator itself. To deal with them in
     /// the type of the generator, we convert them to higher ranked
@@ -192,7 +167,7 @@ pub enum TyKind<I: Interner> {
     /// }
     /// # ;
     /// ```
-    GeneratorWitnessMIR(I::DefId, I::GenericArgsRef),
+    GeneratorWitness(I::DefId, I::GenericArgsRef),
 
     /// The never type `!`.
     Never,
@@ -278,7 +253,7 @@ const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
         Dynamic(..) => 14,
         Closure(_, _) => 15,
         Generator(_, _, _) => 16,
-        GeneratorWitness(_) => 17,
+        GeneratorWitness(_, _) => 17,
         Never => 18,
         Tuple(_) => 19,
         Alias(_, _) => 20,
@@ -287,7 +262,6 @@ const fn tykind_discriminant<I: Interner>(value: &TyKind<I>) -> usize {
         Placeholder(_) => 23,
         Infer(_) => 24,
         Error(_) => 25,
-        GeneratorWitnessMIR(_, _) => 26,
     }
 }
 
@@ -312,8 +286,7 @@ impl<I: Interner> Clone for TyKind<I> {
             Dynamic(p, r, repr) => Dynamic(p.clone(), r.clone(), *repr),
             Closure(d, s) => Closure(d.clone(), s.clone()),
             Generator(d, s, m) => Generator(d.clone(), s.clone(), m.clone()),
-            GeneratorWitness(g) => GeneratorWitness(g.clone()),
-            GeneratorWitnessMIR(d, s) => GeneratorWitnessMIR(d.clone(), s.clone()),
+            GeneratorWitness(d, s) => GeneratorWitness(d.clone(), s.clone()),
             Never => Never,
             Tuple(t) => Tuple(t.clone()),
             Alias(k, p) => Alias(*k, p.clone()),
@@ -355,10 +328,7 @@ impl<I: Interner> PartialEq for TyKind<I> {
             (Generator(a_d, a_s, a_m), Generator(b_d, b_s, b_m)) => {
                 a_d == b_d && a_s == b_s && a_m == b_m
             }
-            (GeneratorWitness(a_g), GeneratorWitness(b_g)) => a_g == b_g,
-            (GeneratorWitnessMIR(a_d, a_s), GeneratorWitnessMIR(b_d, b_s)) => {
-                a_d == b_d && a_s == b_s
-            }
+            (GeneratorWitness(a_d, a_s), GeneratorWitness(b_d, b_s)) => a_d == b_d && a_s == b_s,
             (Tuple(a_t), Tuple(b_t)) => a_t == b_t,
             (Alias(a_i, a_p), Alias(b_i, b_p)) => a_i == b_i && a_p == b_p,
             (Param(a_p), Param(b_p)) => a_p == b_p,
@@ -415,10 +385,9 @@ impl<I: Interner> Ord for TyKind<I> {
                 (Generator(a_d, a_s, a_m), Generator(b_d, b_s, b_m)) => {
                     a_d.cmp(b_d).then_with(|| a_s.cmp(b_s).then_with(|| a_m.cmp(b_m)))
                 }
-                (GeneratorWitness(a_g), GeneratorWitness(b_g)) => a_g.cmp(b_g),
                 (
-                    GeneratorWitnessMIR(a_d, a_s),
-                    GeneratorWitnessMIR(b_d, b_s),
+                    GeneratorWitness(a_d, a_s),
+                    GeneratorWitness(b_d, b_s),
                 ) => match Ord::cmp(a_d, b_d) {
                     Ordering::Equal => Ord::cmp(a_s, b_s),
                     cmp => cmp,
@@ -483,8 +452,7 @@ impl<I: Interner> hash::Hash for TyKind<I> {
                 s.hash(state);
                 m.hash(state)
             }
-            GeneratorWitness(g) => g.hash(state),
-            GeneratorWitnessMIR(d, s) => {
+            GeneratorWitness(d, s) => {
                 d.hash(state);
                 s.hash(state);
             }
@@ -558,28 +526,23 @@ impl<I: Interner> DebugWithInfcx<I> for TyKind<I> {
             },
             Closure(d, s) => f.debug_tuple_field2_finish("Closure", d, &this.wrap(s)),
             Generator(d, s, m) => f.debug_tuple_field3_finish("Generator", d, &this.wrap(s), m),
-            GeneratorWitness(g) => f.debug_tuple_field1_finish("GeneratorWitness", &this.wrap(g)),
-            GeneratorWitnessMIR(d, s) => {
-                f.debug_tuple_field2_finish("GeneratorWitnessMIR", d, &this.wrap(s))
+            GeneratorWitness(d, s) => {
+                f.debug_tuple_field2_finish("GeneratorWitness", d, &this.wrap(s))
             }
             Never => write!(f, "!"),
             Tuple(t) => {
-                let mut iter = t.clone().into_iter();
-
                 write!(f, "(")?;
-
-                match iter.next() {
-                    None => return write!(f, ")"),
-                    Some(ty) => write!(f, "{:?}", &this.wrap(ty))?,
-                };
-
-                match iter.next() {
-                    None => return write!(f, ",)"),
-                    Some(ty) => write!(f, "{:?})", &this.wrap(ty))?,
+                let mut count = 0;
+                for ty in t.clone() {
+                    if count > 0 {
+                        write!(f, ", ")?;
+                    }
+                    write!(f, "{:?}", &this.wrap(ty))?;
+                    count += 1;
                 }
-
-                for ty in iter {
-                    write!(f, ", {:?}", &this.wrap(ty))?;
+                // unary tuples need a trailing comma
+                if count == 1 {
+                    write!(f, ",")?;
                 }
                 write!(f, ")")
             }
@@ -682,10 +645,7 @@ where
                 args.encode(e);
                 m.encode(e);
             }),
-            GeneratorWitness(b) => e.emit_enum_variant(disc, |e| {
-                b.encode(e);
-            }),
-            GeneratorWitnessMIR(def_id, args) => e.emit_enum_variant(disc, |e| {
+            GeneratorWitness(def_id, args) => e.emit_enum_variant(disc, |e| {
                 def_id.encode(e);
                 args.encode(e);
             }),
@@ -762,7 +722,7 @@ where
             14 => Dynamic(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
             15 => Closure(Decodable::decode(d), Decodable::decode(d)),
             16 => Generator(Decodable::decode(d), Decodable::decode(d), Decodable::decode(d)),
-            17 => GeneratorWitness(Decodable::decode(d)),
+            17 => GeneratorWitness(Decodable::decode(d), Decodable::decode(d)),
             18 => Never,
             19 => Tuple(Decodable::decode(d)),
             20 => Alias(Decodable::decode(d), Decodable::decode(d)),
@@ -771,12 +731,11 @@ where
             23 => Placeholder(Decodable::decode(d)),
             24 => Infer(Decodable::decode(d)),
             25 => Error(Decodable::decode(d)),
-            26 => GeneratorWitnessMIR(Decodable::decode(d), Decodable::decode(d)),
             _ => panic!(
                 "{}",
                 format!(
                     "invalid enum variant tag while decoding `{}`, expected 0..{}",
-                    "TyKind", 27,
+                    "TyKind", 26,
                 )
             ),
         }
@@ -870,10 +829,7 @@ where
                 args.hash_stable(__hcx, __hasher);
                 m.hash_stable(__hcx, __hasher);
             }
-            GeneratorWitness(b) => {
-                b.hash_stable(__hcx, __hasher);
-            }
-            GeneratorWitnessMIR(def_id, args) => {
+            GeneratorWitness(def_id, args) => {
                 def_id.hash_stable(__hcx, __hasher);
                 args.hash_stable(__hcx, __hasher);
             }
diff --git a/compiler/stable_mir/Cargo.toml b/compiler/stable_mir/Cargo.toml
new file mode 100644
index 00000000000..c61e217bf9f
--- /dev/null
+++ b/compiler/stable_mir/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "stable_mir"
+version = "0.1.0-preview"
+edition = "2021"
+
+[dependencies]
+tracing = "0.1"
+scoped-tls = "1.0"
diff --git a/compiler/rustc_smir/README.md b/compiler/stable_mir/README.md
index 31dee955f49..31dee955f49 100644
--- a/compiler/rustc_smir/README.md
+++ b/compiler/stable_mir/README.md
diff --git a/compiler/rustc_smir/rust-toolchain.toml b/compiler/stable_mir/rust-toolchain.toml
index d75e8e33b1c..d75e8e33b1c 100644
--- a/compiler/rustc_smir/rust-toolchain.toml
+++ b/compiler/stable_mir/rust-toolchain.toml
diff --git a/compiler/rustc_smir/src/stable_mir/fold.rs b/compiler/stable_mir/src/fold.rs
index 831cfb40a15..6471b2c2a3a 100644
--- a/compiler/rustc_smir/src/stable_mir/fold.rs
+++ b/compiler/stable_mir/src/fold.rs
@@ -1,20 +1,23 @@
 use std::ops::ControlFlow;
 
-use crate::rustc_internal::Opaque;
+use crate::Opaque;
 
 use super::ty::{
     Allocation, Binder, Const, ConstDef, ConstantKind, ExistentialPredicate, FnSig, GenericArgKind,
-    GenericArgs, Promoted, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst,
+    GenericArgs, Promoted, Region, RigidTy, TermKind, Ty, TyKind, UnevaluatedConst,
 };
 
 pub trait Folder: Sized {
     type Break;
-    fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
+    fn fold_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
         ty.super_fold(self)
     }
     fn fold_const(&mut self, c: &Const) -> ControlFlow<Self::Break, Const> {
         c.super_fold(self)
     }
+    fn fold_reg(&mut self, reg: &Region) -> ControlFlow<Self::Break, Region> {
+        reg.super_fold(self)
+    }
 }
 
 pub trait Foldable: Sized + Clone {
@@ -26,7 +29,7 @@ pub trait Foldable: Sized + Clone {
 
 impl Foldable for Ty {
     fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
-        folder.visit_ty(self)
+        folder.fold_ty(self)
     }
     fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
         let mut kind = self.kind();
@@ -81,7 +84,7 @@ impl Foldable for UnevaluatedConst {
 
 impl Foldable for ConstDef {
     fn super_fold<V: Folder>(&self, _folder: &mut V) -> ControlFlow<V::Break, Self> {
-        ControlFlow::Continue(self.clone())
+        ControlFlow::Continue(*self)
     }
 }
 
@@ -96,7 +99,7 @@ impl<T: Foldable> Foldable for Option<T> {
 
 impl Foldable for Promoted {
     fn super_fold<V: Folder>(&self, _folder: &mut V) -> ControlFlow<V::Break, Self> {
-        ControlFlow::Continue(self.clone())
+        ControlFlow::Continue(*self)
     }
 }
 
@@ -106,6 +109,15 @@ impl Foldable for GenericArgs {
     }
 }
 
+impl Foldable for Region {
+    fn fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
+        folder.fold_reg(self)
+    }
+    fn super_fold<V: Folder>(&self, _: &mut V) -> ControlFlow<V::Break, Self> {
+        ControlFlow::Continue(self.clone())
+    }
+}
+
 impl Foldable for GenericArgKind {
     fn super_fold<V: Folder>(&self, folder: &mut V) -> ControlFlow<V::Break, Self> {
         let mut this = self.clone();
@@ -136,7 +148,10 @@ impl Foldable for RigidTy {
             }
             RigidTy::Slice(inner) => *inner = inner.fold(folder)?,
             RigidTy::RawPtr(ty, _) => *ty = ty.fold(folder)?,
-            RigidTy::Ref(_, ty, _) => *ty = ty.fold(folder)?,
+            RigidTy::Ref(reg, ty, _) => {
+                *reg = reg.fold(folder)?;
+                *ty = ty.fold(folder)?
+            }
             RigidTy::FnDef(_, args) => *args = args.fold(folder)?,
             RigidTy::FnPtr(sig) => *sig = sig.fold(folder)?,
             RigidTy::Closure(_, args) => *args = args.fold(folder)?,
@@ -214,7 +229,7 @@ pub enum Never {}
 impl Folder for GenericArgs {
     type Break = Never;
 
-    fn visit_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
+    fn fold_ty(&mut self, ty: &Ty) -> ControlFlow<Self::Break, Ty> {
         ControlFlow::Continue(match ty.kind() {
             TyKind::Param(p) => self[p],
             _ => *ty,
diff --git a/compiler/rustc_smir/src/stable_mir/mod.rs b/compiler/stable_mir/src/lib.rs
index 3c86cb4038a..104985493ef 100644
--- a/compiler/rustc_smir/src/stable_mir/mod.rs
+++ b/compiler/stable_mir/src/lib.rs
@@ -1,15 +1,21 @@
-//! Module that implements the public interface to the Stable MIR.
+//! The WIP stable interface to rustc internals.
 //!
-//! This module shall contain all type definitions and APIs that we expect third-party tools to invoke to
-//! interact with the compiler.
+//! For more information see <https://github.com/rust-lang/project-stable-mir>
 //!
-//! The goal is to eventually move this module to its own crate which shall be published on
-//! [crates.io](https://crates.io).
+//! # Note
+//!
+//! This API is still completely unstable and subject to change.
+
+#![doc(
+    html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/",
+    test(attr(allow(unused_variables), deny(warnings)))
+)]
 //!
-//! ## Note:
+//! This crate shall contain all type definitions and APIs that we expect third-party tools to invoke to
+//! interact with the compiler.
 //!
-//! There shouldn't be any direct references to internal compiler constructs in this module.
-//! If you need an internal construct, consider using `rustc_internal` or `rustc_smir`.
+//! The goal is to eventually be published on
+//! [crates.io](https://crates.io).
 
 use std::cell::Cell;
 use std::fmt;
@@ -18,7 +24,9 @@ use std::fmt::Debug;
 use self::ty::{
     GenericPredicates, Generics, ImplDef, ImplTrait, Span, TraitDecl, TraitDef, Ty, TyKind,
 };
-use crate::rustc_smir::Tables;
+
+#[macro_use]
+extern crate scoped_tls;
 
 pub mod fold;
 pub mod mir;
@@ -33,11 +41,11 @@ pub type CrateNum = usize;
 
 /// A unique identification number for each item accessible for the current compilation unit.
 #[derive(Clone, Copy, PartialEq, Eq)]
-pub struct DefId(pub(crate) usize);
+pub struct DefId(pub usize);
 
 impl Debug for DefId {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.debug_struct("DefId:")
+        f.debug_struct("DefId")
             .field("id", &self.0)
             .field("name", &with(|cx| cx.name_of_def_id(*self)))
             .finish()
@@ -46,7 +54,7 @@ impl Debug for DefId {
 
 /// A unique identification number for each provenance
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct AllocId(pub(crate) usize);
+pub struct AllocId(pub usize);
 
 /// A list of crate items.
 pub type CrateItems = Vec<CrateItem>;
@@ -74,16 +82,18 @@ pub enum CompilerError<T> {
 /// Holds information about a crate.
 #[derive(Clone, PartialEq, Eq, Debug)]
 pub struct Crate {
-    pub(crate) id: CrateNum,
+    pub id: CrateNum,
     pub name: Symbol,
     pub is_local: bool,
 }
 
+pub type DefKind = Opaque;
+
 /// Holds information about an item in the crate.
 /// For now, it only stores the item DefId. Use functions inside `rustc_internal` module to
 /// use this item.
 #[derive(Clone, PartialEq, Eq, Debug)]
-pub struct CrateItem(pub(crate) DefId);
+pub struct CrateItem(pub DefId);
 
 impl CrateItem {
     pub fn body(&self) -> mir::Body {
@@ -93,6 +103,14 @@ impl CrateItem {
     pub fn span(&self) -> Span {
         with(|cx| cx.span_of_an_item(self.0))
     }
+
+    pub fn name(&self) -> String {
+        with(|cx| cx.name_of_def_id(self.0))
+    }
+
+    pub fn kind(&self) -> DefKind {
+        with(|cx| cx.def_kind(self.0))
+    }
 }
 
 /// Return the function where execution starts if the current
@@ -161,6 +179,12 @@ pub trait Context {
     /// Prints the name of given `DefId`
     fn name_of_def_id(&self, def_id: DefId) -> String;
 
+    /// Prints a human readable form of `Span`
+    fn print_span(&self, span: Span) -> String;
+
+    /// Prints the kind of given `DefId`
+    fn def_kind(&mut self, def_id: DefId) -> DefKind;
+
     /// `Span` of an item
     fn span_of_an_item(&mut self, def_id: DefId) -> Span;
 
@@ -169,10 +193,6 @@ pub trait Context {
 
     /// Create a new `Ty` from scratch without information from rustc.
     fn mk_ty(&mut self, kind: TyKind) -> Ty;
-
-    /// HACK: Until we have fully stable consumers, we need an escape hatch
-    /// to get `DefId`s out of `CrateItem`s.
-    fn rustc_tables(&mut self, f: &mut dyn FnMut(&mut Tables<'_>));
 }
 
 // A thread local variable that stores a pointer to the tables mapping between TyCtxt
@@ -192,7 +212,7 @@ pub fn run(mut context: impl Context, f: impl FnOnce()) {
 
 /// Loads the current context and calls a function with it.
 /// Do not nest these, as that will ICE.
-pub(crate) fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
+pub fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
     assert!(TLV.is_set());
     TLV.with(|tlv| {
         let ptr = tlv.get();
@@ -200,3 +220,23 @@ pub(crate) fn with<R>(f: impl FnOnce(&mut dyn Context) -> R) -> R {
         f(unsafe { *(ptr as *mut &mut dyn Context) })
     })
 }
+
+/// A type that provides internal information but that can still be used for debug purpose.
+#[derive(Clone)]
+pub struct Opaque(String);
+
+impl std::fmt::Display for Opaque {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{}", self.0)
+    }
+}
+
+impl std::fmt::Debug for Opaque {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        write!(f, "{:?}", self.0)
+    }
+}
+
+pub fn opaque<T: Debug>(value: &T) -> Opaque {
+    Opaque(format!("{value:?}"))
+}
diff --git a/compiler/rustc_smir/src/stable_mir/mir.rs b/compiler/stable_mir/src/mir.rs
index a9dbc3463f8..a9dbc3463f8 100644
--- a/compiler/rustc_smir/src/stable_mir/mir.rs
+++ b/compiler/stable_mir/src/mir.rs
diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 449ca4b8145..6f8f7b06fa3 100644
--- a/compiler/rustc_smir/src/stable_mir/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -1,8 +1,6 @@
-use crate::rustc_internal::Opaque;
-use crate::stable_mir::ty::{
-    AdtDef, ClosureDef, Const, GeneratorDef, GenericArgs, Movability, Region,
-};
-use crate::stable_mir::{self, ty::Ty, Span};
+use crate::ty::{AdtDef, ClosureDef, Const, GeneratorDef, GenericArgs, Movability, Region};
+use crate::Opaque;
+use crate::{ty::Ty, Span};
 
 #[derive(Clone, Debug)]
 pub struct Body {
@@ -135,7 +133,7 @@ pub enum AsyncGeneratorKind {
 }
 
 pub(crate) type LocalDefId = Opaque;
-/// [`rustc_middle::mir::Coverage`] is heavily tied to internal details of the
+/// The rustc coverage data structures are heavily tied to internal details of the
 /// coverage implementation that are likely to change, and are unlikely to be
 /// useful to third-party tools for the foreseeable future.
 pub(crate) type Coverage = Opaque;
@@ -215,7 +213,7 @@ pub enum Rvalue {
     /// generator lowering, `Generator` aggregate kinds are disallowed too.
     Aggregate(AggregateKind, Vec<Operand>),
 
-    /// * `Offset` has the same semantics as [`offset`](pointer::offset), except that the second
+    /// * `Offset` has the same semantics as `<*const T>::offset`, except that the second
     ///   parameter may be a `usize` as well.
     /// * The comparison operations accept `bool`s, `char`s, signed or unsigned integers, floats,
     ///   raw pointers, or function pointers and return a `bool`. The types of the operands must be
@@ -245,16 +243,14 @@ pub enum Rvalue {
     /// deref operation, immediately followed by one or more projections.
     CopyForDeref(Place),
 
-    /// Computes the discriminant of the place, returning it as an integer of type
-    /// [`discriminant_ty`]. Returns zero for types without discriminant.
+    /// Computes the discriminant of the place, returning it as an integer.
+    /// Returns zero for types without discriminant.
     ///
     /// The validity requirements for the underlying value are undecided for this rvalue, see
     /// [#91095]. Note too that the value of the discriminant is not the same thing as the
-    /// variant index; use [`discriminant_for_variant`] to convert.
+    /// variant index;
     ///
-    /// [`discriminant_ty`]: rustc_middle::ty::Ty::discriminant_ty
     /// [#91095]: https://github.com/rust-lang/rust/issues/91095
-    /// [`discriminant_for_variant`]: rustc_middle::ty::Ty::discriminant_for_variant
     Discriminant(Place),
 
     /// Yields the length of the place, as a `usize`.
@@ -295,7 +291,7 @@ pub enum Rvalue {
     ///
     /// **Needs clarification**: Are there weird additional semantics here related to the runtime
     /// nature of this operation?
-    ThreadLocalRef(stable_mir::CrateItem),
+    ThreadLocalRef(crate::CrateItem),
 
     /// Computes a value as described by the operation.
     NullaryOp(NullOp, Ty),
diff --git a/compiler/rustc_smir/src/stable_mir/ty.rs b/compiler/stable_mir/src/ty.rs
index 3a8fc1a502e..6029e3c11ad 100644
--- a/compiler/rustc_smir/src/stable_mir/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -1,9 +1,9 @@
 use super::{
     mir::Safety,
     mir::{Body, Mutability},
-    with, AllocId, DefId,
+    with, AllocId, DefId, Symbol,
 };
-use crate::rustc_internal::Opaque;
+use crate::Opaque;
 use std::fmt::{self, Debug, Formatter};
 
 #[derive(Copy, Clone)]
@@ -34,15 +34,55 @@ pub struct Const {
 }
 
 type Ident = Opaque;
-pub(crate) type Region = Opaque;
+
+#[derive(Debug, Clone)]
+pub struct Region {
+    pub kind: RegionKind,
+}
+
+#[derive(Debug, Clone)]
+pub enum RegionKind {
+    ReEarlyBound(EarlyBoundRegion),
+    ReLateBound(DebruijnIndex, BoundRegion),
+    ReStatic,
+    RePlaceholder(Placeholder<BoundRegion>),
+    ReErased,
+}
+
+pub(crate) type DebruijnIndex = u32;
+
+#[derive(Debug, Clone)]
+pub struct EarlyBoundRegion {
+    pub def_id: RegionDef,
+    pub index: u32,
+    pub name: Symbol,
+}
+
+pub(crate) type BoundVar = u32;
+
+#[derive(Debug, Clone)]
+pub struct BoundRegion {
+    pub var: BoundVar,
+    pub kind: BoundRegionKind,
+}
+
+pub(crate) type UniverseIndex = u32;
+
+#[derive(Debug, Clone)]
+pub struct Placeholder<T> {
+    pub universe: UniverseIndex,
+    pub bound: T,
+}
+
 #[derive(Clone, Copy, PartialEq, Eq)]
-pub struct Span(pub(crate) usize);
+pub struct Span(pub usize);
 
 impl Debug for Span {
     fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
-        let mut span = None;
-        with(|context| context.rustc_tables(&mut |tables| span = Some(tables.spans[self.0])));
-        f.write_fmt(format_args!("{:?}", &span.unwrap()))
+        f.debug_struct("Span")
+            .field("id", &self.0)
+            .field("repr", &with(|cx| cx.print_span(*self)))
+            .finish()
     }
 }
 
@@ -110,10 +150,10 @@ pub enum Movability {
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ForeignDef(pub(crate) DefId);
+pub struct ForeignDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct FnDef(pub(crate) DefId);
+pub struct FnDef(pub DefId);
 
 impl FnDef {
     pub fn body(&self) -> Body {
@@ -122,34 +162,37 @@ impl FnDef {
 }
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ClosureDef(pub(crate) DefId);
+pub struct ClosureDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct GeneratorDef(pub(crate) DefId);
+pub struct GeneratorDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ParamDef(pub(crate) DefId);
+pub struct ParamDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct BrNamedDef(pub(crate) DefId);
+pub struct BrNamedDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct AdtDef(pub(crate) DefId);
+pub struct AdtDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct AliasDef(pub(crate) DefId);
+pub struct AliasDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct TraitDef(pub(crate) DefId);
+pub struct TraitDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct GenericDef(pub(crate) DefId);
+pub struct GenericDef(pub DefId);
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct ConstDef(pub(crate) DefId);
+pub struct ConstDef(pub DefId);
+
+#[derive(Clone, PartialEq, Eq, Debug)]
+pub struct ImplDef(pub DefId);
 
 #[derive(Clone, PartialEq, Eq, Debug)]
-pub struct ImplDef(pub(crate) DefId);
+pub struct RegionDef(pub DefId);
 
 #[derive(Clone, Debug)]
 pub struct GenericArgs(pub Vec<GenericArgKind>);
@@ -286,7 +329,7 @@ pub enum BoundTyKind {
 
 #[derive(Clone, Debug)]
 pub enum BoundRegionKind {
-    BrAnon(Option<Span>),
+    BrAnon,
     BrNamed(BrNamedDef, String),
     BrEnv,
 }
@@ -333,7 +376,7 @@ pub type Bytes = Vec<Option<u8>>;
 pub type Size = usize;
 
 #[derive(Clone, Copy, PartialEq, Eq, Debug)]
-pub struct Prov(pub(crate) AllocId);
+pub struct Prov(pub AllocId);
 pub type Align = u64;
 pub type Promoted = u32;
 pub type InitMaskMaterialized = Vec<u64>;
diff --git a/compiler/rustc_smir/src/stable_mir/visitor.rs b/compiler/stable_mir/src/visitor.rs
index c86063d2ed6..96100958138 100644
--- a/compiler/rustc_smir/src/stable_mir/visitor.rs
+++ b/compiler/stable_mir/src/visitor.rs
@@ -1,10 +1,10 @@
 use std::ops::ControlFlow;
 
-use crate::rustc_internal::Opaque;
+use crate::Opaque;
 
 use super::ty::{
     Allocation, Binder, Const, ConstDef, ExistentialPredicate, FnSig, GenericArgKind, GenericArgs,
-    Promoted, RigidTy, TermKind, Ty, UnevaluatedConst,
+    Promoted, Region, RigidTy, TermKind, Ty, UnevaluatedConst,
 };
 
 pub trait Visitor: Sized {
@@ -15,6 +15,9 @@ pub trait Visitor: Sized {
     fn visit_const(&mut self, c: &Const) -> ControlFlow<Self::Break> {
         c.super_visit(self)
     }
+    fn visit_reg(&mut self, reg: &Region) -> ControlFlow<Self::Break> {
+        reg.super_visit(self)
+    }
 }
 
 pub trait Visitable {
@@ -101,6 +104,16 @@ impl Visitable for GenericArgs {
     }
 }
 
+impl Visitable for Region {
+    fn visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
+        visitor.visit_reg(self)
+    }
+
+    fn super_visit<V: Visitor>(&self, _: &mut V) -> ControlFlow<V::Break> {
+        ControlFlow::Continue(())
+    }
+}
+
 impl Visitable for GenericArgKind {
     fn super_visit<V: Visitor>(&self, visitor: &mut V) -> ControlFlow<V::Break> {
         match self {
@@ -128,7 +141,10 @@ impl Visitable for RigidTy {
             }
             RigidTy::Slice(inner) => inner.visit(visitor),
             RigidTy::RawPtr(ty, _) => ty.visit(visitor),
-            RigidTy::Ref(_, ty, _) => ty.visit(visitor),
+            RigidTy::Ref(reg, ty, _) => {
+                reg.visit(visitor);
+                ty.visit(visitor)
+            }
             RigidTy::FnDef(_, args) => args.visit(visitor),
             RigidTy::FnPtr(sig) => sig.visit(visitor),
             RigidTy::Closure(_, args) => args.visit(visitor),
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 0fb06b16655..8dbaca223aa 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -2409,6 +2409,27 @@ impl<T> From<T> for Rc<T> {
 }
 
 #[cfg(not(no_global_oom_handling))]
+#[stable(feature = "shared_from_array", since = "CURRENT_RUSTC_VERSION")]
+impl<T, const N: usize> From<[T; N]> for Rc<[T]> {
+    /// Converts a [`[T; N]`](prim@array) into an `Rc<[T]>`.
+    ///
+    /// The conversion moves the array into a newly allocated `Rc`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use std::rc::Rc;
+    /// let original: [i32; 3] = [1, 2, 3];
+    /// let shared: Rc<[i32]> = Rc::from(original);
+    /// assert_eq!(&[1, 2, 3], &shared[..]);
+    /// ```
+    #[inline]
+    fn from(v: [T; N]) -> Rc<[T]> {
+        Rc::<[T; N]>::from(v)
+    }
+}
+
+#[cfg(not(no_global_oom_handling))]
 #[stable(feature = "shared_from_slice", since = "1.21.0")]
 impl<T: Clone> From<&[T]> for Rc<[T]> {
     /// Allocate a reference-counted slice and fill it by cloning `v`'s items.
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index c53e9a5dd7a..61f4bfc54b0 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -1618,7 +1618,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
     #[must_use]
     #[stable(feature = "arc_counts", since = "1.15.0")]
     pub fn weak_count(this: &Self) -> usize {
-        let cnt = this.inner().weak.load(Acquire);
+        let cnt = this.inner().weak.load(Relaxed);
         // If the weak count is currently locked, the value of the
         // count was 0 just before taking the lock.
         if cnt == usize::MAX { 0 } else { cnt - 1 }
@@ -1648,7 +1648,7 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
     #[must_use]
     #[stable(feature = "arc_counts", since = "1.15.0")]
     pub fn strong_count(this: &Self) -> usize {
-        this.inner().strong.load(Acquire)
+        this.inner().strong.load(Relaxed)
     }
 
     /// Increments the strong reference count on the `Arc<T>` associated with the
@@ -2803,7 +2803,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
     #[must_use]
     #[stable(feature = "weak_counts", since = "1.41.0")]
     pub fn strong_count(&self) -> usize {
-        if let Some(inner) = self.inner() { inner.strong.load(Acquire) } else { 0 }
+        if let Some(inner) = self.inner() { inner.strong.load(Relaxed) } else { 0 }
     }
 
     /// Gets an approximation of the number of `Weak` pointers pointing to this
@@ -2822,7 +2822,7 @@ impl<T: ?Sized, A: Allocator> Weak<T, A> {
     pub fn weak_count(&self) -> usize {
         if let Some(inner) = self.inner() {
             let weak = inner.weak.load(Acquire);
-            let strong = inner.strong.load(Acquire);
+            let strong = inner.strong.load(Relaxed);
             if strong == 0 {
                 0
             } else {
@@ -3270,6 +3270,27 @@ impl<T> From<T> for Arc<T> {
 }
 
 #[cfg(not(no_global_oom_handling))]
+#[stable(feature = "shared_from_array", since = "CURRENT_RUSTC_VERSION")]
+impl<T, const N: usize> From<[T; N]> for Arc<[T]> {
+    /// Converts a [`[T; N]`](prim@array) into an `Arc<[T]>`.
+    ///
+    /// The conversion moves the array into a newly allocated `Arc`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// # use std::sync::Arc;
+    /// let original: [i32; 3] = [1, 2, 3];
+    /// let shared: Arc<[i32]> = Arc::from(original);
+    /// assert_eq!(&[1, 2, 3], &shared[..]);
+    /// ```
+    #[inline]
+    fn from(v: [T; N]) -> Arc<[T]> {
+        Arc::<[T; N]>::from(v)
+    }
+}
+
+#[cfg(not(no_global_oom_handling))]
 #[stable(feature = "shared_from_slice", since = "1.21.0")]
 impl<T: Clone> From<&[T]> for Arc<[T]> {
     /// Allocate a reference-counted slice and fill it by cloning `v`'s items.
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 02331db3341..6f0cd5316a0 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -3155,6 +3155,36 @@ impl<T: Clone> From<&mut [T]> for Vec<T> {
 }
 
 #[cfg(not(no_global_oom_handling))]
+#[stable(feature = "vec_from_array_ref", since = "CURRENT_RUSTC_VERSION")]
+impl<T: Clone, const N: usize> From<&[T; N]> for Vec<T> {
+    /// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!(Vec::from(&[1, 2, 3]), vec![1, 2, 3]);
+    /// ```
+    fn from(s: &[T; N]) -> Vec<T> {
+        Self::from(s.as_slice())
+    }
+}
+
+#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "vec_from_array_ref", since = "CURRENT_RUSTC_VERSION")]
+impl<T: Clone, const N: usize> From<&mut [T; N]> for Vec<T> {
+    /// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]);
+    /// ```
+    fn from(s: &mut [T; N]) -> Vec<T> {
+        Self::from(s.as_mut_slice())
+    }
+}
+
+#[cfg(not(no_global_oom_handling))]
 #[stable(feature = "vec_from_array", since = "1.44.0")]
 impl<T, const N: usize> From<[T; N]> for Vec<T> {
     /// Allocate a `Vec<T>` and move `s`'s items into it.
diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs
index 9cb27899f10..d44dcfbf673 100644
--- a/library/alloc/tests/vec.rs
+++ b/library/alloc/tests/vec.rs
@@ -2562,3 +2562,13 @@ fn test_box_zero_allocator() {
     // Ensure all ZSTs have been freed.
     assert!(alloc.state.borrow().0.is_empty());
 }
+
+#[test]
+fn test_vec_from_array_ref() {
+    assert_eq!(Vec::from(&[1, 2, 3]), vec![1, 2, 3]);
+}
+
+#[test]
+fn test_vec_from_array_mut_ref() {
+    assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]);
+}
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 33226b07e04..36080616767 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -291,9 +291,9 @@ pub macro PartialEq($item:item) {
 #[stable(feature = "rust1", since = "1.0.0")]
 #[rustc_diagnostic_item = "Eq"]
 pub trait Eq: PartialEq<Self> {
-    // this method is used solely by #[deriving] to assert
-    // that every component of a type implements #[deriving]
-    // itself, the current deriving infrastructure means doing this
+    // this method is used solely by #[derive(Eq)] to assert
+    // that every component of a type implements `Eq`
+    // itself. The current deriving infrastructure means doing this
     // assertion without using a method on this trait is nearly
     // impossible.
     //
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index 8204b3855bd..fc91d1afc43 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -112,9 +112,9 @@ pub trait Write {
     ///
     /// # Errors
     ///
-    /// This function will return an instance of [`Error`] on error.
+    /// This function will return an instance of [`std::fmt::Error`][Error] on error.
     ///
-    /// The purpose of std::fmt::Error is to abort the formatting operation when the underlying
+    /// The purpose of that error is to abort the formatting operation when the underlying
     /// destination encounters some error preventing it from accepting more text; it should
     /// generally be propagated rather than handled, at least when implementing formatting traits.
     ///
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 8b04bafcda5..be734a9ba52 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -178,6 +178,7 @@
 #![feature(ip)]
 #![feature(ip_bits)]
 #![feature(is_ascii_octdigit)]
+#![feature(isqrt)]
 #![feature(maybe_uninit_uninit_array)]
 #![feature(ptr_alignment_type)]
 #![feature(ptr_metadata)]
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 646100fe27b..c27be8d2ffd 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -321,6 +321,95 @@ pub macro debug_assert_matches($($arg:tt)*) {
     }
 }
 
+/// A macro for defining `#[cfg]` match-like statements.
+///
+/// It is similar to the `if/elif` C preprocessor macro by allowing definition of a cascade of
+/// `#[cfg]` cases, emitting the implementation which matches first.
+///
+/// This allows you to conveniently provide a long list `#[cfg]`'d blocks of code
+/// without having to rewrite each clause multiple times.
+///
+/// Trailing `_` wildcard match arms are **optional** and they indicate a fallback branch when
+/// all previous declarations do not evaluate to true.
+///
+/// # Example
+///
+/// ```
+/// #![feature(cfg_match)]
+///
+/// cfg_match! {
+///     cfg(unix) => {
+///         fn foo() { /* unix specific functionality */ }
+///     }
+///     cfg(target_pointer_width = "32") => {
+///         fn foo() { /* non-unix, 32-bit functionality */ }
+///     }
+///     _ => {
+///         fn foo() { /* fallback implementation */ }
+///     }
+/// }
+/// ```
+#[macro_export]
+#[unstable(feature = "cfg_match", issue = "115585")]
+#[rustc_diagnostic_item = "cfg_match"]
+macro_rules! cfg_match {
+    // with a final wildcard
+    (
+        $(cfg($initial_meta:meta) => { $($initial_tokens:item)* })+
+        _ => { $($extra_tokens:item)* }
+    ) => {
+        cfg_match! {
+            @__items ();
+            $((($initial_meta) ($($initial_tokens)*)),)+
+            (() ($($extra_tokens)*)),
+        }
+    };
+
+    // without a final wildcard
+    (
+        $(cfg($extra_meta:meta) => { $($extra_tokens:item)* })*
+    ) => {
+        cfg_match! {
+            @__items ();
+            $((($extra_meta) ($($extra_tokens)*)),)*
+        }
+    };
+
+    // Internal and recursive macro to emit all the items
+    //
+    // Collects all the previous cfgs in a list at the beginning, so they can be
+    // negated. After the semicolon is all the remaining items.
+    (@__items ($($_:meta,)*);) => {};
+    (
+        @__items ($($no:meta,)*);
+        (($($yes:meta)?) ($($tokens:item)*)),
+        $($rest:tt,)*
+    ) => {
+        // Emit all items within one block, applying an appropriate #[cfg]. The
+        // #[cfg] will require all `$yes` matchers specified and must also negate
+        // all previous matchers.
+        #[cfg(all(
+            $($yes,)?
+            not(any($($no),*))
+        ))]
+        cfg_match! { @__identity $($tokens)* }
+
+        // Recurse to emit all other items in `$rest`, and when we do so add all
+        // our `$yes` matchers to the list of `$no` matchers as future emissions
+        // will have to negate everything we just matched as well.
+        cfg_match! {
+            @__items ($($no,)* $($yes,)?);
+            $($rest,)*
+        }
+    };
+
+    // Internal macro to make __apply work out right for different match types,
+    // because of how macros match/expand stuff.
+    (@__identity $($tokens:item)*) => {
+        $($tokens)*
+    };
+}
+
 /// Returns whether the given expression matches any of the given patterns.
 ///
 /// Like in a `match` expression, the pattern can be optionally followed by `if`
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 5ec751e5168..5ed82e26a0a 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -986,11 +986,16 @@ pub trait Tuple {}
 pub trait PointerLike {}
 
 /// A marker for types which can be used as types of `const` generic parameters.
+///
+/// These types must have a proper equivalence relation (`Eq`) and it must be automatically
+/// derived (`StructuralPartialEq`). There's a hard-coded check in the compiler ensuring
+/// that all fields are also `ConstParamTy`, which implies that recursively, all fields
+/// are `StructuralPartialEq`.
 #[lang = "const_param_ty"]
 #[unstable(feature = "adt_const_params", issue = "95174")]
 #[rustc_on_unimplemented(message = "`{Self}` can't be used as a const parameter type")]
 #[allow(multiple_supertrait_upcastable)]
-pub trait ConstParamTy: StructuralEq + StructuralPartialEq {}
+pub trait ConstParamTy: StructuralEq + StructuralPartialEq + Eq {}
 
 /// Derive macro generating an impl of the trait `ConstParamTy`.
 #[rustc_builtin_macro]
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 1f43520e1b3..3cbb55af3bc 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -898,6 +898,30 @@ macro_rules! int_impl {
             acc.checked_mul(base)
         }
 
+        /// Returns the square root of the number, rounded down.
+        ///
+        /// Returns `None` if `self` is negative.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        /// ```
+        /// #![feature(isqrt)]
+        #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".checked_isqrt(), Some(3));")]
+        /// ```
+        #[unstable(feature = "isqrt", issue = "116226")]
+        #[rustc_const_unstable(feature = "isqrt", issue = "116226")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn checked_isqrt(self) -> Option<Self> {
+            if self < 0 {
+                None
+            } else {
+                Some((self as $UnsignedT).isqrt() as Self)
+            }
+        }
+
         /// Saturating integer addition. Computes `self + rhs`, saturating at the numeric
         /// bounds instead of overflowing.
         ///
@@ -2061,6 +2085,36 @@ macro_rules! int_impl {
             acc * base
         }
 
+        /// Returns the square root of the number, rounded down.
+        ///
+        /// # Panics
+        ///
+        /// This function will panic if `self` is negative.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        /// ```
+        /// #![feature(isqrt)]
+        #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")]
+        /// ```
+        #[unstable(feature = "isqrt", issue = "116226")]
+        #[rustc_const_unstable(feature = "isqrt", issue = "116226")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn isqrt(self) -> Self {
+            // I would like to implement it as
+            // ```
+            // self.checked_isqrt().expect("argument of integer square root must be non-negative")
+            // ```
+            // but `expect` is not yet stable as a `const fn`.
+            match self.checked_isqrt() {
+                Some(sqrt) => sqrt,
+                None => panic!("argument of integer square root must be non-negative"),
+            }
+        }
+
         /// Calculates the quotient of Euclidean division of `self` by `rhs`.
         ///
         /// This computes the integer `q` such that `self = q * rhs + r`, with
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index 23ca37817d4..a9c5312a1c0 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -1259,6 +1259,10 @@ macro_rules! uint_impl {
         /// This function exists, so that all operations
         /// are accounted for in the wrapping operations.
         ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is 0.
+        ///
         /// # Examples
         ///
         /// Basic usage:
@@ -1284,6 +1288,10 @@ macro_rules! uint_impl {
         /// definitions of division are equal, this
         /// is exactly equal to `self.wrapping_div(rhs)`.
         ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is 0.
+        ///
         /// # Examples
         ///
         /// Basic usage:
@@ -1307,6 +1315,10 @@ macro_rules! uint_impl {
         /// This function exists, so that all operations
         /// are accounted for in the wrapping operations.
         ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is 0.
+        ///
         /// # Examples
         ///
         /// Basic usage:
@@ -1333,6 +1345,10 @@ macro_rules! uint_impl {
         /// definitions of division are equal, this
         /// is exactly equal to `self.wrapping_rem(rhs)`.
         ///
+        /// # Panics
+        ///
+        /// This function will panic if `rhs` is 0.
+        ///
         /// # Examples
         ///
         /// Basic usage:
@@ -1979,6 +1995,54 @@ macro_rules! uint_impl {
             acc * base
         }
 
+        /// Returns the square root of the number, rounded down.
+        ///
+        /// # Examples
+        ///
+        /// Basic usage:
+        /// ```
+        /// #![feature(isqrt)]
+        #[doc = concat!("assert_eq!(10", stringify!($SelfT), ".isqrt(), 3);")]
+        /// ```
+        #[unstable(feature = "isqrt", issue = "116226")]
+        #[rustc_const_unstable(feature = "isqrt", issue = "116226")]
+        #[must_use = "this returns the result of the operation, \
+                      without modifying the original"]
+        #[inline]
+        pub const fn isqrt(self) -> Self {
+            if self < 2 {
+                return self;
+            }
+
+            // The algorithm is based on the one presented in
+            // <https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Binary_numeral_system_(base_2)>
+            // which cites as source the following C code:
+            // <https://web.archive.org/web/20120306040058/http://medialab.freaknet.org/martin/src/sqrt/sqrt.c>.
+
+            let mut op = self;
+            let mut res = 0;
+            let mut one = 1 << (self.ilog2() & !1);
+
+            while one != 0 {
+                if op >= res + one {
+                    op -= res + one;
+                    res = (res >> 1) + one;
+                } else {
+                    res >>= 1;
+                }
+                one >>= 2;
+            }
+
+            // SAFETY: the result is positive and fits in an integer with half as many bits.
+            // Inform the optimizer about it.
+            unsafe {
+                intrinsics::assume(0 < res);
+                intrinsics::assume(res < 1 << (Self::BITS / 2));
+            }
+
+            res
+        }
+
         /// Performs Euclidean division.
         ///
         /// Since, for the positive integers, all common
diff --git a/library/core/src/pin.rs b/library/core/src/pin.rs
index 6b319b4355c..94c682b615a 100644
--- a/library/core/src/pin.rs
+++ b/library/core/src/pin.rs
@@ -572,7 +572,10 @@ impl<P: Deref> Pin<P> {
     ///     // though we have previously pinned it! We have violated the pinning API contract.
     /// }
     /// ```
-    /// A value, once pinned, must remain pinned forever (unless its type implements `Unpin`).
+    /// A value, once pinned, must remain pinned until it is dropped (unless its type implements
+    /// `Unpin`). Because `Pin<&mut T>` does not own the value, dropping the `Pin` will not drop
+    /// the value and will not end the pinning contract. So moving the value after dropping the
+    /// `Pin<&mut T>` is still a violation of the API contract.
     ///
     /// Similarly, calling `Pin::new_unchecked` on an `Rc<T>` is unsafe because there could be
     /// aliases to the same data that are not subject to the pinning restrictions:
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index ee69d89a4b7..9af8f1228f0 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -607,7 +607,16 @@ impl<T: ?Sized> *const T {
     /// Calculates the distance between two pointers. The returned value is in
     /// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
     ///
-    /// This function is the inverse of [`offset`].
+    /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`,
+    /// except that it has a lot more opportunities for UB, in exchange for the compiler
+    /// better understanding what you are doing.
+    ///
+    /// The primary motivation of this method is for computing the `len` of an array/slice
+    /// of `T` that you are currently representing as a "start" and "end" pointer
+    /// (and "end" is "one past the end" of the array).
+    /// In that case, `end.offset_from(start)` gets you the length of the array.
+    ///
+    /// All of the following safety requirements are trivially satisfied for this usecase.
     ///
     /// [`offset`]: #method.offset
     ///
@@ -616,7 +625,7 @@ impl<T: ?Sized> *const T {
     /// If any of the following conditions are violated, the result is Undefined
     /// Behavior:
     ///
-    /// * Both the starting and other pointer must be either in bounds or one
+    /// * Both `self` and `origin` must be either in bounds or one
     ///   byte past the end of the same [allocated object].
     ///
     /// * Both pointers must be *derived from* a pointer to the same object.
@@ -646,6 +655,14 @@ impl<T: ?Sized> *const T {
     /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on
     /// such large allocations either.)
     ///
+    /// The requirement for pointers to be derived from the same allocated object is primarily
+    /// needed for `const`-compatibility: the distance between pointers into *different* allocated
+    /// objects is not known at compile-time. However, the requirement also exists at
+    /// runtime and may be exploited by optimizations. If you wish to compute the difference between
+    /// pointers that are not guaranteed to be from the same allocation, use `(self as isize -
+    /// origin as isize) / mem::size_of::<T>()`.
+    // FIXME: recommend `addr()` instead of `as usize` once that is stable.
+    ///
     /// [`add`]: #method.add
     /// [allocated object]: crate::ptr#allocated-object
     ///
@@ -703,7 +720,7 @@ impl<T: ?Sized> *const T {
     /// units of **bytes**.
     ///
     /// This is purely a convenience for casting to a `u8` pointer and
-    /// using [offset_from][pointer::offset_from] on it. See that method for
+    /// using [`offset_from`][pointer::offset_from] on it. See that method for
     /// documentation and safety requirements.
     ///
     /// For non-`Sized` pointees this operation considers only the data pointers,
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 6d623b82c1c..109c286929b 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -781,7 +781,16 @@ impl<T: ?Sized> *mut T {
     /// Calculates the distance between two pointers. The returned value is in
     /// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
     ///
-    /// This function is the inverse of [`offset`].
+    /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`,
+    /// except that it has a lot more opportunities for UB, in exchange for the compiler
+    /// better understanding what you are doing.
+    ///
+    /// The primary motivation of this method is for computing the `len` of an array/slice
+    /// of `T` that you are currently representing as a "start" and "end" pointer
+    /// (and "end" is "one past the end" of the array).
+    /// In that case, `end.offset_from(start)` gets you the length of the array.
+    ///
+    /// All of the following safety requirements are trivially satisfied for this usecase.
     ///
     /// [`offset`]: pointer#method.offset-1
     ///
@@ -790,7 +799,7 @@ impl<T: ?Sized> *mut T {
     /// If any of the following conditions are violated, the result is Undefined
     /// Behavior:
     ///
-    /// * Both the starting and other pointer must be either in bounds or one
+    /// * Both `self` and `origin` must be either in bounds or one
     ///   byte past the end of the same [allocated object].
     ///
     /// * Both pointers must be *derived from* a pointer to the same object.
@@ -820,6 +829,14 @@ impl<T: ?Sized> *mut T {
     /// (Note that [`offset`] and [`add`] also have a similar limitation and hence cannot be used on
     /// such large allocations either.)
     ///
+    /// The requirement for pointers to be derived from the same allocated object is primarily
+    /// needed for `const`-compatibility: the distance between pointers into *different* allocated
+    /// objects is not known at compile-time. However, the requirement also exists at
+    /// runtime and may be exploited by optimizations. If you wish to compute the difference between
+    /// pointers that are not guaranteed to be from the same allocation, use `(self as isize -
+    /// origin as isize) / mem::size_of::<T>()`.
+    // FIXME: recommend `addr()` instead of `as usize` once that is stable.
+    ///
     /// [`add`]: #method.add
     /// [allocated object]: crate::ptr#allocated-object
     ///
@@ -875,7 +892,7 @@ impl<T: ?Sized> *mut T {
     /// units of **bytes**.
     ///
     /// This is purely a convenience for casting to a `u8` pointer and
-    /// using [offset_from][pointer::offset_from] on it. See that method for
+    /// using [`offset_from`][pointer::offset_from] on it. See that method for
     /// documentation and safety requirements.
     ///
     /// For non-`Sized` pointees this operation considers only the data pointers,
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 0d635aced85..a19fcf93c4d 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -3410,7 +3410,7 @@ impl<T> [T] {
     /// assert_eq!(a, ['e', 'f', 'a', 'b', 'c', 'd']);
     /// ```
     ///
-    /// Rotate a subslice:
+    /// Rotating a subslice:
     ///
     /// ```
     /// let mut a = ['a', 'b', 'c', 'd', 'e', 'f'];
diff --git a/library/core/src/sync/exclusive.rs b/library/core/src/sync/exclusive.rs
index 3f3e19c55d4..ff538d55c60 100644
--- a/library/core/src/sync/exclusive.rs
+++ b/library/core/src/sync/exclusive.rs
@@ -2,6 +2,8 @@
 
 use core::fmt;
 use core::future::Future;
+use core::marker::Tuple;
+use core::ops::{Generator, GeneratorState};
 use core::pin::Pin;
 use core::task::{Context, Poll};
 
@@ -168,10 +170,52 @@ impl<T> From<T> for Exclusive<T> {
 }
 
 #[unstable(feature = "exclusive_wrapper", issue = "98407")]
-impl<T: Future + ?Sized> Future for Exclusive<T> {
+impl<F, Args> FnOnce<Args> for Exclusive<F>
+where
+    F: FnOnce<Args>,
+    Args: Tuple,
+{
+    type Output = F::Output;
+
+    extern "rust-call" fn call_once(self, args: Args) -> Self::Output {
+        self.into_inner().call_once(args)
+    }
+}
+
+#[unstable(feature = "exclusive_wrapper", issue = "98407")]
+impl<F, Args> FnMut<Args> for Exclusive<F>
+where
+    F: FnMut<Args>,
+    Args: Tuple,
+{
+    extern "rust-call" fn call_mut(&mut self, args: Args) -> Self::Output {
+        self.get_mut().call_mut(args)
+    }
+}
+
+#[unstable(feature = "exclusive_wrapper", issue = "98407")]
+impl<T> Future for Exclusive<T>
+where
+    T: Future + ?Sized,
+{
     type Output = T::Output;
+
     #[inline]
     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
         self.get_pin_mut().poll(cx)
     }
 }
+
+#[unstable(feature = "generator_trait", issue = "43122")] // also #98407
+impl<R, G> Generator<R> for Exclusive<G>
+where
+    G: Generator<R> + ?Sized,
+{
+    type Yield = G::Yield;
+    type Return = G::Return;
+
+    #[inline]
+    fn resume(self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
+        G::resume(self.get_pin_mut(), arg)
+    }
+}
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 17011b845cf..e4003a208bc 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -56,6 +56,7 @@
 #![feature(min_specialization)]
 #![feature(numfmt)]
 #![feature(num_midpoint)]
+#![feature(isqrt)]
 #![feature(step_trait)]
 #![feature(str_internals)]
 #![feature(std_internals)]
@@ -96,6 +97,7 @@
 #![feature(const_option_ext)]
 #![feature(const_result)]
 #![cfg_attr(target_has_atomic = "128", feature(integer_atomics))]
+#![cfg_attr(test, feature(cfg_match))]
 #![feature(int_roundings)]
 #![feature(slice_group_by)]
 #![feature(split_array)]
@@ -139,6 +141,7 @@ mod hash;
 mod intrinsics;
 mod iter;
 mod lazy;
+#[cfg(test)]
 mod macros;
 mod manually_drop;
 mod mem;
diff --git a/library/core/tests/macros.rs b/library/core/tests/macros.rs
index ff3632e3550..eb886def164 100644
--- a/library/core/tests/macros.rs
+++ b/library/core/tests/macros.rs
@@ -1,3 +1,25 @@
+trait Trait {
+    fn blah(&self);
+}
+
+#[allow(dead_code)]
+struct Struct;
+
+impl Trait for Struct {
+    cfg_match! {
+        cfg(feature = "blah") => {
+            fn blah(&self) {
+                unimplemented!();
+            }
+        }
+        _ => {
+            fn blah(&self) {
+                unimplemented!();
+            }
+        }
+    }
+}
+
 #[test]
 fn assert_eq_trailing_comma() {
     assert_eq!(1, 1,);
@@ -18,3 +40,135 @@ fn assert_ne_trailing_comma() {
 fn matches_leading_pipe() {
     matches!(1, | 1 | 2 | 3);
 }
+
+#[test]
+fn cfg_match_basic() {
+    cfg_match! {
+        cfg(target_pointer_width = "64") => { fn f0_() -> bool { true }}
+    }
+
+    cfg_match! {
+        cfg(unix) => { fn f1_() -> bool { true }}
+        cfg(any(target_os = "macos", target_os = "linux")) => { fn f1_() -> bool { false }}
+    }
+
+    cfg_match! {
+        cfg(target_pointer_width = "32") => { fn f2_() -> bool { false }}
+        cfg(target_pointer_width = "64") => { fn f2_() -> bool { true }}
+    }
+
+    cfg_match! {
+        cfg(target_pointer_width = "16") => { fn f3_() -> i32 { 1 }}
+        _ => { fn f3_() -> i32 { 2 }}
+    }
+
+    #[cfg(target_pointer_width = "64")]
+    assert!(f0_());
+
+    #[cfg(unix)]
+    assert!(f1_());
+
+    #[cfg(target_pointer_width = "32")]
+    assert!(!f2_());
+    #[cfg(target_pointer_width = "64")]
+    assert!(f2_());
+
+    #[cfg(not(target_pointer_width = "16"))]
+    assert_eq!(f3_(), 2);
+}
+
+#[test]
+fn cfg_match_debug_assertions() {
+    cfg_match! {
+        cfg(debug_assertions) => {
+            assert!(cfg!(debug_assertions));
+            assert_eq!(4, 2+2);
+        }
+        _ => {
+            assert!(cfg!(not(debug_assertions)));
+            assert_eq!(10, 5+5);
+        }
+    }
+}
+
+#[cfg(target_pointer_width = "64")]
+#[test]
+fn cfg_match_no_duplication_on_64() {
+    cfg_match! {
+        cfg(windows) => {
+            fn foo() {}
+        }
+        cfg(unix) => {
+            fn foo() {}
+        }
+        cfg(target_pointer_width = "64") => {
+            fn foo() {}
+        }
+    }
+    foo();
+}
+
+#[test]
+fn cfg_match_options() {
+    cfg_match! {
+        cfg(test) => {
+            use core::option::Option as Option2;
+            fn works1() -> Option2<u32> { Some(1) }
+        }
+        _ => { fn works1() -> Option<u32> { None } }
+    }
+
+    cfg_match! {
+        cfg(feature = "foo") => { fn works2() -> bool { false } }
+        cfg(test) => { fn works2() -> bool { true } }
+        _ => { fn works2() -> bool { false } }
+    }
+
+    cfg_match! {
+        cfg(feature = "foo") => { fn works3() -> bool { false } }
+        _ => { fn works3() -> bool { true } }
+    }
+
+    cfg_match! {
+        cfg(test) => {
+            use core::option::Option as Option3;
+            fn works4() -> Option3<u32> { Some(1) }
+        }
+    }
+
+    cfg_match! {
+        cfg(feature = "foo") => { fn works5() -> bool { false } }
+        cfg(test) => { fn works5() -> bool { true } }
+    }
+
+    assert!(works1().is_some());
+    assert!(works2());
+    assert!(works3());
+    assert!(works4().is_some());
+    assert!(works5());
+}
+
+#[test]
+fn cfg_match_two_functions() {
+    cfg_match! {
+        cfg(target_pointer_width = "64") => {
+            fn foo1() {}
+            fn bar1() {}
+        }
+        _ => {
+            fn foo2() {}
+            fn bar2() {}
+        }
+    }
+
+    #[cfg(target_pointer_width = "64")]
+    {
+        foo1();
+        bar1();
+    }
+    #[cfg(not(target_pointer_width = "64"))]
+    {
+        foo2();
+        bar2();
+    }
+}
diff --git a/library/core/tests/num/int_macros.rs b/library/core/tests/num/int_macros.rs
index 439bbe66997..165d9a29617 100644
--- a/library/core/tests/num/int_macros.rs
+++ b/library/core/tests/num/int_macros.rs
@@ -291,6 +291,38 @@ macro_rules! int_module {
             }
 
             #[test]
+            fn test_isqrt() {
+                assert_eq!($T::MIN.checked_isqrt(), None);
+                assert_eq!((-1 as $T).checked_isqrt(), None);
+                assert_eq!((0 as $T).isqrt(), 0 as $T);
+                assert_eq!((1 as $T).isqrt(), 1 as $T);
+                assert_eq!((2 as $T).isqrt(), 1 as $T);
+                assert_eq!((99 as $T).isqrt(), 9 as $T);
+                assert_eq!((100 as $T).isqrt(), 10 as $T);
+            }
+
+            #[cfg(not(miri))] // Miri is too slow
+            #[test]
+            fn test_lots_of_isqrt() {
+                let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T;
+                for n in 0..=n_max {
+                    let isqrt: $T = n.isqrt();
+
+                    assert!(isqrt.pow(2) <= n);
+                    let (square, overflow) = (isqrt + 1).overflowing_pow(2);
+                    assert!(overflow || square > n);
+                }
+
+                for n in ($T::MAX - 127)..=$T::MAX {
+                    let isqrt: $T = n.isqrt();
+
+                    assert!(isqrt.pow(2) <= n);
+                    let (square, overflow) = (isqrt + 1).overflowing_pow(2);
+                    assert!(overflow || square > n);
+                }
+            }
+
+            #[test]
             fn test_div_floor() {
                 let a: $T = 8;
                 let b = 3;
diff --git a/library/core/tests/num/uint_macros.rs b/library/core/tests/num/uint_macros.rs
index 7d6203db0b9..955440647eb 100644
--- a/library/core/tests/num/uint_macros.rs
+++ b/library/core/tests/num/uint_macros.rs
@@ -207,6 +207,35 @@ macro_rules! uint_module {
             }
 
             #[test]
+            fn test_isqrt() {
+                assert_eq!((0 as $T).isqrt(), 0 as $T);
+                assert_eq!((1 as $T).isqrt(), 1 as $T);
+                assert_eq!((2 as $T).isqrt(), 1 as $T);
+                assert_eq!((99 as $T).isqrt(), 9 as $T);
+                assert_eq!((100 as $T).isqrt(), 10 as $T);
+                assert_eq!($T::MAX.isqrt(), (1 << ($T::BITS / 2)) - 1);
+            }
+
+            #[cfg(not(miri))] // Miri is too slow
+            #[test]
+            fn test_lots_of_isqrt() {
+                let n_max: $T = (1024 * 1024).min($T::MAX as u128) as $T;
+                for n in 0..=n_max {
+                    let isqrt: $T = n.isqrt();
+
+                    assert!(isqrt.pow(2) <= n);
+                    assert!(isqrt + 1 == (1 as $T) << ($T::BITS / 2) || (isqrt + 1).pow(2) > n);
+                }
+
+                for n in ($T::MAX - 255)..=$T::MAX {
+                    let isqrt: $T = n.isqrt();
+
+                    assert!(isqrt.pow(2) <= n);
+                    assert!(isqrt + 1 == (1 as $T) << ($T::BITS / 2) || (isqrt + 1).pow(2) > n);
+                }
+            }
+
+            #[test]
             fn test_div_floor() {
                 assert_eq!((8 as $T).div_floor(3), 2);
             }
diff --git a/library/panic_abort/src/lib.rs b/library/panic_abort/src/lib.rs
index d675696f13f..6e097e2caf2 100644
--- a/library/panic_abort/src/lib.rs
+++ b/library/panic_abort/src/lib.rs
@@ -44,7 +44,8 @@ pub unsafe fn __rust_start_panic(_payload: &mut dyn PanicPayload) -> u32 {
             }
         } else if #[cfg(any(target_os = "hermit",
                             all(target_vendor = "fortanix", target_env = "sgx"),
-                            target_os = "xous"
+                            target_os = "xous",
+                            target_os = "uefi",
         ))] {
             unsafe fn abort() -> ! {
                 // call std::sys::abort_internal
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index d382fec9352..0a70c488aec 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -1337,6 +1337,13 @@ impl Literal {
         Literal::new(bridge::LitKind::Char, symbol, None)
     }
 
+    /// Byte character literal.
+    #[unstable(feature = "proc_macro_byte_character", issue = "115268")]
+    pub fn byte_character(byte: u8) -> Literal {
+        let string = [byte].escape_ascii().to_string();
+        Literal::new(bridge::LitKind::Byte, &string, None)
+    }
+
     /// Byte string literal.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn byte_string(bytes: &[u8]) -> Literal {
@@ -1411,7 +1418,15 @@ impl Literal {
                 let hashes = get_hashes_str(n);
                 f(&["br", hashes, "\"", symbol, "\"", hashes, suffix])
             }
-            _ => f(&[symbol, suffix]),
+            bridge::LitKind::CStr => f(&["c\"", symbol, "\"", suffix]),
+            bridge::LitKind::CStrRaw(n) => {
+                let hashes = get_hashes_str(n);
+                f(&["cr", hashes, "\"", symbol, "\"", hashes, suffix])
+            }
+
+            bridge::LitKind::Integer | bridge::LitKind::Float | bridge::LitKind::Err => {
+                f(&[symbol, suffix])
+            }
         })
     }
 }
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index e8f642586cd..965132bdedb 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -48,6 +48,10 @@ hermit-abi = { version = "0.3.2", features = ['rustc-dep-of-std'], public = true
 [target.'cfg(target_os = "wasi")'.dependencies]
 wasi = { version = "0.11.0", features = ['rustc-dep-of-std'], default-features = false }
 
+[target.'cfg(target_os = "uefi")'.dependencies]
+r-efi = { version = "4.2.0", features = ['rustc-dep-of-std']}
+r-efi-alloc = { version = "1.0.0", features = ['rustc-dep-of-std']}
+
 [features]
 backtrace = [
   "gimli-symbolize",
diff --git a/library/std/build.rs b/library/std/build.rs
index e5509504b84..36516978b7a 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -39,6 +39,7 @@ fn main() {
         || target.contains("nto")
         || target.contains("xous")
         || target.contains("hurd")
+        || target.contains("uefi")
         // See src/bootstrap/synthetic_targets.rs
         || env::var("RUSTC_BOOTSTRAP_SYNTHETIC_TARGET").is_ok()
     {
@@ -51,7 +52,6 @@ fn main() {
         // - mipsel-sony-psp
         // - nvptx64-nvidia-cuda
         // - arch=avr
-        // - uefi (x86_64-unknown-uefi, i686-unknown-uefi)
         // - JSON targets
         // - Any new targets that have not been explicitly added above.
         println!("cargo:rustc-cfg=feature=\"restricted-std\"");
diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs
index f63142ff01f..5966416e32a 100644
--- a/library/std/src/io/error.rs
+++ b/library/std/src/io/error.rs
@@ -1,14 +1,14 @@
 #[cfg(test)]
 mod tests;
 
-#[cfg(target_pointer_width = "64")]
+#[cfg(all(target_pointer_width = "64", not(target_os = "uefi")))]
 mod repr_bitpacked;
-#[cfg(target_pointer_width = "64")]
+#[cfg(all(target_pointer_width = "64", not(target_os = "uefi")))]
 use repr_bitpacked::Repr;
 
-#[cfg(not(target_pointer_width = "64"))]
+#[cfg(any(not(target_pointer_width = "64"), target_os = "uefi"))]
 mod repr_unpacked;
-#[cfg(not(target_pointer_width = "64"))]
+#[cfg(any(not(target_pointer_width = "64"), target_os = "uefi"))]
 use repr_unpacked::Repr;
 
 use crate::error;
diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs
index 7582c7444f0..604b795cd52 100644
--- a/library/std/src/io/mod.rs
+++ b/library/std/src/io/mod.rs
@@ -1236,22 +1236,22 @@ impl<'a> IoSliceMut<'a> {
     pub fn advance_slices(bufs: &mut &mut [IoSliceMut<'a>], n: usize) {
         // Number of buffers to remove.
         let mut remove = 0;
-        // Total length of all the to be removed buffers.
-        let mut accumulated_len = 0;
+        // Remaining length before reaching n.
+        let mut left = n;
         for buf in bufs.iter() {
-            if accumulated_len + buf.len() > n {
-                break;
-            } else {
-                accumulated_len += buf.len();
+            if let Some(remainder) = left.checked_sub(buf.len()) {
+                left = remainder;
                 remove += 1;
+            } else {
+                break;
             }
         }
 
         *bufs = &mut take(bufs)[remove..];
         if bufs.is_empty() {
-            assert!(n == accumulated_len, "advancing io slices beyond their length");
+            assert!(left == 0, "advancing io slices beyond their length");
         } else {
-            bufs[0].advance(n - accumulated_len)
+            bufs[0].advance(left);
         }
     }
 }
@@ -1379,22 +1379,25 @@ impl<'a> IoSlice<'a> {
     pub fn advance_slices(bufs: &mut &mut [IoSlice<'a>], n: usize) {
         // Number of buffers to remove.
         let mut remove = 0;
-        // Total length of all the to be removed buffers.
-        let mut accumulated_len = 0;
+        // Remaining length before reaching n. This prevents overflow
+        // that could happen if the length of slices in `bufs` were instead
+        // accumulated. Those slice may be aliased and, if they are large
+        // enough, their added length may overflow a `usize`.
+        let mut left = n;
         for buf in bufs.iter() {
-            if accumulated_len + buf.len() > n {
-                break;
-            } else {
-                accumulated_len += buf.len();
+            if let Some(remainder) = left.checked_sub(buf.len()) {
+                left = remainder;
                 remove += 1;
+            } else {
+                break;
             }
         }
 
         *bufs = &mut take(bufs)[remove..];
         if bufs.is_empty() {
-            assert!(n == accumulated_len, "advancing io slices beyond their length");
+            assert!(left == 0, "advancing io slices beyond their length");
         } else {
-            bufs[0].advance(n - accumulated_len)
+            bufs[0].advance(left);
         }
     }
 }
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 5e3249655b8..f1f0f8b1653 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -665,6 +665,9 @@ pub use core::{
 )]
 pub use core::concat_bytes;
 
+#[unstable(feature = "cfg_match", issue = "115585")]
+pub use core::cfg_match;
+
 #[stable(feature = "core_primitive", since = "1.43.0")]
 pub use core::primitive;
 
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index 24d16e64c86..11ad21515fd 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -142,6 +142,8 @@ pub mod solid;
 #[cfg(target_os = "tvos")]
 #[path = "ios/mod.rs"]
 pub(crate) mod tvos;
+#[cfg(target_os = "uefi")]
+pub mod uefi;
 #[cfg(target_os = "vita")]
 pub mod vita;
 #[cfg(target_os = "vxworks")]
diff --git a/library/std/src/os/uefi/env.rs b/library/std/src/os/uefi/env.rs
new file mode 100644
index 00000000000..5d082e7c113
--- /dev/null
+++ b/library/std/src/os/uefi/env.rs
@@ -0,0 +1,92 @@
+//! UEFI-specific extensions to the primitives in `std::env` module
+
+#![unstable(feature = "uefi_std", issue = "100499")]
+
+use crate::sync::atomic::{AtomicBool, AtomicPtr, Ordering};
+use crate::{ffi::c_void, ptr::NonNull};
+
+static SYSTEM_TABLE: AtomicPtr<c_void> = AtomicPtr::new(crate::ptr::null_mut());
+static IMAGE_HANDLE: AtomicPtr<c_void> = AtomicPtr::new(crate::ptr::null_mut());
+// Flag to check if BootServices are still valid.
+// Start with assuming that they are not available
+static BOOT_SERVICES_FLAG: AtomicBool = AtomicBool::new(false);
+
+/// Initializes the global System Table and Image Handle pointers.
+///
+/// The standard library requires access to the UEFI System Table and the Application Image Handle
+/// to operate. Those are provided to UEFI Applications via their application entry point. By
+/// calling `init_globals()`, those pointers are retained by the standard library for future use.
+/// Thus this function must be called before any of the standard library services are used.
+///
+/// The pointers are never exposed to any entity outside of this application and it is guaranteed
+/// that, once the application exited, these pointers are never dereferenced again.
+///
+/// Callers are required to ensure the pointers are valid for the entire lifetime of this
+/// application. In particular, UEFI Boot Services must not be exited while an application with the
+/// standard library is loaded.
+///
+/// # SAFETY
+/// Calling this function more than once will panic
+pub(crate) unsafe fn init_globals(handle: NonNull<c_void>, system_table: NonNull<c_void>) {
+    IMAGE_HANDLE
+        .compare_exchange(
+            crate::ptr::null_mut(),
+            handle.as_ptr(),
+            Ordering::Release,
+            Ordering::Acquire,
+        )
+        .unwrap();
+    SYSTEM_TABLE
+        .compare_exchange(
+            crate::ptr::null_mut(),
+            system_table.as_ptr(),
+            Ordering::Release,
+            Ordering::Acquire,
+        )
+        .unwrap();
+    BOOT_SERVICES_FLAG.store(true, Ordering::Release)
+}
+
+/// Get the SystemTable Pointer.
+/// If you want to use `BootServices` then please use [`boot_services`] as it performs some
+/// additional checks.
+///
+/// Note: This function panics if the System Table or Image Handle is not initialized
+pub fn system_table() -> NonNull<c_void> {
+    try_system_table().unwrap()
+}
+
+/// Get the ImageHandle Pointer.
+///
+/// Note: This function panics if the System Table or Image Handle is not initialized
+pub fn image_handle() -> NonNull<c_void> {
+    try_image_handle().unwrap()
+}
+
+/// Get the BootServices Pointer.
+/// This function also checks if `ExitBootServices` has already been called.
+pub fn boot_services() -> Option<NonNull<c_void>> {
+    if BOOT_SERVICES_FLAG.load(Ordering::Acquire) {
+        let system_table: NonNull<r_efi::efi::SystemTable> = try_system_table()?.cast();
+        let boot_services = unsafe { (*system_table.as_ptr()).boot_services };
+        NonNull::new(boot_services).map(|x| x.cast())
+    } else {
+        None
+    }
+}
+
+/// Get the SystemTable Pointer.
+/// This function is mostly intended for places where panic is not an option
+pub(crate) fn try_system_table() -> Option<NonNull<c_void>> {
+    NonNull::new(SYSTEM_TABLE.load(Ordering::Acquire))
+}
+
+/// Get the SystemHandle Pointer.
+/// This function is mostly intended for places where panicking is not an option
+pub(crate) fn try_image_handle() -> Option<NonNull<c_void>> {
+    NonNull::new(IMAGE_HANDLE.load(Ordering::Acquire))
+}
+
+pub(crate) fn disable_boot_services() {
+    BOOT_SERVICES_FLAG.store(false, Ordering::Release)
+}
diff --git a/library/std/src/os/uefi/mod.rs b/library/std/src/os/uefi/mod.rs
new file mode 100644
index 00000000000..8ef05eee1f4
--- /dev/null
+++ b/library/std/src/os/uefi/mod.rs
@@ -0,0 +1,8 @@
+//! Platform-specific extensions to `std` for UEFI.
+
+#![unstable(feature = "uefi_std", issue = "100499")]
+#![doc(cfg(target_os = "uefi"))]
+
+pub mod env;
+#[path = "../windows/ffi.rs"]
+pub mod ffi;
diff --git a/library/std/src/os/unix/io/mod.rs b/library/std/src/os/unix/io/mod.rs
index c12d89ed637..827278f8b26 100644
--- a/library/std/src/os/unix/io/mod.rs
+++ b/library/std/src/os/unix/io/mod.rs
@@ -6,7 +6,8 @@
 //!
 //! This module provides three types for representing file descriptors,
 //! with different ownership properties: raw, borrowed, and owned, which are
-//! analogous to types used for representing pointers. These types reflect the Unix version of [I/O safety].
+//! analogous to types used for representing pointers. These types reflect concepts of [I/O
+//! safety][io-safety] on Unix.
 //!
 //! | Type               | Analogous to |
 //! | ------------------ | ------------ |
@@ -17,8 +18,8 @@
 //! Like raw pointers, `RawFd` values are primitive values. And in new code,
 //! they should be considered unsafe to do I/O on (analogous to dereferencing
 //! them). Rust did not always provide this guidance, so existing code in the
-//! Rust ecosystem often doesn't mark `RawFd` usage as unsafe. Once the
-//! `io_safety` feature is stable, libraries will be encouraged to migrate,
+//! Rust ecosystem often doesn't mark `RawFd` usage as unsafe.
+//! Libraries are encouraged to migrate,
 //! either by adding `unsafe` to APIs that dereference `RawFd` values, or by
 //! using to `BorrowedFd` or `OwnedFd` instead.
 //!
@@ -54,6 +55,8 @@
 //! Like boxes, `OwnedFd` values conceptually own the resource they point to,
 //! and free (close) it when they are dropped.
 //!
+//! See the [`io` module docs][io-safety] for a general explanation of I/O safety.
+//!
 //! ## `/proc/self/mem` and similar OS features
 //!
 //! Some platforms have special files, such as `/proc/self/mem`, which
@@ -74,7 +77,7 @@
 //! necessary to use *sandboxing*, which is outside the scope of `std`.
 //!
 //! [`BorrowedFd<'a>`]: crate::os::unix::io::BorrowedFd
-//! [I/O safety]: crate::io#io-safety
+//! [io-safety]: crate::io#io-safety
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/library/std/src/os/unix/process.rs b/library/std/src/os/unix/process.rs
index 2b40b672d9f..5d9f7430ca2 100644
--- a/library/std/src/os/unix/process.rs
+++ b/library/std/src/os/unix/process.rs
@@ -434,6 +434,20 @@ impl From<crate::process::ChildStdin> for OwnedFd {
     }
 }
 
+/// Create a `ChildStdin` from the provided `OwnedFd`.
+///
+/// The provided file descriptor must point to a pipe
+/// with the `CLOEXEC` flag set.
+#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")]
+impl From<OwnedFd> for process::ChildStdin {
+    #[inline]
+    fn from(fd: OwnedFd) -> process::ChildStdin {
+        let fd = sys::fd::FileDesc::from_inner(fd);
+        let pipe = sys::pipe::AnonPipe::from_inner(fd);
+        process::ChildStdin::from_inner(pipe)
+    }
+}
+
 #[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for crate::process::ChildStdout {
     #[inline]
@@ -450,6 +464,20 @@ impl From<crate::process::ChildStdout> for OwnedFd {
     }
 }
 
+/// Create a `ChildStdout` from the provided `OwnedFd`.
+///
+/// The provided file descriptor must point to a pipe
+/// with the `CLOEXEC` flag set.
+#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")]
+impl From<OwnedFd> for process::ChildStdout {
+    #[inline]
+    fn from(fd: OwnedFd) -> process::ChildStdout {
+        let fd = sys::fd::FileDesc::from_inner(fd);
+        let pipe = sys::pipe::AnonPipe::from_inner(fd);
+        process::ChildStdout::from_inner(pipe)
+    }
+}
+
 #[stable(feature = "io_safety", since = "1.63.0")]
 impl AsFd for crate::process::ChildStderr {
     #[inline]
@@ -466,6 +494,20 @@ impl From<crate::process::ChildStderr> for OwnedFd {
     }
 }
 
+/// Create a `ChildStderr` from the provided `OwnedFd`.
+///
+/// The provided file descriptor must point to a pipe
+/// with the `CLOEXEC` flag set.
+#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")]
+impl From<OwnedFd> for process::ChildStderr {
+    #[inline]
+    fn from(fd: OwnedFd) -> process::ChildStderr {
+        let fd = sys::fd::FileDesc::from_inner(fd);
+        let pipe = sys::pipe::AnonPipe::from_inner(fd);
+        process::ChildStderr::from_inner(pipe)
+    }
+}
+
 /// Returns the OS-assigned process identifier associated with this process's parent.
 #[must_use]
 #[stable(feature = "unix_ppid", since = "1.27.0")]
diff --git a/library/std/src/os/windows/io/mod.rs b/library/std/src/os/windows/io/mod.rs
index 3d4bb96d458..3d3ae387886 100644
--- a/library/std/src/os/windows/io/mod.rs
+++ b/library/std/src/os/windows/io/mod.rs
@@ -6,7 +6,8 @@
 //!
 //! This module provides three types for representing raw handles and sockets
 //! with different ownership properties: raw, borrowed, and owned, which are
-//! analogous to types used for representing pointers. These types reflect the Windows version of [I/O safety].
+//! analogous to types used for representing pointers. These types reflect concepts of [I/O
+//! safety][io-safety] on Windows.
 //!
 //! | Type                   | Analogous to |
 //! | ---------------------- | ------------ |
@@ -23,8 +24,8 @@
 //! And in new code, they should be considered unsafe to do I/O on (analogous
 //! to dereferencing them). Rust did not always provide this guidance, so
 //! existing code in the Rust ecosystem often doesn't mark `RawHandle` and
-//! `RawSocket` usage as unsafe. Once the `io_safety` feature is stable,
-//! libraries will be encouraged to migrate, either by adding `unsafe` to APIs
+//! `RawSocket` usage as unsafe.
+//! Libraries are encouraged to migrate, either by adding `unsafe` to APIs
 //! that dereference `RawHandle` and `RawSocket` values, or by using to
 //! `BorrowedHandle`, `BorrowedSocket`, `OwnedHandle`, or `OwnedSocket`.
 //!
@@ -45,9 +46,11 @@
 //! Like boxes, `OwnedHandle` and `OwnedSocket` values conceptually own the
 //! resource they point to, and free (close) it when they are dropped.
 //!
+//! See the [`io` module docs][io-safety] for a general explanation of I/O safety.
+//!
 //! [`BorrowedHandle<'a>`]: crate::os::windows::io::BorrowedHandle
 //! [`BorrowedSocket<'a>`]: crate::os::windows::io::BorrowedSocket
-//! [I/O safety]: crate::io#io-safety
+//! [io-safety]: crate::io#io-safety
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/library/std/src/os/windows/io/socket.rs b/library/std/src/os/windows/io/socket.rs
index 6359835cad5..c80b9e28499 100644
--- a/library/std/src/os/windows/io/socket.rs
+++ b/library/std/src/os/windows/io/socket.rs
@@ -116,7 +116,7 @@ impl BorrowedSocket<'_> {
         let mut info = unsafe { mem::zeroed::<sys::c::WSAPROTOCOL_INFOW>() };
         let result = unsafe {
             sys::c::WSADuplicateSocketW(
-                self.as_raw_socket(),
+                self.as_raw_socket() as sys::c::SOCKET,
                 sys::c::GetCurrentProcessId(),
                 &mut info,
             )
@@ -134,7 +134,7 @@ impl BorrowedSocket<'_> {
         };
 
         if socket != sys::c::INVALID_SOCKET {
-            unsafe { Ok(OwnedSocket::from_raw_socket(socket)) }
+            unsafe { Ok(OwnedSocket::from_raw_socket(socket as RawSocket)) }
         } else {
             let error = unsafe { sys::c::WSAGetLastError() };
 
@@ -158,7 +158,7 @@ impl BorrowedSocket<'_> {
             }
 
             unsafe {
-                let socket = OwnedSocket::from_raw_socket(socket);
+                let socket = OwnedSocket::from_raw_socket(socket as RawSocket);
                 socket.set_no_inherit()?;
                 Ok(socket)
             }
@@ -211,7 +211,7 @@ impl Drop for OwnedSocket {
     #[inline]
     fn drop(&mut self) {
         unsafe {
-            let _ = sys::c::closesocket(self.socket);
+            let _ = sys::c::closesocket(self.socket as sys::c::SOCKET);
         }
     }
 }
diff --git a/library/std/src/os/windows/process.rs b/library/std/src/os/windows/process.rs
index 5d87216ff1b..94173825c4a 100644
--- a/library/std/src/os/windows/process.rs
+++ b/library/std/src/os/windows/process.rs
@@ -106,6 +106,45 @@ impl IntoRawHandle for process::ChildStderr {
     }
 }
 
+/// Create a `ChildStdin` from the provided `OwnedHandle`.
+///
+/// The provided handle must be asynchronous, as reading and
+/// writing from and to it is implemented using asynchronous APIs.
+#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")]
+impl From<OwnedHandle> for process::ChildStdin {
+    fn from(handle: OwnedHandle) -> process::ChildStdin {
+        let handle = sys::handle::Handle::from_inner(handle);
+        let pipe = sys::pipe::AnonPipe::from_inner(handle);
+        process::ChildStdin::from_inner(pipe)
+    }
+}
+
+/// Create a `ChildStdout` from the provided `OwnedHandle`.
+///
+/// The provided handle must be asynchronous, as reading and
+/// writing from and to it is implemented using asynchronous APIs.
+#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")]
+impl From<OwnedHandle> for process::ChildStdout {
+    fn from(handle: OwnedHandle) -> process::ChildStdout {
+        let handle = sys::handle::Handle::from_inner(handle);
+        let pipe = sys::pipe::AnonPipe::from_inner(handle);
+        process::ChildStdout::from_inner(pipe)
+    }
+}
+
+/// Create a `ChildStderr` from the provided `OwnedHandle`.
+///
+/// The provided handle must be asynchronous, as reading and
+/// writing from and to it is implemented using asynchronous APIs.
+#[stable(feature = "child_stream_from_fd", since = "CURRENT_RUSTC_VERSION")]
+impl From<OwnedHandle> for process::ChildStderr {
+    fn from(handle: OwnedHandle) -> process::ChildStderr {
+        let handle = sys::handle::Handle::from_inner(handle);
+        let pipe = sys::pipe::AnonPipe::from_inner(handle);
+        process::ChildStderr::from_inner(pipe)
+    }
+}
+
 /// Windows-specific extensions to [`process::ExitStatus`].
 ///
 /// This trait is sealed: it cannot be implemented outside the standard library.
diff --git a/library/std/src/process.rs b/library/std/src/process.rs
index 948862c2a7d..6cf3bd619b2 100644
--- a/library/std/src/process.rs
+++ b/library/std/src/process.rs
@@ -12,9 +12,9 @@
 //! use std::process::Command;
 //!
 //! let output = Command::new("echo")
-//!                      .arg("Hello world")
-//!                      .output()
-//!                      .expect("Failed to execute command");
+//!     .arg("Hello world")
+//!     .output()
+//!     .expect("Failed to execute command");
 //!
 //! assert_eq!(b"Hello world\n", output.stdout.as_slice());
 //! ```
@@ -154,12 +154,11 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
 /// use std::process::Command;
 ///
 /// let mut child = Command::new("/bin/cat")
-///                         .arg("file.txt")
-///                         .spawn()
-///                         .expect("failed to execute child");
+///     .arg("file.txt")
+///     .spawn()
+///     .expect("failed to execute child");
 ///
-/// let ecode = child.wait()
-///                  .expect("failed to wait on child");
+/// let ecode = child.wait().expect("failed to wait on child");
 ///
 /// assert!(ecode.success());
 /// ```
@@ -481,15 +480,15 @@ impl fmt::Debug for ChildStderr {
 ///
 /// let output = if cfg!(target_os = "windows") {
 ///     Command::new("cmd")
-///             .args(["/C", "echo hello"])
-///             .output()
-///             .expect("failed to execute process")
+///         .args(["/C", "echo hello"])
+///         .output()
+///         .expect("failed to execute process")
 /// } else {
 ///     Command::new("sh")
-///             .arg("-c")
-///             .arg("echo hello")
-///             .output()
-///             .expect("failed to execute process")
+///         .arg("-c")
+///         .arg("echo hello")
+///         .output()
+///         .expect("failed to execute process")
 /// };
 ///
 /// let hello = output.stdout;
@@ -502,8 +501,7 @@ impl fmt::Debug for ChildStderr {
 /// use std::process::Command;
 ///
 /// let mut echo_hello = Command::new("sh");
-/// echo_hello.arg("-c")
-///           .arg("echo hello");
+/// echo_hello.arg("-c").arg("echo hello");
 /// let hello_1 = echo_hello.output().expect("failed to execute process");
 /// let hello_2 = echo_hello.output().expect("failed to execute process");
 /// ```
@@ -576,8 +574,8 @@ impl Command {
     /// use std::process::Command;
     ///
     /// Command::new("sh")
-    ///         .spawn()
-    ///         .expect("sh command failed to start");
+    ///     .spawn()
+    ///     .expect("sh command failed to start");
     /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn new<S: AsRef<OsStr>>(program: S) -> Command {
@@ -620,10 +618,10 @@ impl Command {
     /// use std::process::Command;
     ///
     /// Command::new("ls")
-    ///         .arg("-l")
-    ///         .arg("-a")
-    ///         .spawn()
-    ///         .expect("ls command failed to start");
+    ///     .arg("-l")
+    ///     .arg("-a")
+    ///     .spawn()
+    ///     .expect("ls command failed to start");
     /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn arg<S: AsRef<OsStr>>(&mut self, arg: S) -> &mut Command {
@@ -650,9 +648,9 @@ impl Command {
     /// use std::process::Command;
     ///
     /// Command::new("ls")
-    ///         .args(["-l", "-a"])
-    ///         .spawn()
-    ///         .expect("ls command failed to start");
+    ///     .args(["-l", "-a"])
+    ///     .spawn()
+    ///     .expect("ls command failed to start");
     /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn args<I, S>(&mut self, args: I) -> &mut Command
@@ -688,9 +686,9 @@ impl Command {
     /// use std::process::Command;
     ///
     /// Command::new("ls")
-    ///         .env("PATH", "/bin")
-    ///         .spawn()
-    ///         .expect("ls command failed to start");
+    ///     .env("PATH", "/bin")
+    ///     .spawn()
+    ///     .expect("ls command failed to start");
     /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn env<K, V>(&mut self, key: K, val: V) -> &mut Command
@@ -731,12 +729,12 @@ impl Command {
     ///     ).collect();
     ///
     /// Command::new("printenv")
-    ///         .stdin(Stdio::null())
-    ///         .stdout(Stdio::inherit())
-    ///         .env_clear()
-    ///         .envs(&filtered_env)
-    ///         .spawn()
-    ///         .expect("printenv failed to start");
+    ///     .stdin(Stdio::null())
+    ///     .stdout(Stdio::inherit())
+    ///     .env_clear()
+    ///     .envs(&filtered_env)
+    ///     .spawn()
+    ///     .expect("printenv failed to start");
     /// ```
     #[stable(feature = "command_envs", since = "1.19.0")]
     pub fn envs<I, K, V>(&mut self, vars: I) -> &mut Command
@@ -772,9 +770,9 @@ impl Command {
     /// use std::process::Command;
     ///
     /// Command::new("ls")
-    ///         .env_remove("PATH")
-    ///         .spawn()
-    ///         .expect("ls command failed to start");
+    ///     .env_remove("PATH")
+    ///     .spawn()
+    ///     .expect("ls command failed to start");
     /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn env_remove<K: AsRef<OsStr>>(&mut self, key: K) -> &mut Command {
@@ -802,9 +800,9 @@ impl Command {
     /// use std::process::Command;
     ///
     /// Command::new("ls")
-    ///         .env_clear()
-    ///         .spawn()
-    ///         .expect("ls command failed to start");
+    ///     .env_clear()
+    ///     .spawn()
+    ///     .expect("ls command failed to start");
     /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn env_clear(&mut self) -> &mut Command {
@@ -830,9 +828,9 @@ impl Command {
     /// use std::process::Command;
     ///
     /// Command::new("ls")
-    ///         .current_dir("/bin")
-    ///         .spawn()
-    ///         .expect("ls command failed to start");
+    ///     .current_dir("/bin")
+    ///     .spawn()
+    ///     .expect("ls command failed to start");
     /// ```
     ///
     /// [`canonicalize`]: crate::fs::canonicalize
@@ -861,9 +859,9 @@ impl Command {
     /// use std::process::{Command, Stdio};
     ///
     /// Command::new("ls")
-    ///         .stdin(Stdio::null())
-    ///         .spawn()
-    ///         .expect("ls command failed to start");
+    ///     .stdin(Stdio::null())
+    ///     .spawn()
+    ///     .expect("ls command failed to start");
     /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn stdin<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
@@ -890,9 +888,9 @@ impl Command {
     /// use std::process::{Command, Stdio};
     ///
     /// Command::new("ls")
-    ///         .stdout(Stdio::null())
-    ///         .spawn()
-    ///         .expect("ls command failed to start");
+    ///     .stdout(Stdio::null())
+    ///     .spawn()
+    ///     .expect("ls command failed to start");
     /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn stdout<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
@@ -919,9 +917,9 @@ impl Command {
     /// use std::process::{Command, Stdio};
     ///
     /// Command::new("ls")
-    ///         .stderr(Stdio::null())
-    ///         .spawn()
-    ///         .expect("ls command failed to start");
+    ///     .stderr(Stdio::null())
+    ///     .spawn()
+    ///     .expect("ls command failed to start");
     /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn stderr<T: Into<Stdio>>(&mut self, cfg: T) -> &mut Command {
@@ -941,8 +939,8 @@ impl Command {
     /// use std::process::Command;
     ///
     /// Command::new("ls")
-    ///         .spawn()
-    ///         .expect("ls command failed to start");
+    ///     .spawn()
+    ///     .expect("ls command failed to start");
     /// ```
     #[stable(feature = "process", since = "1.0.0")]
     pub fn spawn(&mut self) -> io::Result<Child> {
@@ -963,9 +961,9 @@ impl Command {
     /// use std::process::Command;
     /// use std::io::{self, Write};
     /// let output = Command::new("/bin/cat")
-    ///                      .arg("file.txt")
-    ///                      .output()
-    ///                      .expect("failed to execute process");
+    ///     .arg("file.txt")
+    ///     .output()
+    ///     .expect("failed to execute process");
     ///
     /// println!("status: {}", output.status);
     /// io::stdout().write_all(&output.stdout).unwrap();
@@ -990,9 +988,9 @@ impl Command {
     /// use std::process::Command;
     ///
     /// let status = Command::new("/bin/cat")
-    ///                      .arg("file.txt")
-    ///                      .status()
-    ///                      .expect("failed to execute process");
+    ///     .arg("file.txt")
+    ///     .status()
+    ///     .expect("failed to execute process");
     ///
     /// println!("process finished with: {status}");
     ///
@@ -1618,9 +1616,9 @@ impl ExitStatus {
     /// use std::process::Command;
     ///
     /// let status = Command::new("ls")
-    ///                      .arg("/dev/nonexistent")
-    ///                      .status()
-    ///                      .expect("ls could not be executed");
+    ///     .arg("/dev/nonexistent")
+    ///     .status()
+    ///     .expect("ls could not be executed");
     ///
     /// println!("ls: {status}");
     /// status.exit_ok().expect_err("/dev/nonexistent could be listed!");
@@ -1640,9 +1638,9 @@ impl ExitStatus {
     /// use std::process::Command;
     ///
     /// let status = Command::new("mkdir")
-    ///                      .arg("projects")
-    ///                      .status()
-    ///                      .expect("failed to execute mkdir");
+    ///     .arg("projects")
+    ///     .status()
+    ///     .expect("failed to execute mkdir");
     ///
     /// if status.success() {
     ///     println!("'projects/' directory created");
@@ -1673,13 +1671,13 @@ impl ExitStatus {
     /// use std::process::Command;
     ///
     /// let status = Command::new("mkdir")
-    ///                      .arg("projects")
-    ///                      .status()
-    ///                      .expect("failed to execute mkdir");
+    ///     .arg("projects")
+    ///     .status()
+    ///     .expect("failed to execute mkdir");
     ///
     /// match status.code() {
     ///     Some(code) => println!("Exited with status code: {code}"),
-    ///     None       => println!("Process terminated by signal")
+    ///     None => println!("Process terminated by signal")
     /// }
     /// ```
     #[must_use]
@@ -1809,9 +1807,9 @@ impl ExitStatusError {
 }
 
 #[unstable(feature = "exit_status_error", issue = "84908")]
-impl Into<ExitStatus> for ExitStatusError {
-    fn into(self) -> ExitStatus {
-        ExitStatus(self.0.into())
+impl From<ExitStatusError> for ExitStatus {
+    fn from(error: ExitStatusError) -> Self {
+        Self(error.0.into())
     }
 }
 
diff --git a/library/std/src/sys/common/thread_local/mod.rs b/library/std/src/sys/common/thread_local/mod.rs
index 975509bd412..8b2c839f837 100644
--- a/library/std/src/sys/common/thread_local/mod.rs
+++ b/library/std/src/sys/common/thread_local/mod.rs
@@ -6,7 +6,7 @@
 // "static" is for single-threaded platforms where a global static is sufficient.
 
 cfg_if::cfg_if! {
-    if #[cfg(all(target_family = "wasm", not(target_feature = "atomics")))] {
+    if #[cfg(any(all(target_family = "wasm", not(target_feature = "atomics")), target_os = "uefi"))] {
         #[doc(hidden)]
         mod static_local;
         #[doc(hidden)]
diff --git a/library/std/src/sys/mod.rs b/library/std/src/sys/mod.rs
index 457eb782ccc..159ffe7ac96 100644
--- a/library/std/src/sys/mod.rs
+++ b/library/std/src/sys/mod.rs
@@ -47,6 +47,9 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "xous")] {
         mod xous;
         pub use self::xous::*;
+    } else if #[cfg(target_os = "uefi")] {
+        mod uefi;
+        pub use self::uefi::*;
     } else if #[cfg(all(target_vendor = "fortanix", target_env = "sgx"))] {
         mod sgx;
         pub use self::sgx::*;
@@ -114,4 +117,5 @@ pub fn log_wrapper<F: Fn(f64) -> f64>(n: f64, log_fn: F) -> f64 {
     log_fn(n)
 }
 
+#[cfg(not(target_os = "uefi"))]
 pub type RawOsError = i32;
diff --git a/library/std/src/sys/uefi/alloc.rs b/library/std/src/sys/uefi/alloc.rs
new file mode 100644
index 00000000000..789e3cbd81a
--- /dev/null
+++ b/library/std/src/sys/uefi/alloc.rs
@@ -0,0 +1,33 @@
+//! Global Allocator for UEFI.
+//! Uses [r-efi-alloc](https://crates.io/crates/r-efi-alloc)
+
+use crate::alloc::{GlobalAlloc, Layout, System};
+
+const MEMORY_TYPE: u32 = r_efi::efi::LOADER_DATA;
+
+#[stable(feature = "alloc_system_type", since = "1.28.0")]
+unsafe impl GlobalAlloc for System {
+    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
+        // Return null pointer if boot services are not available
+        if crate::os::uefi::env::boot_services().is_none() {
+            return crate::ptr::null_mut();
+        }
+
+        // If boot services is valid then SystemTable is not null.
+        let system_table = crate::os::uefi::env::system_table().as_ptr().cast();
+        // The caller must ensure non-0 layout
+        unsafe { r_efi_alloc::raw::alloc(system_table, layout, MEMORY_TYPE) }
+    }
+
+    unsafe fn dealloc(&self, ptr: *mut u8, layout: Layout) {
+        // Do nothing if boot services are not available
+        if crate::os::uefi::env::boot_services().is_none() {
+            return;
+        }
+
+        // If boot services is valid then SystemTable is not null.
+        let system_table = crate::os::uefi::env::system_table().as_ptr().cast();
+        // The caller must ensure non-0 layout
+        unsafe { r_efi_alloc::raw::dealloc(system_table, ptr, layout) }
+    }
+}
diff --git a/library/std/src/sys/uefi/env.rs b/library/std/src/sys/uefi/env.rs
new file mode 100644
index 00000000000..c106d5fed3e
--- /dev/null
+++ b/library/std/src/sys/uefi/env.rs
@@ -0,0 +1,9 @@
+pub mod os {
+    pub const FAMILY: &str = "";
+    pub const OS: &str = "uefi";
+    pub const DLL_PREFIX: &str = "";
+    pub const DLL_SUFFIX: &str = "";
+    pub const DLL_EXTENSION: &str = "";
+    pub const EXE_SUFFIX: &str = ".efi";
+    pub const EXE_EXTENSION: &str = "efi";
+}
diff --git a/library/std/src/sys/uefi/helpers.rs b/library/std/src/sys/uefi/helpers.rs
new file mode 100644
index 00000000000..126661bfc96
--- /dev/null
+++ b/library/std/src/sys/uefi/helpers.rs
@@ -0,0 +1,141 @@
+//! Contains most of the shared UEFI specific stuff. Some of this might be moved to `std::os::uefi`
+//! if needed but no point in adding extra public API when there is not Std support for UEFI in the
+//! first place
+//!
+//! Some Nomenclature
+//! * Protocol:
+//! - Protocols serve to enable communication between separately built modules, including drivers.
+//! - Every protocol has a GUID associated with it. The GUID serves as the name for the protocol.
+//! - Protocols are produced and consumed.
+//! - More information about protocols can be found [here](https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/3_foundation/36_protocols_and_handles)
+
+use r_efi::efi::{self, Guid};
+
+use crate::mem::{size_of, MaybeUninit};
+use crate::os::uefi;
+use crate::ptr::NonNull;
+use crate::{
+    io::{self, const_io_error},
+    os::uefi::env::boot_services,
+};
+
+const BOOT_SERVICES_UNAVAILABLE: io::Error =
+    const_io_error!(io::ErrorKind::Other, "Boot Services are no longer available");
+
+/// Locate Handles with a particular Protocol GUID
+/// Implemented using `EFI_BOOT_SERVICES.LocateHandles()`
+///
+/// Returns an array of [Handles](r_efi::efi::Handle) that support a specified protocol.
+pub(crate) fn locate_handles(mut guid: Guid) -> io::Result<Vec<NonNull<crate::ffi::c_void>>> {
+    fn inner(
+        guid: &mut Guid,
+        boot_services: NonNull<r_efi::efi::BootServices>,
+        buf_size: &mut usize,
+        buf: *mut r_efi::efi::Handle,
+    ) -> io::Result<()> {
+        let r = unsafe {
+            ((*boot_services.as_ptr()).locate_handle)(
+                r_efi::efi::BY_PROTOCOL,
+                guid,
+                crate::ptr::null_mut(),
+                buf_size,
+                buf,
+            )
+        };
+
+        if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
+    }
+
+    let boot_services = boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
+    let mut buf_len = 0usize;
+
+    // This should always fail since the size of buffer is 0. This call should update the buf_len
+    // variable with the required buffer length
+    match inner(&mut guid, boot_services, &mut buf_len, crate::ptr::null_mut()) {
+        Ok(()) => unreachable!(),
+        Err(e) => match e.kind() {
+            io::ErrorKind::FileTooLarge => {}
+            _ => return Err(e),
+        },
+    }
+
+    // The returned buf_len is in bytes
+    assert_eq!(buf_len % size_of::<r_efi::efi::Handle>(), 0);
+    let num_of_handles = buf_len / size_of::<r_efi::efi::Handle>();
+    let mut buf: Vec<r_efi::efi::Handle> = Vec::with_capacity(num_of_handles);
+    match inner(&mut guid, boot_services, &mut buf_len, buf.as_mut_ptr()) {
+        Ok(()) => {
+            // This is safe because the call will succeed only if buf_len >= required length.
+            // Also, on success, the `buf_len` is updated with the size of bufferv (in bytes) written
+            unsafe { buf.set_len(num_of_handles) };
+            Ok(buf.into_iter().filter_map(|x| NonNull::new(x)).collect())
+        }
+        Err(e) => Err(e),
+    }
+}
+
+/// Open Protocol on a handle.
+/// Internally just a call to `EFI_BOOT_SERVICES.OpenProtocol()`.
+///
+/// Queries a handle to determine if it supports a specified protocol. If the protocol is
+/// supported by the handle, it opens the protocol on behalf of the calling agent.
+pub(crate) fn open_protocol<T>(
+    handle: NonNull<crate::ffi::c_void>,
+    mut protocol_guid: Guid,
+) -> io::Result<NonNull<T>> {
+    let boot_services: NonNull<efi::BootServices> =
+        boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
+    let system_handle = uefi::env::image_handle();
+    let mut protocol: MaybeUninit<*mut T> = MaybeUninit::uninit();
+
+    let r = unsafe {
+        ((*boot_services.as_ptr()).open_protocol)(
+            handle.as_ptr(),
+            &mut protocol_guid,
+            protocol.as_mut_ptr().cast(),
+            system_handle.as_ptr(),
+            crate::ptr::null_mut(),
+            r_efi::system::OPEN_PROTOCOL_GET_PROTOCOL,
+        )
+    };
+
+    if r.is_error() {
+        Err(crate::io::Error::from_raw_os_error(r.as_usize()))
+    } else {
+        NonNull::new(unsafe { protocol.assume_init() })
+            .ok_or(const_io_error!(io::ErrorKind::Other, "null protocol"))
+    }
+}
+
+pub(crate) fn create_event(
+    signal: u32,
+    tpl: efi::Tpl,
+    handler: Option<efi::EventNotify>,
+    context: *mut crate::ffi::c_void,
+) -> io::Result<NonNull<crate::ffi::c_void>> {
+    let boot_services: NonNull<efi::BootServices> =
+        boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
+    let mut event: r_efi::efi::Event = crate::ptr::null_mut();
+    let r = unsafe {
+        let create_event = (*boot_services.as_ptr()).create_event;
+        (create_event)(signal, tpl, handler, context, &mut event)
+    };
+    if r.is_error() {
+        Err(crate::io::Error::from_raw_os_error(r.as_usize()))
+    } else {
+        NonNull::new(event).ok_or(const_io_error!(io::ErrorKind::Other, "null protocol"))
+    }
+}
+
+/// # SAFETY
+/// - The supplied event must be valid
+pub(crate) unsafe fn close_event(evt: NonNull<crate::ffi::c_void>) -> io::Result<()> {
+    let boot_services: NonNull<efi::BootServices> =
+        boot_services().ok_or(BOOT_SERVICES_UNAVAILABLE)?.cast();
+    let r = unsafe {
+        let close_event = (*boot_services.as_ptr()).close_event;
+        (close_event)(evt.as_ptr())
+    };
+
+    if r.is_error() { Err(crate::io::Error::from_raw_os_error(r.as_usize())) } else { Ok(()) }
+}
diff --git a/library/std/src/sys/uefi/mod.rs b/library/std/src/sys/uefi/mod.rs
new file mode 100644
index 00000000000..9a10395af8e
--- /dev/null
+++ b/library/std/src/sys/uefi/mod.rs
@@ -0,0 +1,244 @@
+//! Platform-specific extensions to `std` for UEFI platforms.
+//!
+//! Provides access to platform-level information on UEFI platforms, and
+//! exposes UEFI-specific functions that would otherwise be inappropriate as
+//! part of the core `std` library.
+//!
+//! It exposes more ways to deal with platform-specific strings ([`OsStr`],
+//! [`OsString`]), allows to set permissions more granularly, extract low-level
+//! file descriptors from files and sockets, and has platform-specific helpers
+//! for spawning processes.
+//!
+//! [`OsStr`]: crate::ffi::OsStr
+//! [`OsString`]: crate::ffi::OsString
+
+pub mod alloc;
+#[path = "../unsupported/args.rs"]
+pub mod args;
+#[path = "../unix/cmath.rs"]
+pub mod cmath;
+pub mod env;
+#[path = "../unsupported/fs.rs"]
+pub mod fs;
+#[path = "../unsupported/io.rs"]
+pub mod io;
+#[path = "../unsupported/locks/mod.rs"]
+pub mod locks;
+#[path = "../unsupported/net.rs"]
+pub mod net;
+#[path = "../unsupported/once.rs"]
+pub mod once;
+pub mod os;
+#[path = "../windows/os_str.rs"]
+pub mod os_str;
+pub mod path;
+#[path = "../unsupported/pipe.rs"]
+pub mod pipe;
+#[path = "../unsupported/process.rs"]
+pub mod process;
+#[path = "../unsupported/stdio.rs"]
+pub mod stdio;
+#[path = "../unsupported/thread.rs"]
+pub mod thread;
+#[path = "../unsupported/thread_local_key.rs"]
+pub mod thread_local_key;
+#[path = "../unsupported/thread_parking.rs"]
+pub mod thread_parking;
+#[path = "../unsupported/time.rs"]
+pub mod time;
+
+mod helpers;
+
+#[cfg(test)]
+mod tests;
+
+pub type RawOsError = usize;
+
+use crate::io as std_io;
+use crate::os::uefi;
+use crate::ptr::NonNull;
+use crate::sync::atomic::{AtomicPtr, Ordering};
+
+pub mod memchr {
+    pub use core::slice::memchr::{memchr, memrchr};
+}
+
+static EXIT_BOOT_SERVICE_EVENT: AtomicPtr<crate::ffi::c_void> =
+    AtomicPtr::new(crate::ptr::null_mut());
+
+/// # SAFETY
+/// - must be called only once during runtime initialization.
+/// - argc must be 2.
+/// - argv must be &[Handle, *mut SystemTable].
+pub(crate) unsafe fn init(argc: isize, argv: *const *const u8, _sigpipe: u8) {
+    assert_eq!(argc, 2);
+    let image_handle = unsafe { NonNull::new(*argv as *mut crate::ffi::c_void).unwrap() };
+    let system_table = unsafe { NonNull::new(*argv.add(1) as *mut crate::ffi::c_void).unwrap() };
+    unsafe { uefi::env::init_globals(image_handle, system_table) };
+
+    // Register exit boot services handler
+    match helpers::create_event(
+        r_efi::efi::EVT_SIGNAL_EXIT_BOOT_SERVICES,
+        r_efi::efi::TPL_NOTIFY,
+        Some(exit_boot_service_handler),
+        crate::ptr::null_mut(),
+    ) {
+        Ok(x) => {
+            if EXIT_BOOT_SERVICE_EVENT
+                .compare_exchange(
+                    crate::ptr::null_mut(),
+                    x.as_ptr(),
+                    Ordering::Release,
+                    Ordering::Acquire,
+                )
+                .is_err()
+            {
+                abort_internal();
+            };
+        }
+        Err(_) => abort_internal(),
+    }
+}
+
+/// # SAFETY
+/// this is not guaranteed to run, for example when the program aborts.
+/// - must be called only once during runtime cleanup.
+pub unsafe fn cleanup() {
+    if let Some(exit_boot_service_event) =
+        NonNull::new(EXIT_BOOT_SERVICE_EVENT.swap(crate::ptr::null_mut(), Ordering::Acquire))
+    {
+        let _ = unsafe { helpers::close_event(exit_boot_service_event) };
+    }
+}
+
+#[inline]
+pub const fn unsupported<T>() -> std_io::Result<T> {
+    Err(unsupported_err())
+}
+
+#[inline]
+pub const fn unsupported_err() -> std_io::Error {
+    std_io::const_io_error!(std_io::ErrorKind::Unsupported, "operation not supported on UEFI",)
+}
+
+pub fn decode_error_kind(code: RawOsError) -> crate::io::ErrorKind {
+    use crate::io::ErrorKind;
+    use r_efi::efi::Status;
+
+    match r_efi::efi::Status::from_usize(code) {
+        Status::ALREADY_STARTED
+        | Status::COMPROMISED_DATA
+        | Status::CONNECTION_FIN
+        | Status::CRC_ERROR
+        | Status::DEVICE_ERROR
+        | Status::END_OF_MEDIA
+        | Status::HTTP_ERROR
+        | Status::ICMP_ERROR
+        | Status::INCOMPATIBLE_VERSION
+        | Status::LOAD_ERROR
+        | Status::MEDIA_CHANGED
+        | Status::NO_MAPPING
+        | Status::NO_MEDIA
+        | Status::NOT_STARTED
+        | Status::PROTOCOL_ERROR
+        | Status::PROTOCOL_UNREACHABLE
+        | Status::TFTP_ERROR
+        | Status::VOLUME_CORRUPTED => ErrorKind::Other,
+        Status::BAD_BUFFER_SIZE | Status::INVALID_LANGUAGE => ErrorKind::InvalidData,
+        Status::ABORTED => ErrorKind::ConnectionAborted,
+        Status::ACCESS_DENIED => ErrorKind::PermissionDenied,
+        Status::BUFFER_TOO_SMALL => ErrorKind::FileTooLarge,
+        Status::CONNECTION_REFUSED => ErrorKind::ConnectionRefused,
+        Status::CONNECTION_RESET => ErrorKind::ConnectionReset,
+        Status::END_OF_FILE => ErrorKind::UnexpectedEof,
+        Status::HOST_UNREACHABLE => ErrorKind::HostUnreachable,
+        Status::INVALID_PARAMETER => ErrorKind::InvalidInput,
+        Status::IP_ADDRESS_CONFLICT => ErrorKind::AddrInUse,
+        Status::NETWORK_UNREACHABLE => ErrorKind::NetworkUnreachable,
+        Status::NO_RESPONSE => ErrorKind::HostUnreachable,
+        Status::NOT_FOUND => ErrorKind::NotFound,
+        Status::NOT_READY => ErrorKind::ResourceBusy,
+        Status::OUT_OF_RESOURCES => ErrorKind::OutOfMemory,
+        Status::SECURITY_VIOLATION => ErrorKind::PermissionDenied,
+        Status::TIMEOUT => ErrorKind::TimedOut,
+        Status::UNSUPPORTED => ErrorKind::Unsupported,
+        Status::VOLUME_FULL => ErrorKind::StorageFull,
+        Status::WRITE_PROTECTED => ErrorKind::ReadOnlyFilesystem,
+        _ => ErrorKind::Uncategorized,
+    }
+}
+
+pub fn abort_internal() -> ! {
+    if let Some(exit_boot_service_event) =
+        NonNull::new(EXIT_BOOT_SERVICE_EVENT.load(Ordering::Acquire))
+    {
+        let _ = unsafe { helpers::close_event(exit_boot_service_event) };
+    }
+
+    if let (Some(boot_services), Some(handle)) =
+        (uefi::env::boot_services(), uefi::env::try_image_handle())
+    {
+        let boot_services: NonNull<r_efi::efi::BootServices> = boot_services.cast();
+        let _ = unsafe {
+            ((*boot_services.as_ptr()).exit)(
+                handle.as_ptr(),
+                r_efi::efi::Status::ABORTED,
+                0,
+                crate::ptr::null_mut(),
+            )
+        };
+    }
+
+    // In case SystemTable and ImageHandle cannot be reached, use `core::intrinsics::abort`
+    core::intrinsics::abort();
+}
+
+// This function is needed by the panic runtime. The symbol is named in
+// pre-link args for the target specification, so keep that in sync.
+#[cfg(not(test))]
+#[no_mangle]
+pub extern "C" fn __rust_abort() {
+    abort_internal();
+}
+
+#[inline]
+pub fn hashmap_random_keys() -> (u64, u64) {
+    get_random().unwrap()
+}
+
+fn get_random() -> Option<(u64, u64)> {
+    use r_efi::protocols::rng;
+
+    let mut buf = [0u8; 16];
+    let handles = helpers::locate_handles(rng::PROTOCOL_GUID).ok()?;
+    for handle in handles {
+        if let Ok(protocol) = helpers::open_protocol::<rng::Protocol>(handle, rng::PROTOCOL_GUID) {
+            let r = unsafe {
+                ((*protocol.as_ptr()).get_rng)(
+                    protocol.as_ptr(),
+                    crate::ptr::null_mut(),
+                    buf.len(),
+                    buf.as_mut_ptr(),
+                )
+            };
+            if r.is_error() {
+                continue;
+            } else {
+                return Some((
+                    u64::from_le_bytes(buf[..8].try_into().ok()?),
+                    u64::from_le_bytes(buf[8..].try_into().ok()?),
+                ));
+            }
+        }
+    }
+    None
+}
+
+/// Disable access to BootServices if `EVT_SIGNAL_EXIT_BOOT_SERVICES` is signaled
+extern "efiapi" fn exit_boot_service_handler(_e: r_efi::efi::Event, _ctx: *mut crate::ffi::c_void) {
+    uefi::env::disable_boot_services();
+}
+
+pub fn is_interrupted(_code: RawOsError) -> bool {
+    false
+}
diff --git a/library/std/src/sys/uefi/os.rs b/library/std/src/sys/uefi/os.rs
new file mode 100644
index 00000000000..e6693db68e6
--- /dev/null
+++ b/library/std/src/sys/uefi/os.rs
@@ -0,0 +1,237 @@
+use super::{unsupported, RawOsError};
+use crate::error::Error as StdError;
+use crate::ffi::{OsStr, OsString};
+use crate::fmt;
+use crate::io;
+use crate::marker::PhantomData;
+use crate::os::uefi;
+use crate::path::{self, PathBuf};
+use crate::ptr::NonNull;
+use r_efi::efi::Status;
+
+pub fn errno() -> RawOsError {
+    0
+}
+
+pub fn error_string(errno: RawOsError) -> String {
+    // Keep the List in Alphabetical Order
+    // The Messages are taken from UEFI Specification Appendix D - Status Codes
+    match r_efi::efi::Status::from_usize(errno) {
+        Status::ABORTED => "The operation was aborted.".to_owned(),
+        Status::ACCESS_DENIED => "Access was denied.".to_owned(),
+        Status::ALREADY_STARTED => "The protocol has already been started.".to_owned(),
+        Status::BAD_BUFFER_SIZE => "The buffer was not the proper size for the request.".to_owned(),
+        Status::BUFFER_TOO_SMALL => {
+                "The buffer is not large enough to hold the requested data. The required buffer size is returned in the appropriate parameter when this error occurs.".to_owned()
+        }
+        Status::COMPROMISED_DATA => {
+                "The security status of the data is unknown or compromised and the data must be updated or replaced to restore a valid security status.".to_owned()
+        }
+        Status::CONNECTION_FIN => {
+                "The receiving operation fails because the communication peer has closed the connection and there is no more data in the receive buffer of the instance.".to_owned()
+        }
+        Status::CONNECTION_REFUSED => {
+                "The receiving or transmission operation fails because this connection is refused.".to_owned()
+        }
+        Status::CONNECTION_RESET => {
+                "The connect fails because the connection is reset either by instance itself or the communication peer.".to_owned()
+        }
+        Status::CRC_ERROR => "A CRC error was detected.".to_owned(),
+        Status::DEVICE_ERROR =>             "The physical device reported an error while attempting the operation.".to_owned()
+        ,
+        Status::END_OF_FILE => {
+            "The end of the file was reached.".to_owned()
+        }
+        Status::END_OF_MEDIA => {
+            "Beginning or end of media was reached".to_owned()
+        }
+        Status::HOST_UNREACHABLE => {
+            "The remote host is not reachable.".to_owned()
+        }
+        Status::HTTP_ERROR => {
+            "A HTTP error occurred during the network operation.".to_owned()
+        }
+        Status::ICMP_ERROR => {
+                "An ICMP error occurred during the network operation.".to_owned()
+        }
+        Status::INCOMPATIBLE_VERSION => {
+                "The function encountered an internal version that was incompatible with a version requested by the caller.".to_owned()
+        }
+        Status::INVALID_LANGUAGE => {
+            "The language specified was invalid.".to_owned()
+        }
+        Status::INVALID_PARAMETER => {
+            "A parameter was incorrect.".to_owned()
+        }
+        Status::IP_ADDRESS_CONFLICT => {
+            "There is an address conflict address allocation".to_owned()
+        }
+        Status::LOAD_ERROR => {
+            "The image failed to load.".to_owned()
+        }
+        Status::MEDIA_CHANGED => {
+                "The medium in the device has changed since the last access.".to_owned()
+        }
+        Status::NETWORK_UNREACHABLE => {
+                "The network containing the remote host is not reachable.".to_owned()
+        }
+        Status::NO_MAPPING => {
+            "A mapping to a device does not exist.".to_owned()
+        }
+        Status::NO_MEDIA => {
+                "The device does not contain any medium to perform the operation.".to_owned()
+        }
+        Status::NO_RESPONSE => {
+                "The server was not found or did not respond to the request.".to_owned()
+        }
+        Status::NOT_FOUND => "The item was not found.".to_owned(),
+        Status::NOT_READY => {
+            "There is no data pending upon return.".to_owned()
+        }
+        Status::NOT_STARTED => {
+            "The protocol has not been started.".to_owned()
+        }
+        Status::OUT_OF_RESOURCES => {
+            "A resource has run out.".to_owned()
+        }
+        Status::PROTOCOL_ERROR => {
+                "A protocol error occurred during the network operation.".to_owned()
+        }
+        Status::PROTOCOL_UNREACHABLE => {
+            "An ICMP protocol unreachable error is received.".to_owned()
+        }
+        Status::SECURITY_VIOLATION => {
+                "The function was not performed due to a security violation.".to_owned()
+        }
+        Status::TFTP_ERROR => {
+            "A TFTP error occurred during the network operation.".to_owned()
+        }
+        Status::TIMEOUT => "The timeout time expired.".to_owned(),
+        Status::UNSUPPORTED => {
+            "The operation is not supported.".to_owned()
+        }
+        Status::VOLUME_FULL => {
+            "There is no more space on the file system.".to_owned()
+        }
+        Status::VOLUME_CORRUPTED => {
+                "An inconstancy was detected on the file system causing the operating to fail.".to_owned()
+        }
+        Status::WRITE_PROTECTED => {
+            "The device cannot be written to.".to_owned()
+        }
+        _ => format!("Status: {}", errno),
+    }
+}
+
+pub fn getcwd() -> io::Result<PathBuf> {
+    unsupported()
+}
+
+pub fn chdir(_: &path::Path) -> io::Result<()> {
+    unsupported()
+}
+
+pub struct SplitPaths<'a>(!, PhantomData<&'a ()>);
+
+pub fn split_paths(_unparsed: &OsStr) -> SplitPaths<'_> {
+    panic!("unsupported")
+}
+
+impl<'a> Iterator for SplitPaths<'a> {
+    type Item = PathBuf;
+    fn next(&mut self) -> Option<PathBuf> {
+        self.0
+    }
+}
+
+#[derive(Debug)]
+pub struct JoinPathsError;
+
+pub fn join_paths<I, T>(_paths: I) -> Result<OsString, JoinPathsError>
+where
+    I: Iterator<Item = T>,
+    T: AsRef<OsStr>,
+{
+    Err(JoinPathsError)
+}
+
+impl fmt::Display for JoinPathsError {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        "not supported on this platform yet".fmt(f)
+    }
+}
+
+impl StdError for JoinPathsError {}
+
+pub fn current_exe() -> io::Result<PathBuf> {
+    unsupported()
+}
+
+pub struct Env(!);
+
+impl Env {
+    // FIXME(https://github.com/rust-lang/rust/issues/114583): Remove this when <OsStr as Debug>::fmt matches <str as Debug>::fmt.
+    pub fn str_debug(&self) -> impl fmt::Debug + '_ {
+        let Self(inner) = self;
+        match *inner {}
+    }
+}
+
+impl Iterator for Env {
+    type Item = (OsString, OsString);
+    fn next(&mut self) -> Option<(OsString, OsString)> {
+        self.0
+    }
+}
+
+impl fmt::Debug for Env {
+    fn fmt(&self, _: &mut fmt::Formatter<'_>) -> fmt::Result {
+        let Self(inner) = self;
+        match *inner {}
+    }
+}
+
+pub fn env() -> Env {
+    panic!("not supported on this platform")
+}
+
+pub fn getenv(_: &OsStr) -> Option<OsString> {
+    None
+}
+
+pub fn setenv(_: &OsStr, _: &OsStr) -> io::Result<()> {
+    Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot set env vars on this platform"))
+}
+
+pub fn unsetenv(_: &OsStr) -> io::Result<()> {
+    Err(io::const_io_error!(io::ErrorKind::Unsupported, "cannot unset env vars on this platform"))
+}
+
+pub fn temp_dir() -> PathBuf {
+    panic!("no filesystem on this platform")
+}
+
+pub fn home_dir() -> Option<PathBuf> {
+    None
+}
+
+pub fn exit(code: i32) -> ! {
+    if let (Some(boot_services), Some(handle)) =
+        (uefi::env::boot_services(), uefi::env::try_image_handle())
+    {
+        let boot_services: NonNull<r_efi::efi::BootServices> = boot_services.cast();
+        let _ = unsafe {
+            ((*boot_services.as_ptr()).exit)(
+                handle.as_ptr(),
+                Status::from_usize(code as usize),
+                0,
+                crate::ptr::null_mut(),
+            )
+        };
+    }
+    crate::intrinsics::abort()
+}
+
+pub fn getpid() -> u32 {
+    panic!("no pids on this platform")
+}
diff --git a/library/std/src/sys/uefi/path.rs b/library/std/src/sys/uefi/path.rs
new file mode 100644
index 00000000000..106682eee56
--- /dev/null
+++ b/library/std/src/sys/uefi/path.rs
@@ -0,0 +1,25 @@
+use super::unsupported;
+use crate::ffi::OsStr;
+use crate::io;
+use crate::path::{Path, PathBuf, Prefix};
+
+pub const MAIN_SEP_STR: &str = "\\";
+pub const MAIN_SEP: char = '\\';
+
+#[inline]
+pub fn is_sep_byte(b: u8) -> bool {
+    b == b'\\'
+}
+
+#[inline]
+pub fn is_verbatim_sep(b: u8) -> bool {
+    b == b'\\'
+}
+
+pub fn parse_prefix(_p: &OsStr) -> Option<Prefix<'_>> {
+    None
+}
+
+pub(crate) fn absolute(_path: &Path) -> io::Result<PathBuf> {
+    unsupported()
+}
diff --git a/library/std/src/sys/uefi/tests.rs b/library/std/src/sys/uefi/tests.rs
new file mode 100644
index 00000000000..8806eda3ac0
--- /dev/null
+++ b/library/std/src/sys/uefi/tests.rs
@@ -0,0 +1,21 @@
+use super::alloc::*;
+
+#[test]
+fn align() {
+    // UEFI ABI specifies that allocation alignment minimum is always 8. So this can be
+    // statically verified.
+    assert_eq!(POOL_ALIGNMENT, 8);
+
+    // Loop over allocation-request sizes from 0-256 and alignments from 1-128, and verify
+    // that in case of overalignment there is at least space for one additional pointer to
+    // store in the allocation.
+    for i in 0..256 {
+        for j in &[1, 2, 4, 8, 16, 32, 64, 128] {
+            if *j <= 8 {
+                assert_eq!(align_size(i, *j), i);
+            } else {
+                assert!(align_size(i, *j) > i + std::mem::size_of::<*mut ()>());
+            }
+        }
+    }
+}
diff --git a/library/std/src/sys/unix/pipe.rs b/library/std/src/sys/unix/pipe.rs
index 1239c65a483..33db24e77e4 100644
--- a/library/std/src/sys/unix/pipe.rs
+++ b/library/std/src/sys/unix/pipe.rs
@@ -3,7 +3,7 @@ use crate::mem;
 use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, RawFd};
 use crate::sys::fd::FileDesc;
 use crate::sys::{cvt, cvt_r};
-use crate::sys_common::IntoInner;
+use crate::sys_common::{FromInner, IntoInner};
 
 ////////////////////////////////////////////////////////////////////////////////
 // Anonymous pipes
@@ -159,3 +159,9 @@ impl FromRawFd for AnonPipe {
         Self(FromRawFd::from_raw_fd(raw_fd))
     }
 }
+
+impl FromInner<FileDesc> for AnonPipe {
+    fn from_inner(fd: FileDesc) -> Self {
+        Self(fd)
+    }
+}
diff --git a/library/std/src/sys/unix/thread_local_dtor.rs b/library/std/src/sys/unix/thread_local_dtor.rs
index 1da41d4b4bf..fba2a676f28 100644
--- a/library/std/src/sys/unix/thread_local_dtor.rs
+++ b/library/std/src/sys/unix/thread_local_dtor.rs
@@ -48,7 +48,7 @@ pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
 // workaround below is to register, via _tlv_atexit, a custom DTOR list once per
 // thread. thread_local dtors are pushed to the DTOR list without calling
 // _tlv_atexit.
-#[cfg(target_os = "macos")]
+#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
 pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
     use crate::cell::Cell;
     use crate::mem;
diff --git a/library/std/src/sys/unix/thread_parking/darwin.rs b/library/std/src/sys/unix/thread_parking/darwin.rs
index b709fada3b4..8231f3cba2d 100644
--- a/library/std/src/sys/unix/thread_parking/darwin.rs
+++ b/library/std/src/sys/unix/thread_parking/darwin.rs
@@ -2,8 +2,7 @@
 //!
 //! Darwin actually has futex syscalls (`__ulock_wait`/`__ulock_wake`), but they
 //! cannot be used in `std` because they are non-public (their use will lead to
-//! rejection from the App Store) and because they are only available starting
-//! with macOS version 10.12, even though the minimum target version is 10.7.
+//! rejection from the App Store).
 //!
 //! Therefore, we need to look for other synchronization primitives. Luckily, Darwin
 //! supports semaphores, which allow us to implement the behaviour we need with
diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs
index d9ccba0e9da..f3637cbb981 100644
--- a/library/std/src/sys/windows/c.rs
+++ b/library/std/src/sys/windows/c.rs
@@ -46,10 +46,6 @@ pub use FD_SET as fd_set;
 pub use LINGER as linger;
 pub use TIMEVAL as timeval;
 
-pub type CONDITION_VARIABLE = RTL_CONDITION_VARIABLE;
-pub type SRWLOCK = RTL_SRWLOCK;
-pub type INIT_ONCE = RTL_RUN_ONCE;
-
 pub const CONDITION_VARIABLE_INIT: CONDITION_VARIABLE = CONDITION_VARIABLE { Ptr: ptr::null_mut() };
 pub const SRWLOCK_INIT: SRWLOCK = SRWLOCK { Ptr: ptr::null_mut() };
 pub const INIT_ONCE_STATIC_INIT: INIT_ONCE = INIT_ONCE { Ptr: ptr::null_mut() };
@@ -224,7 +220,7 @@ pub unsafe extern "system" fn ReadFileEx(
 ) -> BOOL {
     windows_sys::ReadFileEx(
         hFile.as_raw_handle(),
-        lpBuffer,
+        lpBuffer.cast::<u8>(),
         nNumberOfBytesToRead,
         lpOverlapped,
         lpCompletionRoutine,
diff --git a/library/std/src/sys/windows/c/windows_sys.lst b/library/std/src/sys/windows/c/windows_sys.lst
index 5469ba42eb1..0aca37e2d45 100644
--- a/library/std/src/sys/windows/c/windows_sys.lst
+++ b/library/std/src/sys/windows/c/windows_sys.lst
@@ -1,3 +1,6 @@
+--out windows_sys.rs
+--config flatten std
+--filter
 // tidy-alphabetical-start
 Windows.Wdk.Storage.FileSystem.FILE_COMPLETE_IF_OPLOCKED
 Windows.Wdk.Storage.FileSystem.FILE_CONTAINS_EXTENDED_CREATE_INFORMATION
@@ -2108,7 +2111,6 @@ Windows.Win32.Networking.WinSock.WSABASEERR
 Windows.Win32.Networking.WinSock.WSABUF
 Windows.Win32.Networking.WinSock.WSACleanup
 Windows.Win32.Networking.WinSock.WSADATA
-Windows.Win32.Networking.WinSock.WSADATA
 Windows.Win32.Networking.WinSock.WSADuplicateSocketW
 Windows.Win32.Networking.WinSock.WSAEACCES
 Windows.Win32.Networking.WinSock.WSAEADDRINUSE
@@ -2328,7 +2330,6 @@ Windows.Win32.Storage.FileSystem.FileStandardInfo
 Windows.Win32.Storage.FileSystem.FileStorageInfo
 Windows.Win32.Storage.FileSystem.FileStreamInfo
 Windows.Win32.Storage.FileSystem.FindClose
-Windows.Win32.Storage.FileSystem.FindFileHandle
 Windows.Win32.Storage.FileSystem.FindFirstFileW
 Windows.Win32.Storage.FileSystem.FindNextFileW
 Windows.Win32.Storage.FileSystem.FlushFileBuffers
@@ -2420,8 +2421,6 @@ Windows.Win32.System.Console.STD_OUTPUT_HANDLE
 Windows.Win32.System.Console.WriteConsoleW
 Windows.Win32.System.Diagnostics.Debug.ARM64_NT_NEON128
 Windows.Win32.System.Diagnostics.Debug.CONTEXT
-Windows.Win32.System.Diagnostics.Debug.CONTEXT
-Windows.Win32.System.Diagnostics.Debug.CONTEXT
 Windows.Win32.System.Diagnostics.Debug.EXCEPTION_RECORD
 Windows.Win32.System.Diagnostics.Debug.FACILITY_CODE
 Windows.Win32.System.Diagnostics.Debug.FACILITY_NT_BIT
@@ -2435,7 +2434,6 @@ Windows.Win32.System.Diagnostics.Debug.FORMAT_MESSAGE_OPTIONS
 Windows.Win32.System.Diagnostics.Debug.FormatMessageW
 Windows.Win32.System.Diagnostics.Debug.M128A
 Windows.Win32.System.Diagnostics.Debug.XSAVE_FORMAT
-Windows.Win32.System.Diagnostics.Debug.XSAVE_FORMAT
 Windows.Win32.System.Environment.FreeEnvironmentStringsW
 Windows.Win32.System.Environment.GetCommandLineW
 Windows.Win32.System.Environment.GetCurrentDirectoryW
@@ -2456,7 +2454,6 @@ Windows.Win32.System.Kernel.ExceptionContinueExecution
 Windows.Win32.System.Kernel.ExceptionContinueSearch
 Windows.Win32.System.Kernel.ExceptionNestedException
 Windows.Win32.System.Kernel.FLOATING_SAVE_AREA
-Windows.Win32.System.Kernel.FLOATING_SAVE_AREA
 Windows.Win32.System.Kernel.OBJ_DONT_REPARSE
 Windows.Win32.System.LibraryLoader.GetModuleFileNameW
 Windows.Win32.System.LibraryLoader.GetModuleHandleA
@@ -2482,6 +2479,7 @@ Windows.Win32.System.SystemInformation.GetSystemTimeAsFileTime
 Windows.Win32.System.SystemInformation.GetWindowsDirectoryW
 Windows.Win32.System.SystemInformation.PROCESSOR_ARCHITECTURE
 Windows.Win32.System.SystemInformation.SYSTEM_INFO
+Windows.Win32.System.SystemServices.ALL_PROCESSOR_GROUPS
 Windows.Win32.System.SystemServices.DLL_PROCESS_DETACH
 Windows.Win32.System.SystemServices.DLL_THREAD_DETACH
 Windows.Win32.System.SystemServices.EXCEPTION_MAXIMUM_PARAMETERS
@@ -2514,6 +2512,7 @@ Windows.Win32.System.Threading.DeleteProcThreadAttributeList
 Windows.Win32.System.Threading.DETACHED_PROCESS
 Windows.Win32.System.Threading.ExitProcess
 Windows.Win32.System.Threading.EXTENDED_STARTUPINFO_PRESENT
+Windows.Win32.System.Threading.GetActiveProcessorCount
 Windows.Win32.System.Threading.GetCurrentProcess
 Windows.Win32.System.Threading.GetCurrentProcessId
 Windows.Win32.System.Threading.GetCurrentThread
@@ -2542,9 +2541,6 @@ Windows.Win32.System.Threading.PROFILE_USER
 Windows.Win32.System.Threading.REALTIME_PRIORITY_CLASS
 Windows.Win32.System.Threading.ReleaseSRWLockExclusive
 Windows.Win32.System.Threading.ReleaseSRWLockShared
-Windows.Win32.System.Threading.RTL_CONDITION_VARIABLE
-Windows.Win32.System.Threading.RTL_RUN_ONCE
-Windows.Win32.System.Threading.RTL_SRWLOCK
 Windows.Win32.System.Threading.SetThreadStackGuarantee
 Windows.Win32.System.Threading.Sleep
 Windows.Win32.System.Threading.SleepConditionVariableSRW
@@ -2584,8 +2580,6 @@ Windows.Win32.System.Threading.WaitForMultipleObjects
 Windows.Win32.System.Threading.WaitForSingleObject
 Windows.Win32.System.Threading.WakeAllConditionVariable
 Windows.Win32.System.Threading.WakeConditionVariable
-Windows.Win32.System.WindowsProgramming.IO_STATUS_BLOCK
-Windows.Win32.System.WindowsProgramming.OBJECT_ATTRIBUTES
 Windows.Win32.System.WindowsProgramming.PROGRESS_CONTINUE
 Windows.Win32.UI.Shell.GetUserProfileDirectoryW
 // tidy-alphabetical-end
diff --git a/library/std/src/sys/windows/c/windows_sys.rs b/library/std/src/sys/windows/c/windows_sys.rs
index b24f6dc900f..851d15915c7 100644
--- a/library/std/src/sys/windows/c/windows_sys.rs
+++ b/library/std/src/sys/windows/c/windows_sys.rs
@@ -4,7 +4,7 @@
 // regenerate the bindings.
 //
 // ignore-tidy-filelength
-// Bindings generated by `windows-bindgen` 0.49.0
+// Bindings generated by `windows-bindgen` 0.51.1
 
 #![allow(non_snake_case, non_upper_case_globals, non_camel_case_types, dead_code, clippy::all)]
 #[link(name = "advapi32")]
@@ -32,11 +32,11 @@ extern "system" {
 }
 #[link(name = "kernel32")]
 extern "system" {
-    pub fn AcquireSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> ();
+    pub fn AcquireSRWLockExclusive(srwlock: *mut SRWLOCK) -> ();
 }
 #[link(name = "kernel32")]
 extern "system" {
-    pub fn AcquireSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> ();
+    pub fn AcquireSRWLockShared(srwlock: *mut SRWLOCK) -> ();
 }
 #[link(name = "kernel32")]
 extern "system" {
@@ -189,18 +189,15 @@ extern "system" {
 }
 #[link(name = "kernel32")]
 extern "system" {
-    pub fn FindClose(hfindfile: FindFileHandle) -> BOOL;
+    pub fn FindClose(hfindfile: HANDLE) -> BOOL;
 }
 #[link(name = "kernel32")]
 extern "system" {
-    pub fn FindFirstFileW(
-        lpfilename: PCWSTR,
-        lpfindfiledata: *mut WIN32_FIND_DATAW,
-    ) -> FindFileHandle;
+    pub fn FindFirstFileW(lpfilename: PCWSTR, lpfindfiledata: *mut WIN32_FIND_DATAW) -> HANDLE;
 }
 #[link(name = "kernel32")]
 extern "system" {
-    pub fn FindNextFileW(hfindfile: FindFileHandle, lpfindfiledata: *mut WIN32_FIND_DATAW) -> BOOL;
+    pub fn FindNextFileW(hfindfile: HANDLE, lpfindfiledata: *mut WIN32_FIND_DATAW) -> BOOL;
 }
 #[link(name = "kernel32")]
 extern "system" {
@@ -224,6 +221,10 @@ extern "system" {
 }
 #[link(name = "kernel32")]
 extern "system" {
+    pub fn GetActiveProcessorCount(groupnumber: u16) -> u32;
+}
+#[link(name = "kernel32")]
+extern "system" {
     pub fn GetCommandLineW() -> PCWSTR;
 }
 #[link(name = "kernel32")]
@@ -360,7 +361,7 @@ extern "system" {
 #[link(name = "kernel32")]
 extern "system" {
     pub fn InitOnceBeginInitialize(
-        lpinitonce: *mut RTL_RUN_ONCE,
+        lpinitonce: *mut INIT_ONCE,
         dwflags: u32,
         fpending: *mut BOOL,
         lpcontext: *mut *mut ::core::ffi::c_void,
@@ -369,7 +370,7 @@ extern "system" {
 #[link(name = "kernel32")]
 extern "system" {
     pub fn InitOnceComplete(
-        lpinitonce: *mut RTL_RUN_ONCE,
+        lpinitonce: *mut INIT_ONCE,
         dwflags: u32,
         lpcontext: *const ::core::ffi::c_void,
     ) -> BOOL;
@@ -424,7 +425,7 @@ extern "system" {
 extern "system" {
     pub fn ReadFile(
         hfile: HANDLE,
-        lpbuffer: *mut ::core::ffi::c_void,
+        lpbuffer: *mut u8,
         nnumberofbytestoread: u32,
         lpnumberofbytesread: *mut u32,
         lpoverlapped: *mut OVERLAPPED,
@@ -434,7 +435,7 @@ extern "system" {
 extern "system" {
     pub fn ReadFileEx(
         hfile: HANDLE,
-        lpbuffer: *mut ::core::ffi::c_void,
+        lpbuffer: *mut u8,
         nnumberofbytestoread: u32,
         lpoverlapped: *mut OVERLAPPED,
         lpcompletionroutine: LPOVERLAPPED_COMPLETION_ROUTINE,
@@ -442,11 +443,11 @@ extern "system" {
 }
 #[link(name = "kernel32")]
 extern "system" {
-    pub fn ReleaseSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> ();
+    pub fn ReleaseSRWLockExclusive(srwlock: *mut SRWLOCK) -> ();
 }
 #[link(name = "kernel32")]
 extern "system" {
-    pub fn ReleaseSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> ();
+    pub fn ReleaseSRWLockShared(srwlock: *mut SRWLOCK) -> ();
 }
 #[link(name = "kernel32")]
 extern "system" {
@@ -513,8 +514,8 @@ extern "system" {
 #[link(name = "kernel32")]
 extern "system" {
     pub fn SleepConditionVariableSRW(
-        conditionvariable: *mut RTL_CONDITION_VARIABLE,
-        srwlock: *mut RTL_SRWLOCK,
+        conditionvariable: *mut CONDITION_VARIABLE,
+        srwlock: *mut SRWLOCK,
         dwmilliseconds: u32,
         flags: u32,
     ) -> BOOL;
@@ -549,11 +550,11 @@ extern "system" {
 }
 #[link(name = "kernel32")]
 extern "system" {
-    pub fn TryAcquireSRWLockExclusive(srwlock: *mut RTL_SRWLOCK) -> BOOLEAN;
+    pub fn TryAcquireSRWLockExclusive(srwlock: *mut SRWLOCK) -> BOOLEAN;
 }
 #[link(name = "kernel32")]
 extern "system" {
-    pub fn TryAcquireSRWLockShared(srwlock: *mut RTL_SRWLOCK) -> BOOLEAN;
+    pub fn TryAcquireSRWLockShared(srwlock: *mut SRWLOCK) -> BOOLEAN;
 }
 #[link(name = "kernel32")]
 extern "system" {
@@ -574,19 +575,19 @@ extern "system" {
         lphandles: *const HANDLE,
         bwaitall: BOOL,
         dwmilliseconds: u32,
-    ) -> WIN32_ERROR;
+    ) -> WAIT_EVENT;
 }
 #[link(name = "kernel32")]
 extern "system" {
-    pub fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WIN32_ERROR;
+    pub fn WaitForSingleObject(hhandle: HANDLE, dwmilliseconds: u32) -> WAIT_EVENT;
 }
 #[link(name = "kernel32")]
 extern "system" {
-    pub fn WakeAllConditionVariable(conditionvariable: *mut RTL_CONDITION_VARIABLE) -> ();
+    pub fn WakeAllConditionVariable(conditionvariable: *mut CONDITION_VARIABLE) -> ();
 }
 #[link(name = "kernel32")]
 extern "system" {
-    pub fn WakeConditionVariable(conditionvariable: *mut RTL_CONDITION_VARIABLE) -> ();
+    pub fn WakeConditionVariable(conditionvariable: *mut CONDITION_VARIABLE) -> ();
 }
 #[link(name = "kernel32")]
 extern "system" {
@@ -847,6 +848,7 @@ impl ::core::clone::Clone for ADDRINFOA {
 pub const AF_INET: ADDRESS_FAMILY = 2u16;
 pub const AF_INET6: ADDRESS_FAMILY = 23u16;
 pub const AF_UNSPEC: ADDRESS_FAMILY = 0u16;
+pub const ALL_PROCESSOR_GROUPS: u32 = 65535u32;
 #[repr(C)]
 pub union ARM64_NT_NEON128 {
     pub Anonymous: ARM64_NT_NEON128_0,
@@ -899,7 +901,17 @@ impl ::core::clone::Clone for BY_HANDLE_FILE_INFORMATION {
 }
 pub const CALLBACK_CHUNK_FINISHED: LPPROGRESS_ROUTINE_CALLBACK_REASON = 0u32;
 pub const CALLBACK_STREAM_SWITCH: LPPROGRESS_ROUTINE_CALLBACK_REASON = 1u32;
-pub type COMPARESTRING_RESULT = u32;
+pub type COMPARESTRING_RESULT = i32;
+#[repr(C)]
+pub struct CONDITION_VARIABLE {
+    pub Ptr: *mut ::core::ffi::c_void,
+}
+impl ::core::marker::Copy for CONDITION_VARIABLE {}
+impl ::core::clone::Clone for CONDITION_VARIABLE {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
 pub type CONSOLE_MODE = u32;
 #[repr(C)]
 pub struct CONSOLE_READCONSOLE_CONTROL {
@@ -917,7 +929,7 @@ impl ::core::clone::Clone for CONSOLE_READCONSOLE_CONTROL {
 #[repr(C)]
 #[cfg(target_arch = "aarch64")]
 pub struct CONTEXT {
-    pub ContextFlags: u32,
+    pub ContextFlags: CONTEXT_FLAGS,
     pub Cpsr: u32,
     pub Anonymous: CONTEXT_0,
     pub Sp: u64,
@@ -1004,7 +1016,7 @@ pub struct CONTEXT {
     pub P4Home: u64,
     pub P5Home: u64,
     pub P6Home: u64,
-    pub ContextFlags: u32,
+    pub ContextFlags: CONTEXT_FLAGS,
     pub MxCsr: u32,
     pub SegCs: u16,
     pub SegDs: u16,
@@ -1100,7 +1112,7 @@ impl ::core::clone::Clone for CONTEXT_0_0 {
 #[repr(C)]
 #[cfg(target_arch = "x86")]
 pub struct CONTEXT {
-    pub ContextFlags: u32,
+    pub ContextFlags: CONTEXT_FLAGS,
     pub Dr0: u32,
     pub Dr1: u32,
     pub Dr2: u32,
@@ -1134,6 +1146,7 @@ impl ::core::clone::Clone for CONTEXT {
         *self
     }
 }
+pub type CONTEXT_FLAGS = u32;
 pub const CP_UTF8: u32 = 65001u32;
 pub const CREATE_ALWAYS: FILE_CREATION_DISPOSITION = 2u32;
 pub const CREATE_BREAKAWAY_FROM_JOB: PROCESS_CREATION_FLAGS = 16777216u32;
@@ -1151,9 +1164,9 @@ pub const CREATE_SEPARATE_WOW_VDM: PROCESS_CREATION_FLAGS = 2048u32;
 pub const CREATE_SHARED_WOW_VDM: PROCESS_CREATION_FLAGS = 4096u32;
 pub const CREATE_SUSPENDED: PROCESS_CREATION_FLAGS = 4u32;
 pub const CREATE_UNICODE_ENVIRONMENT: PROCESS_CREATION_FLAGS = 1024u32;
-pub const CSTR_EQUAL: COMPARESTRING_RESULT = 2u32;
-pub const CSTR_GREATER_THAN: COMPARESTRING_RESULT = 3u32;
-pub const CSTR_LESS_THAN: COMPARESTRING_RESULT = 1u32;
+pub const CSTR_EQUAL: COMPARESTRING_RESULT = 2i32;
+pub const CSTR_GREATER_THAN: COMPARESTRING_RESULT = 3i32;
+pub const CSTR_LESS_THAN: COMPARESTRING_RESULT = 1i32;
 pub const DEBUG_ONLY_THIS_PROCESS: PROCESS_CREATION_FLAGS = 2u32;
 pub const DEBUG_PROCESS: PROCESS_CREATION_FLAGS = 1u32;
 pub const DELETE: FILE_ACCESS_RIGHTS = 65536u32;
@@ -3369,7 +3382,6 @@ pub const FileRenameInfoEx: FILE_INFO_BY_HANDLE_CLASS = 22i32;
 pub const FileStandardInfo: FILE_INFO_BY_HANDLE_CLASS = 1i32;
 pub const FileStorageInfo: FILE_INFO_BY_HANDLE_CLASS = 16i32;
 pub const FileStreamInfo: FILE_INFO_BY_HANDLE_CLASS = 7i32;
-pub type FindFileHandle = *mut ::core::ffi::c_void;
 pub type GENERIC_ACCESS_RIGHTS = u32;
 pub const GENERIC_ALL: GENERIC_ACCESS_RIGHTS = 268435456u32;
 pub const GENERIC_EXECUTE: GENERIC_ACCESS_RIGHTS = 536870912u32;
@@ -3383,6 +3395,12 @@ pub struct GUID {
     pub data3: u16,
     pub data4: [u8; 8],
 }
+impl ::core::marker::Copy for GUID {}
+impl ::core::clone::Clone for GUID {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
 impl GUID {
     pub const fn from_u128(uuid: u128) -> Self {
         Self {
@@ -3393,12 +3411,6 @@ impl GUID {
         }
     }
 }
-impl ::core::marker::Copy for GUID {}
-impl ::core::clone::Clone for GUID {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
 pub type HANDLE = *mut ::core::ffi::c_void;
 pub type HANDLE_FLAGS = u32;
 pub const HANDLE_FLAG_INHERIT: HANDLE_FLAGS = 1u32;
@@ -3431,6 +3443,16 @@ impl ::core::clone::Clone for IN6_ADDR_0 {
 pub const INFINITE: u32 = 4294967295u32;
 pub const INHERIT_CALLER_PRIORITY: PROCESS_CREATION_FLAGS = 131072u32;
 pub const INHERIT_PARENT_AFFINITY: PROCESS_CREATION_FLAGS = 65536u32;
+#[repr(C)]
+pub union INIT_ONCE {
+    pub Ptr: *mut ::core::ffi::c_void,
+}
+impl ::core::marker::Copy for INIT_ONCE {}
+impl ::core::clone::Clone for INIT_ONCE {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
 pub const INIT_ONCE_INIT_FAILED: u32 = 4u32;
 pub const INVALID_FILE_ATTRIBUTES: u32 = 4294967295u32;
 pub const INVALID_HANDLE_VALUE: HANDLE = ::core::ptr::invalid_mut(-1i32 as _);
@@ -3659,10 +3681,10 @@ pub type NTSTATUS = i32;
 pub struct OBJECT_ATTRIBUTES {
     pub Length: u32,
     pub RootDirectory: HANDLE,
-    pub ObjectName: *mut UNICODE_STRING,
+    pub ObjectName: *const UNICODE_STRING,
     pub Attributes: u32,
-    pub SecurityDescriptor: *mut ::core::ffi::c_void,
-    pub SecurityQualityOfService: *mut ::core::ffi::c_void,
+    pub SecurityDescriptor: *const ::core::ffi::c_void,
+    pub SecurityQualityOfService: *const ::core::ffi::c_void,
 }
 impl ::core::marker::Copy for OBJECT_ATTRIBUTES {}
 impl ::core::clone::Clone for OBJECT_ATTRIBUTES {
@@ -3712,8 +3734,8 @@ pub type PCSTR = *const u8;
 pub type PCWSTR = *const u16;
 pub type PIO_APC_ROUTINE = ::core::option::Option<
     unsafe extern "system" fn(
-        apccontext: *const ::core::ffi::c_void,
-        iostatusblock: *const IO_STATUS_BLOCK,
+        apccontext: *mut ::core::ffi::c_void,
+        iostatusblock: *mut IO_STATUS_BLOCK,
         reserved: u32,
     ) -> (),
 >;
@@ -3755,36 +3777,6 @@ pub type PSTR = *mut u8;
 pub type PWSTR = *mut u16;
 pub const READ_CONTROL: FILE_ACCESS_RIGHTS = 131072u32;
 pub const REALTIME_PRIORITY_CLASS: PROCESS_CREATION_FLAGS = 256u32;
-#[repr(C)]
-pub struct RTL_CONDITION_VARIABLE {
-    pub Ptr: *mut ::core::ffi::c_void,
-}
-impl ::core::marker::Copy for RTL_CONDITION_VARIABLE {}
-impl ::core::clone::Clone for RTL_CONDITION_VARIABLE {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-#[repr(C)]
-pub union RTL_RUN_ONCE {
-    pub Ptr: *mut ::core::ffi::c_void,
-}
-impl ::core::marker::Copy for RTL_RUN_ONCE {}
-impl ::core::clone::Clone for RTL_RUN_ONCE {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
-#[repr(C)]
-pub struct RTL_SRWLOCK {
-    pub Ptr: *mut ::core::ffi::c_void,
-}
-impl ::core::marker::Copy for RTL_SRWLOCK {}
-impl ::core::clone::Clone for RTL_SRWLOCK {
-    fn clone(&self) -> Self {
-        *self
-    }
-}
 pub const SD_BOTH: WINSOCK_SHUTDOWN_HOW = 2i32;
 pub const SD_RECEIVE: WINSOCK_SHUTDOWN_HOW = 0i32;
 pub const SD_SEND: WINSOCK_SHUTDOWN_HOW = 1i32;
@@ -3821,10 +3813,7 @@ impl ::core::clone::Clone for SOCKADDR {
         *self
     }
 }
-#[cfg(target_pointer_width = "32")]
-pub type SOCKET = u32;
-#[cfg(target_pointer_width = "64")]
-pub type SOCKET = u64;
+pub type SOCKET = usize;
 pub const SOCKET_ERROR: i32 = -1i32;
 pub const SOCK_DGRAM: WINSOCK_SOCKET_TYPE = 2i32;
 pub const SOCK_RAW: WINSOCK_SOCKET_TYPE = 3i32;
@@ -3838,6 +3827,16 @@ pub const SO_LINGER: i32 = 128i32;
 pub const SO_RCVTIMEO: i32 = 4102i32;
 pub const SO_SNDTIMEO: i32 = 4101i32;
 pub const SPECIFIC_RIGHTS_ALL: FILE_ACCESS_RIGHTS = 65535u32;
+#[repr(C)]
+pub struct SRWLOCK {
+    pub Ptr: *mut ::core::ffi::c_void,
+}
+impl ::core::marker::Copy for SRWLOCK {}
+impl ::core::clone::Clone for SRWLOCK {
+    fn clone(&self) -> Self {
+        *self
+    }
+}
 pub const STACK_SIZE_PARAM_IS_A_RESERVATION: THREAD_CREATION_FLAGS = 65536u32;
 pub const STANDARD_RIGHTS_ALL: FILE_ACCESS_RIGHTS = 2031616u32;
 pub const STANDARD_RIGHTS_EXECUTE: FILE_ACCESS_RIGHTS = 131072u32;
@@ -4008,12 +4007,13 @@ impl ::core::clone::Clone for UNICODE_STRING {
 pub const VOLUME_NAME_DOS: GETFINALPATHNAMEBYHANDLE_FLAGS = 0u32;
 pub const VOLUME_NAME_GUID: GETFINALPATHNAMEBYHANDLE_FLAGS = 1u32;
 pub const VOLUME_NAME_NONE: GETFINALPATHNAMEBYHANDLE_FLAGS = 4u32;
-pub const WAIT_ABANDONED: WIN32_ERROR = 128u32;
-pub const WAIT_ABANDONED_0: WIN32_ERROR = 128u32;
-pub const WAIT_FAILED: WIN32_ERROR = 4294967295u32;
-pub const WAIT_IO_COMPLETION: WIN32_ERROR = 192u32;
-pub const WAIT_OBJECT_0: WIN32_ERROR = 0u32;
-pub const WAIT_TIMEOUT: WIN32_ERROR = 258u32;
+pub const WAIT_ABANDONED: WAIT_EVENT = 128u32;
+pub const WAIT_ABANDONED_0: WAIT_EVENT = 128u32;
+pub type WAIT_EVENT = u32;
+pub const WAIT_FAILED: WAIT_EVENT = 4294967295u32;
+pub const WAIT_IO_COMPLETION: WAIT_EVENT = 192u32;
+pub const WAIT_OBJECT_0: WAIT_EVENT = 0u32;
+pub const WAIT_TIMEOUT: WAIT_EVENT = 258u32;
 pub const WC_ERR_INVALID_CHARS: u32 = 128u32;
 pub type WIN32_ERROR = u32;
 #[repr(C)]
diff --git a/library/std/src/sys/windows/handle.rs b/library/std/src/sys/windows/handle.rs
index 84c1fbde32d..56d0d6c0887 100644
--- a/library/std/src/sys/windows/handle.rs
+++ b/library/std/src/sys/windows/handle.rs
@@ -143,13 +143,8 @@ impl Handle {
     ) -> io::Result<Option<usize>> {
         let len = cmp::min(buf.len(), <c::DWORD>::MAX as usize) as c::DWORD;
         let mut amt = 0;
-        let res = cvt(c::ReadFile(
-            self.as_raw_handle(),
-            buf.as_ptr() as c::LPVOID,
-            len,
-            &mut amt,
-            overlapped,
-        ));
+        let res =
+            cvt(c::ReadFile(self.as_raw_handle(), buf.as_mut_ptr(), len, &mut amt, overlapped));
         match res {
             Ok(_) => Ok(Some(amt as usize)),
             Err(e) => {
diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs
index 1ae42cb7eae..abdcab4247f 100644
--- a/library/std/src/sys/windows/net.rs
+++ b/library/std/src/sys/windows/net.rs
@@ -117,7 +117,7 @@ impl Socket {
         };
 
         if socket != c::INVALID_SOCKET {
-            unsafe { Ok(Self::from_raw_socket(socket)) }
+            unsafe { Ok(Self::from_raw(socket)) }
         } else {
             let error = unsafe { c::WSAGetLastError() };
 
@@ -133,7 +133,7 @@ impl Socket {
             }
 
             unsafe {
-                let socket = Self::from_raw_socket(socket);
+                let socket = Self::from_raw(socket);
                 socket.0.set_no_inherit()?;
                 Ok(socket)
             }
@@ -144,7 +144,7 @@ impl Socket {
         self.set_nonblocking(true)?;
         let result = {
             let (addr, len) = addr.into_inner();
-            let result = unsafe { c::connect(self.as_raw_socket(), addr.as_ptr(), len) };
+            let result = unsafe { c::connect(self.as_raw(), addr.as_ptr(), len) };
             cvt(result).map(drop)
         };
         self.set_nonblocking(false)?;
@@ -170,7 +170,7 @@ impl Socket {
                 let fds = {
                     let mut fds = unsafe { mem::zeroed::<c::fd_set>() };
                     fds.fd_count = 1;
-                    fds.fd_array[0] = self.as_raw_socket();
+                    fds.fd_array[0] = self.as_raw();
                     fds
                 };
 
@@ -202,11 +202,11 @@ impl Socket {
     }
 
     pub fn accept(&self, storage: *mut c::SOCKADDR, len: *mut c_int) -> io::Result<Socket> {
-        let socket = unsafe { c::accept(self.as_raw_socket(), storage, len) };
+        let socket = unsafe { c::accept(self.as_raw(), storage, len) };
 
         match socket {
             c::INVALID_SOCKET => Err(last_error()),
-            _ => unsafe { Ok(Self::from_raw_socket(socket)) },
+            _ => unsafe { Ok(Self::from_raw(socket)) },
         }
     }
 
@@ -218,9 +218,8 @@ impl Socket {
         // On unix when a socket is shut down all further reads return 0, so we
         // do the same on windows to map a shut down socket to returning EOF.
         let length = cmp::min(buf.capacity(), i32::MAX as usize) as i32;
-        let result = unsafe {
-            c::recv(self.as_raw_socket(), buf.as_mut().as_mut_ptr() as *mut _, length, flags)
-        };
+        let result =
+            unsafe { c::recv(self.as_raw(), buf.as_mut().as_mut_ptr() as *mut _, length, flags) };
 
         match result {
             c::SOCKET_ERROR => {
@@ -257,7 +256,7 @@ impl Socket {
         let mut flags = 0;
         let result = unsafe {
             c::WSARecv(
-                self.as_raw_socket(),
+                self.as_raw(),
                 bufs.as_mut_ptr() as *mut c::WSABUF,
                 length,
                 &mut nread,
@@ -305,7 +304,7 @@ impl Socket {
         // do the same on windows to map a shut down socket to returning EOF.
         let result = unsafe {
             c::recvfrom(
-                self.as_raw_socket(),
+                self.as_raw(),
                 buf.as_mut_ptr() as *mut _,
                 length,
                 flags,
@@ -341,7 +340,7 @@ impl Socket {
         let mut nwritten = 0;
         let result = unsafe {
             c::WSASend(
-                self.as_raw_socket(),
+                self.as_raw(),
                 bufs.as_ptr() as *const c::WSABUF as *mut _,
                 length,
                 &mut nwritten,
@@ -392,14 +391,14 @@ impl Socket {
             Shutdown::Read => c::SD_RECEIVE,
             Shutdown::Both => c::SD_BOTH,
         };
-        let result = unsafe { c::shutdown(self.as_raw_socket(), how) };
+        let result = unsafe { c::shutdown(self.as_raw(), how) };
         cvt(result).map(drop)
     }
 
     pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
         let mut nonblocking = nonblocking as c_ulong;
         let result =
-            unsafe { c::ioctlsocket(self.as_raw_socket(), c::FIONBIO as c_int, &mut nonblocking) };
+            unsafe { c::ioctlsocket(self.as_raw(), c::FIONBIO as c_int, &mut nonblocking) };
         cvt(result).map(drop)
     }
 
@@ -433,8 +432,15 @@ impl Socket {
     }
 
     // This is used by sys_common code to abstract over Windows and Unix.
-    pub fn as_raw(&self) -> RawSocket {
-        self.as_inner().as_raw_socket()
+    pub fn as_raw(&self) -> c::SOCKET {
+        debug_assert_eq!(mem::size_of::<c::SOCKET>(), mem::size_of::<RawSocket>());
+        debug_assert_eq!(mem::align_of::<c::SOCKET>(), mem::align_of::<RawSocket>());
+        self.as_inner().as_raw_socket() as c::SOCKET
+    }
+    pub unsafe fn from_raw(raw: c::SOCKET) -> Self {
+        debug_assert_eq!(mem::size_of::<c::SOCKET>(), mem::size_of::<RawSocket>());
+        debug_assert_eq!(mem::align_of::<c::SOCKET>(), mem::align_of::<RawSocket>());
+        Self::from_raw_socket(raw as RawSocket)
     }
 }
 
diff --git a/library/std/src/sys/windows/pipe.rs b/library/std/src/sys/windows/pipe.rs
index d07147eccc1..7624e746f5c 100644
--- a/library/std/src/sys/windows/pipe.rs
+++ b/library/std/src/sys/windows/pipe.rs
@@ -12,7 +12,7 @@ use crate::sys::c;
 use crate::sys::fs::{File, OpenOptions};
 use crate::sys::handle::Handle;
 use crate::sys::hashmap_random_keys;
-use crate::sys_common::IntoInner;
+use crate::sys_common::{FromInner, IntoInner};
 
 ////////////////////////////////////////////////////////////////////////////////
 // Anonymous pipes
@@ -28,6 +28,12 @@ impl IntoInner<Handle> for AnonPipe {
     }
 }
 
+impl FromInner<Handle> for AnonPipe {
+    fn from_inner(inner: Handle) -> AnonPipe {
+        Self { inner }
+    }
+}
+
 pub struct Pipes {
     pub ours: AnonPipe,
     pub theirs: AnonPipe,
diff --git a/library/std/src/sys_common/mod.rs b/library/std/src/sys_common/mod.rs
index f7d82175063..e18638f2a5f 100644
--- a/library/std/src/sys_common/mod.rs
+++ b/library/std/src/sys_common/mod.rs
@@ -44,6 +44,7 @@ cfg_if::cfg_if! {
 
 cfg_if::cfg_if! {
     if #[cfg(any(target_os = "l4re",
+                 target_os = "uefi",
                  feature = "restricted-std",
                  all(target_family = "wasm", not(target_os = "emscripten")),
                  target_os = "xous",
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index d58f0d54d3a..fac0cdf2038 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -41,6 +41,10 @@ def get_cpus():
         return 1
 
 
+def eprint(*args, **kwargs):
+    kwargs["file"] = sys.stderr
+    print(*args, **kwargs)
+
 
 def get(base, url, path, checksums, verbose=False):
     with tempfile.NamedTemporaryFile(delete=False) as temp_file:
@@ -57,23 +61,23 @@ def get(base, url, path, checksums, verbose=False):
         if os.path.exists(path):
             if verify(path, sha256, False):
                 if verbose:
-                    print("using already-download file", path, file=sys.stderr)
+                    eprint("using already-download file", path)
                 return
             else:
                 if verbose:
-                    print("ignoring already-download file",
-                        path, "due to failed verification", file=sys.stderr)
+                    eprint("ignoring already-download file",
+                        path, "due to failed verification")
                 os.unlink(path)
         download(temp_path, "{}/{}".format(base, url), True, verbose)
         if not verify(temp_path, sha256, verbose):
             raise RuntimeError("failed verification")
         if verbose:
-            print("moving {} to {}".format(temp_path, path), file=sys.stderr)
+            eprint("moving {} to {}".format(temp_path, path))
         shutil.move(temp_path, path)
     finally:
         if os.path.isfile(temp_path):
             if verbose:
-                print("removing", temp_path, file=sys.stderr)
+                eprint("removing", temp_path)
             os.unlink(temp_path)
 
 
@@ -83,7 +87,7 @@ def download(path, url, probably_big, verbose):
             _download(path, url, probably_big, verbose, True)
             return
         except RuntimeError:
-            print("\nspurious failure, trying again", file=sys.stderr)
+            eprint("\nspurious failure, trying again")
     _download(path, url, probably_big, verbose, False)
 
 
@@ -94,7 +98,7 @@ def _download(path, url, probably_big, verbose, exception):
     #  - If we are on win32 fallback to powershell
     #  - Otherwise raise the error if appropriate
     if probably_big or verbose:
-        print("downloading {}".format(url), file=sys.stderr)
+        eprint("downloading {}".format(url))
 
     try:
         if (probably_big or verbose) and "GITHUB_ACTIONS" not in os.environ:
@@ -129,20 +133,20 @@ def _download(path, url, probably_big, verbose, exception):
 def verify(path, expected, verbose):
     """Check if the sha256 sum of the given path is valid"""
     if verbose:
-        print("verifying", path, file=sys.stderr)
+        eprint("verifying", path)
     with open(path, "rb") as source:
         found = hashlib.sha256(source.read()).hexdigest()
     verified = found == expected
     if not verified:
-        print("invalid checksum:\n"
+        eprint("invalid checksum:\n"
               "    found:    {}\n"
-              "    expected: {}".format(found, expected), file=sys.stderr)
+              "    expected: {}".format(found, expected))
     return verified
 
 
 def unpack(tarball, tarball_suffix, dst, verbose=False, match=None):
     """Unpack the given tarball file"""
-    print("extracting", tarball, file=sys.stderr)
+    eprint("extracting", tarball)
     fname = os.path.basename(tarball).replace(tarball_suffix, "")
     with contextlib.closing(tarfile.open(tarball)) as tar:
         for member in tar.getnames():
@@ -155,7 +159,7 @@ def unpack(tarball, tarball_suffix, dst, verbose=False, match=None):
 
             dst_path = os.path.join(dst, name)
             if verbose:
-                print("  extracting", member, file=sys.stderr)
+                eprint("  extracting", member)
             tar.extract(member, dst)
             src_path = os.path.join(dst, member)
             if os.path.isdir(src_path) and os.path.exists(dst_path):
@@ -167,7 +171,7 @@ def unpack(tarball, tarball_suffix, dst, verbose=False, match=None):
 def run(args, verbose=False, exception=False, is_bootstrap=False, **kwargs):
     """Run a child program in a new process"""
     if verbose:
-        print("running: " + ' '.join(args), file=sys.stderr)
+        eprint("running: " + ' '.join(args))
     sys.stdout.flush()
     # Ensure that the .exe is used on Windows just in case a Linux ELF has been
     # compiled in the same directory.
@@ -207,8 +211,8 @@ def require(cmd, exit=True, exception=False):
         if exception:
             raise
         elif exit:
-            print("error: unable to run `{}`: {}".format(' '.join(cmd), exc), file=sys.stderr)
-            print("Please make sure it's installed and in the path.", file=sys.stderr)
+            eprint("error: unable to run `{}`: {}".format(' '.join(cmd), exc))
+            eprint("Please make sure it's installed and in the path.")
             sys.exit(1)
         return None
 
@@ -239,14 +243,12 @@ def default_build_triple(verbose):
             host = next(x for x in version.split('\n') if x.startswith("host: "))
             triple = host.split("host: ")[1]
             if verbose:
-                print("detected default triple {} from pre-installed rustc".format(triple),
-                    file=sys.stderr)
+                eprint("detected default triple {} from pre-installed rustc".format(triple))
             return triple
         except Exception as e:
             if verbose:
-                print("pre-installed rustc not detected: {}".format(e),
-                    file=sys.stderr)
-                print("falling back to auto-detect", file=sys.stderr)
+                eprint("pre-installed rustc not detected: {}".format(e))
+                eprint("falling back to auto-detect")
 
     required = not platform_is_win32()
     uname = require(["uname", "-smp"], exit=required)
@@ -672,15 +674,14 @@ class RustBuild(object):
             if not is_nixos:
                 in_nix_shell = os.getenv('IN_NIX_SHELL')
                 if in_nix_shell:
-                    print("The IN_NIX_SHELL environment variable is `{}`;".format(in_nix_shell),
-                          "you may need to set `patch-binaries-for-nix=true` in config.toml",
-                          file=sys.stderr)
+                    eprint("The IN_NIX_SHELL environment variable is `{}`;".format(in_nix_shell),
+                          "you may need to set `patch-binaries-for-nix=true` in config.toml")
 
             return is_nixos
 
         answer = self._should_fix_bins_and_dylibs = get_answer()
         if answer:
-            print("info: You seem to be using Nix.", file=sys.stderr)
+            eprint("info: You seem to be using Nix.")
         return answer
 
     def fix_bin_or_dylib(self, fname):
@@ -693,7 +694,7 @@ class RustBuild(object):
         Please see https://nixos.org/patchelf.html for more information
         """
         assert self._should_fix_bins_and_dylibs is True
-        print("attempting to patch", fname, file=sys.stderr)
+        eprint("attempting to patch", fname)
 
         # Only build `.nix-deps` once.
         nix_deps_dir = self.nix_deps_dir
@@ -726,7 +727,7 @@ class RustBuild(object):
                     "nix-build", "-E", nix_expr, "-o", nix_deps_dir,
                 ])
             except subprocess.CalledProcessError as reason:
-                print("warning: failed to call nix-build:", reason, file=sys.stderr)
+                eprint("warning: failed to call nix-build:", reason)
                 return
             self.nix_deps_dir = nix_deps_dir
 
@@ -746,7 +747,7 @@ class RustBuild(object):
         try:
             subprocess.check_output([patchelf] + patchelf_args + [fname])
         except subprocess.CalledProcessError as reason:
-            print("warning: failed to call patchelf:", reason, file=sys.stderr)
+            eprint("warning: failed to call patchelf:", reason)
             return
 
     def rustc_stamp(self):
@@ -888,7 +889,7 @@ class RustBuild(object):
         if "GITHUB_ACTIONS" in env:
             print("::group::Building bootstrap")
         else:
-            print("Building bootstrap", file=sys.stderr)
+            eprint("Building bootstrap")
 
         args = self.build_bootstrap_cmd(env)
         # Run this from the source directory so cargo finds .cargo/config
@@ -997,12 +998,9 @@ class RustBuild(object):
         if 'SUDO_USER' in os.environ and not self.use_vendored_sources:
             if os.getuid() == 0:
                 self.use_vendored_sources = True
-                print('info: looks like you\'re trying to run this command as root',
-                    file=sys.stderr)
-                print('      and so in order to preserve your $HOME this will now',
-                    file=sys.stderr)
-                print('      use vendored sources by default.',
-                    file=sys.stderr)
+                eprint('info: looks like you\'re trying to run this command as root')
+                eprint('      and so in order to preserve your $HOME this will now')
+                eprint('      use vendored sources by default.')
 
         cargo_dir = os.path.join(self.rust_root, '.cargo')
         if self.use_vendored_sources:
@@ -1012,18 +1010,14 @@ class RustBuild(object):
                             "--sync ./src/tools/rust-analyzer/Cargo.toml " \
                             "--sync ./compiler/rustc_codegen_cranelift/Cargo.toml " \
                             "--sync ./src/bootstrap/Cargo.toml "
-                print('error: vendoring required, but vendor directory does not exist.',
-                    file=sys.stderr)
-                print('       Run `cargo vendor {}` to initialize the '
-                      'vendor directory.'.format(sync_dirs),
-                      file=sys.stderr)
-                print('Alternatively, use the pre-vendored `rustc-src` dist component.',
-                    file=sys.stderr)
+                eprint('error: vendoring required, but vendor directory does not exist.')
+                eprint('       Run `cargo vendor {}` to initialize the '
+                      'vendor directory.'.format(sync_dirs))
+                eprint('Alternatively, use the pre-vendored `rustc-src` dist component.')
                 raise Exception("{} not found".format(vendor_dir))
 
             if not os.path.exists(cargo_dir):
-                print('error: vendoring required, but .cargo/config does not exist.',
-                    file=sys.stderr)
+                eprint('error: vendoring required, but .cargo/config does not exist.')
                 raise Exception("{} not found".format(cargo_dir))
         else:
             if os.path.exists(cargo_dir):
@@ -1117,10 +1111,9 @@ def main():
     # If the user is asking for help, let them know that the whole download-and-build
     # process has to happen before anything is printed out.
     if help_triggered:
-        print(
+        eprint(
             "info: Downloading and building bootstrap before processing --help command.\n"
-            "      See src/bootstrap/README.md for help with common commands."
-        , file=sys.stderr)
+            "      See src/bootstrap/README.md for help with common commands.")
 
     exit_code = 0
     success_word = "successfully"
@@ -1131,12 +1124,11 @@ def main():
             exit_code = error.code
         else:
             exit_code = 1
-            print(error, file=sys.stderr)
+            eprint(error)
         success_word = "unsuccessfully"
 
     if not help_triggered:
-        print("Build completed", success_word, "in", format_build_time(time() - start_time),
-            file=sys.stderr)
+        eprint("Build completed", success_word, "in", format_build_time(time() - start_time))
     sys.exit(exit_code)
 
 
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 4f19ffa83db..292ccc5780f 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -1789,7 +1789,10 @@ pub fn run_cargo(
                 // During check builds we need to keep crate metadata
                 keep = true;
             } else if rlib_only_metadata {
-                if filename.contains("jemalloc_sys") || filename.contains("rustc_smir") {
+                if filename.contains("jemalloc_sys")
+                    || filename.contains("rustc_smir")
+                    || filename.contains("stable_mir")
+                {
                     // jemalloc_sys and rustc_smir are not linked into librustc_driver.so,
                     // so we need to distribute them as rlib to be able to use them.
                     keep |= filename.ends_with(".rlib");
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 176ef8e92db..836328f94ef 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -532,11 +532,7 @@ pub struct Target {
 impl Target {
     pub fn from_triple(triple: &str) -> Self {
         let mut target: Self = Default::default();
-        if triple.contains("-none")
-            || triple.contains("nvptx")
-            || triple.contains("switch")
-            || triple.contains("-uefi")
-        {
+        if triple.contains("-none") || triple.contains("nvptx") || triple.contains("switch") {
             target.no_std = true;
         }
         target
diff --git a/src/bootstrap/llvm.rs b/src/bootstrap/llvm.rs
index 7e5ade50ca7..4556831589b 100644
--- a/src/bootstrap/llvm.rs
+++ b/src/bootstrap/llvm.rs
@@ -703,14 +703,7 @@ fn configure_cmake(
         cflags.push(" ");
         cflags.push(s);
     }
-    // Some compiler features used by LLVM (such as thread locals) will not work on a min version below iOS 10.
-    if target.contains("apple-ios") {
-        if target.contains("86-") {
-            cflags.push(" -miphonesimulator-version-min=10.0");
-        } else {
-            cflags.push(" -miphoneos-version-min=10.0");
-        }
-    }
+
     if builder.config.llvm_clang_cl.is_some() {
         cflags.push(&format!(" --target={target}"));
     }
diff --git a/src/ci/docker/README.md b/src/ci/docker/README.md
index b83b198780b..2e645683713 100644
--- a/src/ci/docker/README.md
+++ b/src/ci/docker/README.md
@@ -271,7 +271,7 @@ For targets: `loongarch64-unknown-linux-gnu`
 - Operating System > Linux kernel version = 5.19.16
 - Binary utilities > Version of binutils = 2.40
 - C-library > glibc version = 2.36
-- C compiler > gcc version = 13.1.0
+- C compiler > gcc version = 13.2.0
 - C compiler > C++ = ENABLE -- to cross compile LLVM
 
 ### `mips-linux-gnu.defconfig`
@@ -407,7 +407,7 @@ For targets: `riscv64-unknown-linux-gnu`
 - Target options > Bitness = 64-bit
 - Operating System > Target OS = linux
 - Operating System > Linux kernel version = 4.20.17
-- Binary utilities > Version of binutils = 2.32
+- Binary utilities > Version of binutils = 2.36.1
 - C-library > glibc version = 2.29
 - C compiler > gcc version = 8.5.0
 - C compiler > C++ = ENABLE -- to cross compile LLVM
diff --git a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile
index 78689c429c2..55c737bd0aa 100644
--- a/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-loongarch64-linux/Dockerfile
@@ -3,9 +3,8 @@ FROM ubuntu:22.04
 COPY scripts/cross-apt-packages.sh /scripts/
 RUN sh /scripts/cross-apt-packages.sh
 
-# The latest released version does not support LoongArch.
-COPY scripts/crosstool-ng-git.sh /scripts/
-RUN sh /scripts/crosstool-ng-git.sh
+COPY scripts/crosstool-ng.sh /scripts/
+RUN sh /scripts/crosstool-ng.sh
 
 COPY scripts/rustbuild-setup.sh /scripts/
 RUN sh /scripts/rustbuild-setup.sh
diff --git a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
index 670e37b9d01..01b46118b9c 100644
--- a/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
+++ b/src/ci/docker/host-x86_64/dist-various-2/Dockerfile
@@ -128,6 +128,8 @@ ENV TARGETS=$TARGETS,armv7-unknown-linux-gnueabi
 ENV TARGETS=$TARGETS,armv7-unknown-linux-musleabi
 ENV TARGETS=$TARGETS,i686-unknown-freebsd
 ENV TARGETS=$TARGETS,x86_64-unknown-none
+ENV TARGETS=$TARGETS,loongarch64-unknown-none
+ENV TARGETS=$TARGETS,loongarch64-unknown-none-softfloat
 ENV TARGETS=$TARGETS,aarch64-unknown-uefi
 ENV TARGETS=$TARGETS,i686-unknown-uefi
 ENV TARGETS=$TARGETS,x86_64-unknown-uefi
diff --git a/src/ci/docker/scripts/crosstool-ng-git.sh b/src/ci/docker/scripts/crosstool-ng-git.sh
deleted file mode 100644
index b8d39915327..00000000000
--- a/src/ci/docker/scripts/crosstool-ng-git.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/sh
-set -ex
-
-URL=https://github.com/crosstool-ng/crosstool-ng
-REV=227d99d7f3115f3a078595a580d2b307dcd23e93
-
-mkdir crosstool-ng
-cd crosstool-ng
-git init
-git fetch --depth=1 ${URL} ${REV}
-git reset --hard FETCH_HEAD
-./bootstrap
-./configure --prefix=/usr/local
-make -j$(nproc)
-make install
-cd ..
-rm -rf crosstool-ng
diff --git a/src/ci/docker/scripts/crosstool-ng.sh b/src/ci/docker/scripts/crosstool-ng.sh
index a28d7bde2ac..c3ee19b8d2c 100644
--- a/src/ci/docker/scripts/crosstool-ng.sh
+++ b/src/ci/docker/scripts/crosstool-ng.sh
@@ -1,7 +1,7 @@
 #!/bin/sh
 set -ex
 
-CT_NG=1.25.0
+CT_NG=1.26.0
 
 url="https://github.com/crosstool-ng/crosstool-ng/archive/crosstool-ng-$CT_NG.tar.gz"
 curl -Lf $url | tar xzf -
diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml
index 973b9a0a089..cbf848cb4a3 100644
--- a/src/ci/github-actions/ci.yml
+++ b/src/ci/github-actions/ci.yml
@@ -484,7 +484,7 @@ jobs:
               SCRIPT: ./x.py dist bootstrap --include-default-paths --host=x86_64-apple-darwin --target=x86_64-apple-darwin
               RUST_CONFIGURE_ARGS: --enable-full-tools --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false --set rust.lto=thin
               RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
-              MACOSX_DEPLOYMENT_TARGET: 10.7
+              MACOSX_DEPLOYMENT_TARGET: 10.12
               SELECT_XCODE: /Applications/Xcode_13.4.1.app
               NO_LLVM_ASSERTIONS: 1
               NO_DEBUG_ASSERTIONS: 1
@@ -497,7 +497,7 @@ jobs:
               SCRIPT: ./x.py dist bootstrap --include-default-paths --host='' --target=aarch64-apple-ios,x86_64-apple-ios,aarch64-apple-ios-sim
               RUST_CONFIGURE_ARGS: --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false
               RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
-              MACOSX_DEPLOYMENT_TARGET: 10.7
+              MACOSX_DEPLOYMENT_TARGET: 10.12
               SELECT_XCODE: /Applications/Xcode_13.4.1.app
               NO_LLVM_ASSERTIONS: 1
               NO_DEBUG_ASSERTIONS: 1
@@ -509,8 +509,8 @@ jobs:
               SCRIPT: ./x.py --stage 2 test --skip tests/ui --skip tests/rustdoc --skip tests/run-make-fulldeps
               RUST_CONFIGURE_ARGS: --build=x86_64-apple-darwin --enable-sanitizers --enable-profiler --set rust.jemalloc --set llvm.ninja=false
               RUSTC_RETRY_LINKER_ON_SEGFAULT: 1
-              MACOSX_DEPLOYMENT_TARGET: 10.8
-              MACOSX_STD_DEPLOYMENT_TARGET: 10.7
+              MACOSX_DEPLOYMENT_TARGET: 10.12
+              MACOSX_STD_DEPLOYMENT_TARGET: 10.12
               NO_LLVM_ASSERTIONS: 1
               NO_DEBUG_ASSERTIONS: 1
               NO_OVERFLOW_CHECKS: 1
diff --git a/src/ci/scripts/setup-environment.sh b/src/ci/scripts/setup-environment.sh
index 0bc35f93283..d3c55a4d6b4 100755
--- a/src/ci/scripts/setup-environment.sh
+++ b/src/ci/scripts/setup-environment.sh
@@ -10,7 +10,7 @@ source "$(cd "$(dirname "$0")" && pwd)/../shared.sh"
 
 # Load extra environment variables
 vars="${EXTRA_VARIABLES-}"
-echo "${vars}" | jq '' >/dev/null  # Validate JSON and exit on errors
+echo "${vars}" | jq '.' >/dev/null  # Validate JSON and exit on errors
 for key in $(echo "${vars}" | jq "keys[]" -r); do
     # On Windows, for whatever reason, $key contains the BOM character in it,
     # and that messes up `jq ".${key}"`. This line strips the BOM from the key.
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject 99ad2847b865e96d8ae7b333d3ee96963557e62
+Subproject eac173690b8cc99094e1d88bd49dd61127fbd28
diff --git a/src/doc/nomicon b/src/doc/nomicon
-Subproject e3f3af69dce71cd37a785bccb7e58449197d940
+Subproject ddfa4214487686e91b21aa29afb972c08a8f0d5
diff --git a/src/doc/reference b/src/doc/reference
-Subproject ee7c676fd6e287459cb407337652412c990686c
+Subproject 5262e1c3b43a2c489df8f6717683a44c7a2260f
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 08bb147d51e815b96e8db7ba4cf870f201c11ff
+Subproject a13b7c28ed705891c681ce5417b3d1cdb12cecd
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index 7c0c56035c0..ff831a20504 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -36,7 +36,7 @@ target | notes
 `i686-pc-windows-gnu` | 32-bit MinGW (Windows 7+) [^windows-support]
 `i686-pc-windows-msvc` | 32-bit MSVC (Windows 7+) [^windows-support]
 `i686-unknown-linux-gnu` | 32-bit Linux (kernel 3.2+, glibc 2.17+)
-`x86_64-apple-darwin` | 64-bit macOS (10.7+, Lion+)
+`x86_64-apple-darwin` | 64-bit macOS (10.12+, Sierra+)
 `x86_64-pc-windows-gnu` | 64-bit MinGW (Windows 7+) [^windows-support]
 `x86_64-pc-windows-msvc` | 64-bit MSVC (Windows 7+) [^windows-support]
 `x86_64-unknown-linux-gnu` | 64-bit Linux (kernel 3.2+, glibc 2.17+)
@@ -157,6 +157,8 @@ target | std | notes
 `i686-unknown-freebsd` | ✓ | 32-bit FreeBSD
 `i686-unknown-linux-musl` | ✓ | 32-bit Linux with MUSL
 [`i686-unknown-uefi`](platform-support/unknown-uefi.md) | * | 32-bit UEFI
+[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * |  | LoongArch64 Bare-metal (LP64D ABI)
+[`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * |  | LoongArch64 Bare-metal (LP64S ABI)
 `mips-unknown-linux-musl` | ✓ | MIPS Linux with MUSL
 `mips64-unknown-linux-muslabi64` | ✓ | MIPS64 Linux, n64 ABI, MUSL
 `mips64el-unknown-linux-muslabi64` | ✓ | MIPS64 (LE) Linux, n64 ABI, MUSL
@@ -245,7 +247,6 @@ target | std | host | notes
 `armv6-unknown-freebsd` | ✓ | ✓ | ARMv6 FreeBSD
 [`armv6-unknown-netbsd-eabihf`](platform-support/netbsd.md) | ✓ | ✓ | ARMv6 NetBSD w/hard-float
 [`armv6k-nintendo-3ds`](platform-support/armv6k-nintendo-3ds.md) | ? |  | ARMv6K Nintendo 3DS, Horizon (Requires devkitARM toolchain)
-`armv7-apple-ios` | ✓ |  | ARMv7-A Cortex-A8 iOS
 [`armv7-sony-vita-newlibeabihf`](platform-support/armv7-sony-vita-newlibeabihf.md) | ? |  | ARMv7-A Cortex-A9 Sony PlayStation Vita (requires VITASDK toolchain)
 [`armv7-unknown-linux-ohos`](platform-support/openharmony.md) | ✓ |  | ARMv7-A OpenHarmony |
 [`armv7-unknown-linux-uclibceabi`](platform-support/armv7-unknown-linux-uclibceabi.md) | ✓ | ✓ | ARMv7-A Linux with uClibc, softfloat
@@ -265,7 +266,7 @@ target | std | host | notes
 `hexagon-unknown-linux-musl` | ? |  |
 `i386-apple-ios` | ✓ |  | 32-bit x86 iOS
 [`i586-pc-nto-qnx700`](platform-support/nto-qnx.md) | * |  | 32-bit x86 QNX Neutrino 7.0 RTOS |
-`i686-apple-darwin` | ✓ | ✓ | 32-bit macOS (10.7+, Lion+)
+`i686-apple-darwin` | ✓ | ✓ | 32-bit macOS (10.12+, Sierra+)
 `i686-pc-windows-msvc` | * |  | 32-bit Windows XP support
 [`i686-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
 `i686-unknown-haiku` | ✓ | ✓ | 32-bit Haiku
@@ -275,8 +276,6 @@ target | std | host | notes
 `i686-uwp-windows-gnu` | ? |  |
 `i686-uwp-windows-msvc` | ? |  |
 `i686-wrs-vxworks` | ? |  |
-[`loongarch64-unknown-none`](platform-support/loongarch-none.md) | * |  | LoongArch64 Bare-metal (LP64D ABI)
-[`loongarch64-unknown-none-softfloat`](platform-support/loongarch-none.md) | * |  | LoongArch64 Bare-metal (LP64S ABI)
 [`m68k-unknown-linux-gnu`](platform-support/m68k-unknown-linux-gnu.md) | ? |  | Motorola 680x0 Linux
 `mips-unknown-linux-uclibc` | ✓ |  | MIPS Linux with uClibc
 [`mips64-openwrt-linux-musl`](platform-support/mips64-openwrt-linux-musl.md) | ? |  | MIPS64 for OpenWrt Linux MUSL
diff --git a/src/doc/rustc/src/platform-support/loongarch-none.md b/src/doc/rustc/src/platform-support/loongarch-none.md
index d0ae3425fa8..68d7c9d85e4 100644
--- a/src/doc/rustc/src/platform-support/loongarch-none.md
+++ b/src/doc/rustc/src/platform-support/loongarch-none.md
@@ -1,6 +1,6 @@
 # `loongarch*-unknown-none*`
 
-**Tier: 3**
+**Tier: 2**
 
 Freestanding/bare-metal LoongArch64 binaries in ELF format: firmware, kernels, etc.
 
diff --git a/src/doc/rustc/src/platform-support/unknown-uefi.md b/src/doc/rustc/src/platform-support/unknown-uefi.md
index 03fa284620e..68cd7fae319 100644
--- a/src/doc/rustc/src/platform-support/unknown-uefi.md
+++ b/src/doc/rustc/src/platform-support/unknown-uefi.md
@@ -19,8 +19,8 @@ Available targets:
 ## Requirements
 
 All UEFI targets can be used as `no-std` environments via cross-compilation.
-Support for `std` is missing, but actively worked on. `alloc` is supported if
-an allocator is provided by the user. No host tools are supported.
+Support for `std` is present, but incomplete and extremely new. `alloc` is supported if
+an allocator is provided by the user or if using std. No host tools are supported.
 
 The UEFI environment resembles the environment for Microsoft Windows, with some
 minor differences. Therefore, cross-compiling for UEFI works with the same
@@ -230,3 +230,76 @@ pub extern "C" fn main(_h: efi::Handle, st: *mut efi::SystemTable) -> efi::Statu
     efi::Status::SUCCESS
 }
 ```
+
+## Rust std for UEFI
+This section contains information on how to use std on UEFI.
+
+### Build std
+The building std part is pretty much the same as the official [docs](https://rustc-dev-guide.rust-lang.org/getting-started.html).
+The linker that should be used is `rust-lld`. Here is a sample `config.toml`:
+```toml
+[rust]
+lld = true
+```
+Then just build using `x.py`:
+```sh
+./x.py build --target x86_64-unknown-uefi --stage 1
+```
+Alternatively, it is possible to use the `build-std` feature. However, you must use a toolchain which has the UEFI std patches.
+Then just build the project using the following command:
+```sh
+cargo build --target x86_64-unknown-uefi -Zbuild-std=std,panic_abort
+```
+
+### Implemented features
+#### alloc
+- Implemented using `EFI_BOOT_SERVICES.AllocatePool()` and `EFI_BOOT_SERVICES.FreePool()`.
+- Passes all the tests.
+- Currently uses `EfiLoaderData` as the `EFI_ALLOCATE_POOL->PoolType`.
+#### cmath
+- Provided by compiler-builtins.
+#### env
+- Just some global constants.
+#### locks
+- The provided locks should work on all standard single-threaded UEFI implementations.
+#### os_str
+- While the strings in UEFI should be valid UCS-2, in practice, many implementations just do not care and use UTF-16 strings.
+- Thus, the current implementation supports full UTF-16 strings.
+
+## Example: Hello World With std
+The following code features a valid UEFI application, including stdio and `alloc` (`OsString` and `Vec`):
+
+This example can be compiled as binary crate via `cargo` using the toolchain
+compiled from the above source (named custom):
+
+```sh
+cargo +custom build --target x86_64-unknown-uefi
+```
+
+```rust,ignore (platform-specific)
+#![feature(uefi_std)]
+
+use r_efi::{efi, protocols::simple_text_output};
+use std::{
+  ffi::OsString,
+  os::uefi::{env, ffi::OsStrExt}
+};
+
+pub fn main() {
+  let st = env::system_table().as_ptr() as *mut efi::SystemTable;
+  let mut s: Vec<u16> = OsString::from("Hello World!\n").encode_wide().collect();
+  s.push(0);
+  let r =
+      unsafe {
+        let con_out: *mut simple_text_output::Protocol = (*st).con_out;
+        let output_string: extern "efiapi" fn(_: *mut simple_text_output::Protocol, *mut u16) -> efi::Status = (*con_out).output_string;
+        output_string(con_out, s.as_ptr() as *mut efi::Char16)
+      };
+  assert!(!r.is_error())
+}
+```
+
+### BootServices
+The current implementation of std makes `BootServices` unavailable once `ExitBootServices` is called. Refer to [Runtime Drivers](https://edk2-docs.gitbook.io/edk-ii-uefi-driver-writer-s-guide/7_driver_entry_point/711_runtime_drivers) for more information regarding how to handle switching from using physical addresses to using virtual addresses.
+
+Note: It should be noted that it is up to the user to drop all allocated memory before `ExitBootServices` is called.
diff --git a/src/doc/rustdoc/src/unstable-features.md b/src/doc/rustdoc/src/unstable-features.md
index 0d3f6338af4..7473b09920f 100644
--- a/src/doc/rustdoc/src/unstable-features.md
+++ b/src/doc/rustdoc/src/unstable-features.md
@@ -375,7 +375,7 @@ library, as an equivalent command-line argument is provided to `rustc` when buil
 This feature allows you to generate an index-page with a given markdown file. A good example of it
 is the [rust documentation index](https://doc.rust-lang.org/nightly/index.html).
 
-With this, you'll have a page which you can custom as much as you want at the top of your crates.
+With this, you'll have a page which you can customize as much as you want at the top of your crates.
 
 Using `index-page` option enables `enable-index-page` option as well.
 
diff --git a/src/doc/style-guide/src/items.md b/src/doc/style-guide/src/items.md
index a6d941f6d04..b215de6ad28 100644
--- a/src/doc/style-guide/src/items.md
+++ b/src/doc/style-guide/src/items.md
@@ -367,26 +367,52 @@ where
 ## Type aliases
 
 Keep type aliases on one line when they fit. If necessary to break the line, do
-so after the `=`, and block-indent the right-hand side:
+so before the `=`, and block-indent the right-hand side:
 
 ```rust
 pub type Foo = Bar<T>;
 
 // If multi-line is required
-type VeryLongType<T, U: SomeBound> =
-    AnEvenLongerType<T, U, Foo<T>>;
+type VeryLongType<T, U: SomeBound>
+    = AnEvenLongerType<T, U, Foo<T>>;
 ```
 
-Where possible avoid `where` clauses and keep type constraints inline. Where
-that is not possible split the line before and after the `where` clause (and
-split the `where` clause as normal), e.g.,
+When there is a trailing `where` clause after the type, and no `where` clause
+present before the type, break before the `=` and indent. Then break before the
+`where` keyword and format the clauses normally, e.g.,
 
 ```rust
+// With only a trailing where clause
 type VeryLongType<T, U>
+    = AnEvenLongerType<T, U, Foo<T>>
+where
+    T: U::AnAssociatedType,
+    U: SomeBound;
+```
+
+When there is a `where` clause before the type, format it normally, and break
+after the last clause. Do not indent before the `=` to leave it visually
+distinct from the indented clauses that precede it. If there is additionally a
+`where` clause after the type, break before the `where` keyword and format the
+clauses normally.
+
+```rust
+// With only a preceding where clause.
+type WithPrecedingWC<T, U>
 where
     T: U::AnAssociatedType,
     U: SomeBound,
 = AnEvenLongerType<T, U, Foo<T>>;
+
+// Or with both a preceding and trailing where clause.
+type WithPrecedingWC<T, U>
+where
+    T: U::AnAssociatedType,
+    U: SomeBound,
+= AnEvenLongerType<T, U, Foo<T>>
+where
+    T: U::AnAssociatedType2,
+    U: SomeBound2;
 ```
 
 ## Associated types
diff --git a/src/doc/unstable-book/src/compiler-flags/link-native-libraries.md b/src/doc/unstable-book/src/compiler-flags/link-native-libraries.md
new file mode 100644
index 00000000000..a1fcb631c68
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/link-native-libraries.md
@@ -0,0 +1,8 @@
+# `link-native-libraries`
+
+This option allows ignoring libraries specified in `#[link]` attributes instead of passing them to the linker.
+This can be useful in build systems that manage native libraries themselves and pass them manually,
+e.g. with `-Clink-arg`.
+
+- `yes` - Pass native libraries to the linker. Default.
+- `no` - Don't pass native libraries to the linker.
diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md
index 9e20662fff3..32b882e763d 100644
--- a/src/doc/unstable-book/src/language-features/lang-items.md
+++ b/src/doc/unstable-book/src/language-features/lang-items.md
@@ -37,7 +37,7 @@ Most lang items are defined by `core`, but if you're trying to build
 an executable without the `std` crate, you might run into the need
 for lang item definitions.
 
-[personality]: https://github.com/rust-lang/rust/blob/master/library/std/src/personality/gcc.rs
+[personality]: https://github.com/rust-lang/rust/blob/master/library/std/src/sys/personality/gcc.rs
 
 ## Example: Implementing a `Box`
 
diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md
index 1fade6ce95b..189cc910a8d 100644
--- a/src/doc/unstable-book/src/language-features/plugin.md
+++ b/src/doc/unstable-book/src/language-features/plugin.md
@@ -43,14 +43,14 @@ extern crate rustc_ast;
 
 // Load rustc as a plugin to get macros
 extern crate rustc_driver;
-#[macro_use]
 extern crate rustc_lint;
 #[macro_use]
 extern crate rustc_session;
 
-use rustc_driver::plugin::Registry;
-use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
 use rustc_ast::ast;
+use rustc_driver::plugin::Registry;
+use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
+
 declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
 
 declare_lint_pass!(Pass => [TEST_LINT]);
@@ -58,9 +58,7 @@ declare_lint_pass!(Pass => [TEST_LINT]);
 impl EarlyLintPass for Pass {
     fn check_item(&mut self, cx: &EarlyContext, it: &ast::Item) {
         if it.ident.name.as_str() == "lintme" {
-            cx.lint(TEST_LINT, |lint| {
-                lint.build("item is named 'lintme'").set_span(it.span).emit()
-            });
+            cx.lint(TEST_LINT, "item is named 'lintme'", |lint| lint.set_span(it.span));
         }
     }
 }
diff --git a/src/etc/installer/pkg/Distribution.xml b/src/etc/installer/pkg/Distribution.xml
index 395814e7488..85c26ec4993 100644
--- a/src/etc/installer/pkg/Distribution.xml
+++ b/src/etc/installer/pkg/Distribution.xml
@@ -7,7 +7,7 @@
     <domains enable_anywhere="false" enable_currentUserHome="false" enable_localSystem="true" />
     <volume-check>
         <allowed-os-versions>
-            <os-version min="10.7"/>
+            <os-version min="10.12"/>
         </allowed-os-versions>
     </volume-check>
     <choices-outline>
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index dd43ee03383..fcbcfbf5c67 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -80,7 +80,7 @@ pub(crate) fn try_inline(
             build_impls(cx, did, attrs_without_docs, &mut ret);
             clean::UnionItem(build_union(cx, did))
         }
-        Res::Def(DefKind::TyAlias { .. }, did) => {
+        Res::Def(DefKind::TyAlias, did) => {
             record_extern_fqn(cx, did, ItemType::TypeAlias);
             build_impls(cx, did, attrs_without_docs, &mut ret);
             clean::TypeAliasItem(build_type_alias(cx, did))
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index c4011461885..5a1612e76e3 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1108,10 +1108,7 @@ fn clean_function<'tcx>(
                 clean_args_from_types_and_names(cx, sig.decl.inputs, names)
             }
         };
-        let mut decl = clean_fn_decl_with_args(cx, sig.decl, args);
-        if sig.header.is_async() {
-            decl.output = decl.sugared_async_return_type();
-        }
+        let decl = clean_fn_decl_with_args(cx, sig.decl, Some(&sig.header), args);
         (generics, decl)
     });
     Box::new(Function { decl, generics })
@@ -1162,12 +1159,16 @@ fn clean_args_from_types_and_body_id<'tcx>(
 fn clean_fn_decl_with_args<'tcx>(
     cx: &mut DocContext<'tcx>,
     decl: &hir::FnDecl<'tcx>,
+    header: Option<&hir::FnHeader>,
     args: Arguments,
 ) -> FnDecl {
-    let output = match decl.output {
+    let mut output = match decl.output {
         hir::FnRetTy::Return(typ) => clean_ty(typ, cx),
         hir::FnRetTy::DefaultReturn(..) => Type::Tuple(Vec::new()),
     };
+    if let Some(header) = header && header.is_async() {
+        output = output.sugared_async_return_type();
+    }
     FnDecl { inputs: args, output, c_variadic: decl.c_variadic }
 }
 
@@ -1180,7 +1181,17 @@ fn clean_fn_decl_from_did_and_sig<'tcx>(
 
     // We assume all empty tuples are default return type. This theoretically can discard `-> ()`,
     // but shouldn't change any code meaning.
-    let output = clean_middle_ty(sig.output(), cx, None, None);
+    let mut output = clean_middle_ty(sig.output(), cx, None, None);
+
+    // If the return type isn't an `impl Trait`, we can safely assume that this
+    // function isn't async without needing to execute the query `asyncness` at
+    // all which gives us a noticeable performance boost.
+    if let Some(did) = did
+        && let Type::ImplTrait(_) = output
+        && cx.tcx.asyncness(did).is_async()
+    {
+        output = output.sugared_async_return_type();
+    }
 
     FnDecl {
         output,
@@ -1753,7 +1764,7 @@ fn maybe_expand_private_type_alias<'tcx>(
     cx: &mut DocContext<'tcx>,
     path: &hir::Path<'tcx>,
 ) -> Option<Type> {
-    let Res::Def(DefKind::TyAlias { .. }, def_id) = path.res else { return None };
+    let Res::Def(DefKind::TyAlias, def_id) = path.res else { return None };
     // Substitute private type aliases
     let def_id = def_id.as_local()?;
     let alias = if !cx.cache.effective_visibilities.is_exported(cx.tcx, def_id.to_def_id())
@@ -2022,7 +2033,7 @@ impl<'tcx> ContainerTy<'tcx> {
                 let (DefKind::Struct
                 | DefKind::Union
                 | DefKind::Enum
-                | DefKind::TyAlias { .. }
+                | DefKind::TyAlias
                 | DefKind::Trait) = tcx.def_kind(container)
                 else {
                     return ObjectLifetimeDefault::Empty;
@@ -2288,7 +2299,6 @@ pub(crate) fn clean_middle_ty<'tcx>(
         ty::Bound(..) => panic!("Bound"),
         ty::Placeholder(..) => panic!("Placeholder"),
         ty::GeneratorWitness(..) => panic!("GeneratorWitness"),
-        ty::GeneratorWitnessMIR(..) => panic!("GeneratorWitnessMIR"),
         ty::Infer(..) => panic!("Infer"),
         ty::Error(_) => rustc_errors::FatalError.raise(),
     }
@@ -2567,7 +2577,7 @@ fn clean_bare_fn_ty<'tcx>(
             .map(|x| clean_generic_param(cx, None, x))
             .collect();
         let args = clean_args_from_types_and_names(cx, bare_fn.decl.inputs, bare_fn.param_names);
-        let decl = clean_fn_decl_with_args(cx, bare_fn.decl, args);
+        let decl = clean_fn_decl_with_args(cx, bare_fn.decl, None, args);
         (generic_params, decl)
     });
     BareFunctionDecl { unsafety: bare_fn.unsafety, abi: bare_fn.abi, decl, generic_params }
@@ -2855,7 +2865,7 @@ fn clean_impl<'tcx>(
     let for_ = clean_ty(impl_.self_ty, cx);
     let type_alias =
         for_.def_id(&cx.cache).and_then(|alias_def_id: DefId| match tcx.def_kind(alias_def_id) {
-            DefKind::TyAlias { .. } => Some(clean_middle_ty(
+            DefKind::TyAlias => Some(clean_middle_ty(
                 ty::Binder::dummy(tcx.type_of(def_id).instantiate_identity()),
                 cx,
                 Some(def_id.to_def_id()),
@@ -3078,7 +3088,7 @@ fn clean_maybe_renamed_foreign_item<'tcx>(
                     // NOTE: generics must be cleaned before args
                     let generics = clean_generics(generics, cx);
                     let args = clean_args_from_types_and_names(cx, decl.inputs, names);
-                    let decl = clean_fn_decl_with_args(cx, decl, args);
+                    let decl = clean_fn_decl_with_args(cx, decl, None, args);
                     (generics, decl)
                 });
                 ForeignFunctionItem(Box::new(Function { decl, generics }))
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index b665f684167..1d8fa2e636e 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -1384,28 +1384,6 @@ impl FnDecl {
     pub(crate) fn self_type(&self) -> Option<SelfTy> {
         self.inputs.values.get(0).and_then(|v| v.to_self())
     }
-
-    /// Returns the sugared return type for an async function.
-    ///
-    /// For example, if the return type is `impl std::future::Future<Output = i32>`, this function
-    /// will return `i32`.
-    ///
-    /// # Panics
-    ///
-    /// This function will panic if the return type does not match the expected sugaring for async
-    /// functions.
-    pub(crate) fn sugared_async_return_type(&self) -> Type {
-        if let Type::ImplTrait(v) = &self.output &&
-            let [GenericBound::TraitBound(PolyTrait { trait_, .. }, _ )] = &v[..]
-        {
-            let bindings = trait_.bindings().unwrap();
-            let ret_ty = bindings[0].term();
-            let ty = ret_ty.ty().expect("Unexpected constant return term");
-            ty.clone()
-        } else {
-            panic!("unexpected desugaring of async function")
-        }
-    }
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -1617,6 +1595,30 @@ impl Type {
         }
     }
 
+    /// Returns the sugared return type for an async function.
+    ///
+    /// For example, if the return type is `impl std::future::Future<Output = i32>`, this function
+    /// will return `i32`.
+    ///
+    /// # Panics
+    ///
+    /// This function will panic if the return type does not match the expected sugaring for async
+    /// functions.
+    pub(crate) fn sugared_async_return_type(self) -> Type {
+        if let Type::ImplTrait(mut v) = self
+            && let Some(GenericBound::TraitBound(PolyTrait { mut trait_, .. }, _ )) = v.pop()
+            && let Some(segment) = trait_.segments.pop()
+            && let GenericArgs::AngleBracketed { mut bindings, .. } = segment.args
+            && let Some(binding) = bindings.pop()
+            && let TypeBindingKind::Equality { term } = binding.kind
+            && let Term::Type(ty) = term
+        {
+            ty
+        } else {
+            panic!("unexpected async fn return type")
+        }
+    }
+
     /// Checks if this is a `T::Name` path for an associated type.
     pub(crate) fn is_assoc_ty(&self) -> bool {
         match self {
@@ -2189,16 +2191,6 @@ impl Path {
             }
         })
     }
-
-    pub(crate) fn bindings(&self) -> Option<&[TypeBinding]> {
-        self.segments.last().and_then(|seg| {
-            if let GenericArgs::AngleBracketed { ref bindings, .. } = seg.args {
-                Some(&**bindings)
-            } else {
-                None
-            }
-        })
-    }
 }
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -2478,15 +2470,6 @@ pub(crate) enum TypeBindingKind {
     Constraint { bounds: Vec<GenericBound> },
 }
 
-impl TypeBinding {
-    pub(crate) fn term(&self) -> &Term {
-        match self.kind {
-            TypeBindingKind::Equality { ref term } => term,
-            _ => panic!("expected equality type binding for parenthesized generic args"),
-        }
-    }
-}
-
 /// The type, lifetime, or constant that a private type alias's parameter should be
 /// replaced with when expanding a use of that type alias.
 ///
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index 24597c3aca3..741d329fb19 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -681,7 +681,7 @@ pub(crate) fn make_test(
             if s.contains(crate_name) {
                 // rustdoc implicitly inserts an `extern crate` item for the own crate
                 // which may be unused, so we need to allow the lint.
-                prog.push_str(&format!("#[allow(unused_extern_crates)]\n"));
+                prog.push_str("#[allow(unused_extern_crates)]\n");
 
                 prog.push_str(&format!("extern crate r#{crate_name};\n"));
                 line_offset += 1;
diff --git a/src/librustdoc/formats/item_type.rs b/src/librustdoc/formats/item_type.rs
index fd79160ff4a..be2ee791588 100644
--- a/src/librustdoc/formats/item_type.rs
+++ b/src/librustdoc/formats/item_type.rs
@@ -115,7 +115,7 @@ impl From<DefKind> for ItemType {
             DefKind::Struct => Self::Struct,
             DefKind::Union => Self::Union,
             DefKind::Trait => Self::Trait,
-            DefKind::TyAlias { .. } => Self::TypeAlias,
+            DefKind::TyAlias => Self::TypeAlias,
             DefKind::TraitAlias => Self::TraitAlias,
             DefKind::Macro(kind) => match kind {
                 MacroKind::Bang => ItemType::Macro,
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 6dbf2185e3d..d24e6e5faf5 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -1083,7 +1083,7 @@ impl<'a, 'tcx> TagIterator<'a, 'tcx> {
     }
 
     fn parse_in_attribute_block(&mut self) -> Option<LangStringToken<'a>> {
-        while let Some((pos, c)) = self.inner.next() {
+        if let Some((pos, c)) = self.inner.next() {
             if c == '}' {
                 self.is_in_attribute_block = false;
                 return self.next();
diff --git a/src/librustdoc/html/templates/type_layout.html b/src/librustdoc/html/templates/type_layout.html
index 287cbab07d2..b8b7785a2a1 100644
--- a/src/librustdoc/html/templates/type_layout.html
+++ b/src/librustdoc/html/templates/type_layout.html
@@ -9,12 +9,12 @@
             <strong>Note:</strong> Most layout information is <strong>completely {#+ #}
                 unstable</strong> and may even differ between compilations. {#+ #}
             The only exception is types with certain <code>repr(...)</code> {#+ #}
-            attributes. Please see the Rust Reference’s {#+ #}
+            attributes. Please see the Rust Reference's {#+ #}
             <a href="https://doc.rust-lang.org/reference/type-layout.html">“Type Layout”</a> {#+ #}
             chapter for details on type layout guarantees. {# #}
         </p> {# #}
     </div> {# #}
-    <p><strong>Size:</strong> {{ type_layout_size|safe }}</p> {# #}
+    <p><strong>Size:</strong> {{+ type_layout_size|safe }}</p> {# #}
     {% if !variants.is_empty() %}
     <p> {# #}
         <strong>Size for each variant:</strong> {# #}
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index 0db846bfc7e..d216305e6a9 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -522,8 +522,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
             ty::Alias(..)
             | ty::Closure(..)
             | ty::Generator(..)
-            | ty::GeneratorWitness(_)
-            | ty::GeneratorWitnessMIR(..)
+            | ty::GeneratorWitness(..)
             | ty::Dynamic(..)
             | ty::Param(_)
             | ty::Bound(..)
@@ -594,7 +593,7 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> {
                         .unwrap_or(Vec::new())
                 }
             }
-            Res::Def(DefKind::TyAlias { .. }, did) => {
+            Res::Def(DefKind::TyAlias, did) => {
                 // Resolve the link on the type the alias points to.
                 // FIXME: if the associated item is defined directly on the type alias,
                 // it will show up on its documentation page, we should link there instead.
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 42263494d29febc26d3c1ebdaa7b63677573ec4
+Subproject d404cba4e39df595710869988ded7cbe1104b52
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index 778609da062..5153dd26f4a 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -69,7 +69,6 @@ static TARGETS: &[&str] = &[
     "arm-unknown-linux-musleabihf",
     "armv5te-unknown-linux-gnueabi",
     "armv5te-unknown-linux-musleabi",
-    "armv7-apple-ios",
     "armv7-linux-androideabi",
     "thumbv7neon-linux-androideabi",
     "armv7-unknown-linux-gnueabi",
@@ -99,6 +98,8 @@ static TARGETS: &[&str] = &[
     "i686-unknown-linux-musl",
     "i686-unknown-uefi",
     "loongarch64-unknown-linux-gnu",
+    "loongarch64-unknown-none",
+    "loongarch64-unknown-none-softfloat",
     "m68k-unknown-linux-gnu",
     "csky-unknown-linux-gnuabiv2",
     "mips-unknown-linux-gnu",
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 414d9e3a6d8096f3e276234ce220c868767a879
+Subproject 59596f0f31a94fde48b5aa7e945cd0b7ceca962
diff --git a/src/tools/clippy/.github/workflows/remark.yml b/src/tools/clippy/.github/workflows/remark.yml
index 7d25b6a2b79..30bd476332f 100644
--- a/src/tools/clippy/.github/workflows/remark.yml
+++ b/src/tools/clippy/.github/workflows/remark.yml
@@ -21,7 +21,7 @@ jobs:
     - name: Setup Node.js
       uses: actions/setup-node@v3
       with:
-        node-version: '14.x'
+        node-version: '18.x'
 
     - name: Install remark
       run: npm install remark-cli remark-lint remark-lint-maximum-line-length remark-preset-lint-recommended remark-gfm
@@ -29,19 +29,19 @@ jobs:
     - name: Install mdbook
       run: |
         mkdir mdbook
-        curl -Lf https://github.com/rust-lang/mdBook/releases/download/v0.4.28/mdbook-v0.4.28-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook
+        curl -Lf https://github.com/rust-lang/mdBook/releases/download/v0.4.34/mdbook-v0.4.34-x86_64-unknown-linux-gnu.tar.gz | tar -xz --directory=./mdbook
         echo `pwd`/mdbook >> $GITHUB_PATH
 
     # Run
     - name: Check *.md files
-      run: git ls-files -z '*.md' | xargs -0 -n 1 -I {} ./node_modules/.bin/remark {} -u lint -f > /dev/null
+      run: ./node_modules/.bin/remark -u lint -f .
 
     - name: Linkcheck book
       run: |
         rustup toolchain install nightly --component rust-docs
         curl https://raw.githubusercontent.com/rust-lang/rust/master/src/tools/linkchecker/linkcheck.sh -o linkcheck.sh
         sh linkcheck.sh clippy --path ./book
-        
+
     - name: Build mdbook
       run: mdbook build book
 
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index a7ae4a0ee2c..8c9ab1e2402 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -5171,6 +5171,7 @@ Released 2018-09-13
 [`needless_bool_assign`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_bool_assign
 [`needless_borrow`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrow
 [`needless_borrowed_reference`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrowed_reference
+[`needless_borrows_for_generic_args`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_borrows_for_generic_args
 [`needless_collect`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_collect
 [`needless_continue`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_continue
 [`needless_doctest_main`]: https://rust-lang.github.io/rust-clippy/master/index.html#needless_doctest_main
@@ -5245,6 +5246,7 @@ Released 2018-09-13
 [`partialeq_ne_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_ne_impl
 [`partialeq_to_none`]: https://rust-lang.github.io/rust-clippy/master/index.html#partialeq_to_none
 [`path_buf_push_overwrite`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_buf_push_overwrite
+[`path_ends_with_ext`]: https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext
 [`pattern_type_mismatch`]: https://rust-lang.github.io/rust-clippy/master/index.html#pattern_type_mismatch
 [`permissions_set_readonly_false`]: https://rust-lang.github.io/rust-clippy/master/index.html#permissions_set_readonly_false
 [`positional_named_format_parameters`]: https://rust-lang.github.io/rust-clippy/master/index.html#positional_named_format_parameters
@@ -5279,6 +5281,7 @@ Released 2018-09-13
 [`readonly_write_lock`]: https://rust-lang.github.io/rust-clippy/master/index.html#readonly_write_lock
 [`recursive_format_impl`]: https://rust-lang.github.io/rust-clippy/master/index.html#recursive_format_impl
 [`redundant_allocation`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_allocation
+[`redundant_as_str`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_as_str
 [`redundant_async_block`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_async_block
 [`redundant_at_rest_pattern`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_at_rest_pattern
 [`redundant_clone`]: https://rust-lang.github.io/rust-clippy/master/index.html#redundant_clone
@@ -5437,6 +5440,7 @@ Released 2018-09-13
 [`unnecessary_join`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_join
 [`unnecessary_lazy_evaluations`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_lazy_evaluations
 [`unnecessary_literal_unwrap`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_literal_unwrap
+[`unnecessary_map_on_constructor`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_map_on_constructor
 [`unnecessary_mut_passed`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_mut_passed
 [`unnecessary_operation`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_operation
 [`unnecessary_owned_empty_strings`]: https://rust-lang.github.io/rust-clippy/master/index.html#unnecessary_owned_empty_strings
@@ -5574,5 +5578,6 @@ Released 2018-09-13
 [`allow-one-hash-in-raw-strings`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allow-one-hash-in-raw-strings
 [`absolute-paths-max-segments`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-max-segments
 [`absolute-paths-allowed-crates`]: https://doc.rust-lang.org/clippy/lint_configuration.html#absolute-paths-allowed-crates
+[`allowed-dotfiles`]: https://doc.rust-lang.org/clippy/lint_configuration.html#allowed-dotfiles
 [`enforce-iter-loop-reborrow`]: https://doc.rust-lang.org/clippy/lint_configuration.html#enforce-iter-loop-reborrow
 <!-- end autogenerated links to configuration documentation -->
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 2d8b590dbe3..66786004f6e 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -38,7 +38,6 @@ itertools = "0.10.1"
 
 # UI test dependencies
 clippy_utils = { path = "clippy_utils" }
-derive-new = "0.5"
 if_chain = "1.0"
 quote = "1.0"
 serde = { version = "1.0.125", features = ["derive"] }
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index 52c795e04fe..b980083f1f5 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -703,7 +703,7 @@ Minimum chars an ident can have, anything below or equal to this will be linted.
 ## `accept-comment-above-statement`
 Whether to accept a safety comment to be placed above the statement containing the `unsafe` block
 
-**Default Value:** `false` (`bool`)
+**Default Value:** `true` (`bool`)
 
 ---
 **Affected lints:**
@@ -713,7 +713,7 @@ Whether to accept a safety comment to be placed above the statement containing t
 ## `accept-comment-above-attributes`
 Whether to accept a safety comment to be placed above the attributes for the `unsafe` block
 
-**Default Value:** `false` (`bool`)
+**Default Value:** `true` (`bool`)
 
 ---
 **Affected lints:**
@@ -751,6 +751,16 @@ Which crates to allow absolute paths from
 * [`absolute_paths`](https://rust-lang.github.io/rust-clippy/master/index.html#absolute_paths)
 
 
+## `allowed-dotfiles`
+Additional dotfiles (files or directories starting with a dot) to allow
+
+**Default Value:** `{}` (`rustc_data_structures::fx::FxHashSet<String>`)
+
+---
+**Affected lints:**
+* [`path_ends_with_ext`](https://rust-lang.github.io/rust-clippy/master/index.html#path_ends_with_ext)
+
+
 ## `enforce-iter-loop-reborrow`
 #### Example
 ```
diff --git a/src/tools/clippy/clippy_lints/src/attrs.rs b/src/tools/clippy/clippy_lints/src/attrs.rs
index a88f2b51c82..0546807bac4 100644
--- a/src/tools/clippy/clippy_lints/src/attrs.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs.rs
@@ -616,7 +616,7 @@ fn check_should_panic_reason(cx: &LateContext<'_>, attr: &Attribute) {
             attr.span,
             "#[should_panic] attribute without a reason",
             "consider specifying the expected panic",
-            r#"#[should_panic(expected = /* panic message */)]"#.into(),
+            "#[should_panic(expected = /* panic message */)]".into(),
             Applicability::HasPlaceholders,
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
index d40a385435a..7dd808a7b3b 100644
--- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
+++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
@@ -2,9 +2,9 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::{match_def_path, paths};
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::DefId;
-use rustc_hir::{AsyncGeneratorKind, Body, BodyId, GeneratorKind};
+use rustc_hir::{AsyncGeneratorKind, Body, GeneratorKind};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::GeneratorInteriorTypeCause;
+use rustc_middle::mir::GeneratorLayout;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::{sym, Span};
 
@@ -197,28 +197,35 @@ impl LateLintPass<'_> for AwaitHolding {
     fn check_body(&mut self, cx: &LateContext<'_>, body: &'_ Body<'_>) {
         use AsyncGeneratorKind::{Block, Closure, Fn};
         if let Some(GeneratorKind::Async(Block | Closure | Fn)) = body.generator_kind {
-            let body_id = BodyId {
-                hir_id: body.value.hir_id,
-            };
-            let typeck_results = cx.tcx.typeck_body(body_id);
-            self.check_interior_types(
-                cx,
-                typeck_results.generator_interior_types.as_ref().skip_binder(),
-                body.value.span,
-            );
+            let def_id = cx.tcx.hir().body_owner_def_id(body.id());
+            if let Some(generator_layout) = cx.tcx.mir_generator_witnesses(def_id) {
+                self.check_interior_types(cx, generator_layout);
+            }
         }
     }
 }
 
 impl AwaitHolding {
-    fn check_interior_types(&self, cx: &LateContext<'_>, ty_causes: &[GeneratorInteriorTypeCause<'_>], span: Span) {
-        for ty_cause in ty_causes {
+    fn check_interior_types(&self, cx: &LateContext<'_>, generator: &GeneratorLayout<'_>) {
+        for (ty_index, ty_cause) in generator.field_tys.iter_enumerated() {
             if let rustc_middle::ty::Adt(adt, _) = ty_cause.ty.kind() {
+                let await_points = || {
+                    generator
+                        .variant_source_info
+                        .iter_enumerated()
+                        .filter_map(|(variant, source_info)| {
+                            generator.variant_fields[variant]
+                                .raw
+                                .contains(&ty_index)
+                                .then_some(source_info.span)
+                        })
+                        .collect::<Vec<_>>()
+                };
                 if is_mutex_guard(cx, adt.did()) {
                     span_lint_and_then(
                         cx,
                         AWAIT_HOLDING_LOCK,
-                        ty_cause.span,
+                        ty_cause.source_info.span,
                         "this `MutexGuard` is held across an `await` point",
                         |diag| {
                             diag.help(
@@ -226,7 +233,7 @@ impl AwaitHolding {
                                 `MutexGuard` is dropped before calling await",
                             );
                             diag.span_note(
-                                ty_cause.scope_span.unwrap_or(span),
+                                await_points(),
                                 "these are all the `await` points this lock is held through",
                             );
                         },
@@ -235,18 +242,18 @@ impl AwaitHolding {
                     span_lint_and_then(
                         cx,
                         AWAIT_HOLDING_REFCELL_REF,
-                        ty_cause.span,
+                        ty_cause.source_info.span,
                         "this `RefCell` reference is held across an `await` point",
                         |diag| {
                             diag.help("ensure the reference is dropped before calling `await`");
                             diag.span_note(
-                                ty_cause.scope_span.unwrap_or(span),
+                                await_points(),
                                 "these are all the `await` points this reference is held through",
                             );
                         },
                     );
                 } else if let Some(disallowed) = self.def_ids.get(&adt.did()) {
-                    emit_invalid_type(cx, ty_cause.span, disallowed);
+                    emit_invalid_type(cx, ty_cause.source_info.span, disallowed);
                 }
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
index cf07e050ccc..c586b572be9 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
@@ -25,7 +25,7 @@ pub(super) fn check(
     // The suggestion is to use a function call, so if the original expression
     // has parens on the outside, they are no longer needed.
     let mut applicability = Applicability::MachineApplicable;
-    let opt = snippet_opt(cx, cast_op.span);
+    let opt = snippet_opt(cx, cast_op.span.source_callsite());
     let sugg = opt.as_ref().map_or_else(
         || {
             applicability = Applicability::HasPlaceholders;
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
index 84b99ad5c24..f99a51e2b88 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs
@@ -44,7 +44,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
                 .unwrap_or(u64::max_value())
                 .min(apply_reductions(cx, nbits, left, signed)),
             BinOpKind::Shr => apply_reductions(cx, nbits, left, signed)
-                .saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).expect("shift too high"))),
+                .saturating_sub(constant_int(cx, right).map_or(0, |s| u64::try_from(s).unwrap_or_default())),
             _ => nbits,
         },
         ExprKind::MethodCall(method, left, [right], _) => {
diff --git a/src/tools/clippy/clippy_lints/src/casts/mod.rs b/src/tools/clippy/clippy_lints/src/casts/mod.rs
index 88ffbb55486..b00130ffd76 100644
--- a/src/tools/clippy/clippy_lints/src/casts/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/mod.rs
@@ -20,6 +20,7 @@ mod ptr_as_ptr;
 mod ptr_cast_constness;
 mod unnecessary_cast;
 mod utils;
+mod zero_ptr;
 
 use clippy_utils::is_hir_ty_cfg_dependant;
 use clippy_utils::msrvs::{self, Msrv};
@@ -665,6 +666,29 @@ declare_clippy_lint! {
     "casting a known floating-point NaN into an integer"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Catch casts from `0` to some pointer type
+    ///
+    /// ### Why is this bad?
+    /// This generally means `null` and is better expressed as
+    /// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.
+    ///
+    /// ### Example
+    /// ```rust
+    /// let a = 0 as *const u32;
+    /// ```
+    ///
+    /// Use instead:
+    /// ```rust
+    /// let a = std::ptr::null::<u32>();
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub ZERO_PTR,
+    style,
+    "using `0 as *{const, mut} T`"
+}
+
 pub struct Casts {
     msrv: Msrv,
 }
@@ -699,6 +723,7 @@ impl_lint_pass!(Casts => [
     CAST_SLICE_FROM_RAW_PARTS,
     AS_PTR_CAST_MUT,
     CAST_NAN_TO_INT,
+    ZERO_PTR,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Casts {
@@ -729,6 +754,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
             fn_to_numeric_cast_any::check(cx, expr, cast_expr, cast_from, cast_to);
             fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to);
             fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
+            zero_ptr::check(cx, expr, cast_expr, cast_to_hir);
 
             if cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) {
                 cast_possible_truncation::check(cx, expr, cast_expr, cast_from, cast_to, cast_to_hir.span);
diff --git a/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
new file mode 100644
index 00000000000..5071af5ecb9
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/casts/zero_ptr.rs
@@ -0,0 +1,39 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_opt;
+use clippy_utils::{in_constant, is_integer_literal, std_or_core};
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, Mutability, Ty, TyKind};
+use rustc_lint::LateContext;
+
+use super::ZERO_PTR;
+
+pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>) {
+    if let TyKind::Ptr(ref mut_ty) = to.kind
+        && is_integer_literal(from, 0)
+        && !in_constant(cx, from.hir_id)
+        && let Some(std_or_core) = std_or_core(cx)
+    {
+        let (msg, sugg_fn) = match mut_ty.mutbl {
+            Mutability::Mut => ("`0 as *mut _` detected", "ptr::null_mut"),
+            Mutability::Not => ("`0 as *const _` detected", "ptr::null"),
+        };
+
+        let sugg = if let TyKind::Infer = mut_ty.ty.kind {
+            format!("{std_or_core}::{sugg_fn}()")
+        } else if let Some(mut_ty_snip) = snippet_opt(cx, mut_ty.ty.span) {
+            format!("{std_or_core}::{sugg_fn}::<{mut_ty_snip}>()")
+        } else {
+            return;
+        };
+
+        span_lint_and_sugg(
+            cx,
+            ZERO_PTR,
+            expr.span,
+            msg,
+            "try",
+            sugg,
+            Applicability::MachineApplicable,
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index a4d40df52e7..4d1281ec1e7 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -97,6 +97,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::casts::PTR_AS_PTR_INFO,
     crate::casts::PTR_CAST_CONSTNESS_INFO,
     crate::casts::UNNECESSARY_CAST_INFO,
+    crate::casts::ZERO_PTR_INFO,
     crate::checked_conversions::CHECKED_CONVERSIONS_INFO,
     crate::cognitive_complexity::COGNITIVE_COMPLEXITY_INFO,
     crate::collapsible_if::COLLAPSIBLE_ELSE_IF_INFO,
@@ -399,9 +400,11 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::methods::OR_FUN_CALL_INFO,
     crate::methods::OR_THEN_UNWRAP_INFO,
     crate::methods::PATH_BUF_PUSH_OVERWRITE_INFO,
+    crate::methods::PATH_ENDS_WITH_EXT_INFO,
     crate::methods::RANGE_ZIP_WITH_LEN_INFO,
     crate::methods::READONLY_WRITE_LOCK_INFO,
     crate::methods::READ_LINE_WITHOUT_TRIM_INFO,
+    crate::methods::REDUNDANT_AS_STR_INFO,
     crate::methods::REPEAT_ONCE_INFO,
     crate::methods::RESULT_MAP_OR_INTO_OPTION_INFO,
     crate::methods::SEARCH_IS_SOME_INFO,
@@ -441,7 +444,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::misc::SHORT_CIRCUIT_STATEMENT_INFO,
     crate::misc::TOPLEVEL_REF_ARG_INFO,
     crate::misc::USED_UNDERSCORE_BINDING_INFO,
-    crate::misc::ZERO_PTR_INFO,
     crate::misc_early::BUILTIN_TYPE_SHADOW_INFO,
     crate::misc_early::DOUBLE_NEG_INFO,
     crate::misc_early::DUPLICATE_UNDERSCORE_ARGUMENT_INFO,
@@ -479,6 +481,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::needless_bool::NEEDLESS_BOOL_INFO,
     crate::needless_bool::NEEDLESS_BOOL_ASSIGN_INFO,
     crate::needless_borrowed_ref::NEEDLESS_BORROWED_REFERENCE_INFO,
+    crate::needless_borrows_for_generic_args::NEEDLESS_BORROWS_FOR_GENERIC_ARGS_INFO,
     crate::needless_continue::NEEDLESS_CONTINUE_INFO,
     crate::needless_else::NEEDLESS_ELSE_INFO,
     crate::needless_for_each::NEEDLESS_FOR_EACH_INFO,
@@ -671,6 +674,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::unnamed_address::FN_ADDRESS_COMPARISONS_INFO,
     crate::unnamed_address::VTABLE_ADDRESS_COMPARISONS_INFO,
     crate::unnecessary_box_returns::UNNECESSARY_BOX_RETURNS_INFO,
+    crate::unnecessary_map_on_constructor::UNNECESSARY_MAP_ON_CONSTRUCTOR_INFO,
     crate::unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS_INFO,
     crate::unnecessary_self_imports::UNNECESSARY_SELF_IMPORTS_INFO,
     crate::unnecessary_struct_initialization::UNNECESSARY_STRUCT_INITIALIZATION_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/default_union_representation.rs b/src/tools/clippy/clippy_lints/src/default_union_representation.rs
index bbce6e1dd8f..63ec8195020 100644
--- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs
+++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs
@@ -1,8 +1,8 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use rustc_hir::{self as hir, HirId, Item, ItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir::{HirId, Item, ItemKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf;
+use rustc_middle::ty::{self, FieldDef, GenericArg, List};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::sym;
 
@@ -52,7 +52,10 @@ declare_lint_pass!(DefaultUnionRepresentation => [DEFAULT_UNION_REPRESENTATION])
 
 impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
-        if is_union_with_two_non_zst_fields(cx, item) && !has_c_repr_attr(cx, item.hir_id()) {
+        if !item.span.from_expansion()
+            && is_union_with_two_non_zst_fields(cx, item)
+            && !has_c_repr_attr(cx, item.hir_id())
+        {
             span_lint_and_help(
                 cx,
                 DEFAULT_UNION_REPRESENTATION,
@@ -73,18 +76,17 @@ impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation {
 /// if there is only one field left after ignoring ZST fields then the offset
 /// of that field does not matter either.)
 fn is_union_with_two_non_zst_fields(cx: &LateContext<'_>, item: &Item<'_>) -> bool {
-    if let ItemKind::Union(data, _) = &item.kind {
-        data.fields().iter().filter(|f| !is_zst(cx, f.ty)).count() >= 2
+    if let ItemKind::Union(..) = &item.kind
+        && let ty::Adt(adt_def, args) = cx.tcx.type_of(item.owner_id).instantiate_identity().kind()
+    {
+        adt_def.all_fields().filter(|f| !is_zst(cx, f, args)).count() >= 2
     } else {
         false
     }
 }
 
-fn is_zst(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>) -> bool {
-    if hir_ty.span.from_expansion() {
-        return false;
-    }
-    let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+fn is_zst<'tcx>(cx: &LateContext<'tcx>, field: &FieldDef, args: &'tcx List<GenericArg<'tcx>>) -> bool {
+    let ty = field.ty(cx.tcx, args);
     if let Ok(layout) = cx.layout_of(ty) {
         layout.is_zst()
     } else {
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index 8090f821d1f..14877385646 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -1,41 +1,24 @@
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_hir_and_then};
-use clippy_utils::mir::{enclosing_mir, expr_local, local_assignments, used_exactly_once, PossibleBorrowerMap};
-use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::source::{snippet_with_applicability, snippet_with_context};
 use clippy_utils::sugg::has_enclosing_paren;
-use clippy_utils::ty::{implements_trait, is_copy, peel_mid_ty_refs};
+use clippy_utils::ty::{implements_trait, peel_mid_ty_refs};
 use clippy_utils::{
     expr_use_ctxt, get_parent_expr, get_parent_node, is_lint_allowed, path_to_local, DefinedTy, ExprUseNode,
 };
-
-use hir::def::DefKind;
-use hir::MatchSource;
 use rustc_ast::util::parser::{PREC_POSTFIX, PREC_PREFIX};
 use rustc_data_structures::fx::FxIndexMap;
-use rustc_data_structures::graph::iterate::{CycleDetector, TriColorDepthFirstSearch};
 use rustc_errors::Applicability;
-use rustc_hir::def::Res;
-use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::intravisit::{walk_ty, Visitor};
 use rustc_hir::{
-    self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, Mutability, Node, Pat, PatKind,
-    Path, QPath, TyKind, UnOp,
+    self as hir, BindingAnnotation, Body, BodyId, BorrowKind, Expr, ExprKind, HirId, MatchSource, Mutability, Node,
+    Pat, PatKind, Path, QPath, TyKind, UnOp,
 };
-use rustc_index::bit_set::BitSet;
-use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::mir::{Rvalue, StatementKind};
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AutoBorrow, AutoBorrowMutability};
-use rustc_middle::ty::{
-    self, ClauseKind, EarlyBinder, FnSig, GenericArg, GenericArgKind, List, ParamEnv, ParamTy, ProjectionPredicate, Ty,
-    TyCtxt, TypeVisitableExt, TypeckResults,
-};
+use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt, TypeVisitableExt, TypeckResults};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::symbol::sym;
 use rustc_span::{Span, Symbol};
-use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
-use rustc_trait_selection::traits::{Obligation, ObligationCause};
-use std::collections::VecDeque;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -183,24 +166,6 @@ pub struct Dereferencing<'tcx> {
     ///
     /// e.g. `m!(x) | Foo::Bar(ref x)`
     ref_locals: FxIndexMap<HirId, Option<RefPat>>,
-
-    /// Stack of (body owner, `PossibleBorrowerMap`) pairs. Used by
-    /// `needless_borrow_impl_arg_position` to determine when a borrowed expression can instead
-    /// be moved.
-    possible_borrowers: Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
-
-    // `IntoIterator` for arrays requires Rust 1.53.
-    msrv: Msrv,
-}
-
-impl<'tcx> Dereferencing<'tcx> {
-    #[must_use]
-    pub fn new(msrv: Msrv) -> Self {
-        Self {
-            msrv,
-            ..Dereferencing::default()
-        }
-    }
 }
 
 #[derive(Debug)]
@@ -355,52 +320,6 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
                         ));
                     },
                     (Some(use_cx), RefOp::AddrOf(mutability)) => {
-                        let defined_ty = use_cx.node.defined_ty(cx);
-
-                        // Check needless_borrow for generic arguments.
-                        if !use_cx.is_ty_unified
-                            && let Some(DefinedTy::Mir(ty)) = defined_ty
-                            && let ty::Param(ty) = *ty.value.skip_binder().kind()
-                            && let Some((hir_id, fn_id, i)) = match use_cx.node {
-                                ExprUseNode::MethodArg(_, _, 0) => None,
-                                ExprUseNode::MethodArg(hir_id, None, i) => {
-                                    typeck.type_dependent_def_id(hir_id).map(|id| (hir_id, id, i))
-                                },
-                                ExprUseNode::FnArg(&Expr { kind: ExprKind::Path(ref p), hir_id, .. }, i)
-                                if !path_has_args(p) => match typeck.qpath_res(p, hir_id) {
-                                    Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) => {
-                                        Some((hir_id, id, i))
-                                    },
-                                    _ => None,
-                                },
-                                _ => None,
-                            } && let count = needless_borrow_generic_arg_count(
-                                cx,
-                                &mut self.possible_borrowers,
-                                fn_id,
-                                typeck.node_args(hir_id),
-                                i,
-                                ty,
-                                expr,
-                                &self.msrv,
-                            ) && count != 0
-                        {
-                            self.state = Some((
-                                State::DerefedBorrow(DerefedBorrow {
-                                    count: count - 1,
-                                    msg: "the borrowed expression implements the required traits",
-                                    stability: TyCoercionStability::None,
-                                    for_field_access: None,
-                                }),
-                                StateData {
-                                    span: expr.span,
-                                    hir_id: expr.hir_id,
-                                    adjusted_ty: use_cx.adjustments.last().map_or(expr_ty, |a| a.target),
-                                },
-                            ));
-                            return;
-                        }
-
                         // Find the number of times the borrow is auto-derefed.
                         let mut iter = use_cx.adjustments.iter();
                         let mut deref_count = 0usize;
@@ -419,7 +338,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
                             };
                         };
 
-                        let stability = defined_ty.map_or(TyCoercionStability::None, |ty| {
+                        let stability = use_cx.node.defined_ty(cx).map_or(TyCoercionStability::None, |ty| {
                             TyCoercionStability::for_defined_ty(cx, ty, use_cx.node.is_return())
                         });
                         let can_auto_borrow = match use_cx.node {
@@ -700,12 +619,6 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
     }
 
     fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
-        if self.possible_borrowers.last().map_or(false, |&(local_def_id, _)| {
-            local_def_id == cx.tcx.hir().body_owner_def_id(body.id())
-        }) {
-            self.possible_borrowers.pop();
-        }
-
         if Some(body.id()) == self.current_body {
             for pat in self.ref_locals.drain(..).filter_map(|(_, x)| x) {
                 let replacements = pat.replacements;
@@ -729,8 +642,6 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
             self.current_body = None;
         }
     }
-
-    extract_msrv_attr!(LateContext);
 }
 
 fn try_parse_ref_op<'tcx>(
@@ -788,13 +699,6 @@ fn deref_method_same_type<'tcx>(result_ty: Ty<'tcx>, arg_ty: Ty<'tcx>) -> bool {
     }
 }
 
-fn path_has_args(p: &QPath<'_>) -> bool {
-    match *p {
-        QPath::Resolved(_, Path { segments: [.., s], .. }) | QPath::TypeRelative(_, s) => s.args.is_some(),
-        _ => false,
-    }
-}
-
 fn in_postfix_position<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>) -> bool {
     if let Some(parent) = get_parent_expr(cx, e)
         && parent.span.ctxt() == e.span.ctxt()
@@ -940,7 +844,6 @@ impl TyCoercionStability {
                 | ty::FnDef(..)
                 | ty::Generator(..)
                 | ty::GeneratorWitness(..)
-                | ty::GeneratorWitnessMIR(..)
                 | ty::Closure(..)
                 | ty::Never
                 | ty::Tuple(_)
@@ -981,274 +884,6 @@ fn ty_contains_infer(ty: &hir::Ty<'_>) -> bool {
     v.0
 }
 
-/// Checks for the number of borrow expressions which can be removed from the given expression
-/// where the expression is used as an argument to a function expecting a generic type.
-///
-/// The following constraints will be checked:
-/// * The borrowed expression meets all the generic type's constraints.
-/// * The generic type appears only once in the functions signature.
-/// * The borrowed value will not be moved if it is used later in the function.
-#[expect(clippy::too_many_arguments)]
-fn needless_borrow_generic_arg_count<'tcx>(
-    cx: &LateContext<'tcx>,
-    possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
-    fn_id: DefId,
-    callee_args: &'tcx List<GenericArg<'tcx>>,
-    arg_index: usize,
-    param_ty: ParamTy,
-    mut expr: &Expr<'tcx>,
-    msrv: &Msrv,
-) -> usize {
-    let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait();
-    let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
-
-    let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder();
-    let predicates = cx.tcx.param_env(fn_id).caller_bounds();
-    let projection_predicates = predicates
-        .iter()
-        .filter_map(|predicate| {
-            if let ClauseKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
-                Some(projection_predicate)
-            } else {
-                None
-            }
-        })
-        .collect::<Vec<_>>();
-
-    let mut trait_with_ref_mut_self_method = false;
-
-    // If no traits were found, or only the `Destruct`, `Sized`, or `Any` traits were found, return.
-    if predicates
-        .iter()
-        .filter_map(|predicate| {
-            if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
-                && trait_predicate.trait_ref.self_ty() == param_ty.to_ty(cx.tcx)
-            {
-                Some(trait_predicate.trait_ref.def_id)
-            } else {
-                None
-            }
-        })
-        .inspect(|trait_def_id| {
-            trait_with_ref_mut_self_method |= has_ref_mut_self_method(cx, *trait_def_id);
-        })
-        .all(|trait_def_id| {
-            Some(trait_def_id) == destruct_trait_def_id
-                || Some(trait_def_id) == sized_trait_def_id
-                || cx.tcx.is_diagnostic_item(sym::Any, trait_def_id)
-        })
-    {
-        return 0;
-    }
-
-    // See:
-    // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1289294201
-    // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1292225232
-    if projection_predicates
-        .iter()
-        .any(|projection_predicate| is_mixed_projection_predicate(cx, fn_id, projection_predicate))
-    {
-        return 0;
-    }
-
-    // `args_with_referent_ty` can be constructed outside of `check_referent` because the same
-    // elements are modified each time `check_referent` is called.
-    let mut args_with_referent_ty = callee_args.to_vec();
-
-    let mut check_reference_and_referent = |reference, referent| {
-        let referent_ty = cx.typeck_results().expr_ty(referent);
-
-        if !is_copy(cx, referent_ty)
-            && (referent_ty.has_significant_drop(cx.tcx, cx.param_env)
-                || !referent_used_exactly_once(cx, possible_borrowers, reference))
-        {
-            return false;
-        }
-
-        // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
-        if trait_with_ref_mut_self_method && !matches!(referent_ty.kind(), ty::Ref(_, _, Mutability::Mut)) {
-            return false;
-        }
-
-        if !replace_types(
-            cx,
-            param_ty,
-            referent_ty,
-            fn_sig,
-            arg_index,
-            &projection_predicates,
-            &mut args_with_referent_ty,
-        ) {
-            return false;
-        }
-
-        predicates.iter().all(|predicate| {
-            if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
-                && cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id)
-                && let ty::Param(param_ty) = trait_predicate.self_ty().kind()
-                && let GenericArgKind::Type(ty) = args_with_referent_ty[param_ty.index as usize].unpack()
-                && ty.is_array()
-                && !msrv.meets(msrvs::ARRAY_INTO_ITERATOR)
-            {
-                return false;
-            }
-
-            let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty);
-            let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
-            let infcx = cx.tcx.infer_ctxt().build();
-            infcx.predicate_must_hold_modulo_regions(&obligation)
-        })
-    };
-
-    let mut count = 0;
-    while let ExprKind::AddrOf(_, _, referent) = expr.kind {
-        if !check_reference_and_referent(expr, referent) {
-            break;
-        }
-        expr = referent;
-        count += 1;
-    }
-    count
-}
-
-fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
-    cx.tcx
-        .associated_items(trait_def_id)
-        .in_definition_order()
-        .any(|assoc_item| {
-            if assoc_item.fn_has_self_parameter {
-                let self_ty = cx
-                    .tcx
-                    .fn_sig(assoc_item.def_id)
-                    .instantiate_identity()
-                    .skip_binder()
-                    .inputs()[0];
-                matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Mut))
-            } else {
-                false
-            }
-        })
-}
-
-fn is_mixed_projection_predicate<'tcx>(
-    cx: &LateContext<'tcx>,
-    callee_def_id: DefId,
-    projection_predicate: &ProjectionPredicate<'tcx>,
-) -> bool {
-    let generics = cx.tcx.generics_of(callee_def_id);
-    // The predicate requires the projected type to equal a type parameter from the parent context.
-    if let Some(term_ty) = projection_predicate.term.ty()
-        && let ty::Param(term_param_ty) = term_ty.kind()
-        && (term_param_ty.index as usize) < generics.parent_count
-    {
-        // The inner-most self type is a type parameter from the current function.
-        let mut projection_ty = projection_predicate.projection_ty;
-        loop {
-            match projection_ty.self_ty().kind() {
-                ty::Alias(ty::Projection, inner_projection_ty) => {
-                    projection_ty = *inner_projection_ty;
-                }
-                ty::Param(param_ty) => {
-                    return (param_ty.index as usize) >= generics.parent_count;
-                }
-                _ => {
-                    return false;
-                }
-            }
-        }
-    } else {
-        false
-    }
-}
-
-fn referent_used_exactly_once<'tcx>(
-    cx: &LateContext<'tcx>,
-    possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
-    reference: &Expr<'tcx>,
-) -> bool {
-    if let Some(mir) = enclosing_mir(cx.tcx, reference.hir_id)
-        && let Some(local) = expr_local(cx.tcx, reference)
-        && let [location] = *local_assignments(mir, local).as_slice()
-        && let Some(statement) = mir.basic_blocks[location.block].statements.get(location.statement_index)
-        && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
-        && !place.is_indirect_first_projection()
-        // Ensure not in a loop (https://github.com/rust-lang/rust-clippy/issues/9710)
-        && TriColorDepthFirstSearch::new(&mir.basic_blocks).run_from(location.block, &mut CycleDetector).is_none()
-    {
-        let body_owner_local_def_id = cx.tcx.hir().enclosing_body_owner(reference.hir_id);
-        if possible_borrowers
-            .last()
-            .map_or(true, |&(local_def_id, _)| local_def_id != body_owner_local_def_id)
-        {
-            possible_borrowers.push((body_owner_local_def_id, PossibleBorrowerMap::new(cx, mir)));
-        }
-        let possible_borrower = &mut possible_borrowers.last_mut().unwrap().1;
-        // If `only_borrowers` were used here, the `copyable_iterator::warn` test would fail. The reason is
-        // that `PossibleBorrowerVisitor::visit_terminator` considers `place.local` a possible borrower of
-        // itself. See the comment in that method for an explanation as to why.
-        possible_borrower.bounded_borrowers(&[local], &[local, place.local], place.local, location)
-            && used_exactly_once(mir, place.local).unwrap_or(false)
-    } else {
-        false
-    }
-}
-
-// Iteratively replaces `param_ty` with `new_ty` in `args`, and similarly for each resulting
-// projected type that is a type parameter. Returns `false` if replacing the types would have an
-// effect on the function signature beyond substituting `new_ty` for `param_ty`.
-// See: https://github.com/rust-lang/rust-clippy/pull/9136#discussion_r927212757
-fn replace_types<'tcx>(
-    cx: &LateContext<'tcx>,
-    param_ty: ParamTy,
-    new_ty: Ty<'tcx>,
-    fn_sig: FnSig<'tcx>,
-    arg_index: usize,
-    projection_predicates: &[ProjectionPredicate<'tcx>],
-    args: &mut [ty::GenericArg<'tcx>],
-) -> bool {
-    let mut replaced = BitSet::new_empty(args.len());
-
-    let mut deque = VecDeque::with_capacity(args.len());
-    deque.push_back((param_ty, new_ty));
-
-    while let Some((param_ty, new_ty)) = deque.pop_front() {
-        // If `replaced.is_empty()`, then `param_ty` and `new_ty` are those initially passed in.
-        if !fn_sig
-            .inputs_and_output
-            .iter()
-            .enumerate()
-            .all(|(i, ty)| (replaced.is_empty() && i == arg_index) || !ty.contains(param_ty.to_ty(cx.tcx)))
-        {
-            return false;
-        }
-
-        args[param_ty.index as usize] = ty::GenericArg::from(new_ty);
-
-        // The `replaced.insert(...)` check provides some protection against infinite loops.
-        if replaced.insert(param_ty.index) {
-            for projection_predicate in projection_predicates {
-                if projection_predicate.projection_ty.self_ty() == param_ty.to_ty(cx.tcx)
-                    && let Some(term_ty) = projection_predicate.term.ty()
-                    && let ty::Param(term_param_ty) = term_ty.kind()
-                {
-                    let projection = cx.tcx.mk_ty_from_kind(ty::Alias(
-                        ty::Projection,
-                        projection_predicate.projection_ty.with_self_ty(cx.tcx, new_ty),
-                    ));
-
-                    if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection)
-                        && args[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty)
-                    {
-                        deque.push_back((*term_param_ty, projected_ty));
-                    }
-                }
-            }
-        }
-    }
-
-    true
-}
-
 fn ty_contains_field(ty: Ty<'_>, name: Symbol) -> bool {
     if let ty::Adt(adt, _) = *ty.kind() {
         adt.is_struct() && adt.all_fields().any(|f| f.name == name)
diff --git a/src/tools/clippy/clippy_lints/src/doc.rs b/src/tools/clippy/clippy_lints/src/doc.rs
index bf2add6aa64..e789e0da679 100644
--- a/src/tools/clippy/clippy_lints/src/doc.rs
+++ b/src/tools/clippy/clippy_lints/src/doc.rs
@@ -459,7 +459,7 @@ struct Fragments<'a> {
 
 impl Fragments<'_> {
     fn span(self, cx: &LateContext<'_>, range: Range<usize>) -> Option<Span> {
-        source_span_for_markdown_range(cx.tcx, &self.doc, &range, &self.fragments)
+        source_span_for_markdown_range(cx.tcx, self.doc, &range, self.fragments)
     }
 }
 
@@ -513,6 +513,7 @@ fn check_attrs(cx: &LateContext<'_>, valid_idents: &FxHashSet<String>, attrs: &[
 
 const RUST_CODE: &[&str] = &["rust", "no_run", "should_panic", "compile_fail"];
 
+#[allow(clippy::too_many_lines)] // Only a big match statement
 fn check_doc<'a, Events: Iterator<Item = (pulldown_cmark::Event<'a>, Range<usize>)>>(
     cx: &LateContext<'_>,
     valid_idents: &FxHashSet<String>,
diff --git a/src/tools/clippy/clippy_lints/src/enum_variants.rs b/src/tools/clippy/clippy_lints/src/enum_variants.rs
index d4df6f7aa2d..e332f681b6d 100644
--- a/src/tools/clippy/clippy_lints/src/enum_variants.rs
+++ b/src/tools/clippy/clippy_lints/src/enum_variants.rs
@@ -167,7 +167,10 @@ fn check_variant(cx: &LateContext<'_>, threshold: u64, def: &EnumDef<'_>, item_n
         return;
     }
 
-    let first = &def.variants[0].ident.name.as_str();
+    let first = match def.variants.first() {
+        Some(variant) => variant.ident.name.as_str(),
+        None => return,
+    };
     let mut pre = camel_case_split(first);
     let mut post = pre.clone();
     post.reverse();
diff --git a/src/tools/clippy/clippy_lints/src/error_impl_error.rs b/src/tools/clippy/clippy_lints/src/error_impl_error.rs
index 379af9b2234..f24577c7382 100644
--- a/src/tools/clippy/clippy_lints/src/error_impl_error.rs
+++ b/src/tools/clippy/clippy_lints/src/error_impl_error.rs
@@ -3,7 +3,6 @@ use clippy_utils::path_res;
 use clippy_utils::ty::implements_trait;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::{Item, ItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::Visibility;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -42,9 +41,10 @@ impl<'tcx> LateLintPass<'tcx> for ErrorImplError {
         };
 
         match item.kind {
-            ItemKind::TyAlias(ty, _) if implements_trait(cx, hir_ty_to_ty(cx.tcx, ty), error_def_id, &[])
-                && item.ident.name == sym::Error
-                && is_visible_outside_module(cx, item.owner_id.def_id) =>
+            ItemKind::TyAlias(..) if item.ident.name == sym::Error
+                && is_visible_outside_module(cx, item.owner_id.def_id)
+                && let ty = cx.tcx.type_of(item.owner_id).instantiate_identity()
+                && implements_trait(cx, ty, error_def_id, &[]) =>
             {
                 span_lint(
                     cx,
diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs
index 4b9ca8c917e..b612cc00bf9 100644
--- a/src/tools/clippy/clippy_lints/src/explicit_write.rs
+++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs
@@ -57,54 +57,52 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
             } else {
                 None
             }
+            && let Some(format_args) = find_format_args(cx, write_arg, ExpnId::root())
         {
-            find_format_args(cx, write_arg, ExpnId::root(), |format_args| {
-                let calling_macro =
-                    // ordering is important here, since `writeln!` uses `write!` internally
-                    if is_expn_of(write_call.span, "writeln").is_some() {
-                        Some("writeln")
-                    } else if is_expn_of(write_call.span, "write").is_some() {
-                        Some("write")
-                    } else {
-                        None
-                    };
-                let prefix = if dest_name == "stderr" {
-                    "e"
-                } else {
-                    ""
-                };
+            // ordering is important here, since `writeln!` uses `write!` internally
+            let calling_macro = if is_expn_of(write_call.span, "writeln").is_some() {
+                Some("writeln")
+            } else if is_expn_of(write_call.span, "write").is_some() {
+                Some("write")
+            } else {
+                None
+            };
+            let prefix = if dest_name == "stderr" {
+                "e"
+            } else {
+                ""
+            };
 
-                // We need to remove the last trailing newline from the string because the
-                // underlying `fmt::write` function doesn't know whether `println!` or `print!` was
-                // used.
-                let (used, sugg_mac) = if let Some(macro_name) = calling_macro {
-                    (
-                        format!("{macro_name}!({dest_name}(), ...)"),
-                        macro_name.replace("write", "print"),
-                    )
-                } else {
-                    (
-                        format!("{dest_name}().write_fmt(...)"),
-                        "print".into(),
-                    )
-                };
-                let mut applicability = Applicability::MachineApplicable;
-                let inputs_snippet = snippet_with_applicability(
-                    cx,
-                    format_args_inputs_span(format_args),
-                    "..",
-                    &mut applicability,
-                );
-                span_lint_and_sugg(
-                    cx,
-                    EXPLICIT_WRITE,
-                    expr.span,
-                    &format!("use of `{used}.unwrap()`"),
-                    "try",
-                    format!("{prefix}{sugg_mac}!({inputs_snippet})"),
-                    applicability,
-                );
-            });
+            // We need to remove the last trailing newline from the string because the
+            // underlying `fmt::write` function doesn't know whether `println!` or `print!` was
+            // used.
+            let (used, sugg_mac) = if let Some(macro_name) = calling_macro {
+                (
+                    format!("{macro_name}!({dest_name}(), ...)"),
+                    macro_name.replace("write", "print"),
+                )
+            } else {
+                (
+                    format!("{dest_name}().write_fmt(...)"),
+                    "print".into(),
+                )
+            };
+            let mut applicability = Applicability::MachineApplicable;
+            let inputs_snippet = snippet_with_applicability(
+                cx,
+                format_args_inputs_span(&format_args),
+                "..",
+                &mut applicability,
+            );
+            span_lint_and_sugg(
+                cx,
+                EXPLICIT_WRITE,
+                expr.span,
+                &format!("use of `{used}.unwrap()`"),
+                "try",
+                format!("{prefix}{sugg_mac}!({inputs_snippet})"),
+                applicability,
+            );
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
index c18006a71c2..0a885984abb 100644
--- a/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
+++ b/src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs
@@ -246,8 +246,13 @@ impl<'cx, 'tcx> Visitor<'tcx> for TypeWalker<'cx, 'tcx> {
                 {
                     self.ty_params.remove(&def_id);
                 }
+            } else {
+                // If the bounded type isn't a generic param, but is instead a concrete generic
+                // type, any params we find nested inside of it are being used as concrete types,
+                // and can therefore can be considered used. So, we're fine to walk the left-hand
+                // side of the where bound.
+                walk_ty(self, predicate.bounded_ty);
             }
-            // Only walk the right-hand side of where bounds
             for bound in predicate.bounds {
                 walk_param_bound(self, bound);
             }
diff --git a/src/tools/clippy/clippy_lints/src/format.rs b/src/tools/clippy/clippy_lints/src/format.rs
index f4f8bdc2c44..b748d329367 100644
--- a/src/tools/clippy/clippy_lints/src/format.rs
+++ b/src/tools/clippy/clippy_lints/src/format.rs
@@ -43,14 +43,10 @@ declare_lint_pass!(UselessFormat => [USELESS_FORMAT]);
 
 impl<'tcx> LateLintPass<'tcx> for UselessFormat {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
-            return;
-        };
-        if !cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id) {
-            return;
-        }
-
-        find_format_args(cx, expr, macro_call.expn, |format_args| {
+        if let Some(macro_call) = root_macro_call_first_node(cx, expr)
+            && cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id)
+            && let Some(format_args) = find_format_args(cx, expr, macro_call.expn)
+        {
             let mut applicability = Applicability::MachineApplicable;
             let call_site = macro_call.span;
 
@@ -91,7 +87,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessFormat {
                 },
                 _ => {},
             }
-        });
+        }
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index 01c714c414b..39abf5c2def 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -186,15 +186,10 @@ impl FormatArgs {
 
 impl<'tcx> LateLintPass<'tcx> for FormatArgs {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
-        let Some(macro_call) = root_macro_call_first_node(cx, expr) else {
-            return;
-        };
-        if !is_format_macro(cx, macro_call.def_id) {
-            return;
-        }
-        let name = cx.tcx.item_name(macro_call.def_id);
-
-        find_format_args(cx, expr, macro_call.expn, |format_args| {
+        if let Some(macro_call) = root_macro_call_first_node(cx, expr)
+            && is_format_macro(cx, macro_call.def_id)
+            && let Some(format_args) = find_format_args(cx, expr, macro_call.expn)
+        {
             for piece in &format_args.template {
                 if let FormatArgsPiece::Placeholder(placeholder) = piece
                     && let Ok(index) = placeholder.argument.index
@@ -206,12 +201,13 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
 
                     if placeholder.format_trait != FormatTrait::Display
                         || placeholder.format_options != FormatOptions::default()
-                        || is_aliased(format_args, index)
+                        || is_aliased(&format_args, index)
                     {
                         continue;
                     }
 
                     if let Ok(arg_hir_expr) = arg_expr {
+                        let name = cx.tcx.item_name(macro_call.def_id);
                         check_format_in_format_args(cx, macro_call.span, name, arg_hir_expr);
                         check_to_string_in_format_args(cx, name, arg_hir_expr);
                     }
@@ -219,9 +215,9 @@ impl<'tcx> LateLintPass<'tcx> for FormatArgs {
             }
 
             if self.msrv.meets(msrvs::FORMAT_ARGS_CAPTURE) {
-                check_uninlined_args(cx, format_args, macro_call.span, macro_call.def_id, self.ignore_mixed);
+                check_uninlined_args(cx, &format_args, macro_call.span, macro_call.def_id, self.ignore_mixed);
             }
-        });
+        }
     }
 
     extract_msrv_attr!(LateContext);
diff --git a/src/tools/clippy/clippy_lints/src/format_impl.rs b/src/tools/clippy/clippy_lints/src/format_impl.rs
index 76369bccf9e..1d2f7cb7130 100644
--- a/src/tools/clippy/clippy_lints/src/format_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/format_impl.rs
@@ -170,30 +170,29 @@ fn check_self_in_format_args<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>,
     if let Some(outer_macro) = root_macro_call_first_node(cx, expr)
         && let macro_def_id = outer_macro.def_id
         && is_format_macro(cx, macro_def_id)
+        && let Some(format_args) = find_format_args(cx, expr, outer_macro.expn)
     {
-        find_format_args(cx, expr, outer_macro.expn, |format_args| {
-            for piece in &format_args.template {
-                if let FormatArgsPiece::Placeholder(placeholder) = piece
-                    && let trait_name = match placeholder.format_trait {
-                        FormatTrait::Display => sym::Display,
-                        FormatTrait::Debug => sym::Debug,
-                        FormatTrait::LowerExp => sym!(LowerExp),
-                        FormatTrait::UpperExp => sym!(UpperExp),
-                        FormatTrait::Octal => sym!(Octal),
-                        FormatTrait::Pointer => sym::Pointer,
-                        FormatTrait::Binary => sym!(Binary),
-                        FormatTrait::LowerHex => sym!(LowerHex),
-                        FormatTrait::UpperHex => sym!(UpperHex),
-                    }
-                    && trait_name == impl_trait.name
-                    && let Ok(index) = placeholder.argument.index
-                    && let Some(arg) = format_args.arguments.all_args().get(index)
-                    && let Ok(arg_expr) = find_format_arg_expr(expr, arg)
-                {
-                    check_format_arg_self(cx, expr.span, arg_expr, impl_trait);
+        for piece in &format_args.template {
+            if let FormatArgsPiece::Placeholder(placeholder) = piece
+                && let trait_name = match placeholder.format_trait {
+                    FormatTrait::Display => sym::Display,
+                    FormatTrait::Debug => sym::Debug,
+                    FormatTrait::LowerExp => sym!(LowerExp),
+                    FormatTrait::UpperExp => sym!(UpperExp),
+                    FormatTrait::Octal => sym!(Octal),
+                    FormatTrait::Pointer => sym::Pointer,
+                    FormatTrait::Binary => sym!(Binary),
+                    FormatTrait::LowerHex => sym!(LowerHex),
+                    FormatTrait::UpperHex => sym!(UpperHex),
                 }
+                && trait_name == impl_trait.name
+                && let Ok(index) = placeholder.argument.index
+                && let Some(arg) = format_args.arguments.all_args().get(index)
+                && let Ok(arg_expr) = find_format_arg_expr(expr, arg)
+            {
+                check_format_arg_self(cx, expr.span, arg_expr, impl_trait);
             }
-        });
+        }
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs b/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs
index b00fa104f98..f95d2c2edb1 100644
--- a/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs
+++ b/src/tools/clippy/clippy_lints/src/init_numbered_fields.rs
@@ -50,7 +50,7 @@ impl<'tcx> LateLintPass<'tcx> for NumberedFields {
                 && fields
                     .iter()
                     .all(|f| f.ident.as_str().as_bytes().iter().all(u8::is_ascii_digit))
-                && !matches!(cx.qpath_res(path, e.hir_id), Res::Def(DefKind::TyAlias { .. }, ..))
+                && !matches!(cx.qpath_res(path, e.hir_id), Res::Def(DefKind::TyAlias, ..))
             {
                 let expr_spans = fields
                     .iter()
diff --git a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
index 9b26c3573e1..a4f3d498345 100644
--- a/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_const_arrays.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir::{Item, ItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::{self, ConstKind};
@@ -50,12 +49,12 @@ impl<'tcx> LateLintPass<'tcx> for LargeConstArrays {
     fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'_>) {
         if_chain! {
             if !item.span.from_expansion();
-            if let ItemKind::Const(hir_ty, generics, _) = &item.kind;
+            if let ItemKind::Const(_, generics, _) = &item.kind;
             // Since static items may not have generics, skip generic const items.
             // FIXME(generic_const_items): I don't think checking `generics.hwcp` suffices as it
             // doesn't account for empty where-clauses that only consist of keyword `where` IINM.
             if generics.params.is_empty() && !generics.has_where_clause_predicates;
-            let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+            let ty = cx.tcx.type_of(item.owner_id).instantiate_identity();
             if let ty::Array(element_type, cst) = ty.kind();
             if let ConstKind::Value(ty::ValTree::Leaf(element_count)) = cst.kind();
             if let Ok(element_count) = element_count.try_to_target_usize(cx.tcx);
diff --git a/src/tools/clippy/clippy_lints/src/large_futures.rs b/src/tools/clippy/clippy_lints/src/large_futures.rs
index d67d5899350..19f1e08b57a 100644
--- a/src/tools/clippy/clippy_lints/src/large_futures.rs
+++ b/src/tools/clippy/clippy_lints/src/large_futures.rs
@@ -17,26 +17,20 @@ declare_clippy_lint! {
     ///
     /// ### Example
     /// ```rust
-    /// async fn wait(f: impl std::future::Future<Output = ()>) {}
+    /// async fn large_future(_x: [u8; 16 * 1024]) {}
     ///
-    /// async fn big_fut(arg: [u8; 1024]) {}
-    ///
-    /// pub async fn test() {
-    ///     let fut = big_fut([0u8; 1024]);
-    ///     wait(fut).await;
+    /// pub async fn trigger() {
+    ///     large_future([0u8; 16 * 1024]).await;
     /// }
     /// ```
     ///
     /// `Box::pin` the big future instead.
     ///
     /// ```rust
-    /// async fn wait(f: impl std::future::Future<Output = ()>) {}
-    ///
-    /// async fn big_fut(arg: [u8; 1024]) {}
+    /// async fn large_future(_x: [u8; 16 * 1024]) {}
     ///
-    /// pub async fn test() {
-    ///     let fut = Box::pin(big_fut([0u8; 1024]));
-    ///     wait(fut).await;
+    /// pub async fn trigger() {
+    ///     Box::pin(large_future([0u8; 16 * 1024])).await;
     /// }
     /// ```
     #[clippy::version = "1.70.0"]
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index deba232bdd2..c06b35ca0da 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -424,6 +424,14 @@ fn check_for_is_empty(
     item_name: Symbol,
     item_kind: &str,
 ) {
+    // Implementor may be a type alias, in which case we need to get the `DefId` of the aliased type to
+    // find the correct inherent impls.
+    let impl_ty = if let Some(adt) = cx.tcx.type_of(impl_ty).skip_binder().ty_adt_def() {
+        adt.did()
+    } else {
+        return;
+    };
+
     let is_empty = Symbol::intern("is_empty");
     let is_empty = cx
         .tcx
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index f52614b6208..1271be2fd93 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -230,6 +230,7 @@ mod mutex_atomic;
 mod needless_arbitrary_self_type;
 mod needless_bool;
 mod needless_borrowed_ref;
+mod needless_borrows_for_generic_args;
 mod needless_continue;
 mod needless_else;
 mod needless_for_each;
@@ -331,6 +332,7 @@ mod unit_return_expecting_ord;
 mod unit_types;
 mod unnamed_address;
 mod unnecessary_box_returns;
+mod unnecessary_map_on_constructor;
 mod unnecessary_owned_empty_strings;
 mod unnecessary_self_imports;
 mod unnecessary_struct_initialization;
@@ -610,7 +612,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
                 .collect(),
         ))
     });
-    store.register_early_pass(|| Box::new(utils::format_args_collector::FormatArgsCollector));
+    store.register_early_pass(|| Box::<utils::format_args_collector::FormatArgsCollector>::default());
     store.register_late_pass(|_| Box::new(utils::dump_hir::DumpHir));
     store.register_late_pass(|_| Box::new(utils::author::Author));
     let await_holding_invalid_types = conf.await_holding_invalid_types.clone();
@@ -637,7 +639,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|_| Box::new(needless_bool::NeedlessBool));
     store.register_late_pass(|_| Box::new(needless_bool::BoolComparison));
     store.register_late_pass(|_| Box::new(needless_for_each::NeedlessForEach));
-    store.register_late_pass(|_| Box::<misc::LintPass>::default());
+    store.register_late_pass(|_| Box::new(misc::LintPass));
     store.register_late_pass(|_| Box::new(eta_reduction::EtaReduction));
     store.register_late_pass(|_| Box::new(mut_mut::MutMut));
     store.register_late_pass(|_| Box::new(mut_reference::UnnecessaryMutPassed));
@@ -663,12 +665,19 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     let allow_unwrap_in_tests = conf.allow_unwrap_in_tests;
     let suppress_restriction_lint_in_const = conf.suppress_restriction_lint_in_const;
     store.register_late_pass(move |_| Box::new(approx_const::ApproxConstant::new(msrv())));
+    let allowed_dotfiles = conf
+        .allowed_dotfiles
+        .iter()
+        .cloned()
+        .chain(methods::DEFAULT_ALLOWED_DOTFILES.iter().copied().map(ToOwned::to_owned))
+        .collect::<FxHashSet<_>>();
     store.register_late_pass(move |_| {
         Box::new(methods::Methods::new(
             avoid_breaking_exported_api,
             msrv(),
             allow_expect_in_tests,
             allow_unwrap_in_tests,
+            allowed_dotfiles.clone(),
         ))
     });
     store.register_late_pass(move |_| Box::new(matches::Matches::new(msrv())));
@@ -881,7 +890,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(move |_| Box::new(wildcard_imports::WildcardImports::new(warn_on_all_wildcard_imports)));
     store.register_late_pass(|_| Box::<redundant_pub_crate::RedundantPubCrate>::default());
     store.register_late_pass(|_| Box::new(unnamed_address::UnnamedAddress));
-    store.register_late_pass(move |_| Box::new(dereference::Dereferencing::new(msrv())));
+    store.register_late_pass(|_| Box::<dereference::Dereferencing<'_>>::default());
     store.register_late_pass(|_| Box::new(option_if_let_else::OptionIfLetElse));
     store.register_late_pass(|_| Box::new(future_not_send::FutureNotSend));
     let future_size_threshold = conf.future_size_threshold;
@@ -1104,6 +1113,12 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
     store.register_late_pass(|_| Box::<reserve_after_initialization::ReserveAfterInitialization>::default());
     store.register_late_pass(|_| Box::new(implied_bounds_in_impls::ImpliedBoundsInImpls));
     store.register_late_pass(|_| Box::new(missing_asserts_for_indexing::MissingAssertsForIndexing));
+    store.register_late_pass(|_| Box::new(unnecessary_map_on_constructor::UnnecessaryMapOnConstructor));
+    store.register_late_pass(move |_| {
+        Box::new(needless_borrows_for_generic_args::NeedlessBorrowsForGenericArgs::new(
+            msrv(),
+        ))
+    });
     // add lints here, do not remove this comment, it's used in `new_lint`
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/loops/utils.rs b/src/tools/clippy/clippy_lints/src/loops/utils.rs
index 6edca2d55f6..0a2bd89eb3c 100644
--- a/src/tools/clippy/clippy_lints/src/loops/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/utils.rs
@@ -5,7 +5,6 @@ use rustc_ast::ast::{LitIntType, LitKind};
 use rustc_errors::Applicability;
 use rustc_hir::intravisit::{walk_expr, walk_local, walk_pat, walk_stmt, Visitor};
 use rustc_hir::{BinOpKind, BorrowKind, Expr, ExprKind, HirId, HirIdMap, Local, Mutability, Pat, PatKind, Stmt};
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::LateContext;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::ty::{self, Ty};
@@ -150,7 +149,7 @@ impl<'a, 'tcx> Visitor<'tcx> for InitializeVisitor<'a, 'tcx> {
             if l.pat.hir_id == self.var_id;
             if let PatKind::Binding(.., ident, _) = l.pat.kind;
             then {
-                let ty = l.ty.map(|ty| hir_ty_to_ty(self.cx.tcx, ty));
+                let ty = l.ty.map(|_| self.cx.typeck_results().pat_ty(l.pat));
 
                 self.state = l.init.map_or(InitializeVisitorState::Declared(ident.name, ty), |init| {
                     InitializeVisitorState::Initialized {
diff --git a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
index c4f6852aedc..44dc29c36a6 100644
--- a/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/needless_match.rs
@@ -8,8 +8,7 @@ use clippy_utils::{
 };
 use rustc_errors::Applicability;
 use rustc_hir::LangItem::OptionNone;
-use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, FnRetTy, Guard, Node, Pat, PatKind, Path, QPath};
-use rustc_hir_analysis::hir_ty_to_ty;
+use rustc_hir::{Arm, BindingAnnotation, ByRef, Expr, ExprKind, Guard, ItemKind, Node, Pat, PatKind, Path, QPath};
 use rustc_lint::LateContext;
 use rustc_span::sym;
 
@@ -141,11 +140,15 @@ fn expr_ty_matches_p_ty(cx: &LateContext<'_>, expr: &Expr<'_>, p_expr: &Expr<'_>
                 return same_type_and_consts(results.node_type(local.hir_id), results.expr_ty(expr));
             },
             // compare match_expr ty with RetTy in `fn foo() -> RetTy`
-            Node::Item(..) => {
-                if let Some(fn_decl) = p_node.fn_decl() {
-                    if let FnRetTy::Return(ret_ty) = fn_decl.output {
-                        return same_type_and_consts(hir_ty_to_ty(cx.tcx, ret_ty), cx.typeck_results().expr_ty(expr));
-                    }
+            Node::Item(item) => {
+                if let ItemKind::Fn(..) = item.kind {
+                    let output = cx
+                        .tcx
+                        .fn_sig(item.owner_id)
+                        .instantiate_identity()
+                        .output()
+                        .skip_binder();
+                    return same_type_and_consts(output, cx.typeck_results().expr_ty(expr));
                 }
             },
             // check the parent expr for this whole block `{ match match_expr {..} }`
diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
index 29af4812351..0efeeacc9d9 100644
--- a/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/redundant_guards.rs
@@ -2,11 +2,12 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::path_to_local;
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::visitors::{for_each_expr, is_local_used};
-use rustc_ast::LitKind;
+use rustc_ast::{BorrowKind, LitKind};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Arm, BinOpKind, Expr, ExprKind, Guard, MatchSource, Node, Pat, PatKind};
 use rustc_lint::LateContext;
+use rustc_span::symbol::Ident;
 use rustc_span::Span;
 use std::ops::ControlFlow;
 
@@ -34,32 +35,45 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
                 ],
                 MatchSource::Normal,
             ) = if_expr.kind
+            && let Some(binding) = get_pat_binding(cx, scrutinee, outer_arm)
         {
+            let pat_span = match (arm.pat.kind, binding.byref_ident) {
+                (PatKind::Ref(pat, _), Some(_)) => pat.span,
+                (PatKind::Ref(..), None) | (_, Some(_)) => continue,
+                _ => arm.pat.span,
+            };
             emit_redundant_guards(
                 cx,
                 outer_arm,
                 if_expr.span,
-                scrutinee,
-                arm.pat.span,
+                pat_span,
+                &binding,
                 arm.guard,
             );
         }
         // `Some(x) if let Some(2) = x`
-        else if let Guard::IfLet(let_expr) = guard {
+        else if let Guard::IfLet(let_expr) = guard
+            && let Some(binding) = get_pat_binding(cx, let_expr.init, outer_arm)
+        {
+            let pat_span = match (let_expr.pat.kind, binding.byref_ident) {
+                (PatKind::Ref(pat, _), Some(_)) => pat.span,
+                (PatKind::Ref(..), None) | (_, Some(_)) => continue,
+                _ => let_expr.pat.span,
+            };
             emit_redundant_guards(
                 cx,
                 outer_arm,
                 let_expr.span,
-                let_expr.init,
-                let_expr.pat.span,
+                pat_span,
+                &binding,
                 None,
             );
         }
         // `Some(x) if x == Some(2)`
+        // `Some(x) if Some(2) == x`
         else if let Guard::If(if_expr) = guard
             && let ExprKind::Binary(bin_op, local, pat) = if_expr.kind
             && matches!(bin_op.node, BinOpKind::Eq)
-            && expr_can_be_pat(cx, pat)
             // Ensure they have the same type. If they don't, we'd need deref coercion which isn't
             // possible (currently) in a pattern. In some cases, you can use something like
             // `as_deref` or similar but in general, we shouldn't lint this as it'd create an
@@ -67,43 +81,68 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, arms: &'tcx [Arm<'tcx>]) {
             //
             // This isn't necessary in the other two checks, as they must be a pattern already.
             && cx.typeck_results().expr_ty(local) == cx.typeck_results().expr_ty(pat)
+            // Since we want to lint on both `x == Some(2)` and `Some(2) == x`, we might have to "swap"
+            // `local` and `pat`, depending on which side they are.
+            && let Some((binding, pat)) = get_pat_binding(cx, local, outer_arm)
+                .map(|binding| (binding, pat))
+                .or_else(|| get_pat_binding(cx, pat, outer_arm).map(|binding| (binding, local)))
+            && expr_can_be_pat(cx, pat)
         {
+            let pat_span = match (pat.kind, binding.byref_ident) {
+                (ExprKind::AddrOf(BorrowKind::Ref, _, expr), Some(_)) => expr.span,
+                (ExprKind::AddrOf(..), None) | (_, Some(_)) => continue,
+                _ => pat.span,
+            };
             emit_redundant_guards(
                 cx,
                 outer_arm,
                 if_expr.span,
-                local,
-                pat.span,
+                pat_span,
+                &binding,
                 None,
             );
         }
     }
 }
 
-fn get_pat_binding<'tcx>(cx: &LateContext<'tcx>, guard_expr: &Expr<'_>, outer_arm: &Arm<'tcx>) -> Option<(Span, bool)> {
+struct PatBindingInfo {
+    span: Span,
+    byref_ident: Option<Ident>,
+    is_field: bool,
+}
+
+fn get_pat_binding<'tcx>(
+    cx: &LateContext<'tcx>,
+    guard_expr: &Expr<'_>,
+    outer_arm: &Arm<'tcx>,
+) -> Option<PatBindingInfo> {
     if let Some(local) = path_to_local(guard_expr) && !is_local_used(cx, outer_arm.body, local) {
         let mut span = None;
+        let mut byref_ident = None;
         let mut multiple_bindings = false;
         // `each_binding` gives the `HirId` of the `Pat` itself, not the binding
         outer_arm.pat.walk(|pat| {
-            if let PatKind::Binding(_, hir_id, _, _) = pat.kind
+            if let PatKind::Binding(bind_annot, hir_id, ident, _) = pat.kind
                 && hir_id == local
-                && span.replace(pat.span).is_some()
             {
-                multiple_bindings = true;
-                return false;
+                if matches!(bind_annot.0, rustc_ast::ByRef::Yes) {
+                    let _ = byref_ident.insert(ident);
+                }
+                // the second call of `replace()` returns a `Some(span)`, meaning a multi-binding pattern
+                if span.replace(pat.span).is_some() {
+                    multiple_bindings = true;
+                    return false;
+                }
             }
-
             true
         });
 
         // Ignore bindings from or patterns, like `First(x) | Second(x, _) | Third(x, _, _)`
         if !multiple_bindings {
-            return span.map(|span| {
-                (
-                    span,
-                    !matches!(cx.tcx.hir().get_parent(local), Node::PatField(_)),
-                )
+            return span.map(|span| PatBindingInfo {
+                span,
+                byref_ident,
+                is_field: matches!(cx.tcx.hir().get_parent(local), Node::PatField(_)),
             });
         }
     }
@@ -115,14 +154,11 @@ fn emit_redundant_guards<'tcx>(
     cx: &LateContext<'tcx>,
     outer_arm: &Arm<'tcx>,
     guard_span: Span,
-    local: &Expr<'_>,
     pat_span: Span,
+    pat_binding: &PatBindingInfo,
     inner_guard: Option<Guard<'_>>,
 ) {
     let mut app = Applicability::MaybeIncorrect;
-    let Some((pat_binding, can_use_shorthand)) = get_pat_binding(cx, local, outer_arm) else {
-        return;
-    };
 
     span_lint_and_then(
         cx,
@@ -131,14 +167,21 @@ fn emit_redundant_guards<'tcx>(
         "redundant guard",
         |diag| {
             let binding_replacement = snippet_with_applicability(cx, pat_span, "<binding_repl>", &mut app);
+            let suggestion_span = match *pat_binding {
+                PatBindingInfo {
+                    span,
+                    byref_ident: Some(ident),
+                    is_field: true,
+                } => (span, format!("{ident}: {binding_replacement}")),
+                PatBindingInfo {
+                    span, is_field: true, ..
+                } => (span.shrink_to_hi(), format!(": {binding_replacement}")),
+                PatBindingInfo { span, .. } => (span, binding_replacement.into_owned()),
+            };
             diag.multipart_suggestion_verbose(
                 "try",
                 vec![
-                    if can_use_shorthand {
-                        (pat_binding, binding_replacement.into_owned())
-                    } else {
-                        (pat_binding.shrink_to_hi(), format!(": {binding_replacement}"))
-                    },
+                    suggestion_span,
                     (
                         guard_span.source_callsite().with_lo(outer_arm.pat.span.hi()),
                         inner_guard.map_or_else(String::new, |guard| {
diff --git a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
index d3e90e4bba3..40e487bf650 100644
--- a/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs
@@ -131,13 +131,12 @@ pub(super) fn check<'tcx>(
 
     let mut applicability = Applicability::MachineApplicable;
 
-    //Special handling for `format!` as arg_root
+    // Special handling for `format!` as arg_root
     if let Some(macro_call) = root_macro_call_first_node(cx, arg_root) {
-        if !cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id) {
-            return;
-        }
-        find_format_args(cx, arg_root, macro_call.expn, |format_args| {
-            let span = format_args_inputs_span(format_args);
+        if cx.tcx.is_diagnostic_item(sym::format_macro, macro_call.def_id)
+            && let Some(format_args) = find_format_args(cx, arg_root, macro_call.expn)
+        {
+            let span = format_args_inputs_span(&format_args);
             let sugg = snippet_with_applicability(cx, span, "..", &mut applicability);
             span_lint_and_sugg(
                 cx,
@@ -148,7 +147,7 @@ pub(super) fn check<'tcx>(
                 format!("unwrap_or_else({closure_args} panic!({sugg}))"),
                 applicability,
             );
-        });
+        }
         return;
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
index fafc9709770..33657254965 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_bool_then.rs
@@ -8,6 +8,7 @@ use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
+use rustc_middle::ty::adjustment::Adjust;
 use rustc_middle::ty::Binder;
 use rustc_span::{sym, Span};
 
@@ -36,6 +37,11 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &
         && let Some(def_id) = cx.typeck_results().type_dependent_def_id(value.hir_id)
         && match_def_path(cx, def_id, &BOOL_THEN)
         && !is_from_proc_macro(cx, expr)
+        // Count the number of derefs needed to get to the bool because we need those in the suggestion
+        && let needed_derefs = cx.typeck_results().expr_adjustments(recv)
+            .iter()
+            .filter(|adj| matches!(adj.kind, Adjust::Deref(_)))
+            .count()
         && let Some(param_snippet) = snippet_opt(cx, param.span)
         && let Some(filter) = snippet_opt(cx, recv.span)
         && let Some(map) = snippet_opt(cx, then_body.span)
@@ -46,7 +52,10 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>, arg: &
             call_span,
             "usage of `bool::then` in `filter_map`",
             "use `filter` then `map` instead",
-            format!("filter(|&{param_snippet}| {filter}).map(|{param_snippet}| {map})"),
+            format!(
+                "filter(|&{param_snippet}| {derefs}{filter}).map(|{param_snippet}| {map})",
+                derefs="*".repeat(needed_derefs)
+            ),
             Applicability::MachineApplicable,
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index 81223fa8d95..e7fcef9e9de 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -74,9 +74,11 @@ mod option_map_unwrap_or;
 mod or_fun_call;
 mod or_then_unwrap;
 mod path_buf_push_overwrite;
+mod path_ends_with_ext;
 mod range_zip_with_len;
 mod read_line_without_trim;
 mod readonly_write_lock;
+mod redundant_as_str;
 mod repeat_once;
 mod search_is_some;
 mod seek_from_current;
@@ -120,9 +122,10 @@ use clippy_utils::msrvs::{self, Msrv};
 use clippy_utils::ty::{contains_ty_adt_constructor_opaque, implements_trait, is_copy, is_type_diagnostic_item};
 use clippy_utils::{contains_return, is_bool, is_trait_method, iter_input_pats, peel_blocks, return_ty};
 use if_chain::if_chain;
+pub use path_ends_with_ext::DEFAULT_ALLOWED_DOTFILES;
+use rustc_data_structures::fx::FxHashSet;
 use rustc_hir as hir;
 use rustc_hir::{Expr, ExprKind, Node, Stmt, StmtKind, TraitItem, TraitItemKind};
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::{self, TraitRef, Ty};
@@ -3563,11 +3566,77 @@ declare_clippy_lint! {
     "calls to `.take()` or `.skip()` that are out of bounds"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Looks for calls to `Path::ends_with` calls where the argument looks like a file extension.
+    ///
+    /// By default, Clippy has a short list of known filenames that start with a dot
+    /// but aren't necessarily file extensions (e.g. the `.git` folder), which are allowed by default.
+    /// The `allowed-dotfiles` configuration can be used to allow additional
+    /// file extensions that Clippy should not lint.
+    ///
+    /// ### Why is this bad?
+    /// This doesn't actually compare file extensions. Rather, `ends_with` compares the given argument
+    /// to the last **component** of the path and checks if it matches exactly.
+    ///
+    /// ### Known issues
+    /// File extensions are often at most three characters long, so this only lints in those cases
+    /// in an attempt to avoid false positives.
+    /// Any extension names longer than that are assumed to likely be real path components and are
+    /// therefore ignored.
+    ///
+    /// ### Example
+    /// ```rust
+    /// # use std::path::Path;
+    /// fn is_markdown(path: &Path) -> bool {
+    ///     path.ends_with(".md")
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// # use std::path::Path;
+    /// fn is_markdown(path: &Path) -> bool {
+    ///     path.extension().is_some_and(|ext| ext == "md")
+    /// }
+    /// ```
+    #[clippy::version = "1.74.0"]
+    pub PATH_ENDS_WITH_EXT,
+    suspicious,
+    "attempting to compare file extensions using `Path::ends_with`"
+}
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for usage of `as_str()` on a `String`` chained with a method available on the `String` itself.
+    ///
+    /// ### Why is this bad?
+    /// The `as_str()` conversion is pointless and can be removed for simplicity and cleanliness.
+    ///
+    /// ### Example
+    /// ```rust
+    /// # #![allow(unused)]
+    /// let owned_string = "This is a string".to_owned();
+    /// owned_string.as_str().as_bytes();
+    /// ```
+    ///
+    /// Use instead:
+    /// ```rust
+    /// # #![allow(unused)]
+    /// let owned_string = "This is a string".to_owned();
+    /// owned_string.as_bytes();
+    /// ```
+    #[clippy::version = "1.74.0"]
+    pub REDUNDANT_AS_STR,
+    complexity,
+    "`as_str` used to call a method on `str` that is also available on `String`"
+}
+
 pub struct Methods {
     avoid_breaking_exported_api: bool,
     msrv: Msrv,
     allow_expect_in_tests: bool,
     allow_unwrap_in_tests: bool,
+    allowed_dotfiles: FxHashSet<String>,
 }
 
 impl Methods {
@@ -3577,12 +3646,14 @@ impl Methods {
         msrv: Msrv,
         allow_expect_in_tests: bool,
         allow_unwrap_in_tests: bool,
+        allowed_dotfiles: FxHashSet<String>,
     ) -> Self {
         Self {
             avoid_breaking_exported_api,
             msrv,
             allow_expect_in_tests,
             allow_unwrap_in_tests,
+            allowed_dotfiles,
         }
     }
 }
@@ -3703,6 +3774,8 @@ impl_lint_pass!(Methods => [
     FILTER_MAP_BOOL_THEN,
     READONLY_WRITE_LOCK,
     ITER_OUT_OF_BOUNDS,
+    PATH_ENDS_WITH_EXT,
+    REDUNDANT_AS_STR,
 ]);
 
 /// Extracts a method call name, args, and `Span` of the method name.
@@ -3852,18 +3925,20 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
         if_chain! {
             if let TraitItemKind::Fn(ref sig, _) = item.kind;
             if sig.decl.implicit_self.has_implicit_self();
-            if let Some(first_arg_ty) = sig.decl.inputs.iter().next();
-
+            if let Some(first_arg_hir_ty) = sig.decl.inputs.first();
+            if let Some(&first_arg_ty) = cx.tcx.fn_sig(item.owner_id)
+                .instantiate_identity()
+                .inputs()
+                .skip_binder()
+                .first();
             then {
-                let first_arg_span = first_arg_ty.span;
-                let first_arg_ty = hir_ty_to_ty(cx.tcx, first_arg_ty);
                 let self_ty = TraitRef::identity(cx.tcx, item.owner_id.to_def_id()).self_ty();
                 wrong_self_convention::check(
                     cx,
                     item.ident.name.as_str(),
                     self_ty,
                     first_arg_ty,
-                    first_arg_span,
+                    first_arg_hir_ty.span,
                     false,
                     true,
                 );
@@ -3929,6 +4004,7 @@ impl Methods {
                 ("as_deref" | "as_deref_mut", []) => {
                     needless_option_as_deref::check(cx, expr, recv, name);
                 },
+                ("as_bytes" | "is_empty", []) => if let Some(("as_str", recv, [], as_str_span, _)) = method_call(recv) { redundant_as_str::check(cx, expr, recv, as_str_span, span); },
                 ("as_mut", []) => useless_asref::check(cx, expr, "as_mut", recv),
                 ("as_ref", []) => useless_asref::check(cx, expr, "as_ref", recv),
                 ("assume_init", []) => uninit_assumed_init::check(cx, expr, recv),
@@ -3978,6 +4054,7 @@ impl Methods {
                     if let ExprKind::MethodCall(.., span) = expr.kind {
                         case_sensitive_file_extension_comparisons::check(cx, expr, span, recv, arg);
                     }
+                    path_ends_with_ext::check(cx, recv, arg, expr, &self.msrv, &self.allowed_dotfiles);
                 },
                 ("expect", [_]) => {
                     match method_call(recv) {
diff --git a/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs b/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs
new file mode 100644
index 00000000000..3347c8c1620
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/path_ends_with_ext.rs
@@ -0,0 +1,53 @@
+use super::PATH_ENDS_WITH_EXT;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::msrvs;
+use clippy_utils::msrvs::Msrv;
+use clippy_utils::source::snippet;
+use clippy_utils::ty::is_type_diagnostic_item;
+use rustc_ast::{LitKind, StrStyle};
+use rustc_data_structures::fx::FxHashSet;
+use rustc_errors::Applicability;
+use rustc_hir::{Expr, ExprKind};
+use rustc_lint::LateContext;
+use rustc_span::sym;
+use std::fmt::Write;
+
+pub const DEFAULT_ALLOWED_DOTFILES: &[&str] = &[
+    "git", "svn", "gem", "npm", "vim", "env", "rnd", "ssh", "vnc", "smb", "nvm", "bin",
+];
+
+pub(super) fn check(
+    cx: &LateContext<'_>,
+    recv: &Expr<'_>,
+    path: &Expr<'_>,
+    expr: &Expr<'_>,
+    msrv: &Msrv,
+    allowed_dotfiles: &FxHashSet<String>,
+) {
+    if is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv).peel_refs(), sym::Path)
+        && !path.span.from_expansion()
+        && let ExprKind::Lit(lit) = path.kind
+        && let LitKind::Str(path, StrStyle::Cooked) = lit.node
+        && let Some(path) = path.as_str().strip_prefix('.')
+        && (1..=3).contains(&path.len())
+        && !allowed_dotfiles.contains(path)
+        && path.chars().all(char::is_alphanumeric)
+    {
+        let mut sugg = snippet(cx, recv.span, "..").into_owned();
+        if msrv.meets(msrvs::OPTION_IS_SOME_AND) {
+            let _ = write!(sugg, r#".extension().is_some_and(|ext| ext == "{path}")"#);
+        } else {
+            let _ = write!(sugg, r#".extension().map_or(false, |ext| ext == "{path}")"#);
+        };
+
+        span_lint_and_sugg(
+            cx,
+            PATH_ENDS_WITH_EXT,
+            expr.span,
+            "this looks like a failed attempt at checking for the file extension",
+            "try",
+            sugg,
+            Applicability::MaybeIncorrect
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/redundant_as_str.rs b/src/tools/clippy/clippy_lints/src/methods/redundant_as_str.rs
new file mode 100644
index 00000000000..98cd6afc2b7
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/methods/redundant_as_str.rs
@@ -0,0 +1,34 @@
+use super::REDUNDANT_AS_STR;
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use rustc_errors::Applicability;
+use rustc_hir::Expr;
+use rustc_lint::LateContext;
+use rustc_middle::query::Key;
+use rustc_span::Span;
+
+pub(super) fn check(
+    cx: &LateContext<'_>,
+    _expr: &Expr<'_>,
+    recv: &Expr<'_>,
+    as_str_span: Span,
+    other_method_span: Span,
+) {
+    if cx
+        .tcx
+        .lang_items()
+        .string()
+        .is_some_and(|id| Some(id) == cx.typeck_results().expr_ty(recv).ty_adt_id())
+    {
+        let mut applicability = Applicability::MachineApplicable;
+        span_lint_and_sugg(
+            cx,
+            REDUNDANT_AS_STR,
+            as_str_span.to(other_method_span),
+            "this `as_str` is redundant and can be removed as the method immediately following exists on `String` too",
+            "try",
+            snippet_with_applicability(cx, other_method_span, "..", &mut applicability).into_owned(),
+            applicability,
+        );
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
index 5c5ee262052..50d6f3b7e55 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs
@@ -401,7 +401,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
                     = get_callee_generic_args_and_args(cx, parent_expr)
                 {
                     // FIXME: the `instantiate_identity()` below seems incorrect, since we eventually
-                    // call `tcx.try_subst_and_normalize_erasing_regions` further down
+                    // call `tcx.try_instantiate_and_normalize_erasing_regions` further down
                     // (i.e., we are explicitly not in the identity context).
                     let fn_sig = cx.tcx.fn_sig(callee_def_id).instantiate_identity().skip_binder();
                     if let Some(arg_index) = recv.into_iter().chain(call_args).position(|arg| arg.hir_id == expr.hir_id)
@@ -452,7 +452,7 @@ fn can_change_type<'a>(cx: &LateContext<'a>, mut expr: &'a Expr<'a>, mut ty: Ty<
 
                         let output_ty = fn_sig.output();
                         if output_ty.contains(*param_ty) {
-                            if let Ok(new_ty)  = cx.tcx.try_subst_and_normalize_erasing_regions(
+                            if let Ok(new_ty)  = cx.tcx.try_instantiate_and_normalize_erasing_regions(
                                 new_subst, cx.param_env, EarlyBinder::bind(output_ty)) {
                                 expr = parent_expr;
                                 ty = new_ty;
diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs
index 303f0125690..9c8b47fb303 100644
--- a/src/tools/clippy/clippy_lints/src/misc.rs
+++ b/src/tools/clippy/clippy_lints/src/misc.rs
@@ -1,24 +1,22 @@
-use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_hir_and_then};
-use clippy_utils::source::{snippet, snippet_opt, snippet_with_context};
+use clippy_utils::diagnostics::{span_lint, span_lint_and_then, span_lint_hir_and_then};
+use clippy_utils::source::{snippet, snippet_with_context};
+use clippy_utils::sugg::Sugg;
+use clippy_utils::{
+    any_parent_is_automatically_derived, fulfill_or_allowed, get_parent_expr, is_lint_allowed, iter_input_pats,
+    last_path_segment, SpanlessEq,
+};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
+use rustc_hir::def::Res;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{
-    self as hir, def, BinOpKind, BindingAnnotation, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, Stmt,
-    StmtKind, TyKind,
+    BinOpKind, BindingAnnotation, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind,
 };
-use rustc_lint::{LateContext, LateLintPass};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
-use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::def_id::LocalDefId;
-use rustc_span::hygiene::DesugaringKind;
-use rustc_span::source_map::{ExpnKind, Span};
-
-use clippy_utils::sugg::Sugg;
-use clippy_utils::{
-    get_parent_expr, in_constant, is_integer_literal, is_lint_allowed, is_no_std_crate, iter_input_pats,
-    last_path_segment, SpanlessEq,
-};
+use rustc_span::source_map::Span;
 
 use crate::ref_patterns::REF_PATTERNS;
 
@@ -56,6 +54,7 @@ declare_clippy_lint! {
     style,
     "an entire binding declared as `ref`, in a function argument or a `let` statement"
 }
+
 declare_clippy_lint! {
     /// ### What it does
     /// Checks for the use of bindings with a single leading
@@ -103,51 +102,13 @@ declare_clippy_lint! {
     "using a short circuit boolean condition as a statement"
 }
 
-declare_clippy_lint! {
-    /// ### What it does
-    /// Catch casts from `0` to some pointer type
-    ///
-    /// ### Why is this bad?
-    /// This generally means `null` and is better expressed as
-    /// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.
-    ///
-    /// ### Example
-    /// ```rust
-    /// let a = 0 as *const u32;
-    /// ```
-    ///
-    /// Use instead:
-    /// ```rust
-    /// let a = std::ptr::null::<u32>();
-    /// ```
-    #[clippy::version = "pre 1.29.0"]
-    pub ZERO_PTR,
-    style,
-    "using `0 as *{const, mut} T`"
-}
-
-pub struct LintPass {
-    std_or_core: &'static str,
-}
-impl Default for LintPass {
-    fn default() -> Self {
-        Self { std_or_core: "std" }
-    }
-}
-impl_lint_pass!(LintPass => [
+declare_lint_pass!(LintPass => [
     TOPLEVEL_REF_ARG,
     USED_UNDERSCORE_BINDING,
     SHORT_CIRCUIT_STATEMENT,
-    ZERO_PTR,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for LintPass {
-    fn check_crate(&mut self, cx: &LateContext<'_>) {
-        if is_no_std_crate(cx) {
-            self.std_or_core = "core";
-        }
-    }
-
     fn check_fn(
         &mut self,
         cx: &LateContext<'tcx>,
@@ -253,50 +214,56 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
     }
 
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
-        if let ExprKind::Cast(e, ty) = expr.kind {
-            self.check_cast(cx, expr.span, e, ty);
-            return;
-        }
-        if in_attributes_expansion(expr) || expr.span.is_desugaring(DesugaringKind::Await) {
-            // Don't lint things expanded by #[derive(...)], etc or `await` desugaring
+        if in_external_macro(cx.sess(), expr.span)
+            || expr.span.desugaring_kind().is_some()
+            || any_parent_is_automatically_derived(cx.tcx, expr.hir_id)
+        {
             return;
         }
-        let sym;
-        let binding = match expr.kind {
-            ExprKind::Path(ref qpath) if !matches!(qpath, hir::QPath::LangItem(..)) => {
-                let binding = last_path_segment(qpath).ident.as_str();
-                if binding.starts_with('_') &&
-                    !binding.starts_with("__") &&
-                    binding != "_result" && // FIXME: #944
-                    is_used(cx, expr) &&
-                    // don't lint if the declaration is in a macro
-                    non_macro_local(cx, cx.qpath_res(qpath, expr.hir_id))
+        let (definition_hir_id, ident) = match expr.kind {
+            ExprKind::Path(ref qpath) => {
+                if let QPath::Resolved(None, path) = qpath
+                    && let Res::Local(id) = path.res
+                    && is_used(cx, expr)
                 {
-                    Some(binding)
+                    (id, last_path_segment(qpath).ident)
                 } else {
-                    None
+                    return;
                 }
             },
-            ExprKind::Field(_, ident) => {
-                sym = ident.name;
-                let name = sym.as_str();
-                if name.starts_with('_') && !name.starts_with("__") {
-                    Some(name)
+            ExprKind::Field(recv, ident) => {
+                if let Some(adt_def) = cx.typeck_results().expr_ty_adjusted(recv).ty_adt_def()
+                    && let Some(field) = adt_def.all_fields().find(|field| field.name == ident.name)
+                    && let Some(local_did) = field.did.as_local()
+                    && let Some(hir_id) = cx.tcx.opt_local_def_id_to_hir_id(local_did)
+                    && !cx.tcx.type_of(field.did).skip_binder().is_phantom_data()
+                {
+                    (hir_id, ident)
                 } else {
-                    None
+                    return;
                 }
             },
-            _ => None,
+            _ => return,
         };
-        if let Some(binding) = binding {
-            span_lint(
+
+        let name = ident.name.as_str();
+        if name.starts_with('_')
+            && !name.starts_with("__")
+            && let definition_span = cx.tcx.hir().span(definition_hir_id)
+            && !definition_span.from_expansion()
+            && !fulfill_or_allowed(cx, USED_UNDERSCORE_BINDING, [expr.hir_id, definition_hir_id])
+        {
+            span_lint_and_then(
                 cx,
                 USED_UNDERSCORE_BINDING,
                 expr.span,
                 &format!(
-                    "used binding `{binding}` which is prefixed with an underscore. A leading \
+                    "used binding `{name}` which is prefixed with an underscore. A leading \
                      underscore signals that a binding will not be used"
                 ),
+                |diag| {
+                    diag.span_note(definition_span, format!("`{name}` is defined here"));
+                }
             );
         }
     }
@@ -311,50 +278,3 @@ fn is_used(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
         _ => is_used(cx, parent),
     })
 }
-
-/// Tests whether an expression is in a macro expansion (e.g., something
-/// generated by `#[derive(...)]` or the like).
-fn in_attributes_expansion(expr: &Expr<'_>) -> bool {
-    use rustc_span::hygiene::MacroKind;
-    if expr.span.from_expansion() {
-        let data = expr.span.ctxt().outer_expn_data();
-        matches!(data.kind, ExpnKind::Macro(MacroKind::Attr | MacroKind::Derive, _))
-    } else {
-        false
-    }
-}
-
-/// Tests whether `res` is a variable defined outside a macro.
-fn non_macro_local(cx: &LateContext<'_>, res: def::Res) -> bool {
-    if let def::Res::Local(id) = res {
-        !cx.tcx.hir().span(id).from_expansion()
-    } else {
-        false
-    }
-}
-
-impl LintPass {
-    fn check_cast(&self, cx: &LateContext<'_>, span: Span, e: &Expr<'_>, ty: &hir::Ty<'_>) {
-        if_chain! {
-            if let TyKind::Ptr(ref mut_ty) = ty.kind;
-            if is_integer_literal(e, 0);
-            if !in_constant(cx, e.hir_id);
-            then {
-                let (msg, sugg_fn) = match mut_ty.mutbl {
-                    Mutability::Mut => ("`0 as *mut _` detected", "ptr::null_mut"),
-                    Mutability::Not => ("`0 as *const _` detected", "ptr::null"),
-                };
-
-                let (sugg, appl) = if let TyKind::Infer = mut_ty.ty.kind {
-                    (format!("{}::{sugg_fn}()", self.std_or_core), Applicability::MachineApplicable)
-                } else if let Some(mut_ty_snip) = snippet_opt(cx, mut_ty.ty.span) {
-                    (format!("{}::{sugg_fn}::<{mut_ty_snip}>()", self.std_or_core), Applicability::MachineApplicable)
-                } else {
-                    // `MaybeIncorrect` as type inference may not work with the suggested code
-                    (format!("{}::{sugg_fn}()", self.std_or_core), Applicability::MaybeIncorrect)
-                };
-                span_lint_and_sugg(cx, ZERO_PTR, span, msg, "try", sugg, appl);
-            }
-        }
-    }
-}
diff --git a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
index 3b7eccad79d..f598a65d2e4 100644
--- a/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_const_for_fn.rs
@@ -7,7 +7,6 @@ use rustc_hir as hir;
 use rustc_hir::def_id::CRATE_DEF_ID;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, Constness, FnDecl, GenericParamKind};
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
@@ -124,7 +123,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
             FnKind::Method(_, sig, ..) => {
                 if trait_ref_of_method(cx, def_id).is_some()
                     || already_const(sig.header)
-                    || method_accepts_droppable(cx, sig.decl.inputs)
+                    || method_accepts_droppable(cx, def_id)
                 {
                     return;
                 }
@@ -165,12 +164,11 @@ impl<'tcx> LateLintPass<'tcx> for MissingConstForFn {
 
 /// Returns true if any of the method parameters is a type that implements `Drop`. The method
 /// can't be made const then, because `drop` can't be const-evaluated.
-fn method_accepts_droppable(cx: &LateContext<'_>, param_tys: &[hir::Ty<'_>]) -> bool {
+fn method_accepts_droppable(cx: &LateContext<'_>, def_id: LocalDefId) -> bool {
+    let sig = cx.tcx.fn_sig(def_id).instantiate_identity().skip_binder();
+
     // If any of the params are droppable, return true
-    param_tys.iter().any(|hir_ty| {
-        let ty_ty = hir_ty_to_ty(cx.tcx, hir_ty);
-        has_drop(cx, ty_ty)
-    })
+    sig.inputs().iter().any(|&ty| has_drop(cx, ty))
 }
 
 // We don't have to lint on something that's already `const`
diff --git a/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
new file mode 100644
index 00000000000..d55c77a92b1
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs
@@ -0,0 +1,410 @@
+use clippy_utils::diagnostics::span_lint_and_then;
+use clippy_utils::mir::{enclosing_mir, expr_local, local_assignments, used_exactly_once, PossibleBorrowerMap};
+use clippy_utils::msrvs::{self, Msrv};
+use clippy_utils::source::snippet_with_context;
+use clippy_utils::ty::is_copy;
+use clippy_utils::{expr_use_ctxt, peel_n_hir_expr_refs, DefinedTy, ExprUseNode};
+use rustc_errors::Applicability;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::{Body, Expr, ExprKind, Mutability, Path, QPath};
+use rustc_index::bit_set::BitSet;
+use rustc_infer::infer::TyCtxtInferExt;
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_middle::mir::{Rvalue, StatementKind};
+use rustc_middle::ty::{
+    self, ClauseKind, EarlyBinder, FnSig, GenericArg, GenericArgKind, List, ParamTy, ProjectionPredicate, Ty,
+};
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::symbol::sym;
+use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
+use rustc_trait_selection::traits::{Obligation, ObligationCause};
+use std::collections::VecDeque;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for borrow operations (`&`) that used as a generic argument to a
+    /// function when the borrowed value could be used.
+    ///
+    /// ### Why is this bad?
+    /// Suggests that the receiver of the expression borrows
+    /// the expression.
+    ///
+    /// ### Known problems
+    /// The lint cannot tell when the implementation of a trait
+    /// for `&T` and `T` do different things. Removing a borrow
+    /// in such a case can change the semantics of the code.
+    ///
+    /// ### Example
+    /// ```rust
+    /// fn f(_: impl AsRef<str>) {}
+    ///
+    /// let x = "foo";
+    /// f(&x);
+    /// ```
+    ///
+    /// Use instead:
+    /// ```rust
+    /// fn f(_: impl AsRef<str>) {}
+    ///
+    /// let x = "foo";
+    /// f(x);
+    /// ```
+    #[clippy::version = "pre 1.29.0"]
+    pub NEEDLESS_BORROWS_FOR_GENERIC_ARGS,
+    style,
+    "taking a reference that is going to be automatically dereferenced"
+}
+
+pub struct NeedlessBorrowsForGenericArgs<'tcx> {
+    /// Stack of (body owner, `PossibleBorrowerMap`) pairs. Used by
+    /// `needless_borrow_impl_arg_position` to determine when a borrowed expression can instead
+    /// be moved.
+    possible_borrowers: Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
+
+    // `IntoIterator` for arrays requires Rust 1.53.
+    msrv: Msrv,
+}
+impl_lint_pass!(NeedlessBorrowsForGenericArgs<'_> => [NEEDLESS_BORROWS_FOR_GENERIC_ARGS]);
+
+impl NeedlessBorrowsForGenericArgs<'_> {
+    #[must_use]
+    pub fn new(msrv: Msrv) -> Self {
+        Self {
+            possible_borrowers: Vec::new(),
+            msrv,
+        }
+    }
+}
+
+impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowsForGenericArgs<'tcx> {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
+        if matches!(expr.kind, ExprKind::AddrOf(..))
+            && !expr.span.from_expansion()
+            && let Some(use_cx) = expr_use_ctxt(cx, expr)
+            && !use_cx.is_ty_unified
+            && let Some(DefinedTy::Mir(ty)) = use_cx.node.defined_ty(cx)
+            && let ty::Param(ty) = *ty.value.skip_binder().kind()
+            && let Some((hir_id, fn_id, i)) = match use_cx.node {
+                ExprUseNode::MethodArg(_, _, 0) => None,
+                ExprUseNode::MethodArg(hir_id, None, i) => {
+                    cx.typeck_results().type_dependent_def_id(hir_id).map(|id| (hir_id, id, i))
+                },
+                ExprUseNode::FnArg(&Expr { kind: ExprKind::Path(ref p), hir_id, .. }, i)
+                if !path_has_args(p) => match cx.typeck_results().qpath_res(p, hir_id) {
+                    Res::Def(DefKind::Fn | DefKind::Ctor(..) | DefKind::AssocFn, id) => {
+                        Some((hir_id, id, i))
+                    },
+                    _ => None,
+                },
+                _ => None,
+            } && let count = needless_borrow_count(
+                cx,
+                &mut self.possible_borrowers,
+                fn_id,
+                cx.typeck_results().node_args(hir_id),
+                i,
+                ty,
+                expr,
+                &self.msrv,
+            ) && count != 0
+        {
+            span_lint_and_then(
+                cx,
+                NEEDLESS_BORROWS_FOR_GENERIC_ARGS,
+                expr.span,
+                "the borrowed expression implements the required traits",
+                |diag| {
+                    let mut app = Applicability::MachineApplicable;
+                    let snip_span = peel_n_hir_expr_refs(expr, count).0.span;
+                    let snip = snippet_with_context(cx, snip_span, expr.span.ctxt(), "..", &mut app).0;
+                    diag.span_suggestion(expr.span, "change this to", snip.into_owned(), app);
+                }
+            );
+        }
+    }
+
+    fn check_body_post(&mut self, cx: &LateContext<'tcx>, body: &'tcx Body<'_>) {
+        if self.possible_borrowers.last().map_or(false, |&(local_def_id, _)| {
+            local_def_id == cx.tcx.hir().body_owner_def_id(body.id())
+        }) {
+            self.possible_borrowers.pop();
+        }
+    }
+
+    extract_msrv_attr!(LateContext);
+}
+
+fn path_has_args(p: &QPath<'_>) -> bool {
+    match *p {
+        QPath::Resolved(_, Path { segments: [.., s], .. }) | QPath::TypeRelative(_, s) => s.args.is_some(),
+        _ => false,
+    }
+}
+
+/// Checks for the number of borrow expressions which can be removed from the given expression
+/// where the expression is used as an argument to a function expecting a generic type.
+///
+/// The following constraints will be checked:
+/// * The borrowed expression meets all the generic type's constraints.
+/// * The generic type appears only once in the functions signature.
+/// * The borrowed value will not be moved if it is used later in the function.
+#[expect(clippy::too_many_arguments)]
+fn needless_borrow_count<'tcx>(
+    cx: &LateContext<'tcx>,
+    possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
+    fn_id: DefId,
+    callee_args: &'tcx List<GenericArg<'tcx>>,
+    arg_index: usize,
+    param_ty: ParamTy,
+    mut expr: &Expr<'tcx>,
+    msrv: &Msrv,
+) -> usize {
+    let destruct_trait_def_id = cx.tcx.lang_items().destruct_trait();
+    let sized_trait_def_id = cx.tcx.lang_items().sized_trait();
+
+    let fn_sig = cx.tcx.fn_sig(fn_id).instantiate_identity().skip_binder();
+    let predicates = cx.tcx.param_env(fn_id).caller_bounds();
+    let projection_predicates = predicates
+        .iter()
+        .filter_map(|predicate| {
+            if let ClauseKind::Projection(projection_predicate) = predicate.kind().skip_binder() {
+                Some(projection_predicate)
+            } else {
+                None
+            }
+        })
+        .collect::<Vec<_>>();
+
+    let mut trait_with_ref_mut_self_method = false;
+
+    // If no traits were found, or only the `Destruct`, `Sized`, or `Any` traits were found, return.
+    if predicates
+        .iter()
+        .filter_map(|predicate| {
+            if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
+                && trait_predicate.trait_ref.self_ty() == param_ty.to_ty(cx.tcx)
+            {
+                Some(trait_predicate.trait_ref.def_id)
+            } else {
+                None
+            }
+        })
+        .inspect(|trait_def_id| {
+            trait_with_ref_mut_self_method |= has_ref_mut_self_method(cx, *trait_def_id);
+        })
+        .all(|trait_def_id| {
+            Some(trait_def_id) == destruct_trait_def_id
+                || Some(trait_def_id) == sized_trait_def_id
+                || cx.tcx.is_diagnostic_item(sym::Any, trait_def_id)
+        })
+    {
+        return 0;
+    }
+
+    // See:
+    // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1289294201
+    // - https://github.com/rust-lang/rust-clippy/pull/9674#issuecomment-1292225232
+    if projection_predicates
+        .iter()
+        .any(|projection_predicate| is_mixed_projection_predicate(cx, fn_id, projection_predicate))
+    {
+        return 0;
+    }
+
+    // `args_with_referent_ty` can be constructed outside of `check_referent` because the same
+    // elements are modified each time `check_referent` is called.
+    let mut args_with_referent_ty = callee_args.to_vec();
+
+    let mut check_reference_and_referent = |reference, referent| {
+        let referent_ty = cx.typeck_results().expr_ty(referent);
+
+        if !is_copy(cx, referent_ty)
+            && (referent_ty.has_significant_drop(cx.tcx, cx.param_env)
+                || !referent_used_exactly_once(cx, possible_borrowers, reference))
+        {
+            return false;
+        }
+
+        // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
+        if trait_with_ref_mut_self_method && !matches!(referent_ty.kind(), ty::Ref(_, _, Mutability::Mut)) {
+            return false;
+        }
+
+        if !replace_types(
+            cx,
+            param_ty,
+            referent_ty,
+            fn_sig,
+            arg_index,
+            &projection_predicates,
+            &mut args_with_referent_ty,
+        ) {
+            return false;
+        }
+
+        predicates.iter().all(|predicate| {
+            if let ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder()
+                && cx.tcx.is_diagnostic_item(sym::IntoIterator, trait_predicate.trait_ref.def_id)
+                && let ty::Param(param_ty) = trait_predicate.self_ty().kind()
+                && let GenericArgKind::Type(ty) = args_with_referent_ty[param_ty.index as usize].unpack()
+                && ty.is_array()
+                && !msrv.meets(msrvs::ARRAY_INTO_ITERATOR)
+            {
+                return false;
+            }
+
+            let predicate = EarlyBinder::bind(predicate).instantiate(cx.tcx, &args_with_referent_ty);
+            let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), cx.param_env, predicate);
+            let infcx = cx.tcx.infer_ctxt().build();
+            infcx.predicate_must_hold_modulo_regions(&obligation)
+        })
+    };
+
+    let mut count = 0;
+    while let ExprKind::AddrOf(_, _, referent) = expr.kind {
+        if !check_reference_and_referent(expr, referent) {
+            break;
+        }
+        expr = referent;
+        count += 1;
+    }
+    count
+}
+
+fn has_ref_mut_self_method(cx: &LateContext<'_>, trait_def_id: DefId) -> bool {
+    cx.tcx
+        .associated_items(trait_def_id)
+        .in_definition_order()
+        .any(|assoc_item| {
+            if assoc_item.fn_has_self_parameter {
+                let self_ty = cx
+                    .tcx
+                    .fn_sig(assoc_item.def_id)
+                    .instantiate_identity()
+                    .skip_binder()
+                    .inputs()[0];
+                matches!(self_ty.kind(), ty::Ref(_, _, Mutability::Mut))
+            } else {
+                false
+            }
+        })
+}
+
+fn is_mixed_projection_predicate<'tcx>(
+    cx: &LateContext<'tcx>,
+    callee_def_id: DefId,
+    projection_predicate: &ProjectionPredicate<'tcx>,
+) -> bool {
+    let generics = cx.tcx.generics_of(callee_def_id);
+    // The predicate requires the projected type to equal a type parameter from the parent context.
+    if let Some(term_ty) = projection_predicate.term.ty()
+        && let ty::Param(term_param_ty) = term_ty.kind()
+        && (term_param_ty.index as usize) < generics.parent_count
+    {
+        // The inner-most self type is a type parameter from the current function.
+        let mut projection_ty = projection_predicate.projection_ty;
+        loop {
+            match projection_ty.self_ty().kind() {
+                ty::Alias(ty::Projection, inner_projection_ty) => {
+                    projection_ty = *inner_projection_ty;
+                }
+                ty::Param(param_ty) => {
+                    return (param_ty.index as usize) >= generics.parent_count;
+                }
+                _ => {
+                    return false;
+                }
+            }
+        }
+    } else {
+        false
+    }
+}
+
+fn referent_used_exactly_once<'tcx>(
+    cx: &LateContext<'tcx>,
+    possible_borrowers: &mut Vec<(LocalDefId, PossibleBorrowerMap<'tcx, 'tcx>)>,
+    reference: &Expr<'tcx>,
+) -> bool {
+    if let Some(mir) = enclosing_mir(cx.tcx, reference.hir_id)
+        && let Some(local) = expr_local(cx.tcx, reference)
+        && let [location] = *local_assignments(mir, local).as_slice()
+        && let block_data = &mir.basic_blocks[location.block]
+        && let Some(statement) = block_data.statements.get(location.statement_index)
+        && let StatementKind::Assign(box (_, Rvalue::Ref(_, _, place))) = statement.kind
+        && !place.is_indirect_first_projection()
+    {
+        let body_owner_local_def_id = cx.tcx.hir().enclosing_body_owner(reference.hir_id);
+        if possible_borrowers
+            .last()
+            .map_or(true, |&(local_def_id, _)| local_def_id != body_owner_local_def_id)
+        {
+            possible_borrowers.push((body_owner_local_def_id, PossibleBorrowerMap::new(cx, mir)));
+        }
+        let possible_borrower = &mut possible_borrowers.last_mut().unwrap().1;
+        // If `only_borrowers` were used here, the `copyable_iterator::warn` test would fail. The reason is
+        // that `PossibleBorrowerVisitor::visit_terminator` considers `place.local` a possible borrower of
+        // itself. See the comment in that method for an explanation as to why.
+        possible_borrower.bounded_borrowers(&[local], &[local, place.local], place.local, location)
+            && used_exactly_once(mir, place.local).unwrap_or(false)
+    } else {
+        false
+    }
+}
+
+// Iteratively replaces `param_ty` with `new_ty` in `args`, and similarly for each resulting
+// projected type that is a type parameter. Returns `false` if replacing the types would have an
+// effect on the function signature beyond substituting `new_ty` for `param_ty`.
+// See: https://github.com/rust-lang/rust-clippy/pull/9136#discussion_r927212757
+fn replace_types<'tcx>(
+    cx: &LateContext<'tcx>,
+    param_ty: ParamTy,
+    new_ty: Ty<'tcx>,
+    fn_sig: FnSig<'tcx>,
+    arg_index: usize,
+    projection_predicates: &[ProjectionPredicate<'tcx>],
+    args: &mut [ty::GenericArg<'tcx>],
+) -> bool {
+    let mut replaced = BitSet::new_empty(args.len());
+
+    let mut deque = VecDeque::with_capacity(args.len());
+    deque.push_back((param_ty, new_ty));
+
+    while let Some((param_ty, new_ty)) = deque.pop_front() {
+        // If `replaced.is_empty()`, then `param_ty` and `new_ty` are those initially passed in.
+        if !fn_sig
+            .inputs_and_output
+            .iter()
+            .enumerate()
+            .all(|(i, ty)| (replaced.is_empty() && i == arg_index) || !ty.contains(param_ty.to_ty(cx.tcx)))
+        {
+            return false;
+        }
+
+        args[param_ty.index as usize] = ty::GenericArg::from(new_ty);
+
+        // The `replaced.insert(...)` check provides some protection against infinite loops.
+        if replaced.insert(param_ty.index) {
+            for projection_predicate in projection_predicates {
+                if projection_predicate.projection_ty.self_ty() == param_ty.to_ty(cx.tcx)
+                    && let Some(term_ty) = projection_predicate.term.ty()
+                    && let ty::Param(term_param_ty) = term_ty.kind()
+                {
+                    let projection = cx.tcx.mk_ty_from_kind(ty::Alias(
+                        ty::Projection,
+                        projection_predicate.projection_ty.with_self_ty(cx.tcx, new_ty),
+                    ));
+
+                    if let Ok(projected_ty) = cx.tcx.try_normalize_erasing_regions(cx.param_env, projection)
+                        && args[term_param_ty.index as usize] != ty::GenericArg::from(projected_ty)
+                    {
+                        deque.push_back((*term_param_ty, projected_ty));
+                    }
+                }
+            }
+        }
+    }
+
+    true
+}
diff --git a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
index 7b00eabf97b..57652e5ff54 100644
--- a/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_pass_by_ref_mut.rs
@@ -1,6 +1,7 @@
 use super::needless_pass_by_value::requires_exact_signature;
 use clippy_utils::diagnostics::span_lint_hir_and_then;
 use clippy_utils::source::snippet;
+use clippy_utils::visitors::for_each_expr_with_closures;
 use clippy_utils::{get_parent_node, inherits_cfg, is_from_proc_macro, is_self};
 use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_errors::Applicability;
@@ -9,7 +10,7 @@ use rustc_hir::{
     Body, Closure, Expr, ExprKind, FnDecl, HirId, HirIdMap, HirIdSet, Impl, ItemKind, Mutability, Node, PatKind, QPath,
 };
 use rustc_hir_typeck::expr_use_visitor as euv;
-use rustc_infer::infer::TyCtxtInferExt;
+use rustc_infer::infer::{InferCtxt, TyCtxtInferExt};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::map::associated_body;
 use rustc_middle::hir::nested_filter::OnlyBodies;
@@ -21,6 +22,8 @@ use rustc_span::symbol::kw;
 use rustc_span::Span;
 use rustc_target::spec::abi::Abi;
 
+use core::ops::ControlFlow;
+
 declare_clippy_lint! {
     /// ### What it does
     /// Check if a `&mut` function argument is actually used mutably.
@@ -95,6 +98,30 @@ fn should_skip<'tcx>(
     is_from_proc_macro(cx, &input)
 }
 
+fn check_closures<'tcx>(
+    ctx: &mut MutablyUsedVariablesCtxt<'tcx>,
+    cx: &LateContext<'tcx>,
+    infcx: &InferCtxt<'tcx>,
+    checked_closures: &mut FxHashSet<LocalDefId>,
+    closures: FxHashSet<LocalDefId>,
+) {
+    let hir = cx.tcx.hir();
+    for closure in closures {
+        if !checked_closures.insert(closure) {
+            continue;
+        }
+        ctx.prev_bind = None;
+        ctx.prev_move_to_closure.clear();
+        if let Some(body) = hir
+            .find_by_def_id(closure)
+            .and_then(associated_body)
+            .map(|(_, body_id)| hir.body(body_id))
+        {
+            euv::ExprUseVisitor::new(ctx, infcx, closure, cx.param_env, cx.typeck_results()).consume_body(body);
+        }
+    }
+}
+
 impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
     fn check_fn(
         &mut self,
@@ -161,25 +188,22 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
             euv::ExprUseVisitor::new(&mut ctx, &infcx, fn_def_id, cx.param_env, cx.typeck_results()).consume_body(body);
             if is_async {
                 let mut checked_closures = FxHashSet::default();
+
+                // We retrieve all the closures declared in the async function because they will
+                // not be found by `euv::Delegate`.
+                let mut closures: FxHashSet<LocalDefId> = FxHashSet::default();
+                for_each_expr_with_closures(cx, body, |expr| {
+                    if let ExprKind::Closure(closure) = expr.kind {
+                        closures.insert(closure.def_id);
+                    }
+                    ControlFlow::<()>::Continue(())
+                });
+                check_closures(&mut ctx, cx, &infcx, &mut checked_closures, closures);
+
                 while !ctx.async_closures.is_empty() {
-                    let closures = ctx.async_closures.clone();
+                    let async_closures = ctx.async_closures.clone();
                     ctx.async_closures.clear();
-                    let hir = cx.tcx.hir();
-                    for closure in closures {
-                        if !checked_closures.insert(closure) {
-                            continue;
-                        }
-                        ctx.prev_bind = None;
-                        ctx.prev_move_to_closure.clear();
-                        if let Some(body) = hir
-                            .find_by_def_id(closure)
-                            .and_then(associated_body)
-                            .map(|(_, body_id)| hir.body(body_id))
-                        {
-                            euv::ExprUseVisitor::new(&mut ctx, &infcx, closure, cx.param_env, cx.typeck_results())
-                                .consume_body(body);
-                        }
-                    }
+                    check_closures(&mut ctx, cx, &infcx, &mut checked_closures, async_closures);
                 }
             }
             ctx
@@ -244,6 +268,10 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessPassByRefMut<'tcx> {
 struct MutablyUsedVariablesCtxt<'tcx> {
     mutably_used_vars: HirIdSet,
     prev_bind: Option<HirId>,
+    /// In async functions, the inner AST is composed of multiple layers until we reach the code
+    /// defined by the user. Because of that, some variables are marked as mutably borrowed even
+    /// though they're not. This field lists the `HirId` that should not be considered as mutable
+    /// use of a variable.
     prev_move_to_closure: HirIdSet,
     aliases: HirIdMap<HirId>,
     async_closures: FxHashSet<LocalDefId>,
@@ -308,7 +336,12 @@ impl<'tcx> euv::Delegate<'tcx> for MutablyUsedVariablesCtxt<'tcx> {
     fn borrow(&mut self, cmt: &euv::PlaceWithHirId<'tcx>, _id: HirId, borrow: ty::BorrowKind) {
         self.prev_bind = None;
         if let euv::Place {
-            base: euv::PlaceBase::Local(vid),
+            base:
+                euv::PlaceBase::Local(vid)
+                | euv::PlaceBase::Upvar(UpvarId {
+                    var_path: UpvarPath { hir_id: vid },
+                    ..
+                }),
             base_ty,
             ..
         } = &cmt.place
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index 5f2a324b05f..aee184252fb 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -5,10 +5,8 @@ use clippy_utils::{get_parent_node, is_lint_allowed, peel_blocks};
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{
-    is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, FnRetTy, ItemKind, Node, PatKind, Stmt, StmtKind,
-    UnsafeSource,
+    is_range_literal, BinOpKind, BlockCheckMode, Expr, ExprKind, ItemKind, Node, PatKind, Stmt, StmtKind, UnsafeSource,
 };
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_infer::infer::TyCtxtInferExt as _;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
@@ -99,14 +97,13 @@ fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
                 |diag| {
                     for parent in cx.tcx.hir().parent_iter(stmt.hir_id) {
                         if let Node::Item(item) = parent.1
-                            && let ItemKind::Fn(sig, ..) = item.kind
-                            && let FnRetTy::Return(ret_ty) = sig.decl.output
+                            && let ItemKind::Fn(..) = item.kind
                             && let Some(Node::Block(block)) = get_parent_node(cx.tcx, stmt.hir_id)
                             && let [.., final_stmt] = block.stmts
                             && final_stmt.hir_id == stmt.hir_id
                         {
                             let expr_ty = cx.typeck_results().expr_ty(expr);
-                            let mut ret_ty = hir_ty_to_ty(cx.tcx, ret_ty);
+                            let mut ret_ty = cx.tcx.fn_sig(item.owner_id).instantiate_identity().output().skip_binder();
 
                             // Remove `impl Future<Output = T>` to get `T`
                             if cx.tcx.ty_is_opaque_future(ret_ty) &&
@@ -115,7 +112,7 @@ fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
                                 ret_ty = true_ret_ty;
                             }
 
-                            if ret_ty == expr_ty {
+                            if !ret_ty.is_unit() && ret_ty == expr_ty {
                                 diag.span_suggestion(
                                     stmt.span.shrink_to_lo(),
                                     "did you mean to return it?",
diff --git a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
index 4b24f059afd..20b4b4f03ed 100644
--- a/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/non_canonical_impls.rs
@@ -4,7 +4,7 @@ use clippy_utils::ty::implements_trait;
 use clippy_utils::{get_parent_node, is_res_lang_ctor, last_path_segment, match_def_path, path_res, std_or_core};
 use rustc_errors::Applicability;
 use rustc_hir::def_id::LocalDefId;
-use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, ItemKind, LangItem, Node, UnOp};
+use rustc_hir::{Expr, ExprKind, ImplItem, ImplItemKind, LangItem, Node, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::EarlyBinder;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
@@ -122,9 +122,6 @@ impl LateLintPass<'_> for NonCanonicalImpls {
         if cx.tcx.is_automatically_derived(item.owner_id.to_def_id()) {
             return;
         }
-        let ItemKind::Impl(_) = item.kind else {
-            return;
-        };
         let ImplItemKind::Fn(_, impl_item_id) = cx.tcx.hir().impl_item(impl_item.impl_item_id()).kind else {
             return;
         };
@@ -180,17 +177,8 @@ impl LateLintPass<'_> for NonCanonicalImpls {
 
         if cx.tcx.is_diagnostic_item(sym::PartialOrd, trait_impl.def_id)
             && impl_item.ident.name == sym::partial_cmp
-            && let Some(ord_def_id) = cx
-                .tcx
-                .diagnostic_items(trait_impl.def_id.krate)
-                .name_to_id
-                .get(&sym::Ord)
-            && implements_trait(
-                    cx,
-                    trait_impl.self_ty(),
-                    *ord_def_id,
-                    &[],
-                )
+            && let Some(ord_def_id) = cx.tcx.get_diagnostic_item(sym::Ord)
+            && implements_trait(cx, trait_impl.self_ty(), ord_def_id, &[])
         {
             // If the `cmp` call likely needs to be fully qualified in the suggestion
             // (like `std::cmp::Ord::cmp`). It's unfortunate we must put this here but we can't
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index 88466333787..2b4e3260c56 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -13,7 +13,6 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::{
     BodyId, Expr, ExprKind, HirId, Impl, ImplItem, ImplItemKind, Item, ItemKind, Node, TraitItem, TraitItemKind, UnOp,
 };
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass, Lint};
 use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult, GlobalId};
 use rustc_middle::ty::adjustment::Adjust;
@@ -297,8 +296,8 @@ declare_lint_pass!(NonCopyConst => [DECLARE_INTERIOR_MUTABLE_CONST, BORROW_INTER
 
 impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
     fn check_item(&mut self, cx: &LateContext<'tcx>, it: &'tcx Item<'_>) {
-        if let ItemKind::Const(hir_ty, _generics, body_id) = it.kind {
-            let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+        if let ItemKind::Const(.., body_id) = it.kind {
+            let ty = cx.tcx.type_of(it.owner_id).instantiate_identity();
             if !ignored_macro(cx, it) && is_unfrozen(cx, ty) && is_value_unfrozen_poly(cx, body_id, ty) {
                 lint(cx, Source::Item { item: it.span });
             }
@@ -306,8 +305,8 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
     }
 
     fn check_trait_item(&mut self, cx: &LateContext<'tcx>, trait_item: &'tcx TraitItem<'_>) {
-        if let TraitItemKind::Const(hir_ty, body_id_opt) = &trait_item.kind {
-            let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+        if let TraitItemKind::Const(_, body_id_opt) = &trait_item.kind {
+            let ty = cx.tcx.type_of(trait_item.owner_id).instantiate_identity();
 
             // Normalize assoc types because ones originated from generic params
             // bounded other traits could have their bound.
@@ -333,7 +332,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx ImplItem<'_>) {
-        if let ImplItemKind::Const(hir_ty, body_id) = &impl_item.kind {
+        if let ImplItemKind::Const(_, body_id) = &impl_item.kind {
             let item_def_id = cx.tcx.hir().get_parent_item(impl_item.hir_id()).def_id;
             let item = cx.tcx.hir().expect_item(item_def_id);
 
@@ -366,7 +365,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
                             // we should use here as a frozen variant is a potential to be frozen
                             // similar to unknown layouts.
                             // e.g. `layout_of(...).is_err() || has_frozen_variant(...);`
-                        let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+                        let ty = cx.tcx.type_of(impl_item.owner_id).instantiate_identity();
                         let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
                         if is_unfrozen(cx, normalized);
                         if is_value_unfrozen_poly(cx, *body_id, normalized);
@@ -381,7 +380,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
                     }
                 },
                 ItemKind::Impl(Impl { of_trait: None, .. }) => {
-                    let ty = hir_ty_to_ty(cx.tcx, hir_ty);
+                    let ty = cx.tcx.type_of(impl_item.owner_id).instantiate_identity();
                     // Normalize assoc types originated from generic params.
                     let normalized = cx.tcx.normalize_erasing_regions(cx.param_env, ty);
 
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index bf031ac8454..7dabdcd58ec 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -16,7 +16,6 @@ use rustc_hir::{
     ImplItemKind, ItemKind, Lifetime, Mutability, Node, Param, PatKind, QPath, TraitFn, TraitItem, TraitItemKind,
     TyKind, Unsafety,
 };
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::{Obligation, ObligationCause};
 use rustc_lint::{LateContext, LateLintPass};
@@ -172,13 +171,8 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
 
             for arg in check_fn_args(
                 cx,
-                cx.tcx
-                    .fn_sig(item.owner_id)
-                    .instantiate_identity()
-                    .skip_binder()
-                    .inputs(),
+                cx.tcx.fn_sig(item.owner_id).instantiate_identity().skip_binder(),
                 sig.decl.inputs,
-                &sig.decl.output,
                 &[],
             )
             .filter(|arg| arg.mutability() == Mutability::Not)
@@ -237,7 +231,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
 
         let decl = sig.decl;
         let sig = cx.tcx.fn_sig(item_id).instantiate_identity().skip_binder();
-        let lint_args: Vec<_> = check_fn_args(cx, sig.inputs(), decl.inputs, &decl.output, body.params)
+        let lint_args: Vec<_> = check_fn_args(cx, sig, decl.inputs, body.params)
             .filter(|arg| !is_trait_item || arg.mutability() == Mutability::Not)
             .collect();
         let results = check_ptr_arg_usage(cx, body, &lint_args);
@@ -443,12 +437,13 @@ impl<'tcx> DerefTy<'tcx> {
 #[expect(clippy::too_many_lines)]
 fn check_fn_args<'cx, 'tcx: 'cx>(
     cx: &'cx LateContext<'tcx>,
-    tys: &'tcx [Ty<'tcx>],
+    fn_sig: ty::FnSig<'tcx>,
     hir_tys: &'tcx [hir::Ty<'tcx>],
-    ret_ty: &'tcx FnRetTy<'tcx>,
     params: &'tcx [Param<'tcx>],
 ) -> impl Iterator<Item = PtrArg<'tcx>> + 'cx {
-    tys.iter()
+    fn_sig
+        .inputs()
+        .iter()
         .zip(hir_tys.iter())
         .enumerate()
         .filter_map(move |(i, (ty, hir_ty))| {
@@ -494,9 +489,7 @@ fn check_fn_args<'cx, 'tcx: 'cx>(
                                 })
                             {
                                 if !lifetime.is_anonymous()
-                                    && let FnRetTy::Return(ret_ty) = ret_ty
-                                    && let ret_ty = hir_ty_to_ty(cx.tcx, ret_ty)
-                                    && ret_ty
+                                    && fn_sig.output()
                                         .walk()
                                         .filter_map(|arg| {
                                             arg.as_region().and_then(|lifetime| {
diff --git a/src/tools/clippy/clippy_lints/src/raw_strings.rs b/src/tools/clippy/clippy_lints/src/raw_strings.rs
index e8018462d75..8a7e4874666 100644
--- a/src/tools/clippy/clippy_lints/src/raw_strings.rs
+++ b/src/tools/clippy/clippy_lints/src/raw_strings.rs
@@ -50,7 +50,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.72.0"]
     pub NEEDLESS_RAW_STRING_HASHES,
-    style,
+    pedantic,
     "suggests reducing the number of hashes around a raw string literal"
 }
 impl_lint_pass!(RawStrings => [NEEDLESS_RAW_STRINGS, NEEDLESS_RAW_STRING_HASHES]);
@@ -93,7 +93,7 @@ impl EarlyLintPass for RawStrings {
                             diag.span_suggestion(
                                 start,
                                 "use a string literal instead",
-                                format!("\"{}\"", str),
+                                format!("\"{str}\""),
                                 Applicability::MachineApplicable,
                             );
                         } else {
@@ -105,8 +105,9 @@ impl EarlyLintPass for RawStrings {
                         }
                     },
                 );
-
-                return;
+                if !matches!(cx.get_lint_level(NEEDLESS_RAW_STRINGS), rustc_lint::Allow) {
+                    return;
+                }
             }
 
             let req = {
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs
index 4944381da24..b26365e34ab 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_null_to_fn.rs
@@ -28,35 +28,43 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'t
         return false;
     }
 
-    match arg.kind {
+    let casts_peeled = peel_casts(arg);
+    match casts_peeled.kind {
         // Catching:
         // transmute over constants that resolve to `null`.
-        ExprKind::Path(ref _qpath) if matches!(constant(cx, cx.typeck_results(), arg), Some(Constant::RawPtr(0))) => {
+        ExprKind::Path(ref _qpath)
+            if matches!(
+                constant(cx, cx.typeck_results(), casts_peeled),
+                Some(Constant::RawPtr(0))
+            ) =>
+        {
             lint_expr(cx, expr);
             true
         },
-
-        // Catching:
-        // `std::mem::transmute(0 as *const i32)`
-        ExprKind::Cast(inner_expr, _cast_ty) if is_integer_literal(inner_expr, 0) => {
-            lint_expr(cx, expr);
-            true
-        },
-
         // Catching:
         // `std::mem::transmute(std::ptr::null::<i32>())`
         ExprKind::Call(func1, []) if is_path_diagnostic_item(cx, func1, sym::ptr_null) => {
             lint_expr(cx, expr);
             true
         },
-
         _ => {
             // FIXME:
             // Also catch transmutations of variables which are known nulls.
             // To do this, MIR const propagation seems to be the better tool.
             // Whenever MIR const prop routines are more developed, this will
             // become available. As of this writing (25/03/19) it is not yet.
+            if is_integer_literal(casts_peeled, 0) {
+                lint_expr(cx, expr);
+                return true;
+            }
             false
         },
     }
 }
+
+fn peel_casts<'tcx>(expr: &'tcx Expr<'tcx>) -> &'tcx Expr<'tcx> {
+    match &expr.kind {
+        ExprKind::Cast(inner_expr, _) => peel_casts(inner_expr),
+        _ => expr,
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/types/mod.rs b/src/tools/clippy/clippy_lints/src/types/mod.rs
index 79f9d45d597..71a4b3fba1b 100644
--- a/src/tools/clippy/clippy_lints/src/types/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/types/mod.rs
@@ -315,7 +315,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
     fn check_fn(
         &mut self,
         cx: &LateContext<'_>,
-        _: FnKind<'_>,
+        fn_kind: FnKind<'_>,
         decl: &FnDecl<'_>,
         _: &Body<'_>,
         _: Span,
@@ -340,6 +340,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
             CheckTyContext {
                 is_in_trait_impl,
                 is_exported,
+                in_body: matches!(fn_kind, FnKind::Closure),
                 ..CheckTyContext::default()
             },
         );
@@ -427,7 +428,7 @@ impl<'tcx> LateLintPass<'tcx> for Types {
                 cx,
                 ty,
                 CheckTyContext {
-                    is_local: true,
+                    in_body: true,
                     ..CheckTyContext::default()
                 },
             );
@@ -481,7 +482,7 @@ impl Types {
         }
 
         match hir_ty.kind {
-            TyKind::Path(ref qpath) if !context.is_local => {
+            TyKind::Path(ref qpath) if !context.in_body => {
                 let hir_id = hir_ty.hir_id;
                 let res = cx.qpath_res(qpath, hir_id);
                 if let Some(def_id) = res.opt_def_id() {
@@ -581,8 +582,8 @@ impl Types {
 #[derive(Clone, Copy, Default)]
 struct CheckTyContext {
     is_in_trait_impl: bool,
-    /// `true` for types on local variables.
-    is_local: bool,
+    /// `true` for types on local variables and in closure signatures.
+    in_body: bool,
     /// `true` for types that are part of the public API.
     is_exported: bool,
     is_nested_call: bool,
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
index 704d7abd7e5..e7915953d85 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs
@@ -7,7 +7,7 @@ use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::{Expr, ExprKind, HirId, HirIdSet, Local, MatchSource, Node, PatKind, QPath, TyKind};
 use rustc_lint::{LateContext, LintContext};
-use rustc_middle::lint::in_external_macro;
+use rustc_middle::lint::{in_external_macro, is_from_async_await};
 use rustc_middle::ty;
 
 use super::LET_UNIT_VALUE;
@@ -16,6 +16,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
     if let Some(init) = local.init
         && !local.pat.span.from_expansion()
         && !in_external_macro(cx.sess(), local.span)
+        && !is_from_async_await(local.span)
         && cx.typeck_results().pat_ty(local.pat).is_unit()
     {
         if (local.ty.map_or(false, |ty| !matches!(ty.kind, TyKind::Infer))
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs b/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs
new file mode 100644
index 00000000000..5aa057580e9
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs
@@ -0,0 +1,93 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use clippy_utils::source::snippet_with_applicability;
+use clippy_utils::ty::get_type_diagnostic_name;
+use rustc_errors::Applicability;
+use rustc_hir as hir;
+use rustc_lint::{LateContext, LateLintPass};
+use rustc_session::{declare_lint_pass, declare_tool_lint};
+use rustc_span::sym;
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Suggest removing the use of a may (or map_err) method when an Option or Result is being construted.
+    ///
+    /// ### Why is this bad?
+    /// It introduces unnecessary complexity. In this case the function can be used directly and
+    /// construct the Option or Result from the output.
+    ///
+    /// ### Example
+    /// ```rust
+    /// Some(4).map(i32::swap_bytes);
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// Some(i32::swap_bytes(4));
+    /// ```
+    #[clippy::version = "1.73.0"]
+    pub UNNECESSARY_MAP_ON_CONSTRUCTOR,
+    complexity,
+    "using `map`/`map_err` on `Option` or `Result` constructors"
+}
+declare_lint_pass!(UnnecessaryMapOnConstructor => [UNNECESSARY_MAP_ON_CONSTRUCTOR]);
+
+impl<'tcx> LateLintPass<'tcx> for UnnecessaryMapOnConstructor {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
+        if expr.span.from_expansion() {
+            return;
+        }
+        if let hir::ExprKind::MethodCall(path, recv, args, ..) = expr.kind
+            && let Some(sym::Option | sym::Result) = get_type_diagnostic_name(cx, cx.typeck_results().expr_ty(recv)){
+            let (constructor_path, constructor_item) =
+                if let hir::ExprKind::Call(constructor, constructor_args) = recv.kind
+                    && let hir::ExprKind::Path(constructor_path) = constructor.kind
+                    && let Some(arg) = constructor_args.get(0)
+                {
+                    if constructor.span.from_expansion() || arg.span.from_expansion() {
+                        return;
+                    }
+                    (constructor_path, arg)
+                } else {
+                    return;
+                };
+            let constructor_symbol = match constructor_path {
+                hir::QPath::Resolved(_, path) => {
+                    if let Some(path_segment) = path.segments.last() {
+                        path_segment.ident.name
+                    } else {
+                        return;
+                    }
+                },
+                hir::QPath::TypeRelative(_, path) => path.ident.name,
+                hir::QPath::LangItem(_, _, _) => return,
+            };
+            match constructor_symbol {
+                sym::Some | sym::Ok if path.ident.name == rustc_span::sym::map => (),
+                sym::Err if path.ident.name == sym!(map_err) => (),
+                _ => return,
+            }
+
+            if let Some(map_arg) = args.get(0)
+                && let hir::ExprKind::Path(fun) = map_arg.kind
+            {
+                if map_arg.span.from_expansion() {
+                    return;
+                }
+                let mut applicability = Applicability::MachineApplicable;
+                let fun_snippet = snippet_with_applicability(cx, fun.span(), "_", &mut applicability);
+                let constructor_snippet =
+                    snippet_with_applicability(cx, constructor_path.span(), "_", &mut applicability);
+                let constructor_arg_snippet =
+                    snippet_with_applicability(cx, constructor_item.span, "_", &mut applicability);
+                span_lint_and_sugg(
+                    cx,
+                    UNNECESSARY_MAP_ON_CONSTRUCTOR,
+                    expr.span,
+                    &format!("unnecessary {} on constructor {constructor_snippet}(_)", path.ident.name),
+                    "try",
+                    format!("{constructor_snippet}({fun_snippet}({constructor_arg_snippet}))"),
+                    applicability,
+                );
+            }
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index 5ac4f0aa46c..f32e7edad6c 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -8,10 +8,14 @@ use rustc_errors::Applicability;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BindingAnnotation, Expr, ExprKind, HirId, MatchSource, Node, PatKind};
+use rustc_infer::infer::TyCtxtInferExt;
+use rustc_infer::traits::Obligation;
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty;
+use rustc_middle::traits::ObligationCause;
+use rustc_middle::ty::{self, EarlyBinder, GenericArg, GenericArgsRef, Ty, TypeVisitableExt};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::{sym, Span};
+use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -61,22 +65,69 @@ impl MethodOrFunction {
     }
 }
 
-/// Returns the span of the `IntoIterator` trait bound in the function pointed to by `fn_did`
-fn into_iter_bound(cx: &LateContext<'_>, fn_did: DefId, into_iter_did: DefId, param_index: u32) -> Option<Span> {
-    cx.tcx
-        .predicates_of(fn_did)
-        .predicates
-        .iter()
-        .find_map(|&(ref pred, span)| {
-            if let ty::ClauseKind::Trait(tr) = pred.kind().skip_binder()
-                && tr.def_id() == into_iter_did
-                && tr.self_ty().is_param(param_index)
-            {
-                Some(span)
-            } else {
-                None
+/// Returns the span of the `IntoIterator` trait bound in the function pointed to by `fn_did`,
+/// iff all of the bounds also hold for the type of the `.into_iter()` receiver.
+/// ```ignore
+/// pub fn foo<I>(i: I)
+/// where I: IntoIterator<Item=i32> + ExactSizeIterator
+///                                   ^^^^^^^^^^^^^^^^^ this extra bound stops us from suggesting to remove `.into_iter()` ...
+/// {
+///     assert_eq!(i.len(), 3);
+/// }
+///
+/// pub fn bar() {
+///     foo([1, 2, 3].into_iter());
+///                  ^^^^^^^^^^^^ ... here, because `[i32; 3]` is not `ExactSizeIterator`
+/// }
+/// ```
+fn into_iter_bound<'tcx>(
+    cx: &LateContext<'tcx>,
+    fn_did: DefId,
+    into_iter_did: DefId,
+    into_iter_receiver: Ty<'tcx>,
+    param_index: u32,
+    node_args: GenericArgsRef<'tcx>,
+) -> Option<Span> {
+    let param_env = cx.tcx.param_env(fn_did);
+    let mut into_iter_span = None;
+
+    for (pred, span) in cx.tcx.explicit_predicates_of(fn_did).predicates {
+        if let ty::ClauseKind::Trait(tr) = pred.kind().skip_binder() {
+            if tr.self_ty().is_param(param_index) {
+                if tr.def_id() == into_iter_did {
+                    into_iter_span = Some(*span);
+                } else {
+                    let tr = cx.tcx.erase_regions(tr);
+                    if tr.has_escaping_bound_vars() {
+                        return None;
+                    }
+
+                    // Substitute generics in the predicate and replace the IntoIterator type parameter with the
+                    // `.into_iter()` receiver to see if the bound also holds for that type.
+                    let args = cx.tcx.mk_args_from_iter(node_args.iter().enumerate().map(|(i, arg)| {
+                        if i == param_index as usize {
+                            GenericArg::from(into_iter_receiver)
+                        } else {
+                            arg
+                        }
+                    }));
+
+                    let predicate = EarlyBinder::bind(tr).instantiate(cx.tcx, args);
+                    let obligation = Obligation::new(cx.tcx, ObligationCause::dummy(), param_env, predicate);
+                    if !cx
+                        .tcx
+                        .infer_ctxt()
+                        .build()
+                        .predicate_must_hold_modulo_regions(&obligation)
+                    {
+                        return None;
+                    }
+                }
             }
-        })
+        }
+    }
+
+    into_iter_span
 }
 
 /// Extracts the receiver of a `.into_iter()` method call.
@@ -160,22 +211,41 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
                                     // `fn_sig` does not ICE. (see #11065)
                                     && cx.tcx.opt_def_kind(did).is_some_and(DefKind::is_fn_like) =>
                             {
-                                    Some((did, args, MethodOrFunction::Function))
+                                Some((
+                                    did,
+                                    args,
+                                    cx.typeck_results().node_args(recv.hir_id),
+                                    MethodOrFunction::Function
+                                ))
                             }
                             ExprKind::MethodCall(.., args, _) => {
                                 cx.typeck_results().type_dependent_def_id(parent.hir_id)
-                                    .map(|did| (did, args, MethodOrFunction::Method))
+                                    .map(|did| {
+                                        return (
+                                            did,
+                                            args,
+                                            cx.typeck_results().node_args(parent.hir_id),
+                                            MethodOrFunction::Method
+                                        );
+                                    })
                             }
                             _ => None,
                         };
 
-                        if let Some((parent_fn_did, args, kind)) = parent_fn
+                        if let Some((parent_fn_did, args, node_args, kind)) = parent_fn
                             && let Some(into_iter_did) = cx.tcx.get_diagnostic_item(sym::IntoIterator)
                             && let sig = cx.tcx.fn_sig(parent_fn_did).skip_binder().skip_binder()
                             && let Some(arg_pos) = args.iter().position(|x| x.hir_id == e.hir_id)
                             && let Some(&into_iter_param) = sig.inputs().get(kind.param_pos(arg_pos))
                             && let ty::Param(param) = into_iter_param.kind()
-                            && let Some(span) = into_iter_bound(cx, parent_fn_did, into_iter_did, param.index)
+                            && let Some(span) = into_iter_bound(
+                                cx,
+                                parent_fn_did,
+                                into_iter_did,
+                                cx.typeck_results().expr_ty(into_iter_recv),
+                                param.index,
+                                node_args
+                            )
                             && self.expn_depth == 0
                         {
                             // Get the "innermost" `.into_iter()` call, e.g. given this expression:
diff --git a/src/tools/clippy/clippy_lints/src/utils/conf.rs b/src/tools/clippy/clippy_lints/src/utils/conf.rs
index 26889475522..75c3c7a958a 100644
--- a/src/tools/clippy/clippy_lints/src/utils/conf.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/conf.rs
@@ -542,11 +542,11 @@ define_Conf! {
     /// Lint: UNDOCUMENTED_UNSAFE_BLOCKS.
     ///
     /// Whether to accept a safety comment to be placed above the statement containing the `unsafe` block
-    (accept_comment_above_statement: bool = false),
+    (accept_comment_above_statement: bool = true),
     /// Lint: UNDOCUMENTED_UNSAFE_BLOCKS.
     ///
     /// Whether to accept a safety comment to be placed above the attributes for the `unsafe` block
-    (accept_comment_above_attributes: bool = false),
+    (accept_comment_above_attributes: bool = true),
     /// Lint: UNNECESSARY_RAW_STRING_HASHES.
     ///
     /// Whether to allow `r#""#` when `r""` can be used
@@ -561,6 +561,11 @@ define_Conf! {
     /// Which crates to allow absolute paths from
     (absolute_paths_allowed_crates: rustc_data_structures::fx::FxHashSet<String> =
         rustc_data_structures::fx::FxHashSet::default()),
+    /// Lint: PATH_ENDS_WITH_EXT.
+    ///
+    /// Additional dotfiles (files or directories starting with a dot) to allow
+    (allowed_dotfiles: rustc_data_structures::fx::FxHashSet<String> =
+        rustc_data_structures::fx::FxHashSet::default()),
     /// Lint: EXPLICIT_ITER_LOOP
     ///
     /// Whether to recommend using implicit into iter for reborrowed values.
diff --git a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
index 6d3493523e6..94a9a7c241b 100644
--- a/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/format_args_collector.rs
@@ -1,12 +1,15 @@
-use clippy_utils::macros::collect_ast_format_args;
+use clippy_utils::macros::AST_FORMAT_ARGS;
 use clippy_utils::source::snippet_opt;
 use itertools::Itertools;
-use rustc_ast::{Expr, ExprKind, FormatArgs};
+use rustc_ast::{Crate, Expr, ExprKind, FormatArgs};
+use rustc_data_structures::fx::FxHashMap;
 use rustc_lexer::{tokenize, TokenKind};
 use rustc_lint::{EarlyContext, EarlyLintPass};
-use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::hygiene;
+use rustc_session::{declare_tool_lint, impl_lint_pass};
+use rustc_span::{hygiene, Span};
 use std::iter::once;
+use std::mem;
+use std::rc::Rc;
 
 declare_clippy_lint! {
     /// ### What it does
@@ -17,7 +20,12 @@ declare_clippy_lint! {
     "collects `format_args` AST nodes for use in later lints"
 }
 
-declare_lint_pass!(FormatArgsCollector => [FORMAT_ARGS_COLLECTOR]);
+#[derive(Default)]
+pub struct FormatArgsCollector {
+    format_args: FxHashMap<Span, Rc<FormatArgs>>,
+}
+
+impl_lint_pass!(FormatArgsCollector => [FORMAT_ARGS_COLLECTOR]);
 
 impl EarlyLintPass for FormatArgsCollector {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, expr: &Expr) {
@@ -26,9 +34,17 @@ impl EarlyLintPass for FormatArgsCollector {
                 return;
             }
 
-            collect_ast_format_args(expr.span, args);
+            self.format_args
+                .insert(expr.span.with_parent(None), Rc::new((**args).clone()));
         }
     }
+
+    fn check_crate_post(&mut self, _: &EarlyContext<'_>, _: &Crate) {
+        AST_FORMAT_ARGS.with(|ast_format_args| {
+            let result = ast_format_args.set(mem::take(&mut self.format_args));
+            debug_assert!(result.is_ok());
+        });
+    }
 }
 
 /// Detects if the format string or an argument has its span set by a proc macro to something inside
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
index da8654d9388..82f9d4e41e8 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/interning_defined_symbol.rs
@@ -10,7 +10,7 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::mir::interpret::ConstValue;
+use rustc_middle::mir::ConstValue;
 use rustc_middle::ty;
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::symbol::Symbol;
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
index 4ed985f54d0..25077223885 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/invalid_paths.rs
@@ -5,10 +5,9 @@ use if_chain::if_chain;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::Item;
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::fast_reject::SimplifiedType;
-use rustc_middle::ty::{self, FloatTy};
+use rustc_middle::ty::FloatTy;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 use rustc_span::symbol::Symbol;
 
@@ -34,25 +33,20 @@ impl<'tcx> LateLintPass<'tcx> for InvalidPaths {
         let mod_name = &cx.tcx.item_name(local_def_id.to_def_id());
         if_chain! {
             if mod_name.as_str() == "paths";
-            if let hir::ItemKind::Const(ty, _, body_id) = item.kind;
-            let ty = hir_ty_to_ty(cx.tcx, ty);
-            if let ty::Array(el_ty, _) = &ty.kind();
-            if let ty::Ref(_, el_ty, _) = &el_ty.kind();
-            if el_ty.is_str();
+            if let hir::ItemKind::Const(.., body_id) = item.kind;
             let body = cx.tcx.hir().body(body_id);
             let typeck_results = cx.tcx.typeck_body(body_id);
             if let Some(Constant::Vec(path)) = constant_simple(cx, typeck_results, body.value);
-            let path: Vec<&str> = path
+            if let Some(path) = path
                 .iter()
                 .map(|x| {
                     if let Constant::Str(s) = x {
-                        s.as_str()
+                        Some(s.as_str())
                     } else {
-                        // We checked the type of the constant above
-                        unreachable!()
+                        None
                     }
                 })
-                .collect();
+                .collect::<Option<Vec<&str>>>();
             if !check_path(cx, &path[..]);
             then {
                 span_lint(cx, INVALID_PATHS, item.span, "invalid path");
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
index 87380f14f9a..bbb5ade8b9f 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs
@@ -28,8 +28,8 @@ declare_clippy_lint! {
     /// know the name of the lint.
     ///
     /// ### Known problems
-    /// Only checks for lints associated using the
-    /// `declare_lint_pass!`, `impl_lint_pass!`, and `lint_array!` macros.
+    /// Only checks for lints associated using the `declare_lint_pass!` and
+    /// `impl_lint_pass!` macros.
     ///
     /// ### Example
     /// ```rust,ignore
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
index f49c3fadb07..c38a3e81b0f 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs
@@ -31,7 +31,7 @@ use serde::{Serialize, Serializer};
 use std::collections::{BTreeSet, BinaryHeap};
 use std::fmt;
 use std::fmt::Write as _;
-use std::fs::{self, OpenOptions};
+use std::fs::{self, File};
 use std::io::prelude::*;
 use std::path::{Path, PathBuf};
 use std::process::Command;
@@ -229,25 +229,10 @@ impl Drop for MetadataCollector {
         collect_renames(&mut lints);
 
         // Outputting json
-        if Path::new(JSON_OUTPUT_FILE).exists() {
-            fs::remove_file(JSON_OUTPUT_FILE).unwrap();
-        }
-        let mut file = OpenOptions::new()
-            .write(true)
-            .create(true)
-            .open(JSON_OUTPUT_FILE)
-            .unwrap();
-        writeln!(file, "{}", serde_json::to_string_pretty(&lints).unwrap()).unwrap();
+        fs::write(JSON_OUTPUT_FILE, serde_json::to_string_pretty(&lints).unwrap()).unwrap();
 
         // Outputting markdown
-        if Path::new(MARKDOWN_OUTPUT_FILE).exists() {
-            fs::remove_file(MARKDOWN_OUTPUT_FILE).unwrap();
-        }
-        let mut file = OpenOptions::new()
-            .write(true)
-            .create(true)
-            .open(MARKDOWN_OUTPUT_FILE)
-            .unwrap();
+        let mut file = File::create(MARKDOWN_OUTPUT_FILE).unwrap();
         writeln!(
             file,
             "<!--
@@ -261,17 +246,15 @@ Please use that command to update the file and do not edit it by hand.
         .unwrap();
 
         // Write configuration links to CHANGELOG.md
-        let mut changelog = std::fs::read_to_string(CHANGELOG_PATH).unwrap();
-        let mut changelog_file = OpenOptions::new().read(true).write(true).open(CHANGELOG_PATH).unwrap();
-
-        if let Some(position) = changelog.find("<!-- begin autogenerated links to configuration documentation -->") {
-            // I know this is kinda wasteful, we just don't have regex on `clippy_lints` so... this is the best
-            // we can do AFAIK.
-            changelog = changelog[..position].to_string();
-        }
+        let changelog = std::fs::read_to_string(CHANGELOG_PATH).unwrap();
+        let mut changelog_file = File::create(CHANGELOG_PATH).unwrap();
+        let position = changelog
+            .find("<!-- begin autogenerated links to configuration documentation -->")
+            .unwrap();
         writeln!(
             changelog_file,
-            "{changelog}<!-- begin autogenerated links to configuration documentation -->\n{}\n<!-- end autogenerated links to configuration documentation -->",
+            "{}<!-- begin autogenerated links to configuration documentation -->\n{}\n<!-- end autogenerated links to configuration documentation -->",
+            &changelog[..position],
             self.configs_to_markdown(ClippyConfiguration::to_markdown_link)
         )
         .unwrap();
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
index bf835f89cfc..86b77a77f17 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs
@@ -5,9 +5,8 @@ use clippy_utils::{match_def_path, paths};
 use if_chain::if_chain;
 use rustc_errors::Applicability;
 use rustc_hir as hir;
-use rustc_hir_analysis::hir_ty_to_ty;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
-use rustc_middle::ty::{self, GenericArgKind};
+use rustc_middle::ty::{self, EarlyBinder, GenericArgKind};
 use rustc_session::{declare_lint_pass, declare_tool_lint};
 
 declare_clippy_lint! {
@@ -25,16 +24,14 @@ impl LateLintPass<'_> for MsrvAttrImpl {
     fn check_item(&mut self, cx: &LateContext<'_>, item: &hir::Item<'_>) {
         if_chain! {
             if let hir::ItemKind::Impl(hir::Impl {
-                of_trait: Some(lint_pass_trait_ref),
-                self_ty,
+                of_trait: Some(_),
                 items,
                 ..
             }) = &item.kind;
-            if let Some(lint_pass_trait_def_id) = lint_pass_trait_ref.trait_def_id();
-            let is_late_pass = match_def_path(cx, lint_pass_trait_def_id, &paths::LATE_LINT_PASS);
-            if is_late_pass || match_def_path(cx, lint_pass_trait_def_id, &paths::EARLY_LINT_PASS);
-            let self_ty = hir_ty_to_ty(cx.tcx, self_ty);
-            if let ty::Adt(self_ty_def, _) = self_ty.kind();
+            if let Some(trait_ref) = cx.tcx.impl_trait_ref(item.owner_id).map(EarlyBinder::instantiate_identity);
+            let is_late_pass = match_def_path(cx, trait_ref.def_id, &paths::LATE_LINT_PASS);
+            if is_late_pass || match_def_path(cx, trait_ref.def_id, &paths::EARLY_LINT_PASS);
+            if let ty::Adt(self_ty_def, _) = trait_ref.self_ty().kind();
             if self_ty_def.is_struct();
             if self_ty_def.all_fields().any(|f| {
                 cx.tcx
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
index 4a5b6fa5c18..a3acb8f1762 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs
@@ -10,7 +10,8 @@ use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_hir::{Expr, ExprKind, Local, Mutability, Node};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::mir::interpret::{Allocation, ConstValue, GlobalAlloc};
+use rustc_middle::mir::interpret::{Allocation, GlobalAlloc};
+use rustc_middle::mir::ConstValue;
 use rustc_middle::ty::{self, Ty};
 use rustc_session::{declare_tool_lint, impl_lint_pass};
 use rustc_span::symbol::Symbol;
@@ -232,7 +233,8 @@ fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Ve
                 cx.tcx.type_of(def_id).instantiate_identity(),
             ),
             Res::Def(DefKind::Const, def_id) => match cx.tcx.const_eval_poly(def_id).ok()? {
-                ConstValue::Indirect { alloc, offset } if offset.bytes() == 0 => {
+                ConstValue::Indirect { alloc_id, offset } if offset.bytes() == 0 => {
+                    let alloc = cx.tcx.global_alloc(alloc_id).unwrap_memory();
                     read_mir_alloc_def_path(cx, alloc.inner(), cx.tcx.type_of(def_id).instantiate_identity())
                 },
                 _ => None,
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index a9957b18a53..da083fb14aa 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -304,7 +304,7 @@ impl<'tcx> LateLintPass<'tcx> for Write {
             _ => return,
         }
 
-        find_format_args(cx, expr, macro_call.expn, |format_args| {
+        if let Some(format_args) = find_format_args(cx, expr, macro_call.expn) {
             // ignore `writeln!(w)` and `write!(v, some_macro!())`
             if format_args.span.from_expansion() {
                 return;
@@ -312,15 +312,15 @@ impl<'tcx> LateLintPass<'tcx> for Write {
 
             match diag_name {
                 sym::print_macro | sym::eprint_macro | sym::write_macro => {
-                    check_newline(cx, format_args, &macro_call, name);
+                    check_newline(cx, &format_args, &macro_call, name);
                 },
                 sym::println_macro | sym::eprintln_macro | sym::writeln_macro => {
-                    check_empty_string(cx, format_args, &macro_call, name);
+                    check_empty_string(cx, &format_args, &macro_call, name);
                 },
                 _ => {},
             }
 
-            check_literal(cx, format_args, name);
+            check_literal(cx, &format_args, name);
 
             if !self.in_debug_impl {
                 for piece in &format_args.template {
@@ -334,7 +334,7 @@ impl<'tcx> LateLintPass<'tcx> for Write {
                     }
                 }
             }
-        });
+        }
     }
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 6b1a738aaa9..d596eed4b7c 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -671,10 +671,11 @@ pub fn miri_to_const<'tcx>(lcx: &LateContext<'tcx>, result: mir::Const<'tcx>) ->
             ty::RawPtr(_) => Some(Constant::RawPtr(int.assert_bits(int.size()))),
             _ => None,
         },
-        mir::Const::Val(cv, _) if matches!(result.ty().kind(), ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), ty::Str)) => {
+        mir::Const::Val(cv, _) if matches!(result.ty().kind(), ty::Ref(_, inner_ty, _) if matches!(inner_ty.kind(), ty::Str)) =>
+        {
             let data = cv.try_get_slice_bytes_for_diagnostics(lcx.tcx)?;
             String::from_utf8(data.to_owned()).ok().map(Constant::Str)
-        }
+        },
         mir::Const::Val(ConstValue::Indirect { alloc_id, offset: _ }, _) => {
             let alloc = lcx.tcx.global_alloc(alloc_id).unwrap_memory();
             match result.ty().kind() {
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index be1c46319c2..13da79fba7e 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -288,7 +288,7 @@ pub fn is_wild(pat: &Pat<'_>) -> bool {
 /// Checks if the given `QPath` belongs to a type alias.
 pub fn is_ty_alias(qpath: &QPath<'_>) -> bool {
     match *qpath {
-        QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias { .. } | DefKind::AssocTy, ..)),
+        QPath::Resolved(_, path) => matches!(path.res, Res::Def(DefKind::TyAlias | DefKind::AssocTy, ..)),
         QPath::TypeRelative(ty, _) if let TyKind::Path(qpath) = ty.kind => { is_ty_alias(&qpath) },
         _ => false,
     }
@@ -1785,6 +1785,33 @@ pub fn is_try<'tcx>(cx: &LateContext<'_>, expr: &'tcx Expr<'tcx>) -> Option<&'tc
     None
 }
 
+/// Returns `true` if the lint is `#[allow]`ed or `#[expect]`ed at any of the `ids`, fulfilling all
+/// of the expectations in `ids`
+///
+/// This should only be used when the lint would otherwise be emitted, for a way to check if a lint
+/// is allowed early to skip work see [`is_lint_allowed`]
+///
+/// To emit at a lint at a different context than the one current see
+/// [`span_lint_hir`](diagnostics::span_lint_hir) or
+/// [`span_lint_hir_and_then`](diagnostics::span_lint_hir_and_then)
+pub fn fulfill_or_allowed(cx: &LateContext<'_>, lint: &'static Lint, ids: impl IntoIterator<Item = HirId>) -> bool {
+    let mut suppress_lint = false;
+
+    for id in ids {
+        let (level, _) = cx.tcx.lint_level_at_node(lint, id);
+        if let Some(expectation) = level.get_expectation_id() {
+            cx.fulfill_expectation(expectation);
+        }
+
+        match level {
+            Level::Allow | Level::Expect(_) => suppress_lint = true,
+            Level::Warn | Level::ForceWarn(_) | Level::Deny | Level::Forbid => {},
+        }
+    }
+
+    suppress_lint
+}
+
 /// Returns `true` if the lint is allowed in the current context. This is useful for
 /// skipping long running code when it's unnecessary
 ///
@@ -1958,7 +1985,7 @@ pub fn if_sequence<'tcx>(mut expr: &'tcx Expr<'tcx>) -> (Vec<&'tcx Expr<'tcx>>,
 /// Checks if the given function kind is an async function.
 pub fn is_async_fn(kind: FnKind<'_>) -> bool {
     match kind {
-        FnKind::ItemFn(_, _, header) => header.asyncness .is_async(),
+        FnKind::ItemFn(_, _, header) => header.asyncness.is_async(),
         FnKind::Method(_, sig) => sig.header.asyncness.is_async(),
         FnKind::Closure => false,
     }
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index 173f9841d44..82508bcdb85 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -10,8 +10,9 @@ use rustc_lint::LateContext;
 use rustc_span::def_id::DefId;
 use rustc_span::hygiene::{self, MacroKind, SyntaxContext};
 use rustc_span::{sym, BytePos, ExpnData, ExpnId, ExpnKind, Span, SpanData, Symbol};
-use std::cell::RefCell;
+use std::cell::OnceCell;
 use std::ops::ControlFlow;
+use std::rc::Rc;
 use std::sync::atomic::{AtomicBool, Ordering};
 
 const FORMAT_MACRO_DIAG_ITEMS: &[Symbol] = &[
@@ -374,28 +375,21 @@ thread_local! {
     /// A thread local is used because [`FormatArgs`] is `!Send` and `!Sync`, we are making an
     /// assumption that the early pass that populates the map and the later late passes will all be
     /// running on the same thread.
-    static AST_FORMAT_ARGS: RefCell<FxHashMap<Span, FormatArgs>> = {
+    #[doc(hidden)]
+    pub static AST_FORMAT_ARGS: OnceCell<FxHashMap<Span, Rc<FormatArgs>>> = {
         static CALLED: AtomicBool = AtomicBool::new(false);
         debug_assert!(
             !CALLED.swap(true, Ordering::SeqCst),
             "incorrect assumption: `AST_FORMAT_ARGS` should only be accessed by a single thread",
         );
 
-        RefCell::default()
+        OnceCell::new()
     };
 }
 
-/// Record [`rustc_ast::FormatArgs`] for use in late lint passes, this should only be called by
-/// `FormatArgsCollector`
-pub fn collect_ast_format_args(span: Span, format_args: &FormatArgs) {
-    AST_FORMAT_ARGS.with(|ast_format_args| {
-        ast_format_args.borrow_mut().insert(span, format_args.clone());
-    });
-}
-
-/// Calls `callback` with an AST [`FormatArgs`] node if a `format_args` expansion is found as a
-/// descendant of `expn_id`
-pub fn find_format_args(cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId, callback: impl FnOnce(&FormatArgs)) {
+/// Returns an AST [`FormatArgs`] node if a `format_args` expansion is found as a descendant of
+/// `expn_id`
+pub fn find_format_args(cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId) -> Option<Rc<FormatArgs>> {
     let format_args_expr = for_each_expr(start, |expr| {
         let ctxt = expr.span.ctxt();
         if ctxt.outer_expn().is_descendant_of(expn_id) {
@@ -410,13 +404,14 @@ pub fn find_format_args(cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId,
         } else {
             ControlFlow::Continue(Descend::No)
         }
-    });
+    })?;
 
-    if let Some(expr) = format_args_expr {
-        AST_FORMAT_ARGS.with(|ast_format_args| {
-            ast_format_args.borrow().get(&expr.span).map(callback);
-        });
-    }
+    AST_FORMAT_ARGS.with(|ast_format_args| {
+        ast_format_args
+            .get()?
+            .get(&format_args_expr.span.with_parent(None))
+            .map(Rc::clone)
+    })
 }
 
 /// Attempt to find the [`rustc_hir::Expr`] that corresponds to the [`FormatArgument`]'s value, if
diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs
index 131f3c0aa39..9dbb4c68d13 100644
--- a/src/tools/clippy/clippy_utils/src/mir/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs
@@ -1,7 +1,8 @@
 use rustc_hir::{Expr, HirId};
+use rustc_index::bit_set::BitSet;
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::{
-    traversal, Body, InlineAsmOperand, Local, Location, Place, StatementKind, TerminatorKind, START_BLOCK,
+    traversal, BasicBlock, Body, InlineAsmOperand, Local, Location, Place, StatementKind, TerminatorKind, START_BLOCK,
 };
 use rustc_middle::ty::TyCtxt;
 
@@ -29,20 +30,26 @@ pub fn visit_local_usage(locals: &[Local], mir: &Body<'_>, location: Location) -
         locals.len()
     ];
 
-    traversal::ReversePostorder::new(mir, location.block).try_fold(init, |usage, (tbb, tdata)| {
-        // Give up on loops
-        if tdata.terminator().successors().any(|s| s == location.block) {
-            return None;
-        }
+    traversal::Postorder::new(&mir.basic_blocks, location.block)
+        .collect::<Vec<_>>()
+        .into_iter()
+        .rev()
+        .try_fold(init, |usage, tbb| {
+            let tdata = &mir.basic_blocks[tbb];
 
-        let mut v = V {
-            locals,
-            location,
-            results: usage,
-        };
-        v.visit_basic_block_data(tbb, tdata);
-        Some(v.results)
-    })
+            // Give up on loops
+            if tdata.terminator().successors().any(|s| s == location.block) {
+                return None;
+            }
+
+            let mut v = V {
+                locals,
+                location,
+                results: usage,
+            };
+            v.visit_basic_block_data(tbb, tdata);
+            Some(v.results)
+        })
 }
 
 struct V<'a> {
@@ -79,8 +86,32 @@ impl<'a, 'tcx> Visitor<'tcx> for V<'a> {
     }
 }
 
+/// Checks if the block is part of a cycle
+pub fn block_in_cycle(body: &Body<'_>, block: BasicBlock) -> bool {
+    let mut seen = BitSet::new_empty(body.basic_blocks.len());
+    let mut to_visit = Vec::with_capacity(body.basic_blocks.len() / 2);
+
+    seen.insert(block);
+    let mut next = block;
+    loop {
+        for succ in body.basic_blocks[next].terminator().successors() {
+            if seen.insert(succ) {
+                to_visit.push(succ);
+            } else if succ == block {
+                return true;
+            }
+        }
+
+        if let Some(x) = to_visit.pop() {
+            next = x;
+        } else {
+            return false;
+        }
+    }
+}
+
 /// Convenience wrapper around `visit_local_usage`.
-pub fn used_exactly_once(mir: &rustc_middle::mir::Body<'_>, local: rustc_middle::mir::Local) -> Option<bool> {
+pub fn used_exactly_once(mir: &Body<'_>, local: rustc_middle::mir::Local) -> Option<bool> {
     visit_local_usage(
         &[local],
         mir,
@@ -91,11 +122,14 @@ pub fn used_exactly_once(mir: &rustc_middle::mir::Body<'_>, local: rustc_middle:
     )
     .map(|mut vec| {
         let LocalUsage { local_use_locs, .. } = vec.remove(0);
-        local_use_locs
+        let mut locations = local_use_locs
             .into_iter()
-            .filter(|location| !is_local_assignment(mir, local, *location))
-            .count()
-            == 1
+            .filter(|&location| !is_local_assignment(mir, local, location));
+        if let Some(location) = locations.next() {
+            locations.next().is_none() && !block_in_cycle(mir, location.block)
+        } else {
+            false
+        }
     })
 }
 
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 9e25d97f5a6..604dc76912e 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -13,7 +13,8 @@ use rustc_hir::{Expr, FnDecl, LangItem, TyKind, Unsafety};
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::LateContext;
-use rustc_middle::mir::{ConstValue, interpret::Scalar};
+use rustc_middle::mir::interpret::Scalar;
+use rustc_middle::mir::ConstValue;
 use rustc_middle::traits::EvaluationResult;
 use rustc_middle::ty::layout::ValidityRequirement;
 use rustc_middle::ty::{
diff --git a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
index 4b06b12fb94..75064672326 100644
--- a/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/ty/type_certainty/mod.rs
@@ -207,9 +207,8 @@ fn path_segment_certainty(
             // Checking `res_generics_def_id(..)` before calling `generics_of` avoids an ICE.
             if cx.tcx.res_generics_def_id(path_segment.res).is_some() {
                 let generics = cx.tcx.generics_of(def_id);
-                let count = generics.params.len() - generics.host_effect_index.is_some() as usize;
-                let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && count == 0
-                {
+                let count = generics.params.len() - usize::from(generics.host_effect_index.is_some());
+                let lhs = if (parent_certainty.is_certain() || generics.parent_count == 0) && count == 0 {
                     Certainty::Certain(None)
                 } else {
                     Certainty::Uncertain
@@ -220,7 +219,7 @@ fn path_segment_certainty(
                 // See the comment preceding `qpath_certainty`. `def_id` could refer to a type or a value.
                 let certainty = lhs.join_clearing_def_ids(rhs);
                 if resolves_to_type {
-                    if let DefKind::TyAlias { .. } = cx.tcx.def_kind(def_id) {
+                    if let DefKind::TyAlias = cx.tcx.def_kind(def_id) {
                         adt_def_id(cx.tcx.type_of(def_id).instantiate_identity())
                             .map_or(certainty, |def_id| certainty.with_def_id(def_id))
                     } else {
@@ -300,10 +299,11 @@ fn type_is_inferrable_from_arguments(cx: &LateContext<'_>, expr: &Expr<'_>) -> b
 
     // Check that all type parameters appear in the functions input types.
     (0..(generics.parent_count + generics.params.len()) as u32).all(|index| {
-        Some(index as usize) == generics.host_effect_index || fn_sig
-            .inputs()
-            .iter()
-            .any(|input_ty| contains_param(*input_ty.skip_binder(), index))
+        Some(index as usize) == generics.host_effect_index
+            || fn_sig
+                .inputs()
+                .iter()
+                .any(|input_ty| contains_param(*input_ty.skip_binder(), index))
     })
 }
 
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index 9f5116eb73b..5ce22b65f00 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2023-09-07"
+channel = "nightly-2023-09-25"
 components = ["cargo", "llvm-tools", "rust-src", "rust-std", "rustc", "rustc-dev", "rustfmt"]
diff --git a/src/tools/clippy/tests/compile-test.rs b/src/tools/clippy/tests/compile-test.rs
index 9fcc269dbf8..f340cf5938a 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -18,7 +18,6 @@ use test_utils::IS_RUSTC_TEST_SUITE;
 // in the depinfo file (otherwise cargo thinks they are unused)
 extern crate clippy_lints;
 extern crate clippy_utils;
-extern crate derive_new;
 extern crate futures;
 extern crate if_chain;
 extern crate itertools;
@@ -33,7 +32,6 @@ mod test_utils;
 static TEST_DEPENDENCIES: &[&str] = &[
     "clippy_lints",
     "clippy_utils",
-    "derive_new",
     "futures",
     "if_chain",
     "itertools",
diff --git a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs
index fbef5c4564b..868cf00a8d4 100644
--- a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs
+++ b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.rs
@@ -7,8 +7,10 @@ async fn bad() -> u32 {
 }
 
 async fn bad_reason() -> u32 {
-    let _x = Ipv4Addr::new(127, 0, 0, 1);
-    baz().await
+    let x = Ipv4Addr::new(127, 0, 0, 1);
+    let y = baz().await;
+    let _x = x;
+    y
 }
 
 async fn good() -> u32 {
diff --git a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr
index 6f8b04fd12b..ddcd1940d47 100644
--- a/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr
+++ b/src/tools/clippy/tests/ui-toml/await_holding_invalid_type/await_holding_invalid_type.stderr
@@ -11,11 +11,11 @@ LL |     let _x = String::from("hello");
 error: `std::net::Ipv4Addr` may not be held across an `await` point per `clippy.toml`
   --> $DIR/await_holding_invalid_type.rs:10:9
    |
-LL |     let _x = Ipv4Addr::new(127, 0, 0, 1);
-   |         ^^
+LL |     let x = Ipv4Addr::new(127, 0, 0, 1);
+   |         ^
 
 error: `std::string::String` may not be held across an `await` point per `clippy.toml`
-  --> $DIR/await_holding_invalid_type.rs:31:13
+  --> $DIR/await_holding_invalid_type.rs:33:13
    |
 LL |         let _x = String::from("hi!");
    |             ^^
diff --git a/src/tools/clippy/tests/ui-toml/decimal_literal_representation/clippy.toml b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/clippy.toml
new file mode 100644
index 00000000000..74fc5d249d0
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/clippy.toml
@@ -0,0 +1 @@
+literal-representation-threshold = 0xFFFFFF
diff --git a/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.fixed b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.fixed
new file mode 100644
index 00000000000..750f3be84c0
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.fixed
@@ -0,0 +1,6 @@
+#![warn(clippy::decimal_literal_representation)]
+fn main() {
+    let _ = 8388608;
+    let _ = 0x00FF_FFFF;
+    //~^ ERROR: integer literal has a better hexadecimal representation
+}
diff --git a/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.rs b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.rs
new file mode 100644
index 00000000000..26b3354d159
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.rs
@@ -0,0 +1,6 @@
+#![warn(clippy::decimal_literal_representation)]
+fn main() {
+    let _ = 8388608;
+    let _ = 16777215;
+    //~^ ERROR: integer literal has a better hexadecimal representation
+}
diff --git a/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.stderr b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.stderr
new file mode 100644
index 00000000000..6f817a3fdde
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/decimal_literal_representation/decimal_literal_representation.stderr
@@ -0,0 +1,11 @@
+error: integer literal has a better hexadecimal representation
+  --> $DIR/decimal_literal_representation.rs:4:13
+   |
+LL |     let _ = 16777215;
+   |             ^^^^^^^^ help: consider: `0x00FF_FFFF`
+   |
+   = note: `-D clippy::decimal-literal-representation` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::decimal_literal_representation)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_script_idents/clippy.toml b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/clippy.toml
new file mode 100644
index 00000000000..26cb2d77bfd
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/clippy.toml
@@ -0,0 +1 @@
+allowed-scripts = ["Cyrillic"]
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.rs b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.rs
new file mode 100644
index 00000000000..9df1ec6fab0
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.rs
@@ -0,0 +1,6 @@
+#![warn(clippy::disallowed_script_idents)]
+fn main() {
+    let счётчик = 10;
+    let カウンタ = 10;
+    //~^ ERROR: identifier `カウンタ` has a Unicode script that is not allowed by configuration
+}
diff --git a/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.stderr b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.stderr
new file mode 100644
index 00000000000..31bb5ee3514
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/disallowed_script_idents/disallowed_script_idents.stderr
@@ -0,0 +1,11 @@
+error: identifier `カウンタ` has a Unicode script that is not allowed by configuration: Katakana
+  --> $DIR/disallowed_script_idents.rs:4:9
+   |
+LL |     let カウンタ = 10;
+   |         ^^^^^^^^
+   |
+   = note: `-D clippy::disallowed-script-idents` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::disallowed_script_idents)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_names/clippy.toml b/src/tools/clippy/tests/ui-toml/enum_variant_names/clippy.toml
new file mode 100644
index 00000000000..0ad7a979948
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_names/clippy.toml
@@ -0,0 +1 @@
+enum-variant-name-threshold = 5
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs b/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs
new file mode 100644
index 00000000000..8f4e178ccfe
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.rs
@@ -0,0 +1,16 @@
+enum Foo {
+    AFoo,
+    BFoo,
+    CFoo,
+    DFoo,
+}
+enum Foo2 {
+    //~^ ERROR: all variants have the same postfix
+    AFoo,
+    BFoo,
+    CFoo,
+    DFoo,
+    EFoo,
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr b/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr
new file mode 100644
index 00000000000..11039b1db48
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_names/enum_variant_names.stderr
@@ -0,0 +1,18 @@
+error: all variants have the same postfix: `Foo`
+  --> $DIR/enum_variant_names.rs:7:1
+   |
+LL | / enum Foo2 {
+LL | |
+LL | |     AFoo,
+LL | |     BFoo,
+...  |
+LL | |     EFoo,
+LL | | }
+   | |_^
+   |
+   = help: remove the postfixes and use full paths to the variants instead of glob imports
+   = note: `-D clippy::enum-variant-names` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::enum_variant_names)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/clippy.toml b/src/tools/clippy/tests/ui-toml/enum_variant_size/clippy.toml
new file mode 100644
index 00000000000..64a8017fe02
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/clippy.toml
@@ -0,0 +1 @@
+enum-variant-size-threshold = 500
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.fixed b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.fixed
new file mode 100644
index 00000000000..9ae760ae41a
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.fixed
@@ -0,0 +1,11 @@
+enum Fine {
+    A(()),
+    B([u8; 500]),
+}
+enum Bad {
+    //~^ ERROR: large size difference between variants
+    A(()),
+    B(Box<[u8; 501]>),
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.rs b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.rs
new file mode 100644
index 00000000000..cf7f432bf0b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.rs
@@ -0,0 +1,11 @@
+enum Fine {
+    A(()),
+    B([u8; 500]),
+}
+enum Bad {
+    //~^ ERROR: large size difference between variants
+    A(()),
+    B([u8; 501]),
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr
new file mode 100644
index 00000000000..4d9bc9d48e4
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variant_size/enum_variant_size.stderr
@@ -0,0 +1,21 @@
+error: large size difference between variants
+  --> $DIR/enum_variant_size.rs:5:1
+   |
+LL | / enum Bad {
+LL | |
+LL | |     A(()),
+   | |     ----- the second-largest variant contains at least 0 bytes
+LL | |     B([u8; 501]),
+   | |     ------------ the largest variant contains at least 501 bytes
+LL | | }
+   | |_^ the entire enum is at least 502 bytes
+   |
+   = note: `-D clippy::large-enum-variant` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::large_enum_variant)]`
+help: consider boxing the large fields to reduce the total size of the enum
+   |
+LL |     B(Box<[u8; 501]>),
+   |       ~~~~~~~~~~~~~~
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/clippy.toml b/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/clippy.toml
new file mode 100644
index 00000000000..f85aade6ae8
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/clippy.toml
@@ -0,0 +1 @@
+enum-variant-name-threshold = 0
diff --git a/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/enum_variants_name_threshold.rs b/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/enum_variants_name_threshold.rs
new file mode 100644
index 00000000000..6918d7528c1
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/enum_variants_threshold0/enum_variants_name_threshold.rs
@@ -0,0 +1,3 @@
+enum Actions {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/explicit_iter_loop/clippy.toml b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/clippy.toml
new file mode 100644
index 00000000000..15d175ef147
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/clippy.toml
@@ -0,0 +1 @@
+enforce-iter-loop-reborrow = true
diff --git a/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.fixed b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.fixed
new file mode 100644
index 00000000000..468da22a926
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.fixed
@@ -0,0 +1,10 @@
+#![warn(clippy::explicit_iter_loop)]
+
+fn main() {
+    let mut vec = vec![1, 2, 3];
+    let rmvec = &mut vec;
+    for _ in &*rmvec {}
+    //~^ ERROR: it is more concise to loop over references to containers
+    for _ in &mut *rmvec {}
+    //~^ ERROR: it is more concise to loop over references to containers
+}
diff --git a/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs
new file mode 100644
index 00000000000..a934648608c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.rs
@@ -0,0 +1,10 @@
+#![warn(clippy::explicit_iter_loop)]
+
+fn main() {
+    let mut vec = vec![1, 2, 3];
+    let rmvec = &mut vec;
+    for _ in rmvec.iter() {}
+    //~^ ERROR: it is more concise to loop over references to containers
+    for _ in rmvec.iter_mut() {}
+    //~^ ERROR: it is more concise to loop over references to containers
+}
diff --git a/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.stderr b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.stderr
new file mode 100644
index 00000000000..587d4f9b3f0
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/explicit_iter_loop/explicit_iter_loop.stderr
@@ -0,0 +1,17 @@
+error: it is more concise to loop over references to containers instead of using explicit iteration methods
+  --> $DIR/explicit_iter_loop.rs:6:14
+   |
+LL |     for _ in rmvec.iter() {}
+   |              ^^^^^^^^^^^^ help: to write this more concisely, try: `&*rmvec`
+   |
+   = note: `-D clippy::explicit-iter-loop` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::explicit_iter_loop)]`
+
+error: it is more concise to loop over references to containers instead of using explicit iteration methods
+  --> $DIR/explicit_iter_loop.rs:8:14
+   |
+LL |     for _ in rmvec.iter_mut() {}
+   |              ^^^^^^^^^^^^^^^^ help: to write this more concisely, try: `&mut *rmvec`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui-toml/large_stack_frames/clippy.toml b/src/tools/clippy/tests/ui-toml/large_stack_frames/clippy.toml
new file mode 100644
index 00000000000..584335dc28f
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_stack_frames/clippy.toml
@@ -0,0 +1 @@
+stack-size-threshold = 1000
diff --git a/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.rs b/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.rs
new file mode 100644
index 00000000000..39798ffea49
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.rs
@@ -0,0 +1,17 @@
+#![warn(clippy::large_stack_frames)]
+
+// We use this helper function instead of writing [0; 4294967297] directly to represent a
+// case that large_stack_arrays can't catch
+fn create_array<const N: usize>() -> [u8; N] {
+    [0; N]
+}
+
+fn f() {
+    let _x = create_array::<1000>();
+}
+fn f2() {
+    //~^ ERROR: this function allocates a large amount of stack space
+    let _x = create_array::<1001>();
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.stderr b/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.stderr
new file mode 100644
index 00000000000..67ee57ab672
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.stderr
@@ -0,0 +1,15 @@
+error: this function allocates a large amount of stack space
+  --> $DIR/large_stack_frames.rs:12:1
+   |
+LL | / fn f2() {
+LL | |
+LL | |     let _x = create_array::<1001>();
+LL | | }
+   | |_^
+   |
+   = note: allocating large amounts of stack space can overflow the stack
+   = note: `-D clippy::large-stack-frames` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/clippy.toml b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/clippy.toml
new file mode 100644
index 00000000000..45bcbce1e3c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/clippy.toml
@@ -0,0 +1 @@
+pass-by-value-size-limit = 512
diff --git a/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.fixed b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.fixed
new file mode 100644
index 00000000000..3c87c79cf2f
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.fixed
@@ -0,0 +1,7 @@
+#![warn(clippy::large_types_passed_by_value)]
+
+fn f(_v: [u8; 512]) {}
+fn f2(_v: &[u8; 513]) {}
+//~^ ERROR: this argument (513 byte) is passed by value
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.rs b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.rs
new file mode 100644
index 00000000000..0572373a611
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.rs
@@ -0,0 +1,7 @@
+#![warn(clippy::large_types_passed_by_value)]
+
+fn f(_v: [u8; 512]) {}
+fn f2(_v: [u8; 513]) {}
+//~^ ERROR: this argument (513 byte) is passed by value
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.stderr b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.stderr
new file mode 100644
index 00000000000..6678a2b4721
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/large_types_passed_by_value/large_types_passed_by_value.stderr
@@ -0,0 +1,11 @@
+error: this argument (513 byte) is passed by value, but might be more efficient if passed by reference (limit: 512 byte)
+  --> $DIR/large_types_passed_by_value.rs:4:11
+   |
+LL | fn f2(_v: [u8; 513]) {}
+   |           ^^^^^^^^^ help: consider passing by reference instead: `&[u8; 513]`
+   |
+   = note: `-D clippy::large-types-passed-by-value` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::large_types_passed_by_value)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/manual_let_else/clippy.toml b/src/tools/clippy/tests/ui-toml/manual_let_else/clippy.toml
new file mode 100644
index 00000000000..cdae1da011b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/manual_let_else/clippy.toml
@@ -0,0 +1 @@
+matches-for-let-else = "AllTypes"
diff --git a/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.fixed b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.fixed
new file mode 100644
index 00000000000..972f6aa4030
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.fixed
@@ -0,0 +1,10 @@
+#![warn(clippy::manual_let_else)]
+
+enum Foo {
+    A(u8),
+    B,
+}
+
+fn main() {
+    let Foo::A(x) = Foo::A(1) else { return };
+}
diff --git a/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.rs b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.rs
new file mode 100644
index 00000000000..fdaba4ad2a6
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.rs
@@ -0,0 +1,14 @@
+#![warn(clippy::manual_let_else)]
+
+enum Foo {
+    A(u8),
+    B,
+}
+
+fn main() {
+    let x = match Foo::A(1) {
+        //~^ ERROR: this could be rewritten as `let...else`
+        Foo::A(x) => x,
+        Foo::B => return,
+    };
+}
diff --git a/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.stderr b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.stderr
new file mode 100644
index 00000000000..5c2c86c3731
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/manual_let_else/manual_let_else.stderr
@@ -0,0 +1,15 @@
+error: this could be rewritten as `let...else`
+  --> $DIR/manual_let_else.rs:9:5
+   |
+LL | /     let x = match Foo::A(1) {
+LL | |
+LL | |         Foo::A(x) => x,
+LL | |         Foo::B => return,
+LL | |     };
+   | |______^ help: consider writing: `let Foo::A(x) = Foo::A(1) else { return };`
+   |
+   = note: `-D clippy::manual-let-else` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::manual_let_else)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/path_ends_with_ext/clippy.toml b/src/tools/clippy/tests/ui-toml/path_ends_with_ext/clippy.toml
new file mode 100644
index 00000000000..40d7dfd938c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/path_ends_with_ext/clippy.toml
@@ -0,0 +1 @@
+allowed-dotfiles = ["dot"]
diff --git a/src/tools/clippy/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs b/src/tools/clippy/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs
new file mode 100644
index 00000000000..a34b15f4ac9
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/path_ends_with_ext/path_ends_with_ext.rs
@@ -0,0 +1,9 @@
+#![warn(clippy::path_ends_with_ext)]
+
+use std::path::Path;
+
+fn f(p: &Path) {
+    p.ends_with(".dot");
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/result_large_err/clippy.toml b/src/tools/clippy/tests/ui-toml/result_large_err/clippy.toml
new file mode 100644
index 00000000000..df505ed9672
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/result_large_err/clippy.toml
@@ -0,0 +1 @@
+large-error-threshold = 512
diff --git a/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.rs b/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.rs
new file mode 100644
index 00000000000..dea4d61a96b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.rs
@@ -0,0 +1,10 @@
+#![warn(clippy::result_large_err)]
+
+fn f() -> Result<(), [u8; 511]> {
+    todo!()
+}
+fn f2() -> Result<(), [u8; 512]> {
+    //~^ ERROR: the `Err`-variant returned from this function is very large
+    todo!()
+}
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.stderr b/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.stderr
new file mode 100644
index 00000000000..b0936319d1b
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/result_large_err/result_large_err.stderr
@@ -0,0 +1,12 @@
+error: the `Err`-variant returned from this function is very large
+  --> $DIR/result_large_err.rs:6:12
+   |
+LL | fn f2() -> Result<(), [u8; 512]> {
+   |            ^^^^^^^^^^^^^^^^^^^^^ the `Err`-variant is at least 512 bytes
+   |
+   = help: try reducing the size of `[u8; 512]`, for example by boxing large elements or replacing it with `Box<[u8; 512]>`
+   = note: `-D clippy::result-large-err` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::result_large_err)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
index b97bb144468..4bed5c149f5 100644
--- a/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
+++ b/src/tools/clippy/tests/ui-toml/toml_unknown_key/conf_unknown_key.stderr
@@ -10,6 +10,7 @@ error: error reading Clippy's configuration file: unknown field `foobar`, expect
            allow-print-in-tests
            allow-private-module-inception
            allow-unwrap-in-tests
+           allowed-dotfiles
            allowed-idents-below-min-chars
            allowed-scripts
            arithmetic-side-effects-allowed
@@ -82,6 +83,7 @@ error: error reading Clippy's configuration file: unknown field `barfoo`, expect
            allow-print-in-tests
            allow-private-module-inception
            allow-unwrap-in-tests
+           allowed-dotfiles
            allowed-idents-below-min-chars
            allowed-scripts
            arithmetic-side-effects-allowed
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.rs b/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.rs
new file mode 100644
index 00000000000..2f023612206
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.rs
@@ -0,0 +1,5 @@
+fn f(x: Box<[u8; 500]>) {}
+//~^ ERROR: local variable doesn't need to be boxed here
+fn f2(x: Box<[u8; 501]>) {}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.stderr b/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.stderr
new file mode 100644
index 00000000000..2859a29f1b2
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/boxed_local.stderr
@@ -0,0 +1,11 @@
+error: local variable doesn't need to be boxed here
+  --> $DIR/boxed_local.rs:1:6
+   |
+LL | fn f(x: Box<[u8; 500]>) {}
+   |      ^
+   |
+   = note: `-D clippy::boxed-local` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::boxed_local)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/clippy.toml b/src/tools/clippy/tests/ui-toml/too_large_for_stack/clippy.toml
new file mode 100644
index 00000000000..a9c42fca468
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/clippy.toml
@@ -0,0 +1 @@
+too-large-for-stack = 500
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.fixed b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.fixed
new file mode 100644
index 00000000000..ebe92d9b599
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.fixed
@@ -0,0 +1,9 @@
+#![warn(clippy::useless_vec)]
+
+fn main() {
+    let x = [0u8; 500];
+    //~^ ERROR: useless use of `vec!`
+    x.contains(&1);
+    let y = vec![0u8; 501];
+    y.contains(&1);
+}
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.rs b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.rs
new file mode 100644
index 00000000000..e2886a8ccd1
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.rs
@@ -0,0 +1,9 @@
+#![warn(clippy::useless_vec)]
+
+fn main() {
+    let x = vec![0u8; 500];
+    //~^ ERROR: useless use of `vec!`
+    x.contains(&1);
+    let y = vec![0u8; 501];
+    y.contains(&1);
+}
diff --git a/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.stderr b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.stderr
new file mode 100644
index 00000000000..923cded5eef
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_large_for_stack/useless_vec.stderr
@@ -0,0 +1,11 @@
+error: useless use of `vec!`
+  --> $DIR/useless_vec.rs:4:13
+   |
+LL |     let x = vec![0u8; 500];
+   |             ^^^^^^^^^^^^^^ help: you can use an array directly: `[0u8; 500]`
+   |
+   = note: `-D clippy::useless-vec` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::useless_vec)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/too_many_arguments/clippy.toml b/src/tools/clippy/tests/ui-toml/too_many_arguments/clippy.toml
new file mode 100644
index 00000000000..15906305c89
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_many_arguments/clippy.toml
@@ -0,0 +1 @@
+too-many-arguments-threshold = 10
diff --git a/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.rs b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.rs
new file mode 100644
index 00000000000..7b2d6897d3c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.rs
@@ -0,0 +1,7 @@
+#![warn(clippy::too_many_arguments)]
+
+fn not_too_many(p1: u8, p2: u8, p3: u8, p4: u8, p5: u8, p6: u8, p7: u8, p8: u8, p9: u8, p10: u8) {}
+fn too_many(p1: u8, p2: u8, p3: u8, p4: u8, p5: u8, p6: u8, p7: u8, p8: u8, p9: u8, p10: u8, p11: u8) {}
+//~^ ERROR: this function has too many arguments
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr
new file mode 100644
index 00000000000..a52e1fcb9e3
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/too_many_arguments/too_many_arguments.stderr
@@ -0,0 +1,11 @@
+error: this function has too many arguments (11/10)
+  --> $DIR/too_many_arguments.rs:4:1
+   |
+LL | fn too_many(p1: u8, p2: u8, p3: u8, p4: u8, p5: u8, p6: u8, p7: u8, p8: u8, p9: u8, p10: u8, p11: u8) {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::too-many-arguments` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::too_many_arguments)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/type_complexity/clippy.toml b/src/tools/clippy/tests/ui-toml/type_complexity/clippy.toml
new file mode 100644
index 00000000000..bf2ffdd0e30
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_complexity/clippy.toml
@@ -0,0 +1 @@
+type-complexity-threshold = 500
diff --git a/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.rs b/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.rs
new file mode 100644
index 00000000000..b95f5134347
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.rs
@@ -0,0 +1,7 @@
+// 480
+fn f(_: (u8, (u8, (u8, (u8, (u8, (u8,))))))) {}
+// 550
+fn f2(_: (u8, (u8, (u8, (u8, (u8, (u8, u8))))))) {}
+//~^ ERROR: very complex type used
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.stderr b/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.stderr
new file mode 100644
index 00000000000..8ca637f7222
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_complexity/type_complexity.stderr
@@ -0,0 +1,11 @@
+error: very complex type used. Consider factoring parts into `type` definitions
+  --> $DIR/type_complexity.rs:4:10
+   |
+LL | fn f2(_: (u8, (u8, (u8, (u8, (u8, (u8, u8))))))) {}
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::type-complexity` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::type_complexity)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/clippy.toml b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/clippy.toml
new file mode 100644
index 00000000000..2f91866aa93
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/clippy.toml
@@ -0,0 +1 @@
+max-trait-bounds = 5
diff --git a/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.rs b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.rs
new file mode 100644
index 00000000000..2454c10382d
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.rs
@@ -0,0 +1,18 @@
+#![warn(clippy::type_repetition_in_bounds)]
+
+fn f<T>()
+where
+    T: Copy + Clone + Sync + Send + ?Sized + Unpin,
+    T: PartialEq,
+{
+}
+
+fn f2<T>()
+where
+    T: Copy + Clone + Sync + Send + ?Sized,
+    T: Unpin + PartialEq,
+    //~^ ERROR: this type has already been used as a bound predicate
+{
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.stderr b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.stderr
new file mode 100644
index 00000000000..2ae2984975f
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/type_repetition_in_bounds/main.stderr
@@ -0,0 +1,12 @@
+error: this type has already been used as a bound predicate
+  --> $DIR/main.rs:13:5
+   |
+LL |     T: Unpin + PartialEq,
+   |     ^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider combining the bounds: `T: Copy + Clone + Sync + Send + ?Sized + Unpin + PartialEq`
+   = note: `-D clippy::type-repetition-in-bounds` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::type_repetition_in_bounds)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml
deleted file mode 100644
index e6dbb3d3784..00000000000
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/clippy.toml
+++ /dev/null
@@ -1,2 +0,0 @@
-accept-comment-above-statement = true
-accept-comment-above-attributes = true
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/default/clippy.toml b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/default/clippy.toml
new file mode 100644
index 00000000000..3b205d536f2
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/default/clippy.toml
@@ -0,0 +1,2 @@
+# default configuration has `accept-comment-above-statement` and
+# `accept-comment-above-attributes` true
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/disabled/clippy.toml b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/disabled/clippy.toml
new file mode 100644
index 00000000000..57ecb902d65
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/disabled/clippy.toml
@@ -0,0 +1,3 @@
+# test with these options disabled
+accept-comment-above-statement = false
+accept-comment-above-attributes = false
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
index 183c07fe786..15edf2a7dae 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.stderr
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.default.stderr
@@ -1,5 +1,5 @@
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:263:19
+  --> $DIR/undocumented_unsafe_blocks.rs:266:19
    |
 LL |     /* Safety: */ unsafe {}
    |                   ^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     /* Safety: */ unsafe {}
    = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]`
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:267:5
+  --> $DIR/undocumented_unsafe_blocks.rs:270:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     unsafe {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:271:14
+  --> $DIR/undocumented_unsafe_blocks.rs:274:14
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |              ^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:271:29
+  --> $DIR/undocumented_unsafe_blocks.rs:274:29
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                             ^^^^^^^^^^^^^
@@ -33,7 +33,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:271:48
+  --> $DIR/undocumented_unsafe_blocks.rs:274:48
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                                                ^^^^^^^^^^^^^
@@ -41,7 +41,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:275:18
+  --> $DIR/undocumented_unsafe_blocks.rs:278:18
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                  ^^^^^^^^^
@@ -49,7 +49,7 @@ LL |     let _ = (42, unsafe {}, "test", unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:275:37
+  --> $DIR/undocumented_unsafe_blocks.rs:278:37
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                                     ^^^^^^^^^
@@ -57,7 +57,7 @@ LL |     let _ = (42, unsafe {}, "test", unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:279:14
+  --> $DIR/undocumented_unsafe_blocks.rs:282:14
    |
 LL |     let _ = *unsafe { &42 };
    |              ^^^^^^^^^^^^^^
@@ -65,7 +65,7 @@ LL |     let _ = *unsafe { &42 };
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:284:19
+  --> $DIR/undocumented_unsafe_blocks.rs:287:19
    |
 LL |     let _ = match unsafe {} {
    |                   ^^^^^^^^^
@@ -73,7 +73,7 @@ LL |     let _ = match unsafe {} {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:290:14
+  --> $DIR/undocumented_unsafe_blocks.rs:293:14
    |
 LL |     let _ = &unsafe {};
    |              ^^^^^^^^^
@@ -81,7 +81,7 @@ LL |     let _ = &unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:294:14
+  --> $DIR/undocumented_unsafe_blocks.rs:297:14
    |
 LL |     let _ = [unsafe {}; 5];
    |              ^^^^^^^^^
@@ -89,7 +89,7 @@ LL |     let _ = [unsafe {}; 5];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:298:13
+  --> $DIR/undocumented_unsafe_blocks.rs:301:13
    |
 LL |     let _ = unsafe {};
    |             ^^^^^^^^^
@@ -97,7 +97,7 @@ LL |     let _ = unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:308:8
+  --> $DIR/undocumented_unsafe_blocks.rs:311:8
    |
 LL |     t!(unsafe {});
    |        ^^^^^^^^^
@@ -105,7 +105,7 @@ LL |     t!(unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:314:13
+  --> $DIR/undocumented_unsafe_blocks.rs:317:13
    |
 LL |             unsafe {}
    |             ^^^^^^^^^
@@ -117,7 +117,7 @@ LL |     t!();
    = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:322:5
+  --> $DIR/undocumented_unsafe_blocks.rs:325:5
    |
 LL |     unsafe {} // SAFETY:
    |     ^^^^^^^^^
@@ -125,7 +125,7 @@ LL |     unsafe {} // SAFETY:
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:326:5
+  --> $DIR/undocumented_unsafe_blocks.rs:329:5
    |
 LL |     unsafe {
    |     ^^^^^^^^
@@ -133,7 +133,7 @@ LL |     unsafe {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:336:5
+  --> $DIR/undocumented_unsafe_blocks.rs:339:5
    |
 LL |     unsafe {};
    |     ^^^^^^^^^
@@ -141,7 +141,7 @@ LL |     unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:340:20
+  --> $DIR/undocumented_unsafe_blocks.rs:343:20
    |
 LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -149,7 +149,7 @@ LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:347:5
+  --> $DIR/undocumented_unsafe_blocks.rs:350:5
    |
 LL |     unsafe impl A for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -157,7 +157,7 @@ LL |     unsafe impl A for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:354:9
+  --> $DIR/undocumented_unsafe_blocks.rs:357:9
    |
 LL |         unsafe impl B for (u32) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -165,7 +165,7 @@ LL |         unsafe impl B for (u32) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:375:13
+  --> $DIR/undocumented_unsafe_blocks.rs:378:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -177,7 +177,7 @@ LL |     no_safety_comment!(());
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:400:13
+  --> $DIR/undocumented_unsafe_blocks.rs:403:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -189,7 +189,7 @@ LL |     no_safety_comment!(());
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:408:5
+  --> $DIR/undocumented_unsafe_blocks.rs:411:5
    |
 LL |     unsafe impl T for (i32) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -197,7 +197,7 @@ LL |     unsafe impl T for (i32) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:400:13
+  --> $DIR/undocumented_unsafe_blocks.rs:403:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -209,7 +209,7 @@ LL |     no_safety_comment!(u32);
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:414:5
+  --> $DIR/undocumented_unsafe_blocks.rs:417:5
    |
 LL |     unsafe impl T for (bool) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -217,7 +217,7 @@ LL |     unsafe impl T for (bool) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:460:5
+  --> $DIR/undocumented_unsafe_blocks.rs:463:5
    |
 LL |     unsafe impl NoComment for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -225,7 +225,7 @@ LL |     unsafe impl NoComment for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:464:19
+  --> $DIR/undocumented_unsafe_blocks.rs:467:19
    |
 LL |     /* SAFETY: */ unsafe impl InlineComment for () {}
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -233,7 +233,7 @@ LL |     /* SAFETY: */ unsafe impl InlineComment for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:468:5
+  --> $DIR/undocumented_unsafe_blocks.rs:471:5
    |
 LL |     unsafe impl TrailingComment for () {} // SAFETY:
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -241,13 +241,13 @@ LL |     unsafe impl TrailingComment for () {} // SAFETY:
    = help: consider adding a safety comment on the preceding line
 
 error: constant item has unnecessary safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:472:5
+  --> $DIR/undocumented_unsafe_blocks.rs:475:5
    |
 LL |     const BIG_NUMBER: i32 = 1000000;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: consider removing the safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:471:5
+  --> $DIR/undocumented_unsafe_blocks.rs:474:5
    |
 LL |     // SAFETY:
    |     ^^^^^^^^^^
@@ -255,7 +255,7 @@ LL |     // SAFETY:
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:473:5
+  --> $DIR/undocumented_unsafe_blocks.rs:476:5
    |
 LL |     unsafe impl Interference for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -263,7 +263,7 @@ LL |     unsafe impl Interference for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:480:5
+  --> $DIR/undocumented_unsafe_blocks.rs:483:5
    |
 LL |     unsafe impl ImplInFn for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -271,7 +271,7 @@ LL |     unsafe impl ImplInFn for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:489:1
+  --> $DIR/undocumented_unsafe_blocks.rs:492:1
    |
 LL | unsafe impl CrateRoot for () {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -279,7 +279,7 @@ LL | unsafe impl CrateRoot for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: statement has unnecessary safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:502:5
+  --> $DIR/undocumented_unsafe_blocks.rs:505:5
    |
 LL | /     let _ = {
 LL | |         if unsafe { true } {
@@ -291,13 +291,13 @@ LL | |     };
    | |______^
    |
 help: consider removing the safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:501:5
+  --> $DIR/undocumented_unsafe_blocks.rs:504:5
    |
 LL |     // SAFETY: this is more than one level away, so it should warn
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:503:12
+  --> $DIR/undocumented_unsafe_blocks.rs:506:12
    |
 LL |         if unsafe { true } {
    |            ^^^^^^^^^^^^^^^
@@ -305,7 +305,7 @@ LL |         if unsafe { true } {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:506:23
+  --> $DIR/undocumented_unsafe_blocks.rs:509:23
    |
 LL |             let bar = unsafe {};
    |                       ^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
index 77f6aea2e0d..cc9530f79b6 100644
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.disabled.stderr
@@ -1,5 +1,5 @@
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:262:19
+  --> $DIR/undocumented_unsafe_blocks.rs:266:19
    |
 LL |     /* Safety: */ unsafe {}
    |                   ^^^^^^^^^
@@ -9,7 +9,7 @@ LL |     /* Safety: */ unsafe {}
    = help: to override `-D warnings` add `#[allow(clippy::undocumented_unsafe_blocks)]`
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:266:5
+  --> $DIR/undocumented_unsafe_blocks.rs:270:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
@@ -17,7 +17,7 @@ LL |     unsafe {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:270:14
+  --> $DIR/undocumented_unsafe_blocks.rs:274:14
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |              ^^^^^^^^^^^^^
@@ -25,7 +25,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:270:29
+  --> $DIR/undocumented_unsafe_blocks.rs:274:29
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                             ^^^^^^^^^^^^^
@@ -33,7 +33,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:270:48
+  --> $DIR/undocumented_unsafe_blocks.rs:274:48
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                                                ^^^^^^^^^^^^^
@@ -41,7 +41,7 @@ LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:274:18
+  --> $DIR/undocumented_unsafe_blocks.rs:278:18
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                  ^^^^^^^^^
@@ -49,7 +49,7 @@ LL |     let _ = (42, unsafe {}, "test", unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:274:37
+  --> $DIR/undocumented_unsafe_blocks.rs:278:37
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                                     ^^^^^^^^^
@@ -57,7 +57,7 @@ LL |     let _ = (42, unsafe {}, "test", unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:278:14
+  --> $DIR/undocumented_unsafe_blocks.rs:282:14
    |
 LL |     let _ = *unsafe { &42 };
    |              ^^^^^^^^^^^^^^
@@ -65,7 +65,7 @@ LL |     let _ = *unsafe { &42 };
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:283:19
+  --> $DIR/undocumented_unsafe_blocks.rs:287:19
    |
 LL |     let _ = match unsafe {} {
    |                   ^^^^^^^^^
@@ -73,7 +73,7 @@ LL |     let _ = match unsafe {} {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:289:14
+  --> $DIR/undocumented_unsafe_blocks.rs:293:14
    |
 LL |     let _ = &unsafe {};
    |              ^^^^^^^^^
@@ -81,7 +81,7 @@ LL |     let _ = &unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:293:14
+  --> $DIR/undocumented_unsafe_blocks.rs:297:14
    |
 LL |     let _ = [unsafe {}; 5];
    |              ^^^^^^^^^
@@ -89,7 +89,7 @@ LL |     let _ = [unsafe {}; 5];
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:297:13
+  --> $DIR/undocumented_unsafe_blocks.rs:301:13
    |
 LL |     let _ = unsafe {};
    |             ^^^^^^^^^
@@ -97,7 +97,7 @@ LL |     let _ = unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:307:8
+  --> $DIR/undocumented_unsafe_blocks.rs:311:8
    |
 LL |     t!(unsafe {});
    |        ^^^^^^^^^
@@ -105,7 +105,7 @@ LL |     t!(unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:313:13
+  --> $DIR/undocumented_unsafe_blocks.rs:317:13
    |
 LL |             unsafe {}
    |             ^^^^^^^^^
@@ -117,7 +117,7 @@ LL |     t!();
    = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:321:5
+  --> $DIR/undocumented_unsafe_blocks.rs:325:5
    |
 LL |     unsafe {} // SAFETY:
    |     ^^^^^^^^^
@@ -125,7 +125,7 @@ LL |     unsafe {} // SAFETY:
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:325:5
+  --> $DIR/undocumented_unsafe_blocks.rs:329:5
    |
 LL |     unsafe {
    |     ^^^^^^^^
@@ -133,7 +133,7 @@ LL |     unsafe {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:335:5
+  --> $DIR/undocumented_unsafe_blocks.rs:339:5
    |
 LL |     unsafe {};
    |     ^^^^^^^^^
@@ -141,7 +141,7 @@ LL |     unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:339:20
+  --> $DIR/undocumented_unsafe_blocks.rs:343:20
    |
 LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -149,7 +149,7 @@ LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:346:5
+  --> $DIR/undocumented_unsafe_blocks.rs:350:5
    |
 LL |     unsafe impl A for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^
@@ -157,7 +157,7 @@ LL |     unsafe impl A for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:353:9
+  --> $DIR/undocumented_unsafe_blocks.rs:357:9
    |
 LL |         unsafe impl B for (u32) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -165,7 +165,7 @@ LL |         unsafe impl B for (u32) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:374:13
+  --> $DIR/undocumented_unsafe_blocks.rs:378:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -177,7 +177,7 @@ LL |     no_safety_comment!(());
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:399:13
+  --> $DIR/undocumented_unsafe_blocks.rs:403:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -189,7 +189,7 @@ LL |     no_safety_comment!(());
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:407:5
+  --> $DIR/undocumented_unsafe_blocks.rs:411:5
    |
 LL |     unsafe impl T for (i32) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -197,7 +197,7 @@ LL |     unsafe impl T for (i32) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:399:13
+  --> $DIR/undocumented_unsafe_blocks.rs:403:13
    |
 LL |             unsafe impl T for $t {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^
@@ -209,7 +209,7 @@ LL |     no_safety_comment!(u32);
    = note: this error originates in the macro `no_safety_comment` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:413:5
+  --> $DIR/undocumented_unsafe_blocks.rs:417:5
    |
 LL |     unsafe impl T for (bool) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -217,7 +217,7 @@ LL |     unsafe impl T for (bool) {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:459:5
+  --> $DIR/undocumented_unsafe_blocks.rs:463:5
    |
 LL |     unsafe impl NoComment for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -225,7 +225,7 @@ LL |     unsafe impl NoComment for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:463:19
+  --> $DIR/undocumented_unsafe_blocks.rs:467:19
    |
 LL |     /* SAFETY: */ unsafe impl InlineComment for () {}
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -233,7 +233,7 @@ LL |     /* SAFETY: */ unsafe impl InlineComment for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:467:5
+  --> $DIR/undocumented_unsafe_blocks.rs:471:5
    |
 LL |     unsafe impl TrailingComment for () {} // SAFETY:
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -241,13 +241,13 @@ LL |     unsafe impl TrailingComment for () {} // SAFETY:
    = help: consider adding a safety comment on the preceding line
 
 error: constant item has unnecessary safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:471:5
+  --> $DIR/undocumented_unsafe_blocks.rs:475:5
    |
 LL |     const BIG_NUMBER: i32 = 1000000;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 help: consider removing the safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:470:5
+  --> $DIR/undocumented_unsafe_blocks.rs:474:5
    |
 LL |     // SAFETY:
    |     ^^^^^^^^^^
@@ -255,7 +255,7 @@ LL |     // SAFETY:
    = help: to override `-D warnings` add `#[allow(clippy::unnecessary_safety_comment)]`
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:472:5
+  --> $DIR/undocumented_unsafe_blocks.rs:476:5
    |
 LL |     unsafe impl Interference for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -263,7 +263,7 @@ LL |     unsafe impl Interference for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:479:5
+  --> $DIR/undocumented_unsafe_blocks.rs:483:5
    |
 LL |     unsafe impl ImplInFn for () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -271,7 +271,7 @@ LL |     unsafe impl ImplInFn for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe impl missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:488:1
+  --> $DIR/undocumented_unsafe_blocks.rs:492:1
    |
 LL | unsafe impl CrateRoot for () {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -279,7 +279,7 @@ LL | unsafe impl CrateRoot for () {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:498:9
+  --> $DIR/undocumented_unsafe_blocks.rs:502:9
    |
 LL |         unsafe {};
    |         ^^^^^^^^^
@@ -287,7 +287,7 @@ LL |         unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: statement has unnecessary safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:501:5
+  --> $DIR/undocumented_unsafe_blocks.rs:505:5
    |
 LL | /     let _ = {
 LL | |         if unsafe { true } {
@@ -299,13 +299,13 @@ LL | |     };
    | |______^
    |
 help: consider removing the safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:500:5
+  --> $DIR/undocumented_unsafe_blocks.rs:504:5
    |
 LL |     // SAFETY: this is more than one level away, so it should warn
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:502:12
+  --> $DIR/undocumented_unsafe_blocks.rs:506:12
    |
 LL |         if unsafe { true } {
    |            ^^^^^^^^^^^^^^^
@@ -313,7 +313,7 @@ LL |         if unsafe { true } {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:505:23
+  --> $DIR/undocumented_unsafe_blocks.rs:509:23
    |
 LL |             let bar = unsafe {};
    |                       ^^^^^^^^^
@@ -321,7 +321,7 @@ LL |             let bar = unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:523:9
+  --> $DIR/undocumented_unsafe_blocks.rs:527:9
    |
 LL |         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -329,7 +329,7 @@ LL |         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:527:9
+  --> $DIR/undocumented_unsafe_blocks.rs:531:9
    |
 LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -337,12 +337,60 @@ LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line()
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:531:9
+  --> $DIR/undocumented_unsafe_blocks.rs:535:9
+   |
+LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:541:5
+   |
+LL |     unsafe {}
+   |     ^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:545:5
+   |
+LL |     unsafe {
+   |     ^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:552:9
+   |
+LL |         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:557:9
+   |
+LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:563:9
    |
 LL |         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: consider adding a safety comment on the preceding line
 
-error: aborting due to 39 previous errors
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:568:5
+   |
+LL |     unsafe {}
+   |     ^^^^^^^^^
+   |
+   = help: consider adding a safety comment on the preceding line
+
+error: aborting due to 45 previous errors
 
diff --git a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
index b28e1b7d180..a2781398760 100644
--- a/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/tests/ui-toml/undocumented_unsafe_blocks/undocumented_unsafe_blocks.rs
@@ -1,4 +1,7 @@
 //@aux-build:../../ui/auxiliary/proc_macro_unsafe.rs
+//@revisions: default disabled
+//@[default] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/default
+//@[disabled] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/undocumented_unsafe_blocks/disabled
 
 #![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]
 #![allow(deref_nullptr, clippy::let_unit_value, clippy::missing_safety_doc)]
@@ -491,7 +494,7 @@ unsafe impl CrateRoot for () {}
 // SAFETY: ok
 unsafe impl CrateRoot for (i32) {}
 
-fn issue_9142() {
+fn nested_block_separation_issue_9142() {
     // SAFETY: ok
     let _ =
         // we need this comment to avoid rustfmt putting
@@ -518,49 +521,50 @@ pub const unsafe fn a_const_function_with_a_very_long_name_to_break_the_line() -
     2
 }
 
-fn issue_10832() {
-    // Safety: A safety comment
+fn separate_line_from_let_issue_10832() {
+    // SAFETY: fail ONLY if `accept-comment-above-statement = false`
     let _some_variable_with_a_very_long_name_to_break_the_line =
         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
 
-    // Safety: Another safety comment
+    // SAFETY: fail ONLY if `accept-comment-above-statement = false`
     const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
 
-    // Safety: Yet another safety comment
+    // SAFETY: fail ONLY if `accept-comment-above-statement = false`
     static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
 }
 
-fn issue_8679<T: Copy>() {
-    // SAFETY:
+fn above_expr_attribute_issue_8679<T: Copy>() {
+    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
     #[allow(unsafe_code)]
     unsafe {}
 
-    // SAFETY:
+    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
     #[expect(unsafe_code, reason = "totally safe")]
     unsafe {
         *std::ptr::null::<T>()
     };
 
-    // Safety: A safety comment
+    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
     #[allow(unsafe_code)]
     let _some_variable_with_a_very_long_name_to_break_the_line =
         unsafe { a_function_with_a_very_long_name_to_break_the_line() };
 
-    // Safety: Another safety comment
+    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
     #[allow(unsafe_code)]
     const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
 
-    // Safety: Yet another safety comment
+    // SAFETY: fail ONLY if `accept-comment-above-attribute = false`
     #[allow(unsafe_code)]
-    static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
+    #[allow(non_upper_case_globals)]
+    static _some_static_with_a_very_long_name_to_break_the_line: u32 =
         unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
 
     // SAFETY:
     #[allow(unsafe_code)]
-    // This also works I guess
+    // This shouldn't work either
     unsafe {}
 }
 
diff --git a/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/clippy.toml b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/clippy.toml
new file mode 100644
index 00000000000..7c3ffc2908f
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/clippy.toml
@@ -0,0 +1 @@
+unnecessary-box-size = 64
diff --git a/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.fixed b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.fixed
new file mode 100644
index 00000000000..413bc0bf1e3
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.fixed
@@ -0,0 +1,11 @@
+#![warn(clippy::unnecessary_box_returns)]
+
+fn f() -> [u8; 64] {
+    //~^ ERROR: boxed return of the sized type `[u8; 64]`
+    todo!()
+}
+fn f2() -> Box<[u8; 65]> {
+    todo!()
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.rs b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.rs
new file mode 100644
index 00000000000..b44fbb55448
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.rs
@@ -0,0 +1,11 @@
+#![warn(clippy::unnecessary_box_returns)]
+
+fn f() -> Box<[u8; 64]> {
+    //~^ ERROR: boxed return of the sized type `[u8; 64]`
+    todo!()
+}
+fn f2() -> Box<[u8; 65]> {
+    todo!()
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.stderr b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.stderr
new file mode 100644
index 00000000000..df9aa37ac10
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/unnecessary_box_returns/unnecessary_box_returns.stderr
@@ -0,0 +1,12 @@
+error: boxed return of the sized type `[u8; 64]`
+  --> $DIR/unnecessary_box_returns.rs:3:11
+   |
+LL | fn f() -> Box<[u8; 64]> {
+   |           ^^^^^^^^^^^^^ help: try: `[u8; 64]`
+   |
+   = help: changing this also requires a change to the return expressions in this function
+   = note: `-D clippy::unnecessary-box-returns` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_box_returns)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/verbose_bit_mask/clippy.toml b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/clippy.toml
new file mode 100644
index 00000000000..55a202eefb9
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/clippy.toml
@@ -0,0 +1 @@
+verbose-bit-mask-threshold = 31
diff --git a/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.fixed b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.fixed
new file mode 100644
index 00000000000..437692a4d78
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.fixed
@@ -0,0 +1,7 @@
+#![warn(clippy::verbose_bit_mask)]
+fn main() {
+    let v: i32 = 0;
+    let _ = v & 0b11111 == 0;
+    let _ = v.trailing_zeros() >= 6;
+    //~^ ERROR: bit mask could be simplified
+}
diff --git a/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.rs b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.rs
new file mode 100644
index 00000000000..ce102708055
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.rs
@@ -0,0 +1,7 @@
+#![warn(clippy::verbose_bit_mask)]
+fn main() {
+    let v: i32 = 0;
+    let _ = v & 0b11111 == 0;
+    let _ = v & 0b111111 == 0;
+    //~^ ERROR: bit mask could be simplified
+}
diff --git a/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.stderr b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.stderr
new file mode 100644
index 00000000000..7377921b42a
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/verbose_bit_mask/verbose_bit_mask.stderr
@@ -0,0 +1,11 @@
+error: bit mask could be simplified with a call to `trailing_zeros`
+  --> $DIR/verbose_bit_mask.rs:5:13
+   |
+LL |     let _ = v & 0b111111 == 0;
+   |             ^^^^^^^^^^^^^^^^^ help: try: `v.trailing_zeros() >= 6`
+   |
+   = note: `-D clippy::verbose-bit-mask` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::verbose_bit_mask)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml b/src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml
new file mode 100644
index 00000000000..875aaeef6c9
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/clippy.toml
@@ -0,0 +1 @@
+warn-on-all-wildcard-imports = true
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed
new file mode 100644
index 00000000000..1752f48856c
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.fixed
@@ -0,0 +1,11 @@
+#![warn(clippy::wildcard_imports)]
+
+mod prelude {
+    pub const FOO: u8 = 1;
+}
+use prelude::FOO;
+//~^ ERROR: usage of wildcard import
+
+fn main() {
+    let _ = FOO;
+}
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs
new file mode 100644
index 00000000000..331c2c59c22
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.rs
@@ -0,0 +1,11 @@
+#![warn(clippy::wildcard_imports)]
+
+mod prelude {
+    pub const FOO: u8 = 1;
+}
+use prelude::*;
+//~^ ERROR: usage of wildcard import
+
+fn main() {
+    let _ = FOO;
+}
diff --git a/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr
new file mode 100644
index 00000000000..13ec3a229ce
--- /dev/null
+++ b/src/tools/clippy/tests/ui-toml/wildcard_imports/wildcard_imports.stderr
@@ -0,0 +1,11 @@
+error: usage of wildcard import
+  --> $DIR/wildcard_imports.rs:6:5
+   |
+LL | use prelude::*;
+   |     ^^^^^^^^^^ help: try: `prelude::FOO`
+   |
+   = note: `-D clippy::wildcard-imports` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::wildcard_imports)]`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/await_holding_lock.stderr b/src/tools/clippy/tests/ui/await_holding_lock.stderr
index 56b111c4d9e..47821040002 100644
--- a/src/tools/clippy/tests/ui/await_holding_lock.stderr
+++ b/src/tools/clippy/tests/ui/await_holding_lock.stderr
@@ -6,13 +6,10 @@ LL |         let guard = x.lock().unwrap();
    |
    = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
 note: these are all the `await` points this lock is held through
-  --> $DIR/await_holding_lock.rs:9:9
+  --> $DIR/await_holding_lock.rs:11:15
    |
-LL | /         let guard = x.lock().unwrap();
-LL | |
-LL | |         baz().await
-LL | |     }
-   | |_____^
+LL |         baz().await
+   |               ^^^^^
    = note: `-D clippy::await-holding-lock` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::await_holding_lock)]`
 
@@ -24,13 +21,10 @@ LL |         let guard = x.read().unwrap();
    |
    = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
 note: these are all the `await` points this lock is held through
-  --> $DIR/await_holding_lock.rs:25:9
+  --> $DIR/await_holding_lock.rs:27:15
    |
-LL | /         let guard = x.read().unwrap();
-LL | |
-LL | |         baz().await
-LL | |     }
-   | |_____^
+LL |         baz().await
+   |               ^^^^^
 
 error: this `MutexGuard` is held across an `await` point
   --> $DIR/await_holding_lock.rs:31:13
@@ -40,13 +34,10 @@ LL |         let mut guard = x.write().unwrap();
    |
    = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
 note: these are all the `await` points this lock is held through
-  --> $DIR/await_holding_lock.rs:31:9
+  --> $DIR/await_holding_lock.rs:33:15
    |
-LL | /         let mut guard = x.write().unwrap();
-LL | |
-LL | |         baz().await
-LL | |     }
-   | |_____^
+LL |         baz().await
+   |               ^^^^^
 
 error: this `MutexGuard` is held across an `await` point
   --> $DIR/await_holding_lock.rs:53:13
@@ -56,16 +47,13 @@ LL |         let guard = x.lock().unwrap();
    |
    = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
 note: these are all the `await` points this lock is held through
-  --> $DIR/await_holding_lock.rs:53:9
-   |
-LL | /         let guard = x.lock().unwrap();
-LL | |
-LL | |
-LL | |         let second = baz().await;
-...  |
-LL | |         first + second + third
-LL | |     }
-   | |_____^
+  --> $DIR/await_holding_lock.rs:56:28
+   |
+LL |         let second = baz().await;
+   |                            ^^^^^
+LL |
+LL |         let third = baz().await;
+   |                           ^^^^^
 
 error: this `MutexGuard` is held across an `await` point
   --> $DIR/await_holding_lock.rs:67:17
@@ -75,13 +63,10 @@ LL |             let guard = x.lock().unwrap();
    |
    = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
 note: these are all the `await` points this lock is held through
-  --> $DIR/await_holding_lock.rs:67:13
+  --> $DIR/await_holding_lock.rs:69:19
    |
-LL | /             let guard = x.lock().unwrap();
-LL | |
-LL | |             baz().await
-LL | |         };
-   | |_________^
+LL |             baz().await
+   |                   ^^^^^
 
 error: this `MutexGuard` is held across an `await` point
   --> $DIR/await_holding_lock.rs:80:17
@@ -91,13 +76,10 @@ LL |             let guard = x.lock().unwrap();
    |
    = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
 note: these are all the `await` points this lock is held through
-  --> $DIR/await_holding_lock.rs:80:13
+  --> $DIR/await_holding_lock.rs:82:19
    |
-LL | /             let guard = x.lock().unwrap();
-LL | |
-LL | |             baz().await
-LL | |         }
-   | |_________^
+LL |             baz().await
+   |                   ^^^^^
 
 error: this `MutexGuard` is held across an `await` point
   --> $DIR/await_holding_lock.rs:93:13
@@ -107,13 +89,10 @@ LL |         let guard = x.lock();
    |
    = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
 note: these are all the `await` points this lock is held through
-  --> $DIR/await_holding_lock.rs:93:9
+  --> $DIR/await_holding_lock.rs:95:15
    |
-LL | /         let guard = x.lock();
-LL | |
-LL | |         baz().await
-LL | |     }
-   | |_____^
+LL |         baz().await
+   |               ^^^^^
 
 error: this `MutexGuard` is held across an `await` point
   --> $DIR/await_holding_lock.rs:109:13
@@ -123,13 +102,10 @@ LL |         let guard = x.read();
    |
    = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
 note: these are all the `await` points this lock is held through
-  --> $DIR/await_holding_lock.rs:109:9
+  --> $DIR/await_holding_lock.rs:111:15
    |
-LL | /         let guard = x.read();
-LL | |
-LL | |         baz().await
-LL | |     }
-   | |_____^
+LL |         baz().await
+   |               ^^^^^
 
 error: this `MutexGuard` is held across an `await` point
   --> $DIR/await_holding_lock.rs:115:13
@@ -139,13 +115,10 @@ LL |         let mut guard = x.write();
    |
    = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
 note: these are all the `await` points this lock is held through
-  --> $DIR/await_holding_lock.rs:115:9
+  --> $DIR/await_holding_lock.rs:117:15
    |
-LL | /         let mut guard = x.write();
-LL | |
-LL | |         baz().await
-LL | |     }
-   | |_____^
+LL |         baz().await
+   |               ^^^^^
 
 error: this `MutexGuard` is held across an `await` point
   --> $DIR/await_holding_lock.rs:137:13
@@ -155,16 +128,13 @@ LL |         let guard = x.lock();
    |
    = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
 note: these are all the `await` points this lock is held through
-  --> $DIR/await_holding_lock.rs:137:9
-   |
-LL | /         let guard = x.lock();
-LL | |
-LL | |
-LL | |         let second = baz().await;
-...  |
-LL | |         first + second + third
-LL | |     }
-   | |_____^
+  --> $DIR/await_holding_lock.rs:140:28
+   |
+LL |         let second = baz().await;
+   |                            ^^^^^
+LL |
+LL |         let third = baz().await;
+   |                           ^^^^^
 
 error: this `MutexGuard` is held across an `await` point
   --> $DIR/await_holding_lock.rs:151:17
@@ -174,13 +144,10 @@ LL |             let guard = x.lock();
    |
    = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
 note: these are all the `await` points this lock is held through
-  --> $DIR/await_holding_lock.rs:151:13
+  --> $DIR/await_holding_lock.rs:153:19
    |
-LL | /             let guard = x.lock();
-LL | |
-LL | |             baz().await
-LL | |         };
-   | |_________^
+LL |             baz().await
+   |                   ^^^^^
 
 error: this `MutexGuard` is held across an `await` point
   --> $DIR/await_holding_lock.rs:164:17
@@ -190,13 +157,10 @@ LL |             let guard = x.lock();
    |
    = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
 note: these are all the `await` points this lock is held through
-  --> $DIR/await_holding_lock.rs:164:13
+  --> $DIR/await_holding_lock.rs:166:19
    |
-LL | /             let guard = x.lock();
-LL | |
-LL | |             baz().await
-LL | |         }
-   | |_________^
+LL |             baz().await
+   |                   ^^^^^
 
 error: this `MutexGuard` is held across an `await` point
   --> $DIR/await_holding_lock.rs:185:9
@@ -206,15 +170,10 @@ LL |     let mut guard = x.lock().unwrap();
    |
    = help: consider using an async-aware `Mutex` type or ensuring the `MutexGuard` is dropped before calling await
 note: these are all the `await` points this lock is held through
-  --> $DIR/await_holding_lock.rs:185:5
-   |
-LL | /     let mut guard = x.lock().unwrap();
-LL | |
-LL | |     *guard += 1;
-LL | |     drop(guard);
-LL | |     baz().await;
-LL | | }
-   | |_^
+  --> $DIR/await_holding_lock.rs:189:11
+   |
+LL |     baz().await;
+   |           ^^^^^
 
 error: aborting due to 13 previous errors
 
diff --git a/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr b/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr
index 6b7e1d1afdd..9264af93dc1 100644
--- a/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr
+++ b/src/tools/clippy/tests/ui/await_holding_refcell_ref.stderr
@@ -6,13 +6,10 @@ LL |     let b = x.borrow();
    |
    = help: ensure the reference is dropped before calling `await`
 note: these are all the `await` points this reference is held through
-  --> $DIR/await_holding_refcell_ref.rs:6:5
+  --> $DIR/await_holding_refcell_ref.rs:8:11
    |
-LL | /     let b = x.borrow();
-LL | |
-LL | |     baz().await
-LL | | }
-   | |_^
+LL |     baz().await
+   |           ^^^^^
    = note: `-D clippy::await-holding-refcell-ref` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::await_holding_refcell_ref)]`
 
@@ -24,13 +21,10 @@ LL |     let b = x.borrow_mut();
    |
    = help: ensure the reference is dropped before calling `await`
 note: these are all the `await` points this reference is held through
-  --> $DIR/await_holding_refcell_ref.rs:12:5
+  --> $DIR/await_holding_refcell_ref.rs:14:11
    |
-LL | /     let b = x.borrow_mut();
-LL | |
-LL | |     baz().await
-LL | | }
-   | |_^
+LL |     baz().await
+   |           ^^^^^
 
 error: this `RefCell` reference is held across an `await` point
   --> $DIR/await_holding_refcell_ref.rs:34:9
@@ -40,16 +34,13 @@ LL |     let b = x.borrow_mut();
    |
    = help: ensure the reference is dropped before calling `await`
 note: these are all the `await` points this reference is held through
-  --> $DIR/await_holding_refcell_ref.rs:34:5
-   |
-LL | /     let b = x.borrow_mut();
-LL | |
-LL | |
-LL | |     let second = baz().await;
-...  |
-LL | |     first + second + third
-LL | | }
-   | |_^
+  --> $DIR/await_holding_refcell_ref.rs:37:24
+   |
+LL |     let second = baz().await;
+   |                        ^^^^^
+LL |
+LL |     let third = baz().await;
+   |                       ^^^^^
 
 error: this `RefCell` reference is held across an `await` point
   --> $DIR/await_holding_refcell_ref.rs:47:9
@@ -59,16 +50,10 @@ LL |     let b = x.borrow_mut();
    |
    = help: ensure the reference is dropped before calling `await`
 note: these are all the `await` points this reference is held through
-  --> $DIR/await_holding_refcell_ref.rs:47:5
-   |
-LL | /     let b = x.borrow_mut();
-LL | |
-LL | |
-LL | |     let second = baz().await;
-...  |
-LL | |     first + second + third
-LL | | }
-   | |_^
+  --> $DIR/await_holding_refcell_ref.rs:50:24
+   |
+LL |     let second = baz().await;
+   |                        ^^^^^
 
 error: this `RefCell` reference is held across an `await` point
   --> $DIR/await_holding_refcell_ref.rs:63:13
@@ -78,13 +63,10 @@ LL |         let b = x.borrow_mut();
    |
    = help: ensure the reference is dropped before calling `await`
 note: these are all the `await` points this reference is held through
-  --> $DIR/await_holding_refcell_ref.rs:63:9
+  --> $DIR/await_holding_refcell_ref.rs:65:15
    |
-LL | /         let b = x.borrow_mut();
-LL | |
-LL | |         baz().await
-LL | |     };
-   | |_____^
+LL |         baz().await
+   |               ^^^^^
 
 error: this `RefCell` reference is held across an `await` point
   --> $DIR/await_holding_refcell_ref.rs:76:13
@@ -94,13 +76,10 @@ LL |         let b = x.borrow_mut();
    |
    = help: ensure the reference is dropped before calling `await`
 note: these are all the `await` points this reference is held through
-  --> $DIR/await_holding_refcell_ref.rs:76:9
+  --> $DIR/await_holding_refcell_ref.rs:78:15
    |
-LL | /         let b = x.borrow_mut();
-LL | |
-LL | |         baz().await
-LL | |     }
-   | |_____^
+LL |         baz().await
+   |               ^^^^^
 
 error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast.rs b/src/tools/clippy/tests/ui/cast.rs
index d0a092093f3..1ca18170f8a 100644
--- a/src/tools/clippy/tests/ui/cast.rs
+++ b/src/tools/clippy/tests/ui/cast.rs
@@ -361,3 +361,7 @@ fn avoid_subtract_overflow(q: u32) {
     //~^ ERROR: casting `u32` to `u8` may truncate the value
     c as usize;
 }
+
+fn issue11426() {
+    (&42u8 >> 0xa9008fb6c9d81e42_0e25730562a601c8_u128) as usize;
+}
diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.fixed b/src/tools/clippy/tests/ui/cast_lossless_integer.fixed
index 6547107f500..5e7e545e764 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_integer.fixed
+++ b/src/tools/clippy/tests/ui/cast_lossless_integer.fixed
@@ -49,3 +49,14 @@ mod cast_lossless_in_impl {
 enum Test {
     A = u32::MAX as i64 + 1,
 }
+
+fn issue11458() {
+    macro_rules! sign_cast {
+        ($var: ident, $src: ty, $dest: ty) => {
+            <$dest>::from_ne_bytes(($var as $src).to_ne_bytes())
+        };
+    }
+    let x = 10_u128;
+    let _ = i32::from(sign_cast!(x, u8, i8));
+    let _ = i32::from(sign_cast!(x, u8, i8) + 1);
+}
diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.rs b/src/tools/clippy/tests/ui/cast_lossless_integer.rs
index 79af9a83ca2..0d69ddbd586 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_integer.rs
+++ b/src/tools/clippy/tests/ui/cast_lossless_integer.rs
@@ -49,3 +49,14 @@ mod cast_lossless_in_impl {
 enum Test {
     A = u32::MAX as i64 + 1,
 }
+
+fn issue11458() {
+    macro_rules! sign_cast {
+        ($var: ident, $src: ty, $dest: ty) => {
+            <$dest>::from_ne_bytes(($var as $src).to_ne_bytes())
+        };
+    }
+    let x = 10_u128;
+    let _ = sign_cast!(x, u8, i8) as i32;
+    let _ = (sign_cast!(x, u8, i8) + 1) as i32;
+}
diff --git a/src/tools/clippy/tests/ui/cast_lossless_integer.stderr b/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
index da75cb195eb..f9f111a7c20 100644
--- a/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
+++ b/src/tools/clippy/tests/ui/cast_lossless_integer.stderr
@@ -115,5 +115,17 @@ error: casting `u8` to `u16` may become silently lossy if you later change the t
 LL |     let _ = (1u8 + 1u8) as u16;
    |             ^^^^^^^^^^^^^^^^^^ help: try: `u16::from(1u8 + 1u8)`
 
-error: aborting due to 19 previous errors
+error: casting `i8` to `i32` may become silently lossy if you later change the type
+  --> $DIR/cast_lossless_integer.rs:60:13
+   |
+LL |     let _ = sign_cast!(x, u8, i8) as i32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::from(sign_cast!(x, u8, i8))`
+
+error: casting `i8` to `i32` may become silently lossy if you later change the type
+  --> $DIR/cast_lossless_integer.rs:61:13
+   |
+LL |     let _ = (sign_cast!(x, u8, i8) + 1) as i32;
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::from(sign_cast!(x, u8, i8) + 1)`
+
+error: aborting due to 21 previous errors
 
diff --git a/src/tools/clippy/tests/ui/eta.fixed b/src/tools/clippy/tests/ui/eta.fixed
index f1cac8c5fbc..32c7499bf73 100644
--- a/src/tools/clippy/tests/ui/eta.fixed
+++ b/src/tools/clippy/tests/ui/eta.fixed
@@ -7,7 +7,8 @@
     clippy::option_map_unit_fn,
     clippy::redundant_closure_call,
     clippy::uninlined_format_args,
-    clippy::useless_vec
+    clippy::useless_vec,
+    clippy::unnecessary_map_on_constructor
 )]
 
 use std::path::{Path, PathBuf};
diff --git a/src/tools/clippy/tests/ui/eta.rs b/src/tools/clippy/tests/ui/eta.rs
index c7a470b5be6..25b7431ba8c 100644
--- a/src/tools/clippy/tests/ui/eta.rs
+++ b/src/tools/clippy/tests/ui/eta.rs
@@ -7,7 +7,8 @@
     clippy::option_map_unit_fn,
     clippy::redundant_closure_call,
     clippy::uninlined_format_args,
-    clippy::useless_vec
+    clippy::useless_vec,
+    clippy::unnecessary_map_on_constructor
 )]
 
 use std::path::{Path, PathBuf};
diff --git a/src/tools/clippy/tests/ui/eta.stderr b/src/tools/clippy/tests/ui/eta.stderr
index 7c7f1797462..951e4ac749c 100644
--- a/src/tools/clippy/tests/ui/eta.stderr
+++ b/src/tools/clippy/tests/ui/eta.stderr
@@ -1,5 +1,5 @@
 error: redundant closure
-  --> $DIR/eta.rs:28:27
+  --> $DIR/eta.rs:29:27
    |
 LL |     let a = Some(1u8).map(|a| foo(a));
    |                           ^^^^^^^^^^ help: replace the closure with the function itself: `foo`
@@ -8,31 +8,31 @@ LL |     let a = Some(1u8).map(|a| foo(a));
    = help: to override `-D warnings` add `#[allow(clippy::redundant_closure)]`
 
 error: redundant closure
-  --> $DIR/eta.rs:32:40
+  --> $DIR/eta.rs:33:40
    |
 LL |     let _: Option<Vec<u8>> = true.then(|| vec![]); // special case vec!
    |                                        ^^^^^^^^^ help: replace the closure with `Vec::new`: `std::vec::Vec::new`
 
 error: redundant closure
-  --> $DIR/eta.rs:33:35
+  --> $DIR/eta.rs:34:35
    |
 LL |     let d = Some(1u8).map(|a| foo((|b| foo2(b))(a))); //is adjusted?
    |                                   ^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo2`
 
 error: redundant closure
-  --> $DIR/eta.rs:34:26
+  --> $DIR/eta.rs:35:26
    |
 LL |     all(&[1, 2, 3], &&2, |x, y| below(x, y)); //is adjusted
    |                          ^^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `below`
 
 error: redundant closure
-  --> $DIR/eta.rs:41:27
+  --> $DIR/eta.rs:42:27
    |
 LL |     let e = Some(1u8).map(|a| generic(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `generic`
 
 error: redundant closure
-  --> $DIR/eta.rs:93:51
+  --> $DIR/eta.rs:94:51
    |
 LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
    |                                                   ^^^^^^^^^^^ help: replace the closure with the method itself: `TestStruct::foo`
@@ -41,127 +41,127 @@ LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.foo());
    = help: to override `-D warnings` add `#[allow(clippy::redundant_closure_for_method_calls)]`
 
 error: redundant closure
-  --> $DIR/eta.rs:94:51
+  --> $DIR/eta.rs:95:51
    |
 LL |     let e = Some(TestStruct { some_ref: &i }).map(|a| a.trait_foo());
    |                                                   ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `TestTrait::trait_foo`
 
 error: redundant closure
-  --> $DIR/eta.rs:96:42
+  --> $DIR/eta.rs:97:42
    |
 LL |     let e = Some(&mut vec![1, 2, 3]).map(|v| v.clear());
    |                                          ^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::vec::Vec::clear`
 
 error: redundant closure
-  --> $DIR/eta.rs:100:29
+  --> $DIR/eta.rs:101:29
    |
 LL |     let e = Some("str").map(|s| s.to_string());
    |                             ^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `std::string::ToString::to_string`
 
 error: redundant closure
-  --> $DIR/eta.rs:101:27
+  --> $DIR/eta.rs:102:27
    |
 LL |     let e = Some('a').map(|s| s.to_uppercase());
    |                           ^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_uppercase`
 
 error: redundant closure
-  --> $DIR/eta.rs:103:65
+  --> $DIR/eta.rs:104:65
    |
 LL |     let e: std::vec::Vec<char> = vec!['a', 'b', 'c'].iter().map(|c| c.to_ascii_uppercase()).collect();
    |                                                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `char::to_ascii_uppercase`
 
 error: redundant closure
-  --> $DIR/eta.rs:166:22
+  --> $DIR/eta.rs:167:22
    |
 LL |     requires_fn_once(|| x());
    |                      ^^^^^^ help: replace the closure with the function itself: `x`
 
 error: redundant closure
-  --> $DIR/eta.rs:173:27
+  --> $DIR/eta.rs:174:27
    |
 LL |     let a = Some(1u8).map(|a| foo_ptr(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `foo_ptr`
 
 error: redundant closure
-  --> $DIR/eta.rs:178:27
+  --> $DIR/eta.rs:179:27
    |
 LL |     let a = Some(1u8).map(|a| closure(a));
    |                           ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `closure`
 
 error: redundant closure
-  --> $DIR/eta.rs:210:28
+  --> $DIR/eta.rs:211:28
    |
 LL |     x.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
 
 error: redundant closure
-  --> $DIR/eta.rs:211:28
+  --> $DIR/eta.rs:212:28
    |
 LL |     y.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut add_to_res`
 
 error: redundant closure
-  --> $DIR/eta.rs:212:28
+  --> $DIR/eta.rs:213:28
    |
 LL |     z.into_iter().for_each(|x| add_to_res(x));
    |                            ^^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `add_to_res`
 
 error: redundant closure
-  --> $DIR/eta.rs:219:21
+  --> $DIR/eta.rs:220:21
    |
 LL |         Some(1).map(|n| closure(n));
    |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut closure`
 
 error: redundant closure
-  --> $DIR/eta.rs:223:21
+  --> $DIR/eta.rs:224:21
    |
 LL |         Some(1).map(|n| in_loop(n));
    |                     ^^^^^^^^^^^^^^ help: replace the closure with the function itself: `in_loop`
 
 error: redundant closure
-  --> $DIR/eta.rs:316:18
+  --> $DIR/eta.rs:317:18
    |
 LL |     takes_fn_mut(|| f());
    |                  ^^^^^^ help: replace the closure with the function itself: `&mut f`
 
 error: redundant closure
-  --> $DIR/eta.rs:319:19
+  --> $DIR/eta.rs:320:19
    |
 LL |     takes_fn_once(|| f());
    |                   ^^^^^^ help: replace the closure with the function itself: `&mut f`
 
 error: redundant closure
-  --> $DIR/eta.rs:323:26
+  --> $DIR/eta.rs:324:26
    |
 LL |     move || takes_fn_mut(|| f_used_once())
    |                          ^^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `&mut f_used_once`
 
 error: redundant closure
-  --> $DIR/eta.rs:335:19
+  --> $DIR/eta.rs:336:19
    |
 LL |     array_opt.map(|a| a.as_slice());
    |                   ^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8; 3]>::as_slice`
 
 error: redundant closure
-  --> $DIR/eta.rs:338:19
+  --> $DIR/eta.rs:339:19
    |
 LL |     slice_opt.map(|s| s.len());
    |                   ^^^^^^^^^^^ help: replace the closure with the method itself: `<[u8]>::len`
 
 error: redundant closure
-  --> $DIR/eta.rs:341:17
+  --> $DIR/eta.rs:342:17
    |
 LL |     ptr_opt.map(|p| p.is_null());
    |                 ^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<*const usize>::is_null`
 
 error: redundant closure
-  --> $DIR/eta.rs:345:17
+  --> $DIR/eta.rs:346:17
    |
 LL |     dyn_opt.map(|d| d.method_on_dyn());
    |                 ^^^^^^^^^^^^^^^^^^^^^ help: replace the closure with the method itself: `<dyn TestTrait>::method_on_dyn`
 
 error: redundant closure
-  --> $DIR/eta.rs:388:19
+  --> $DIR/eta.rs:389:19
    |
 LL |     let _ = f(&0, |x, y| f2(x, y));
    |                   ^^^^^^^^^^^^^^^ help: replace the closure with the function itself: `f2`
diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed b/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed
index a4943344a11..c9bebabdf17 100644
--- a/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed
+++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters.fixed
@@ -113,4 +113,19 @@ with_span!(
     }
 );
 
+mod issue11302 {
+    use std::fmt::Debug;
+    use std::marker::PhantomData;
+
+    #[derive(Debug)]
+    struct Wrapper<T>(PhantomData<T>);
+
+    fn store<T: 'static>(v: &mut Vec<Box<dyn Debug>>)
+    where
+        Wrapper<T>: Debug,
+    {
+        v.push(Box::new(Wrapper(PhantomData)));
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs b/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs
index 6d85b1ce9d4..1bc0047adf0 100644
--- a/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs
+++ b/src/tools/clippy/tests/ui/extra_unused_type_parameters.rs
@@ -113,4 +113,19 @@ with_span!(
     }
 );
 
+mod issue11302 {
+    use std::fmt::Debug;
+    use std::marker::PhantomData;
+
+    #[derive(Debug)]
+    struct Wrapper<T>(PhantomData<T>);
+
+    fn store<T: 'static>(v: &mut Vec<Box<dyn Debug>>)
+    where
+        Wrapper<T>: Debug,
+    {
+        v.push(Box::new(Wrapper(PhantomData)));
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/filter_map_bool_then.fixed b/src/tools/clippy/tests/ui/filter_map_bool_then.fixed
index 6de870a9289..6a1b81fdbcb 100644
--- a/src/tools/clippy/tests/ui/filter_map_bool_then.fixed
+++ b/src/tools/clippy/tests/ui/filter_map_bool_then.fixed
@@ -55,3 +55,27 @@ fn main() {
 fn issue11309<'a>(iter: impl Iterator<Item = (&'a str, &'a str)>) -> Vec<&'a str> {
     iter.filter_map(|(_, s): (&str, _)| Some(s)).collect()
 }
+
+fn issue11503() {
+    let bools: &[bool] = &[true, false, false, true];
+    let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| *b).map(|(i, b)| i).collect();
+
+    // Need to insert multiple derefs if there is more than one layer of references
+    let bools: &[&&bool] = &[&&true, &&false, &&false, &&true];
+    let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| ***b).map(|(i, b)| i).collect();
+
+    // Should also suggest derefs when going through a mutable reference
+    let bools: &[&mut bool] = &[&mut true];
+    let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| **b).map(|(i, b)| i).collect();
+
+    // Should also suggest derefs when going through a custom deref
+    struct DerefToBool;
+    impl std::ops::Deref for DerefToBool {
+        type Target = bool;
+        fn deref(&self) -> &Self::Target {
+            &true
+        }
+    }
+    let bools: &[&&DerefToBool] = &[&&DerefToBool];
+    let _: Vec<usize> = bools.iter().enumerate().filter(|&(i, b)| ****b).map(|(i, b)| i).collect();
+}
diff --git a/src/tools/clippy/tests/ui/filter_map_bool_then.rs b/src/tools/clippy/tests/ui/filter_map_bool_then.rs
index 4108177e3a0..a41e88f8805 100644
--- a/src/tools/clippy/tests/ui/filter_map_bool_then.rs
+++ b/src/tools/clippy/tests/ui/filter_map_bool_then.rs
@@ -55,3 +55,27 @@ fn main() {
 fn issue11309<'a>(iter: impl Iterator<Item = (&'a str, &'a str)>) -> Vec<&'a str> {
     iter.filter_map(|(_, s): (&str, _)| Some(s)).collect()
 }
+
+fn issue11503() {
+    let bools: &[bool] = &[true, false, false, true];
+    let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+
+    // Need to insert multiple derefs if there is more than one layer of references
+    let bools: &[&&bool] = &[&&true, &&false, &&false, &&true];
+    let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+
+    // Should also suggest derefs when going through a mutable reference
+    let bools: &[&mut bool] = &[&mut true];
+    let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+
+    // Should also suggest derefs when going through a custom deref
+    struct DerefToBool;
+    impl std::ops::Deref for DerefToBool {
+        type Target = bool;
+        fn deref(&self) -> &Self::Target {
+            &true
+        }
+    }
+    let bools: &[&&DerefToBool] = &[&&DerefToBool];
+    let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+}
diff --git a/src/tools/clippy/tests/ui/filter_map_bool_then.stderr b/src/tools/clippy/tests/ui/filter_map_bool_then.stderr
index 86ef6edf8ee..fab6987913a 100644
--- a/src/tools/clippy/tests/ui/filter_map_bool_then.stderr
+++ b/src/tools/clippy/tests/ui/filter_map_bool_then.stderr
@@ -37,5 +37,29 @@ error: usage of `bool::then` in `filter_map`
 LL |     v.clone().iter().filter_map(|i| (i == &NonCopy).then(|| i));
    |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&i| (i == &NonCopy)).map(|i| i)`
 
-error: aborting due to 6 previous errors
+error: usage of `bool::then` in `filter_map`
+  --> $DIR/filter_map_bool_then.rs:61:50
+   |
+LL |     let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| *b).map(|(i, b)| i)`
+
+error: usage of `bool::then` in `filter_map`
+  --> $DIR/filter_map_bool_then.rs:65:50
+   |
+LL |     let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| ***b).map(|(i, b)| i)`
+
+error: usage of `bool::then` in `filter_map`
+  --> $DIR/filter_map_bool_then.rs:69:50
+   |
+LL |     let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| **b).map(|(i, b)| i)`
+
+error: usage of `bool::then` in `filter_map`
+  --> $DIR/filter_map_bool_then.rs:80:50
+   |
+LL |     let _: Vec<usize> = bools.iter().enumerate().filter_map(|(i, b)| b.then(|| i)).collect();
+   |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `filter` then `map` instead: `filter(|&(i, b)| ****b).map(|(i, b)| i)`
+
+error: aborting due to 10 previous errors
 
diff --git a/src/tools/clippy/tests/ui/future_not_send.rs b/src/tools/clippy/tests/ui/future_not_send.rs
index 06090e2713d..9274340b5ca 100644
--- a/src/tools/clippy/tests/ui/future_not_send.rs
+++ b/src/tools/clippy/tests/ui/future_not_send.rs
@@ -59,6 +59,7 @@ where
 {
     let rt = &t;
     async { true }.await;
+    let _ = rt;
     t
 }
 
diff --git a/src/tools/clippy/tests/ui/future_not_send.stderr b/src/tools/clippy/tests/ui/future_not_send.stderr
index e417de723ff..f43e3c8ff9f 100644
--- a/src/tools/clippy/tests/ui/future_not_send.stderr
+++ b/src/tools/clippy/tests/ui/future_not_send.stderr
@@ -12,19 +12,12 @@ LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
 LL |
 LL |     async { true }.await
    |                    ^^^^^ await occurs here, with `rc` maybe used later
-LL | }
-   | - `rc` is later dropped here
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/future_not_send.rs:9:20
+note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
+  --> $DIR/future_not_send.rs:7:39
    |
 LL | async fn private_future(rc: Rc<[u8]>, cell: &Cell<usize>) -> bool {
-   |                                       ---- has type `&std::cell::Cell<usize>` which is not `Send`
-LL |
-LL |     async { true }.await
-   |                    ^^^^^ await occurs here, with `cell` maybe used later
-LL | }
-   | - `cell` is later dropped here
+   |                                       ^^^^ has type `&std::cell::Cell<usize>` which is not `Send`, because `std::cell::Cell<usize>` is not `Sync`
    = note: `std::cell::Cell<usize>` doesn't implement `std::marker::Sync`
    = note: `-D clippy::future-not-send` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::future_not_send)]`
@@ -43,8 +36,6 @@ LL | pub async fn public_future(rc: Rc<[u8]>) {
 LL |
 LL |     async { true }.await;
    |                    ^^^^^ await occurs here, with `rc` maybe used later
-LL | }
-   | - `rc` is later dropped here
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Send`
 
 error: future cannot be sent between threads safely
@@ -93,9 +84,6 @@ LL |     async fn private_future(&self) -> usize {
 LL |
 LL |         async { true }.await;
    |                        ^^^^^ await occurs here, with `&self` maybe used later
-LL |         self.rc.len()
-LL |     }
-   |     - `&self` is later dropped here
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync`
 
 error: future cannot be sent between threads safely
@@ -104,16 +92,11 @@ error: future cannot be sent between threads safely
 LL |     pub async fn public_future(&self) {
    |                                       ^ future returned by `public_future` is not `Send`
    |
-note: future is not `Send` as this value is used across an await
-  --> $DIR/future_not_send.rs:46:31
+note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
+  --> $DIR/future_not_send.rs:44:32
    |
 LL |     pub async fn public_future(&self) {
-   |                                ----- has type `&Dummy` which is not `Send`
-LL |
-LL |         self.private_future().await;
-   |                               ^^^^^ await occurs here, with `&self` maybe used later
-LL |     }
-   |     - `&self` is later dropped here
+   |                                ^^^^^ has type `&Dummy` which is not `Send`, because `Dummy` is not `Sync`
    = note: `std::rc::Rc<[u8]>` doesn't implement `std::marker::Sync`
 
 error: future cannot be sent between threads safely
@@ -129,19 +112,16 @@ LL |     let rt = &t;
    |         -- has type `&T` which is not `Send`
 LL |     async { true }.await;
    |                    ^^^^^ await occurs here, with `rt` maybe used later
-LL |     t
-LL | }
-   | - `rt` is later dropped here
    = note: `T` doesn't implement `std::marker::Sync`
 
 error: future cannot be sent between threads safely
-  --> $DIR/future_not_send.rs:72:34
+  --> $DIR/future_not_send.rs:73:34
    |
 LL | async fn unclear_future<T>(t: T) {}
    |                                  ^ future returned by `unclear_future` is not `Send`
    |
 note: captured value is not `Send`
-  --> $DIR/future_not_send.rs:72:28
+  --> $DIR/future_not_send.rs:73:28
    |
 LL | async fn unclear_future<T>(t: T) {}
    |                            ^ has type `T` which is not `Send`
diff --git a/src/tools/clippy/tests/ui/len_without_is_empty.rs b/src/tools/clippy/tests/ui/len_without_is_empty.rs
index ac6c3e06365..d623601110e 100644
--- a/src/tools/clippy/tests/ui/len_without_is_empty.rs
+++ b/src/tools/clippy/tests/ui/len_without_is_empty.rs
@@ -436,4 +436,27 @@ impl DifferingErrors {
     }
 }
 
+// Issue #11165
+pub struct Aliased1;
+pub type Alias1 = Aliased1;
+
+impl Alias1 {
+    pub fn len(&self) -> usize {
+        todo!()
+    }
+
+    pub fn is_empty(&self) -> bool {
+        todo!()
+    }
+}
+
+pub struct Aliased2;
+pub type Alias2 = Aliased2;
+impl Alias2 {
+    pub fn len(&self) -> usize {
+        //~^ ERROR: type `Alias2` has a public `len` method, but no `is_empty` method
+        todo!()
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/len_without_is_empty.stderr b/src/tools/clippy/tests/ui/len_without_is_empty.stderr
index 4815ce6a04b..8e51c28b330 100644
--- a/src/tools/clippy/tests/ui/len_without_is_empty.stderr
+++ b/src/tools/clippy/tests/ui/len_without_is_empty.stderr
@@ -141,5 +141,11 @@ error: struct `AsyncResultLenWithoutIsEmpty` has a public `len` method, but no `
 LL |     pub async fn len(&self) -> Result<usize, ()> {
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 15 previous errors
+error: type `Alias2` has a public `len` method, but no `is_empty` method
+  --> $DIR/len_without_is_empty.rs:456:5
+   |
+LL |     pub fn len(&self) -> usize {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 16 previous errors
 
diff --git a/src/tools/clippy/tests/ui/let_unit.fixed b/src/tools/clippy/tests/ui/let_unit.fixed
index 57374bd5fcd..f98ce9d50a9 100644
--- a/src/tools/clippy/tests/ui/let_unit.fixed
+++ b/src/tools/clippy/tests/ui/let_unit.fixed
@@ -177,3 +177,5 @@ fn attributes() {
 async fn issue10433() {
     let _pending: () = std::future::pending().await;
 }
+
+pub async fn issue11502(a: ()) {}
diff --git a/src/tools/clippy/tests/ui/let_unit.rs b/src/tools/clippy/tests/ui/let_unit.rs
index 09077c60d50..6d942ca8908 100644
--- a/src/tools/clippy/tests/ui/let_unit.rs
+++ b/src/tools/clippy/tests/ui/let_unit.rs
@@ -177,3 +177,5 @@ fn attributes() {
 async fn issue10433() {
     let _pending: () = std::future::pending().await;
 }
+
+pub async fn issue11502(a: ()) {}
diff --git a/src/tools/clippy/tests/ui/manual_map_option.fixed b/src/tools/clippy/tests/ui/manual_map_option.fixed
index f6a964da418..16cee3fd382 100644
--- a/src/tools/clippy/tests/ui/manual_map_option.fixed
+++ b/src/tools/clippy/tests/ui/manual_map_option.fixed
@@ -5,6 +5,7 @@
     clippy::unit_arg,
     clippy::match_ref_pats,
     clippy::redundant_pattern_matching,
+    clippy::unnecessary_map_on_constructor,
     for_loops_over_fallibles,
     dead_code
 )]
diff --git a/src/tools/clippy/tests/ui/manual_map_option.rs b/src/tools/clippy/tests/ui/manual_map_option.rs
index df9dc256d30..4655acf1406 100644
--- a/src/tools/clippy/tests/ui/manual_map_option.rs
+++ b/src/tools/clippy/tests/ui/manual_map_option.rs
@@ -5,6 +5,7 @@
     clippy::unit_arg,
     clippy::match_ref_pats,
     clippy::redundant_pattern_matching,
+    clippy::unnecessary_map_on_constructor,
     for_loops_over_fallibles,
     dead_code
 )]
diff --git a/src/tools/clippy/tests/ui/manual_map_option.stderr b/src/tools/clippy/tests/ui/manual_map_option.stderr
index ff6ed974d4a..3754a982cb9 100644
--- a/src/tools/clippy/tests/ui/manual_map_option.stderr
+++ b/src/tools/clippy/tests/ui/manual_map_option.stderr
@@ -1,5 +1,5 @@
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:13:5
+  --> $DIR/manual_map_option.rs:14:5
    |
 LL | /     match Some(0) {
 LL | |         Some(_) => Some(2),
@@ -11,7 +11,7 @@ LL | |     };
    = help: to override `-D warnings` add `#[allow(clippy::manual_map)]`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:18:5
+  --> $DIR/manual_map_option.rs:19:5
    |
 LL | /     match Some(0) {
 LL | |         Some(x) => Some(x + 1),
@@ -20,7 +20,7 @@ LL | |     };
    | |_____^ help: try: `Some(0).map(|x| x + 1)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:23:5
+  --> $DIR/manual_map_option.rs:24:5
    |
 LL | /     match Some("") {
 LL | |         Some(x) => Some(x.is_empty()),
@@ -29,7 +29,7 @@ LL | |     };
    | |_____^ help: try: `Some("").map(|x| x.is_empty())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:28:5
+  --> $DIR/manual_map_option.rs:29:5
    |
 LL | /     if let Some(x) = Some(0) {
 LL | |         Some(!x)
@@ -39,7 +39,7 @@ LL | |     };
    | |_____^ help: try: `Some(0).map(|x| !x)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:35:5
+  --> $DIR/manual_map_option.rs:36:5
    |
 LL | /     match Some(0) {
 LL | |         Some(x) => { Some(std::convert::identity(x)) }
@@ -48,7 +48,7 @@ LL | |     };
    | |_____^ help: try: `Some(0).map(std::convert::identity)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:40:5
+  --> $DIR/manual_map_option.rs:41:5
    |
 LL | /     match Some(&String::new()) {
 LL | |         Some(x) => Some(str::len(x)),
@@ -57,7 +57,7 @@ LL | |     };
    | |_____^ help: try: `Some(&String::new()).map(|x| str::len(x))`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:50:5
+  --> $DIR/manual_map_option.rs:51:5
    |
 LL | /     match &Some([0, 1]) {
 LL | |         Some(x) => Some(x[0]),
@@ -66,7 +66,7 @@ LL | |     };
    | |_____^ help: try: `Some([0, 1]).as_ref().map(|x| x[0])`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:55:5
+  --> $DIR/manual_map_option.rs:56:5
    |
 LL | /     match &Some(0) {
 LL | |         &Some(x) => Some(x * 2),
@@ -75,7 +75,7 @@ LL | |     };
    | |_____^ help: try: `Some(0).map(|x| x * 2)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:60:5
+  --> $DIR/manual_map_option.rs:61:5
    |
 LL | /     match Some(String::new()) {
 LL | |         Some(ref x) => Some(x.is_empty()),
@@ -84,7 +84,7 @@ LL | |     };
    | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.is_empty())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:65:5
+  --> $DIR/manual_map_option.rs:66:5
    |
 LL | /     match &&Some(String::new()) {
 LL | |         Some(x) => Some(x.len()),
@@ -93,7 +93,7 @@ LL | |     };
    | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.len())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:70:5
+  --> $DIR/manual_map_option.rs:71:5
    |
 LL | /     match &&Some(0) {
 LL | |         &&Some(x) => Some(x + x),
@@ -102,7 +102,7 @@ LL | |     };
    | |_____^ help: try: `Some(0).map(|x| x + x)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:83:9
+  --> $DIR/manual_map_option.rs:84:9
    |
 LL | /         match &mut Some(String::new()) {
 LL | |             Some(x) => Some(x.push_str("")),
@@ -111,7 +111,7 @@ LL | |         };
    | |_________^ help: try: `Some(String::new()).as_mut().map(|x| x.push_str(""))`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:89:5
+  --> $DIR/manual_map_option.rs:90:5
    |
 LL | /     match &mut Some(String::new()) {
 LL | |         Some(ref x) => Some(x.len()),
@@ -120,7 +120,7 @@ LL | |     };
    | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.len())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:94:5
+  --> $DIR/manual_map_option.rs:95:5
    |
 LL | /     match &mut &Some(String::new()) {
 LL | |         Some(x) => Some(x.is_empty()),
@@ -129,7 +129,7 @@ LL | |     };
    | |_____^ help: try: `Some(String::new()).as_ref().map(|x| x.is_empty())`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:99:5
+  --> $DIR/manual_map_option.rs:100:5
    |
 LL | /     match Some((0, 1, 2)) {
 LL | |         Some((x, y, z)) => Some(x + y + z),
@@ -138,7 +138,7 @@ LL | |     };
    | |_____^ help: try: `Some((0, 1, 2)).map(|(x, y, z)| x + y + z)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:104:5
+  --> $DIR/manual_map_option.rs:105:5
    |
 LL | /     match Some([1, 2, 3]) {
 LL | |         Some([first, ..]) => Some(first),
@@ -147,7 +147,7 @@ LL | |     };
    | |_____^ help: try: `Some([1, 2, 3]).map(|[first, ..]| first)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:109:5
+  --> $DIR/manual_map_option.rs:110:5
    |
 LL | /     match &Some((String::new(), "test")) {
 LL | |         Some((x, y)) => Some((y, x)),
@@ -156,7 +156,7 @@ LL | |     };
    | |_____^ help: try: `Some((String::new(), "test")).as_ref().map(|(x, y)| (y, x))`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:167:5
+  --> $DIR/manual_map_option.rs:168:5
    |
 LL | /     match Some(0) {
 LL | |         Some(x) => Some(vec![x]),
@@ -165,7 +165,7 @@ LL | |     };
    | |_____^ help: try: `Some(0).map(|x| vec![x])`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:172:5
+  --> $DIR/manual_map_option.rs:173:5
    |
 LL | /     match option_env!("") {
 LL | |         Some(x) => Some(String::from(x)),
@@ -174,7 +174,7 @@ LL | |     };
    | |_____^ help: try: `option_env!("").map(String::from)`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:192:12
+  --> $DIR/manual_map_option.rs:193:12
    |
 LL |       } else if let Some(x) = Some(0) {
    |  ____________^
@@ -185,7 +185,7 @@ LL | |     };
    | |_____^ help: try: `{ Some(0).map(|x| x + 1) }`
 
 error: manual implementation of `Option::map`
-  --> $DIR/manual_map_option.rs:200:12
+  --> $DIR/manual_map_option.rs:201:12
    |
 LL |       } else if let Some(x) = Some(0) {
    |  ____________^
diff --git a/src/tools/clippy/tests/ui/needless_borrow.fixed b/src/tools/clippy/tests/ui/needless_borrow.fixed
index 0a52b25229d..c2c5f765abf 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.fixed
+++ b/src/tools/clippy/tests/ui/needless_borrow.fixed
@@ -131,21 +131,6 @@ fn main() {
             0
         }
     }
-
-    let _ = std::process::Command::new("ls").args(["-a", "-l"]).status().unwrap();
-    let _ = std::path::Path::new(".").join(".");
-    deref_target_is_x(X);
-    multiple_constraints([[""]]);
-    multiple_constraints_normalizes_to_same(X, X);
-    let _ = Some("").unwrap_or("");
-    let _ = std::fs::write("x", "".to_string());
-
-    only_sized(&""); // Don't lint. `Sized` is only bound
-    let _ = std::any::Any::type_id(&""); // Don't lint. `Any` is only bound
-    let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
-    ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
-    refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
-    multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
 }
 
 #[allow(clippy::needless_borrowed_reference)]
@@ -201,103 +186,6 @@ mod issue9160 {
     }
 }
 
-#[derive(Clone, Copy)]
-struct X;
-
-impl std::ops::Deref for X {
-    type Target = X;
-    fn deref(&self) -> &Self::Target {
-        self
-    }
-}
-
-fn deref_target_is_x<T>(_: T)
-where
-    T: std::ops::Deref<Target = X>,
-{
-}
-
-fn multiple_constraints<T, U, V, X, Y>(_: T)
-where
-    T: IntoIterator<Item = U> + IntoIterator<Item = X>,
-    U: IntoIterator<Item = V>,
-    V: AsRef<str>,
-    X: IntoIterator<Item = Y>,
-    Y: AsRef<std::ffi::OsStr>,
-{
-}
-
-fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
-where
-    T: std::ops::Deref<Target = U>,
-    U: std::ops::Deref<Target = V>,
-{
-}
-
-fn only_sized<T>(_: T) {}
-
-fn ref_as_ref_path<T: 'static>(_: &'static T)
-where
-    &'static T: AsRef<std::path::Path>,
-{
-}
-
-trait RefsOnly {
-    type Referent;
-}
-
-impl<T> RefsOnly for &T {
-    type Referent = T;
-}
-
-fn refs_only<T, U>(_: T)
-where
-    T: RefsOnly<Referent = U>,
-{
-}
-
-fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
-where
-    T: IntoIterator<Item = U>,
-    U: IntoIterator<Item = V>,
-    V: AsRef<str>,
-{
-}
-
-// https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
-mod copyable_iterator {
-    #[derive(Clone, Copy)]
-    struct Iter;
-    impl Iterator for Iter {
-        type Item = ();
-        fn next(&mut self) -> Option<Self::Item> {
-            None
-        }
-    }
-    fn takes_iter(_: impl Iterator) {}
-    fn dont_warn(mut x: Iter) {
-        takes_iter(&mut x);
-    }
-    #[allow(unused_mut)]
-    fn warn(mut x: &mut Iter) {
-        takes_iter(x)
-    }
-}
-
-#[clippy::msrv = "1.52.0"]
-mod under_msrv {
-    fn foo() {
-        let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
-    }
-}
-
-#[clippy::msrv = "1.53.0"]
-mod meets_msrv {
-    fn foo() {
-        let _ = std::process::Command::new("ls").args(["-a", "-l"]).status().unwrap();
-    }
-}
-
 fn issue9383() {
     // Should not lint because unions need explicit deref when accessing field
     use std::mem::ManuallyDrop;
@@ -326,184 +214,6 @@ fn issue9383() {
     }
 }
 
-fn closure_test() {
-    let env = "env".to_owned();
-    let arg = "arg".to_owned();
-    let f = |arg| {
-        let loc = "loc".to_owned();
-        let _ = std::fs::write("x", &env); // Don't lint. In environment
-        let _ = std::fs::write("x", arg);
-        let _ = std::fs::write("x", loc);
-    };
-    let _ = std::fs::write("x", &env); // Don't lint. Borrowed by `f`
-    f(arg);
-}
-
-mod significant_drop {
-    #[derive(Debug)]
-    struct X;
-
-    #[derive(Debug)]
-    struct Y;
-
-    impl Drop for Y {
-        fn drop(&mut self) {}
-    }
-
-    fn foo(x: X, y: Y) {
-        debug(x);
-        debug(&y); // Don't lint. Has significant drop
-    }
-
-    fn debug(_: impl std::fmt::Debug) {}
-}
-
-mod used_exactly_once {
-    fn foo(x: String) {
-        use_x(x);
-    }
-    fn use_x(_: impl AsRef<str>) {}
-}
-
-mod used_more_than_once {
-    fn foo(x: String) {
-        use_x(&x);
-        use_x_again(&x);
-    }
-    fn use_x(_: impl AsRef<str>) {}
-    fn use_x_again(_: impl AsRef<str>) {}
-}
-
-// https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
-mod issue_9111 {
-    struct A;
-
-    impl Extend<u8> for A {
-        fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
-            unimplemented!()
-        }
-    }
-
-    impl<'a> Extend<&'a u8> for A {
-        fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
-            unimplemented!()
-        }
-    }
-
-    fn main() {
-        let mut a = A;
-        a.extend(&[]); // vs a.extend([]);
-    }
-}
-
-mod issue_9710 {
-    fn main() {
-        let string = String::new();
-        for _i in 0..10 {
-            f(&string);
-        }
-    }
-
-    fn f<T: AsRef<str>>(_: T) {}
-}
-
-mod issue_9739 {
-    fn foo<D: std::fmt::Display>(_it: impl IntoIterator<Item = D>) {}
-
-    fn main() {
-        foo(if std::env::var_os("HI").is_some() {
-            &[0]
-        } else {
-            &[] as &[u32]
-        });
-    }
-}
-
-mod issue_9739_method_variant {
-    struct S;
-
-    impl S {
-        fn foo<D: std::fmt::Display>(&self, _it: impl IntoIterator<Item = D>) {}
-    }
-
-    fn main() {
-        S.foo(if std::env::var_os("HI").is_some() {
-            &[0]
-        } else {
-            &[] as &[u32]
-        });
-    }
-}
-
-mod issue_9782 {
-    fn foo<T: AsRef<[u8]>>(t: T) {
-        println!("{}", std::mem::size_of::<T>());
-        let _t: &[u8] = t.as_ref();
-    }
-
-    fn main() {
-        let a: [u8; 100] = [0u8; 100];
-
-        // 100
-        foo::<[u8; 100]>(a);
-        foo(a);
-
-        // 16
-        foo::<&[u8]>(&a);
-        foo(a.as_slice());
-
-        // 8
-        foo::<&[u8; 100]>(&a);
-        foo(a);
-    }
-}
-
-mod issue_9782_type_relative_variant {
-    struct S;
-
-    impl S {
-        fn foo<T: AsRef<[u8]>>(t: T) {
-            println!("{}", std::mem::size_of::<T>());
-            let _t: &[u8] = t.as_ref();
-        }
-    }
-
-    fn main() {
-        let a: [u8; 100] = [0u8; 100];
-
-        S::foo::<&[u8; 100]>(&a);
-    }
-}
-
-mod issue_9782_method_variant {
-    struct S;
-
-    impl S {
-        fn foo<T: AsRef<[u8]>>(&self, t: T) {
-            println!("{}", std::mem::size_of::<T>());
-            let _t: &[u8] = t.as_ref();
-        }
-    }
-
-    fn main() {
-        let a: [u8; 100] = [0u8; 100];
-
-        S.foo::<&[u8; 100]>(&a);
-    }
-}
-
-mod issue_10535 {
-    static SOME_STATIC: String = String::new();
-
-    static UNIT: () = compute(&SOME_STATIC);
-
-    pub const fn compute<T>(_: T)
-    where
-        T: Copy,
-    {
-    }
-}
-
 mod issue_10253 {
     struct S;
     trait X {
diff --git a/src/tools/clippy/tests/ui/needless_borrow.rs b/src/tools/clippy/tests/ui/needless_borrow.rs
index 34a95d18463..0cd6e41b8a4 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.rs
+++ b/src/tools/clippy/tests/ui/needless_borrow.rs
@@ -131,21 +131,6 @@ fn main() {
             0
         }
     }
-
-    let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
-    let _ = std::path::Path::new(".").join(&&".");
-    deref_target_is_x(&X);
-    multiple_constraints(&[[""]]);
-    multiple_constraints_normalizes_to_same(&X, X);
-    let _ = Some("").unwrap_or(&"");
-    let _ = std::fs::write("x", &"".to_string());
-
-    only_sized(&""); // Don't lint. `Sized` is only bound
-    let _ = std::any::Any::type_id(&""); // Don't lint. `Any` is only bound
-    let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
-    ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
-    refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
-    multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
 }
 
 #[allow(clippy::needless_borrowed_reference)]
@@ -201,103 +186,6 @@ mod issue9160 {
     }
 }
 
-#[derive(Clone, Copy)]
-struct X;
-
-impl std::ops::Deref for X {
-    type Target = X;
-    fn deref(&self) -> &Self::Target {
-        self
-    }
-}
-
-fn deref_target_is_x<T>(_: T)
-where
-    T: std::ops::Deref<Target = X>,
-{
-}
-
-fn multiple_constraints<T, U, V, X, Y>(_: T)
-where
-    T: IntoIterator<Item = U> + IntoIterator<Item = X>,
-    U: IntoIterator<Item = V>,
-    V: AsRef<str>,
-    X: IntoIterator<Item = Y>,
-    Y: AsRef<std::ffi::OsStr>,
-{
-}
-
-fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
-where
-    T: std::ops::Deref<Target = U>,
-    U: std::ops::Deref<Target = V>,
-{
-}
-
-fn only_sized<T>(_: T) {}
-
-fn ref_as_ref_path<T: 'static>(_: &'static T)
-where
-    &'static T: AsRef<std::path::Path>,
-{
-}
-
-trait RefsOnly {
-    type Referent;
-}
-
-impl<T> RefsOnly for &T {
-    type Referent = T;
-}
-
-fn refs_only<T, U>(_: T)
-where
-    T: RefsOnly<Referent = U>,
-{
-}
-
-fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
-where
-    T: IntoIterator<Item = U>,
-    U: IntoIterator<Item = V>,
-    V: AsRef<str>,
-{
-}
-
-// https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
-mod copyable_iterator {
-    #[derive(Clone, Copy)]
-    struct Iter;
-    impl Iterator for Iter {
-        type Item = ();
-        fn next(&mut self) -> Option<Self::Item> {
-            None
-        }
-    }
-    fn takes_iter(_: impl Iterator) {}
-    fn dont_warn(mut x: Iter) {
-        takes_iter(&mut x);
-    }
-    #[allow(unused_mut)]
-    fn warn(mut x: &mut Iter) {
-        takes_iter(&mut x)
-    }
-}
-
-#[clippy::msrv = "1.52.0"]
-mod under_msrv {
-    fn foo() {
-        let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
-    }
-}
-
-#[clippy::msrv = "1.53.0"]
-mod meets_msrv {
-    fn foo() {
-        let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
-    }
-}
-
 fn issue9383() {
     // Should not lint because unions need explicit deref when accessing field
     use std::mem::ManuallyDrop;
@@ -326,184 +214,6 @@ fn issue9383() {
     }
 }
 
-fn closure_test() {
-    let env = "env".to_owned();
-    let arg = "arg".to_owned();
-    let f = |arg| {
-        let loc = "loc".to_owned();
-        let _ = std::fs::write("x", &env); // Don't lint. In environment
-        let _ = std::fs::write("x", &arg);
-        let _ = std::fs::write("x", &loc);
-    };
-    let _ = std::fs::write("x", &env); // Don't lint. Borrowed by `f`
-    f(arg);
-}
-
-mod significant_drop {
-    #[derive(Debug)]
-    struct X;
-
-    #[derive(Debug)]
-    struct Y;
-
-    impl Drop for Y {
-        fn drop(&mut self) {}
-    }
-
-    fn foo(x: X, y: Y) {
-        debug(&x);
-        debug(&y); // Don't lint. Has significant drop
-    }
-
-    fn debug(_: impl std::fmt::Debug) {}
-}
-
-mod used_exactly_once {
-    fn foo(x: String) {
-        use_x(&x);
-    }
-    fn use_x(_: impl AsRef<str>) {}
-}
-
-mod used_more_than_once {
-    fn foo(x: String) {
-        use_x(&x);
-        use_x_again(&x);
-    }
-    fn use_x(_: impl AsRef<str>) {}
-    fn use_x_again(_: impl AsRef<str>) {}
-}
-
-// https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
-mod issue_9111 {
-    struct A;
-
-    impl Extend<u8> for A {
-        fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
-            unimplemented!()
-        }
-    }
-
-    impl<'a> Extend<&'a u8> for A {
-        fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
-            unimplemented!()
-        }
-    }
-
-    fn main() {
-        let mut a = A;
-        a.extend(&[]); // vs a.extend([]);
-    }
-}
-
-mod issue_9710 {
-    fn main() {
-        let string = String::new();
-        for _i in 0..10 {
-            f(&string);
-        }
-    }
-
-    fn f<T: AsRef<str>>(_: T) {}
-}
-
-mod issue_9739 {
-    fn foo<D: std::fmt::Display>(_it: impl IntoIterator<Item = D>) {}
-
-    fn main() {
-        foo(if std::env::var_os("HI").is_some() {
-            &[0]
-        } else {
-            &[] as &[u32]
-        });
-    }
-}
-
-mod issue_9739_method_variant {
-    struct S;
-
-    impl S {
-        fn foo<D: std::fmt::Display>(&self, _it: impl IntoIterator<Item = D>) {}
-    }
-
-    fn main() {
-        S.foo(if std::env::var_os("HI").is_some() {
-            &[0]
-        } else {
-            &[] as &[u32]
-        });
-    }
-}
-
-mod issue_9782 {
-    fn foo<T: AsRef<[u8]>>(t: T) {
-        println!("{}", std::mem::size_of::<T>());
-        let _t: &[u8] = t.as_ref();
-    }
-
-    fn main() {
-        let a: [u8; 100] = [0u8; 100];
-
-        // 100
-        foo::<[u8; 100]>(a);
-        foo(a);
-
-        // 16
-        foo::<&[u8]>(&a);
-        foo(a.as_slice());
-
-        // 8
-        foo::<&[u8; 100]>(&a);
-        foo(&a);
-    }
-}
-
-mod issue_9782_type_relative_variant {
-    struct S;
-
-    impl S {
-        fn foo<T: AsRef<[u8]>>(t: T) {
-            println!("{}", std::mem::size_of::<T>());
-            let _t: &[u8] = t.as_ref();
-        }
-    }
-
-    fn main() {
-        let a: [u8; 100] = [0u8; 100];
-
-        S::foo::<&[u8; 100]>(&a);
-    }
-}
-
-mod issue_9782_method_variant {
-    struct S;
-
-    impl S {
-        fn foo<T: AsRef<[u8]>>(&self, t: T) {
-            println!("{}", std::mem::size_of::<T>());
-            let _t: &[u8] = t.as_ref();
-        }
-    }
-
-    fn main() {
-        let a: [u8; 100] = [0u8; 100];
-
-        S.foo::<&[u8; 100]>(&a);
-    }
-}
-
-mod issue_10535 {
-    static SOME_STATIC: String = String::new();
-
-    static UNIT: () = compute(&SOME_STATIC);
-
-    pub const fn compute<T>(_: T)
-    where
-        T: Copy,
-    {
-    }
-}
-
 mod issue_10253 {
     struct S;
     trait X {
diff --git a/src/tools/clippy/tests/ui/needless_borrow.stderr b/src/tools/clippy/tests/ui/needless_borrow.stderr
index 8e27014d53c..e91b78b0a15 100644
--- a/src/tools/clippy/tests/ui/needless_borrow.stderr
+++ b/src/tools/clippy/tests/ui/needless_borrow.stderr
@@ -121,101 +121,17 @@ error: this expression creates a reference which is immediately dereferenced by
 LL |     (&&5).foo();
    |     ^^^^^ help: change this to: `(&5)`
 
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:135:51
-   |
-LL |     let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
-   |                                                   ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:136:44
-   |
-LL |     let _ = std::path::Path::new(".").join(&&".");
-   |                                            ^^^^^ help: change this to: `"."`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:137:23
-   |
-LL |     deref_target_is_x(&X);
-   |                       ^^ help: change this to: `X`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:138:26
-   |
-LL |     multiple_constraints(&[[""]]);
-   |                          ^^^^^^^ help: change this to: `[[""]]`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:139:45
-   |
-LL |     multiple_constraints_normalizes_to_same(&X, X);
-   |                                             ^^ help: change this to: `X`
-
-error: this expression creates a reference which is immediately dereferenced by the compiler
-  --> $DIR/needless_borrow.rs:140:32
-   |
-LL |     let _ = Some("").unwrap_or(&"");
-   |                                ^^^ help: change this to: `""`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:141:33
-   |
-LL |     let _ = std::fs::write("x", &"".to_string());
-   |                                 ^^^^^^^^^^^^^^^ help: change this to: `"".to_string()`
-
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:190:13
+  --> $DIR/needless_borrow.rs:175:13
    |
 LL |             (&self.f)()
    |             ^^^^^^^^^ help: change this to: `(self.f)`
 
 error: this expression borrows a value the compiler would automatically borrow
-  --> $DIR/needless_borrow.rs:199:13
+  --> $DIR/needless_borrow.rs:184:13
    |
 LL |             (&mut self.f)()
    |             ^^^^^^^^^^^^^ help: change this to: `(self.f)`
 
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:283:20
-   |
-LL |         takes_iter(&mut x)
-   |                    ^^^^^^ help: change this to: `x`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:297:55
-   |
-LL |         let _ = std::process::Command::new("ls").args(&["-a", "-l"]).status().unwrap();
-   |                                                       ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:335:37
-   |
-LL |         let _ = std::fs::write("x", &arg);
-   |                                     ^^^^ help: change this to: `arg`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:336:37
-   |
-LL |         let _ = std::fs::write("x", &loc);
-   |                                     ^^^^ help: change this to: `loc`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:354:15
-   |
-LL |         debug(&x);
-   |               ^^ help: change this to: `x`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:363:15
-   |
-LL |         use_x(&x);
-   |               ^^ help: change this to: `x`
-
-error: the borrowed expression implements the required traits
-  --> $DIR/needless_borrow.rs:457:13
-   |
-LL |         foo(&a);
-   |             ^^ help: change this to: `a`
-
-error: aborting due to 36 previous errors
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed
new file mode 100644
index 00000000000..2a335516f51
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.fixed
@@ -0,0 +1,287 @@
+#![warn(clippy::needless_borrows_for_generic_args)]
+#![allow(
+    clippy::unnecessary_to_owned,
+    clippy::unnecessary_literal_unwrap,
+    clippy::needless_borrow
+)]
+
+use core::ops::Deref;
+use std::any::Any;
+use std::ffi::OsStr;
+use std::fmt::{Debug, Display};
+use std::path::Path;
+use std::process::Command;
+
+fn main() {
+    let _ = Command::new("ls").args(["-a", "-l"]).status().unwrap();
+    let _ = Path::new(".").join(".");
+    let _ = Any::type_id(&""); // Don't lint. `Any` is only bound
+    let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
+    let _ = Some("").unwrap_or(&"");
+    let _ = std::fs::write("x", "".to_string());
+
+    {
+        #[derive(Clone, Copy)]
+        struct X;
+
+        impl Deref for X {
+            type Target = X;
+            fn deref(&self) -> &Self::Target {
+                self
+            }
+        }
+
+        fn deref_target_is_x<T: Deref<Target = X>>(_: T) {}
+
+        deref_target_is_x(X);
+    }
+    {
+        fn multiple_constraints<T, U, V, X, Y>(_: T)
+        where
+            T: IntoIterator<Item = U> + IntoIterator<Item = X>,
+            U: IntoIterator<Item = V>,
+            V: AsRef<str>,
+            X: IntoIterator<Item = Y>,
+            Y: AsRef<OsStr>,
+        {
+        }
+
+        multiple_constraints([[""]]);
+    }
+    {
+        #[derive(Clone, Copy)]
+        struct X;
+
+        impl Deref for X {
+            type Target = X;
+            fn deref(&self) -> &Self::Target {
+                self
+            }
+        }
+
+        fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
+        where
+            T: Deref<Target = U>,
+            U: Deref<Target = V>,
+        {
+        }
+
+        multiple_constraints_normalizes_to_same(X, X);
+    }
+    {
+        fn only_sized<T>(_: T) {}
+        only_sized(&""); // Don't lint. `Sized` is only bound
+    }
+    {
+        fn ref_as_ref_path<T: 'static>(_: &'static T)
+        where
+            &'static T: AsRef<Path>,
+        {
+        }
+
+        ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
+    }
+    {
+        trait RefsOnly {
+            type Referent;
+        }
+
+        impl<T> RefsOnly for &T {
+            type Referent = T;
+        }
+
+        fn refs_only<T, U>(_: T)
+        where
+            T: RefsOnly<Referent = U>,
+        {
+        }
+
+        refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
+    }
+    {
+        fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
+        where
+            T: IntoIterator<Item = U>,
+            U: IntoIterator<Item = V>,
+            V: AsRef<str>,
+        {
+        }
+        multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
+    }
+    // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
+    {
+        #[derive(Clone, Copy)]
+        struct Iter;
+        impl Iterator for Iter {
+            type Item = ();
+            fn next(&mut self) -> Option<Self::Item> {
+                None
+            }
+        }
+        fn takes_iter(_: impl Iterator) {}
+        fn dont_warn(mut x: Iter) {
+            takes_iter(&mut x);
+        }
+        #[allow(unused_mut)]
+        fn warn(mut x: &mut Iter) {
+            takes_iter(x)
+        }
+    }
+    #[clippy::msrv = "1.52.0"]
+    {
+        let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+    };
+    #[clippy::msrv = "1.53.0"]
+    {
+        let _ = Command::new("ls").args(["-a", "-l"]).status().unwrap();
+    };
+    {
+        let env = "env".to_owned();
+        let arg = "arg".to_owned();
+        let f = |arg| {
+            let loc = "loc".to_owned();
+            let _ = std::fs::write("x", &env); // Don't lint. In environment
+            let _ = std::fs::write("x", arg);
+            let _ = std::fs::write("x", loc);
+        };
+        let _ = std::fs::write("x", &env); // Don't lint. Borrowed by `f`
+        f(arg);
+    }
+    {
+        #[derive(Debug)]
+        struct X;
+
+        impl Drop for X {
+            fn drop(&mut self) {}
+        }
+
+        fn f(_: impl Debug) {}
+
+        let x = X;
+        f(&x); // Don't lint. Has significant drop
+    }
+    {
+        fn f(_: impl AsRef<str>) {}
+
+        let x = String::new();
+        f(x);
+    }
+    {
+        fn f(_: impl AsRef<str>) {}
+        fn f2(_: impl AsRef<str>) {}
+
+        let x = String::new();
+        f(&x);
+        f2(&x);
+    }
+    // https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
+    // issue 9111
+    {
+        struct A;
+
+        impl Extend<u8> for A {
+            fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
+                unimplemented!()
+            }
+        }
+
+        impl<'a> Extend<&'a u8> for A {
+            fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
+                unimplemented!()
+            }
+        }
+
+        let mut a = A;
+        a.extend(&[]); // vs a.extend([]);
+    }
+    // issue 9710
+    {
+        fn f(_: impl AsRef<str>) {}
+
+        let x = String::new();
+        for _ in 0..10 {
+            f(&x);
+        }
+    }
+    // issue 9739
+    {
+        fn foo<D: Display>(_it: impl IntoIterator<Item = D>) {}
+        foo(if std::env::var_os("HI").is_some() {
+            &[0]
+        } else {
+            &[] as &[u32]
+        });
+    }
+    {
+        struct S;
+
+        impl S {
+            fn foo<D: Display>(&self, _it: impl IntoIterator<Item = D>) {}
+        }
+
+        S.foo(if std::env::var_os("HI").is_some() {
+            &[0]
+        } else {
+            &[] as &[u32]
+        });
+    }
+    // issue 9782
+    {
+        fn foo<T: AsRef<[u8]>>(t: T) {
+            println!("{}", std::mem::size_of::<T>());
+            let _t: &[u8] = t.as_ref();
+        }
+
+        let a: [u8; 100] = [0u8; 100];
+
+        // 100
+        foo::<[u8; 100]>(a);
+        foo(a);
+
+        // 16
+        foo::<&[u8]>(&a);
+        foo(a.as_slice());
+
+        // 8
+        foo::<&[u8; 100]>(&a);
+        foo(a);
+    }
+    {
+        struct S;
+
+        impl S {
+            fn foo<T: AsRef<[u8]>>(t: T) {
+                println!("{}", std::mem::size_of::<T>());
+                let _t: &[u8] = t.as_ref();
+            }
+        }
+
+        let a: [u8; 100] = [0u8; 100];
+        S::foo::<&[u8; 100]>(&a);
+    }
+    {
+        struct S;
+
+        impl S {
+            fn foo<T: AsRef<[u8]>>(&self, t: T) {
+                println!("{}", std::mem::size_of::<T>());
+                let _t: &[u8] = t.as_ref();
+            }
+        }
+
+        let a: [u8; 100] = [0u8; 100];
+        S.foo::<&[u8; 100]>(&a);
+    }
+    // issue 10535
+    {
+        static SOME_STATIC: String = String::new();
+
+        static UNIT: () = compute(&SOME_STATIC);
+
+        pub const fn compute<T>(_: T)
+        where
+            T: Copy,
+        {
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs
new file mode 100644
index 00000000000..f0567f486ac
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.rs
@@ -0,0 +1,287 @@
+#![warn(clippy::needless_borrows_for_generic_args)]
+#![allow(
+    clippy::unnecessary_to_owned,
+    clippy::unnecessary_literal_unwrap,
+    clippy::needless_borrow
+)]
+
+use core::ops::Deref;
+use std::any::Any;
+use std::ffi::OsStr;
+use std::fmt::{Debug, Display};
+use std::path::Path;
+use std::process::Command;
+
+fn main() {
+    let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+    let _ = Path::new(".").join(&&".");
+    let _ = Any::type_id(&""); // Don't lint. `Any` is only bound
+    let _ = Box::new(&""); // Don't lint. Type parameter appears in return type
+    let _ = Some("").unwrap_or(&"");
+    let _ = std::fs::write("x", &"".to_string());
+
+    {
+        #[derive(Clone, Copy)]
+        struct X;
+
+        impl Deref for X {
+            type Target = X;
+            fn deref(&self) -> &Self::Target {
+                self
+            }
+        }
+
+        fn deref_target_is_x<T: Deref<Target = X>>(_: T) {}
+
+        deref_target_is_x(&X);
+    }
+    {
+        fn multiple_constraints<T, U, V, X, Y>(_: T)
+        where
+            T: IntoIterator<Item = U> + IntoIterator<Item = X>,
+            U: IntoIterator<Item = V>,
+            V: AsRef<str>,
+            X: IntoIterator<Item = Y>,
+            Y: AsRef<OsStr>,
+        {
+        }
+
+        multiple_constraints(&[[""]]);
+    }
+    {
+        #[derive(Clone, Copy)]
+        struct X;
+
+        impl Deref for X {
+            type Target = X;
+            fn deref(&self) -> &Self::Target {
+                self
+            }
+        }
+
+        fn multiple_constraints_normalizes_to_same<T, U, V>(_: T, _: V)
+        where
+            T: Deref<Target = U>,
+            U: Deref<Target = V>,
+        {
+        }
+
+        multiple_constraints_normalizes_to_same(&X, X);
+    }
+    {
+        fn only_sized<T>(_: T) {}
+        only_sized(&""); // Don't lint. `Sized` is only bound
+    }
+    {
+        fn ref_as_ref_path<T: 'static>(_: &'static T)
+        where
+            &'static T: AsRef<Path>,
+        {
+        }
+
+        ref_as_ref_path(&""); // Don't lint. Argument type is not a type parameter
+    }
+    {
+        trait RefsOnly {
+            type Referent;
+        }
+
+        impl<T> RefsOnly for &T {
+            type Referent = T;
+        }
+
+        fn refs_only<T, U>(_: T)
+        where
+            T: RefsOnly<Referent = U>,
+        {
+        }
+
+        refs_only(&()); // Don't lint. `&T` implements trait, but `T` doesn't
+    }
+    {
+        fn multiple_constraints_normalizes_to_different<T, U, V>(_: T, _: U)
+        where
+            T: IntoIterator<Item = U>,
+            U: IntoIterator<Item = V>,
+            V: AsRef<str>,
+        {
+        }
+        multiple_constraints_normalizes_to_different(&[[""]], &[""]); // Don't lint. Projected type appears in arguments
+    }
+    // https://github.com/rust-lang/rust-clippy/pull/9136#pullrequestreview-1037379321
+    {
+        #[derive(Clone, Copy)]
+        struct Iter;
+        impl Iterator for Iter {
+            type Item = ();
+            fn next(&mut self) -> Option<Self::Item> {
+                None
+            }
+        }
+        fn takes_iter(_: impl Iterator) {}
+        fn dont_warn(mut x: Iter) {
+            takes_iter(&mut x);
+        }
+        #[allow(unused_mut)]
+        fn warn(mut x: &mut Iter) {
+            takes_iter(&mut x)
+        }
+    }
+    #[clippy::msrv = "1.52.0"]
+    {
+        let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+    };
+    #[clippy::msrv = "1.53.0"]
+    {
+        let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+    };
+    {
+        let env = "env".to_owned();
+        let arg = "arg".to_owned();
+        let f = |arg| {
+            let loc = "loc".to_owned();
+            let _ = std::fs::write("x", &env); // Don't lint. In environment
+            let _ = std::fs::write("x", &arg);
+            let _ = std::fs::write("x", &loc);
+        };
+        let _ = std::fs::write("x", &env); // Don't lint. Borrowed by `f`
+        f(arg);
+    }
+    {
+        #[derive(Debug)]
+        struct X;
+
+        impl Drop for X {
+            fn drop(&mut self) {}
+        }
+
+        fn f(_: impl Debug) {}
+
+        let x = X;
+        f(&x); // Don't lint. Has significant drop
+    }
+    {
+        fn f(_: impl AsRef<str>) {}
+
+        let x = String::new();
+        f(&x);
+    }
+    {
+        fn f(_: impl AsRef<str>) {}
+        fn f2(_: impl AsRef<str>) {}
+
+        let x = String::new();
+        f(&x);
+        f2(&x);
+    }
+    // https://github.com/rust-lang/rust-clippy/issues/9111#issuecomment-1277114280
+    // issue 9111
+    {
+        struct A;
+
+        impl Extend<u8> for A {
+            fn extend<T: IntoIterator<Item = u8>>(&mut self, _: T) {
+                unimplemented!()
+            }
+        }
+
+        impl<'a> Extend<&'a u8> for A {
+            fn extend<T: IntoIterator<Item = &'a u8>>(&mut self, _: T) {
+                unimplemented!()
+            }
+        }
+
+        let mut a = A;
+        a.extend(&[]); // vs a.extend([]);
+    }
+    // issue 9710
+    {
+        fn f(_: impl AsRef<str>) {}
+
+        let x = String::new();
+        for _ in 0..10 {
+            f(&x);
+        }
+    }
+    // issue 9739
+    {
+        fn foo<D: Display>(_it: impl IntoIterator<Item = D>) {}
+        foo(if std::env::var_os("HI").is_some() {
+            &[0]
+        } else {
+            &[] as &[u32]
+        });
+    }
+    {
+        struct S;
+
+        impl S {
+            fn foo<D: Display>(&self, _it: impl IntoIterator<Item = D>) {}
+        }
+
+        S.foo(if std::env::var_os("HI").is_some() {
+            &[0]
+        } else {
+            &[] as &[u32]
+        });
+    }
+    // issue 9782
+    {
+        fn foo<T: AsRef<[u8]>>(t: T) {
+            println!("{}", std::mem::size_of::<T>());
+            let _t: &[u8] = t.as_ref();
+        }
+
+        let a: [u8; 100] = [0u8; 100];
+
+        // 100
+        foo::<[u8; 100]>(a);
+        foo(a);
+
+        // 16
+        foo::<&[u8]>(&a);
+        foo(a.as_slice());
+
+        // 8
+        foo::<&[u8; 100]>(&a);
+        foo(&a);
+    }
+    {
+        struct S;
+
+        impl S {
+            fn foo<T: AsRef<[u8]>>(t: T) {
+                println!("{}", std::mem::size_of::<T>());
+                let _t: &[u8] = t.as_ref();
+            }
+        }
+
+        let a: [u8; 100] = [0u8; 100];
+        S::foo::<&[u8; 100]>(&a);
+    }
+    {
+        struct S;
+
+        impl S {
+            fn foo<T: AsRef<[u8]>>(&self, t: T) {
+                println!("{}", std::mem::size_of::<T>());
+                let _t: &[u8] = t.as_ref();
+            }
+        }
+
+        let a: [u8; 100] = [0u8; 100];
+        S.foo::<&[u8; 100]>(&a);
+    }
+    // issue 10535
+    {
+        static SOME_STATIC: String = String::new();
+
+        static UNIT: () = compute(&SOME_STATIC);
+
+        pub const fn compute<T>(_: T)
+        where
+            T: Copy,
+        {
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.stderr b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.stderr
new file mode 100644
index 00000000000..e2cde2c59a6
--- /dev/null
+++ b/src/tools/clippy/tests/ui/needless_borrows_for_generic_args.stderr
@@ -0,0 +1,77 @@
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:16:37
+   |
+LL |     let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+   |                                     ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
+   |
+   = note: `-D clippy::needless-borrows-for-generic-args` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::needless_borrows_for_generic_args)]`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:17:33
+   |
+LL |     let _ = Path::new(".").join(&&".");
+   |                                 ^^^^^ help: change this to: `"."`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:21:33
+   |
+LL |     let _ = std::fs::write("x", &"".to_string());
+   |                                 ^^^^^^^^^^^^^^^ help: change this to: `"".to_string()`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:36:27
+   |
+LL |         deref_target_is_x(&X);
+   |                           ^^ help: change this to: `X`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:49:30
+   |
+LL |         multiple_constraints(&[[""]]);
+   |                              ^^^^^^^ help: change this to: `[[""]]`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:69:49
+   |
+LL |         multiple_constraints_normalizes_to_same(&X, X);
+   |                                                 ^^ help: change this to: `X`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:127:24
+   |
+LL |             takes_iter(&mut x)
+   |                        ^^^^^^ help: change this to: `x`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:136:41
+   |
+LL |         let _ = Command::new("ls").args(&["-a", "-l"]).status().unwrap();
+   |                                         ^^^^^^^^^^^^^ help: change this to: `["-a", "-l"]`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:144:41
+   |
+LL |             let _ = std::fs::write("x", &arg);
+   |                                         ^^^^ help: change this to: `arg`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:145:41
+   |
+LL |             let _ = std::fs::write("x", &loc);
+   |                                         ^^^^ help: change this to: `loc`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:167:11
+   |
+LL |         f(&x);
+   |           ^^ help: change this to: `x`
+
+error: the borrowed expression implements the required traits
+  --> $DIR/needless_borrows_for_generic_args.rs:247:13
+   |
+LL |         foo(&a);
+   |             ^^ help: change this to: `a`
+
+error: aborting due to 12 previous errors
+
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
index e1e5e8fd220..9cddcb3df23 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::if_same_then_else, clippy::no_effect)]
+#![allow(clippy::if_same_then_else, clippy::no_effect, clippy::redundant_closure_call)]
 #![feature(lint_reasons)]
 //@no-rustfix
 use std::ptr::NonNull;
@@ -230,6 +230,44 @@ async fn async_vec(b: &mut Vec<bool>) {
 async fn async_vec2(b: &mut Vec<bool>) {
     b.push(true);
 }
+fn non_mut(n: &str) {}
+//Should warn
+pub async fn call_in_closure1(n: &mut str) {
+    (|| non_mut(n))()
+}
+fn str_mut(str: &mut String) -> bool {
+    str.pop().is_some()
+}
+//Should not warn
+pub async fn call_in_closure2(str: &mut String) {
+    (|| str_mut(str))();
+}
+
+// Should not warn.
+pub async fn closure(n: &mut usize) -> impl '_ + FnMut() {
+    || {
+        *n += 1;
+    }
+}
+
+// Should warn.
+pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {
+    //~^ ERROR: this argument is a mutable reference, but not used mutably
+    || *n + 1
+}
+
+// Should not warn.
+pub async fn closure3(n: &mut usize) {
+    (|| *n += 1)();
+}
+
+// Should warn.
+pub async fn closure4(n: &mut usize) {
+    //~^ ERROR: this argument is a mutable reference, but not used mutably
+    (|| {
+        let _x = *n + 1;
+    })();
+}
 
 fn main() {
     let mut u = 0;
diff --git a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
index df3df045776..0c7fbd5df6d 100644
--- a/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
+++ b/src/tools/clippy/tests/ui/needless_pass_by_ref_mut.stderr
@@ -107,5 +107,37 @@ error: this argument is a mutable reference, but not used mutably
 LL | async fn inner_async3(x: &mut i32, y: &mut u32) {
    |                          ^^^^^^^^ help: consider changing to: `&i32`
 
-error: aborting due to 17 previous errors
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:235:34
+   |
+LL | pub async fn call_in_closure1(n: &mut str) {
+   |                                  ^^^^^^^^ help: consider changing to: `&str`
+   |
+   = warning: changing this function will impact semver compatibility
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:247:25
+   |
+LL | pub async fn closure(n: &mut usize) -> impl '_ + FnMut() {
+   |                         ^^^^^^^^^^ help: consider changing to: `&usize`
+   |
+   = warning: changing this function will impact semver compatibility
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:254:20
+   |
+LL | pub fn closure2(n: &mut usize) -> impl '_ + FnMut() -> usize {
+   |                    ^^^^^^^^^^ help: consider changing to: `&usize`
+   |
+   = warning: changing this function will impact semver compatibility
+
+error: this argument is a mutable reference, but not used mutably
+  --> $DIR/needless_pass_by_ref_mut.rs:265:26
+   |
+LL | pub async fn closure4(n: &mut usize) {
+   |                          ^^^^^^^^^^ help: consider changing to: `&usize`
+   |
+   = warning: changing this function will impact semver compatibility
+
+error: aborting due to 21 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed b/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed
index e980adeeff4..c99c2f46532 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed
+++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.fixed
@@ -21,4 +21,7 @@ fn main() {
         multiline
         string
     ";
+
+    r"rust";
+    r"hello world";
 }
diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs b/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs
index 6113c5f25ae..dcc2af69f4e 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs
+++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.rs
@@ -21,4 +21,7 @@ fn main() {
         multiline
         string
     "#;
+
+    r###"rust"###;
+    r#"hello world"#;
 }
diff --git a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
index 5a8e3d04543..4399c6555c2 100644
--- a/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
+++ b/src/tools/clippy/tests/ui/needless_raw_string_hashes.stderr
@@ -163,5 +163,29 @@ LL |         string
 LL ~     ";
    |
 
-error: aborting due to 13 previous errors
+error: unnecessary hashes around raw string literal
+  --> $DIR/needless_raw_string_hashes.rs:25:5
+   |
+LL |     r###"rust"###;
+   |     ^^^^^^^^^^^^^
+   |
+help: remove all the hashes around the literal
+   |
+LL -     r###"rust"###;
+LL +     r"rust";
+   |
+
+error: unnecessary hashes around raw string literal
+  --> $DIR/needless_raw_string_hashes.rs:26:5
+   |
+LL |     r#"hello world"#;
+   |     ^^^^^^^^^^^^^^^^
+   |
+help: remove all the hashes around the literal
+   |
+LL -     r#"hello world"#;
+LL +     r"hello world";
+   |
+
+error: aborting due to 15 previous errors
 
diff --git a/src/tools/clippy/tests/ui/no_effect_return.rs b/src/tools/clippy/tests/ui/no_effect_return.rs
index f6585aa30a6..e46c0d73518 100644
--- a/src/tools/clippy/tests/ui/no_effect_return.rs
+++ b/src/tools/clippy/tests/ui/no_effect_return.rs
@@ -76,6 +76,7 @@ fn h() -> Vec<u16> {
 
 fn i() -> () {
     {
+        // does not suggest on function with explicit unit return type
         ();
         //~^ ERROR: statement with no effect
     }
diff --git a/src/tools/clippy/tests/ui/no_effect_return.stderr b/src/tools/clippy/tests/ui/no_effect_return.stderr
index b036e634204..aed079f09b9 100644
--- a/src/tools/clippy/tests/ui/no_effect_return.stderr
+++ b/src/tools/clippy/tests/ui/no_effect_return.stderr
@@ -54,15 +54,13 @@ LL |         ControlFlow::Break::<()>(());
    |         help: did you mean to return it?: `return`
 
 error: statement with no effect
-  --> $DIR/no_effect_return.rs:79:9
+  --> $DIR/no_effect_return.rs:80:9
    |
 LL |         ();
-   |         -^^
-   |         |
-   |         help: did you mean to return it?: `return`
+   |         ^^^
 
 error: statement with no effect
-  --> $DIR/no_effect_return.rs:88:9
+  --> $DIR/no_effect_return.rs:89:9
    |
 LL |         ();
    |         ^^^
diff --git a/src/tools/clippy/tests/ui/option_filter_map.fixed b/src/tools/clippy/tests/ui/option_filter_map.fixed
index d4c04ff907b..ee004c0e194 100644
--- a/src/tools/clippy/tests/ui/option_filter_map.fixed
+++ b/src/tools/clippy/tests/ui/option_filter_map.fixed
@@ -1,5 +1,5 @@
 #![warn(clippy::option_filter_map)]
-#![allow(clippy::map_flatten)]
+#![allow(clippy::map_flatten, clippy::unnecessary_map_on_constructor)]
 
 fn main() {
     let _ = Some(Some(1)).flatten();
diff --git a/src/tools/clippy/tests/ui/option_filter_map.rs b/src/tools/clippy/tests/ui/option_filter_map.rs
index 99fb4723cab..eae2fa176a8 100644
--- a/src/tools/clippy/tests/ui/option_filter_map.rs
+++ b/src/tools/clippy/tests/ui/option_filter_map.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::option_filter_map)]
-#![allow(clippy::map_flatten)]
+#![allow(clippy::map_flatten, clippy::unnecessary_map_on_constructor)]
 
 fn main() {
     let _ = Some(Some(1)).filter(Option::is_some).map(Option::unwrap);
diff --git a/src/tools/clippy/tests/ui/path_ends_with_ext.fixed b/src/tools/clippy/tests/ui/path_ends_with_ext.fixed
new file mode 100644
index 00000000000..49767e242ce
--- /dev/null
+++ b/src/tools/clippy/tests/ui/path_ends_with_ext.fixed
@@ -0,0 +1,36 @@
+#![warn(clippy::path_ends_with_ext)]
+use std::path::Path;
+
+macro_rules! arg {
+    () => {
+        ".md"
+    };
+}
+
+fn test(path: &Path) {
+    path.extension().is_some_and(|ext| ext == "md");
+    //~^ ERROR: this looks like a failed attempt at checking for the file extension
+
+    // some "extensions" are allowed by default
+    path.ends_with(".git");
+
+    // most legitimate "dotfiles" are longer than 3 chars, so we allow them as well
+    path.ends_with(".bashrc");
+
+    // argument from expn shouldn't trigger
+    path.ends_with(arg!());
+
+    path.ends_with("..");
+    path.ends_with("./a");
+    path.ends_with(".");
+    path.ends_with("");
+}
+
+// is_some_and was stabilized in 1.70, so suggest map_or(false, ..) if under that
+#[clippy::msrv = "1.69"]
+fn under_msv(path: &Path) -> bool {
+    path.extension().map_or(false, |ext| ext == "md")
+    //~^ ERROR: this looks like a failed attempt at checking for the file extension
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/path_ends_with_ext.rs b/src/tools/clippy/tests/ui/path_ends_with_ext.rs
new file mode 100644
index 00000000000..2dfd046218a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/path_ends_with_ext.rs
@@ -0,0 +1,36 @@
+#![warn(clippy::path_ends_with_ext)]
+use std::path::Path;
+
+macro_rules! arg {
+    () => {
+        ".md"
+    };
+}
+
+fn test(path: &Path) {
+    path.ends_with(".md");
+    //~^ ERROR: this looks like a failed attempt at checking for the file extension
+
+    // some "extensions" are allowed by default
+    path.ends_with(".git");
+
+    // most legitimate "dotfiles" are longer than 3 chars, so we allow them as well
+    path.ends_with(".bashrc");
+
+    // argument from expn shouldn't trigger
+    path.ends_with(arg!());
+
+    path.ends_with("..");
+    path.ends_with("./a");
+    path.ends_with(".");
+    path.ends_with("");
+}
+
+// is_some_and was stabilized in 1.70, so suggest map_or(false, ..) if under that
+#[clippy::msrv = "1.69"]
+fn under_msv(path: &Path) -> bool {
+    path.ends_with(".md")
+    //~^ ERROR: this looks like a failed attempt at checking for the file extension
+}
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/path_ends_with_ext.stderr b/src/tools/clippy/tests/ui/path_ends_with_ext.stderr
new file mode 100644
index 00000000000..a73ab4d08e9
--- /dev/null
+++ b/src/tools/clippy/tests/ui/path_ends_with_ext.stderr
@@ -0,0 +1,17 @@
+error: this looks like a failed attempt at checking for the file extension
+  --> $DIR/path_ends_with_ext.rs:11:5
+   |
+LL |     path.ends_with(".md");
+   |     ^^^^^^^^^^^^^^^^^^^^^ help: try: `path.extension().is_some_and(|ext| ext == "md")`
+   |
+   = note: `-D clippy::path-ends-with-ext` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::path_ends_with_ext)]`
+
+error: this looks like a failed attempt at checking for the file extension
+  --> $DIR/path_ends_with_ext.rs:32:5
+   |
+LL |     path.ends_with(".md")
+   |     ^^^^^^^^^^^^^^^^^^^^^ help: try: `path.extension().map_or(false, |ext| ext == "md")`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/redundant_allocation.rs b/src/tools/clippy/tests/ui/redundant_allocation.rs
index b3257c04f82..e70f8e71fae 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation.rs
+++ b/src/tools/clippy/tests/ui/redundant_allocation.rs
@@ -159,4 +159,9 @@ mod box_fat_ptr {
     //~| NOTE: `Box<Box<DynSized>>` is already on the heap, `Rc<Box<Box<DynSized>>>` makes
 }
 
+// https://github.com/rust-lang/rust-clippy/issues/11417
+fn type_in_closure() {
+    let _ = |_: &mut Box<Box<dyn ToString>>| {};
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/redundant_as_str.fixed b/src/tools/clippy/tests/ui/redundant_as_str.fixed
new file mode 100644
index 00000000000..a38523a7c79
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_as_str.fixed
@@ -0,0 +1,24 @@
+#![warn(clippy::redundant_as_str)]
+
+fn main() {
+    let string = "Hello, world!".to_owned();
+
+    // These methods are redundant and the `as_str` can be removed
+    let _redundant = string.as_bytes();
+    let _redundant = string.is_empty();
+
+    // These methods don't use `as_str` when they are redundant
+    let _no_as_str = string.as_bytes();
+    let _no_as_str = string.is_empty();
+
+    // These methods are not redundant, and are equivelant to
+    // doing dereferencing the string and applying the method
+    let _not_redundant = string.as_str().escape_unicode();
+    let _not_redundant = string.as_str().trim();
+    let _not_redundant = string.as_str().split_whitespace();
+
+    // These methods don't use `as_str` and are applied on a `str` directly
+    let borrowed_str = "Hello, world!";
+    let _is_str = borrowed_str.as_bytes();
+    let _is_str = borrowed_str.is_empty();
+}
diff --git a/src/tools/clippy/tests/ui/redundant_as_str.rs b/src/tools/clippy/tests/ui/redundant_as_str.rs
new file mode 100644
index 00000000000..33adb609996
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_as_str.rs
@@ -0,0 +1,24 @@
+#![warn(clippy::redundant_as_str)]
+
+fn main() {
+    let string = "Hello, world!".to_owned();
+
+    // These methods are redundant and the `as_str` can be removed
+    let _redundant = string.as_str().as_bytes();
+    let _redundant = string.as_str().is_empty();
+
+    // These methods don't use `as_str` when they are redundant
+    let _no_as_str = string.as_bytes();
+    let _no_as_str = string.is_empty();
+
+    // These methods are not redundant, and are equivelant to
+    // doing dereferencing the string and applying the method
+    let _not_redundant = string.as_str().escape_unicode();
+    let _not_redundant = string.as_str().trim();
+    let _not_redundant = string.as_str().split_whitespace();
+
+    // These methods don't use `as_str` and are applied on a `str` directly
+    let borrowed_str = "Hello, world!";
+    let _is_str = borrowed_str.as_bytes();
+    let _is_str = borrowed_str.is_empty();
+}
diff --git a/src/tools/clippy/tests/ui/redundant_as_str.stderr b/src/tools/clippy/tests/ui/redundant_as_str.stderr
new file mode 100644
index 00000000000..0ea42a94a81
--- /dev/null
+++ b/src/tools/clippy/tests/ui/redundant_as_str.stderr
@@ -0,0 +1,17 @@
+error: this `as_str` is redundant and can be removed as the method immediately following exists on `String` too
+  --> $DIR/redundant_as_str.rs:7:29
+   |
+LL |     let _redundant = string.as_str().as_bytes();
+   |                             ^^^^^^^^^^^^^^^^^ help: try: `as_bytes`
+   |
+   = note: `-D clippy::redundant-as-str` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::redundant_as_str)]`
+
+error: this `as_str` is redundant and can be removed as the method immediately following exists on `String` too
+  --> $DIR/redundant_as_str.rs:8:29
+   |
+LL |     let _redundant = string.as_str().is_empty();
+   |                             ^^^^^^^^^^^^^^^^^ help: try: `is_empty`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.fixed b/src/tools/clippy/tests/ui/redundant_field_names.fixed
index bbe3b38e547..c578e786426 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.fixed
+++ b/src/tools/clippy/tests/ui/redundant_field_names.fixed
@@ -1,8 +1,9 @@
+//@aux-build:proc_macros.rs
 #![warn(clippy::redundant_field_names)]
 #![allow(clippy::extra_unused_type_parameters, clippy::no_effect, dead_code, unused_variables)]
 
 #[macro_use]
-extern crate derive_new;
+extern crate proc_macros;
 
 use std::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
 
@@ -18,7 +19,6 @@ struct Person {
     foo: u8,
 }
 
-#[derive(new)]
 pub struct S {
     v: String,
 }
@@ -57,6 +57,13 @@ fn main() {
     let _ = Range { start, end };
     let _ = RangeInclusive::new(start, end);
     let _ = RangeToInclusive { end };
+
+    external! {
+        let v = String::new();
+        let _ = S {
+            v: v
+        };
+    }
 }
 
 fn issue_3476() {
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.rs b/src/tools/clippy/tests/ui/redundant_field_names.rs
index 9afa191ce7c..d8c2286d5ad 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.rs
+++ b/src/tools/clippy/tests/ui/redundant_field_names.rs
@@ -1,8 +1,9 @@
+//@aux-build:proc_macros.rs
 #![warn(clippy::redundant_field_names)]
 #![allow(clippy::extra_unused_type_parameters, clippy::no_effect, dead_code, unused_variables)]
 
 #[macro_use]
-extern crate derive_new;
+extern crate proc_macros;
 
 use std::ops::{Range, RangeFrom, RangeInclusive, RangeTo, RangeToInclusive};
 
@@ -18,7 +19,6 @@ struct Person {
     foo: u8,
 }
 
-#[derive(new)]
 pub struct S {
     v: String,
 }
@@ -57,6 +57,13 @@ fn main() {
     let _ = Range { start: start, end: end };
     let _ = RangeInclusive::new(start, end);
     let _ = RangeToInclusive { end: end };
+
+    external! {
+        let v = String::new();
+        let _ = S {
+            v: v
+        };
+    }
 }
 
 fn issue_3476() {
diff --git a/src/tools/clippy/tests/ui/redundant_field_names.stderr b/src/tools/clippy/tests/ui/redundant_field_names.stderr
index 5fee60b8ea4..6eb1cc75319 100644
--- a/src/tools/clippy/tests/ui/redundant_field_names.stderr
+++ b/src/tools/clippy/tests/ui/redundant_field_names.stderr
@@ -44,7 +44,7 @@ LL |     let _ = RangeToInclusive { end: end };
    |                                ^^^^^^^^ help: replace it with: `end`
 
 error: redundant field names in struct initialization
-  --> $DIR/redundant_field_names.rs:81:25
+  --> $DIR/redundant_field_names.rs:88:25
    |
 LL |     let _ = RangeFrom { start: start };
    |                         ^^^^^^^^^^^^ help: replace it with: `start`
diff --git a/src/tools/clippy/tests/ui/redundant_guards.fixed b/src/tools/clippy/tests/ui/redundant_guards.fixed
index 9a1ec3a4d36..f23116a7e1c 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.fixed
+++ b/src/tools/clippy/tests/ui/redundant_guards.fixed
@@ -43,6 +43,7 @@ fn main() {
         },
         Some(Some(1)) => ..,
         Some(Some(2)) => ..,
+        Some(Some(2)) => ..,
         // Don't lint, since x is used in the body
         Some(x) if let Some(1) = x => {
             x;
@@ -56,11 +57,13 @@ fn main() {
         Some(x) if matches!(y, 1 if true) => ..,
         Some(x) if let 1 = y => ..,
         Some(x) if y == 2 => ..,
+        Some(x) if 2 == y => ..,
         _ => todo!(),
     };
     let a = A(1);
     match a {
         _ if a.0 == 1 => {},
+        _ if 1 == a.0 => {},
         _ => todo!(),
     }
     let b = B { e: Some(A(0)) };
@@ -119,6 +122,7 @@ fn h(v: Option<u32>) {
 fn f(s: Option<std::ffi::OsString>) {
     match s {
         Some(x) if x == "a" => {},
+        Some(x) if "a" == x => {},
         _ => {},
     }
 }
@@ -140,6 +144,52 @@ static CONST_S: S = S { a: 1 };
 fn g(opt_s: Option<S>) {
     match opt_s {
         Some(x) if x == CONST_S => {},
+        Some(x) if CONST_S == x => {},
         _ => {},
     }
 }
+
+mod issue11465 {
+    enum A {
+        Foo([u8; 3]),
+    }
+
+    struct B {
+        b: String,
+        c: i32,
+    }
+
+    fn issue11465() {
+        let c = Some(1);
+        match c {
+            Some(1) => {},
+            Some(1) => {},
+            Some(2) => {},
+            Some(3) => {},
+            _ => {},
+        };
+
+        let enum_a = A::Foo([98, 97, 114]);
+        match enum_a {
+            A::Foo(ref arr) if arr == b"foo" => {},
+            A::Foo(ref arr) if b"foo" == arr => {},
+            A::Foo(ref arr) if let b"bar" = arr => {},
+            A::Foo(ref arr) if matches!(arr, b"baz") => {},
+            _ => {},
+        };
+
+        let struct_b = B {
+            b: "bar".to_string(),
+            c: 42,
+        };
+        match struct_b {
+            B { ref b, .. } if b == "bar" => {},
+            B { ref b, .. } if "bar" == b => {},
+            B { c: 1, .. } => {},
+            B { c: 1, .. } => {},
+            B { c: 1, .. } => {},
+            B { c: 1, .. } => {},
+            _ => {},
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/redundant_guards.rs b/src/tools/clippy/tests/ui/redundant_guards.rs
index e2e0ee816c5..c0206b4cec7 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.rs
+++ b/src/tools/clippy/tests/ui/redundant_guards.rs
@@ -43,6 +43,7 @@ fn main() {
         },
         Some(x) if let Some(1) = x => ..,
         Some(x) if x == Some(2) => ..,
+        Some(x) if Some(2) == x => ..,
         // Don't lint, since x is used in the body
         Some(x) if let Some(1) = x => {
             x;
@@ -56,11 +57,13 @@ fn main() {
         Some(x) if matches!(y, 1 if true) => ..,
         Some(x) if let 1 = y => ..,
         Some(x) if y == 2 => ..,
+        Some(x) if 2 == y => ..,
         _ => todo!(),
     };
     let a = A(1);
     match a {
         _ if a.0 == 1 => {},
+        _ if 1 == a.0 => {},
         _ => todo!(),
     }
     let b = B { e: Some(A(0)) };
@@ -119,6 +122,7 @@ fn h(v: Option<u32>) {
 fn f(s: Option<std::ffi::OsString>) {
     match s {
         Some(x) if x == "a" => {},
+        Some(x) if "a" == x => {},
         _ => {},
     }
 }
@@ -140,6 +144,52 @@ static CONST_S: S = S { a: 1 };
 fn g(opt_s: Option<S>) {
     match opt_s {
         Some(x) if x == CONST_S => {},
+        Some(x) if CONST_S == x => {},
         _ => {},
     }
 }
+
+mod issue11465 {
+    enum A {
+        Foo([u8; 3]),
+    }
+
+    struct B {
+        b: String,
+        c: i32,
+    }
+
+    fn issue11465() {
+        let c = Some(1);
+        match c {
+            Some(ref x) if x == &1 => {},
+            Some(ref x) if &1 == x => {},
+            Some(ref x) if let &2 = x => {},
+            Some(ref x) if matches!(x, &3) => {},
+            _ => {},
+        };
+
+        let enum_a = A::Foo([98, 97, 114]);
+        match enum_a {
+            A::Foo(ref arr) if arr == b"foo" => {},
+            A::Foo(ref arr) if b"foo" == arr => {},
+            A::Foo(ref arr) if let b"bar" = arr => {},
+            A::Foo(ref arr) if matches!(arr, b"baz") => {},
+            _ => {},
+        };
+
+        let struct_b = B {
+            b: "bar".to_string(),
+            c: 42,
+        };
+        match struct_b {
+            B { ref b, .. } if b == "bar" => {},
+            B { ref b, .. } if "bar" == b => {},
+            B { ref c, .. } if c == &1 => {},
+            B { ref c, .. } if &1 == c => {},
+            B { ref c, .. } if let &1 = c => {},
+            B { ref c, .. } if matches!(c, &1) => {},
+            _ => {},
+        }
+    }
+}
diff --git a/src/tools/clippy/tests/ui/redundant_guards.stderr b/src/tools/clippy/tests/ui/redundant_guards.stderr
index 0a45a6d7619..b8d7834e358 100644
--- a/src/tools/clippy/tests/ui/redundant_guards.stderr
+++ b/src/tools/clippy/tests/ui/redundant_guards.stderr
@@ -60,7 +60,19 @@ LL +         Some(Some(2)) => ..,
    |
 
 error: redundant guard
-  --> $DIR/redundant_guards.rs:68:20
+  --> $DIR/redundant_guards.rs:46:20
+   |
+LL |         Some(x) if Some(2) == x => ..,
+   |                    ^^^^^^^^^^^^
+   |
+help: try
+   |
+LL -         Some(x) if Some(2) == x => ..,
+LL +         Some(Some(2)) => ..,
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:71:20
    |
 LL |         B { e } if matches!(e, Some(A(2))) => ..,
    |                    ^^^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +84,7 @@ LL +         B { e: Some(A(2)) } => ..,
    |
 
 error: redundant guard
-  --> $DIR/redundant_guards.rs:105:20
+  --> $DIR/redundant_guards.rs:108:20
    |
 LL |         E::A(y) if y == "not from an or pattern" => {},
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,7 +96,7 @@ LL +         E::A("not from an or pattern") => {},
    |
 
 error: redundant guard
-  --> $DIR/redundant_guards.rs:112:14
+  --> $DIR/redundant_guards.rs:115:14
    |
 LL |         x if matches!(x, Some(0)) => ..,
    |              ^^^^^^^^^^^^^^^^^^^^
@@ -95,5 +107,101 @@ LL -         x if matches!(x, Some(0)) => ..,
 LL +         Some(0) => ..,
    |
 
-error: aborting due to 8 previous errors
+error: redundant guard
+  --> $DIR/redundant_guards.rs:165:28
+   |
+LL |             Some(ref x) if x == &1 => {},
+   |                            ^^^^^^^
+   |
+help: try
+   |
+LL -             Some(ref x) if x == &1 => {},
+LL +             Some(1) => {},
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:166:28
+   |
+LL |             Some(ref x) if &1 == x => {},
+   |                            ^^^^^^^
+   |
+help: try
+   |
+LL -             Some(ref x) if &1 == x => {},
+LL +             Some(1) => {},
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:167:28
+   |
+LL |             Some(ref x) if let &2 = x => {},
+   |                            ^^^^^^^^^^
+   |
+help: try
+   |
+LL -             Some(ref x) if let &2 = x => {},
+LL +             Some(2) => {},
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:168:28
+   |
+LL |             Some(ref x) if matches!(x, &3) => {},
+   |                            ^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL -             Some(ref x) if matches!(x, &3) => {},
+LL +             Some(3) => {},
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:188:32
+   |
+LL |             B { ref c, .. } if c == &1 => {},
+   |                                ^^^^^^^
+   |
+help: try
+   |
+LL -             B { ref c, .. } if c == &1 => {},
+LL +             B { c: 1, .. } => {},
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:189:32
+   |
+LL |             B { ref c, .. } if &1 == c => {},
+   |                                ^^^^^^^
+   |
+help: try
+   |
+LL -             B { ref c, .. } if &1 == c => {},
+LL +             B { c: 1, .. } => {},
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:190:32
+   |
+LL |             B { ref c, .. } if let &1 = c => {},
+   |                                ^^^^^^^^^^
+   |
+help: try
+   |
+LL -             B { ref c, .. } if let &1 = c => {},
+LL +             B { c: 1, .. } => {},
+   |
+
+error: redundant guard
+  --> $DIR/redundant_guards.rs:191:32
+   |
+LL |             B { ref c, .. } if matches!(c, &1) => {},
+   |                                ^^^^^^^^^^^^^^^
+   |
+help: try
+   |
+LL -             B { ref c, .. } if matches!(c, &1) => {},
+LL +             B { c: 1, .. } => {},
+   |
+
+error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/regex.rs b/src/tools/clippy/tests/ui/regex.rs
index 5259d9ce04b..094d9574ae9 100644
--- a/src/tools/clippy/tests/ui/regex.rs
+++ b/src/tools/clippy/tests/ui/regex.rs
@@ -2,7 +2,8 @@
     unused,
     clippy::needless_raw_strings,
     clippy::needless_raw_string_hashes,
-    clippy::needless_borrow
+    clippy::needless_borrow,
+    clippy::needless_borrows_for_generic_args
 )]
 #![warn(clippy::invalid_regex, clippy::trivial_regex)]
 
diff --git a/src/tools/clippy/tests/ui/regex.stderr b/src/tools/clippy/tests/ui/regex.stderr
index 91f90157e68..6d98d691d6f 100644
--- a/src/tools/clippy/tests/ui/regex.stderr
+++ b/src/tools/clippy/tests/ui/regex.stderr
@@ -1,5 +1,5 @@
 error: trivial regex
-  --> $DIR/regex.rs:18:45
+  --> $DIR/regex.rs:19:45
    |
 LL |     let pipe_in_wrong_position = Regex::new("|");
    |                                             ^^^
@@ -9,7 +9,7 @@ LL |     let pipe_in_wrong_position = Regex::new("|");
    = help: to override `-D warnings` add `#[allow(clippy::trivial_regex)]`
 
 error: trivial regex
-  --> $DIR/regex.rs:20:60
+  --> $DIR/regex.rs:21:60
    |
 LL |     let pipe_in_wrong_position_builder = RegexBuilder::new("|");
    |                                                            ^^^
@@ -17,7 +17,7 @@ LL |     let pipe_in_wrong_position_builder = RegexBuilder::new("|");
    = help: the regex is unlikely to be useful as it is
 
 error: regex syntax error: invalid character class range, the start must be <= the end
-  --> $DIR/regex.rs:22:42
+  --> $DIR/regex.rs:23:42
    |
 LL |     let wrong_char_ranice = Regex::new("[z-a]");
    |                                          ^^^
@@ -26,7 +26,7 @@ LL |     let wrong_char_ranice = Regex::new("[z-a]");
    = help: to override `-D warnings` add `#[allow(clippy::invalid_regex)]`
 
 error: regex syntax error: invalid character class range, the start must be <= the end
-  --> $DIR/regex.rs:25:37
+  --> $DIR/regex.rs:26:37
    |
 LL |     let some_unicode = Regex::new("[é-è]");
    |                                     ^^^
@@ -35,13 +35,13 @@ error: regex parse error:
            (
            ^
        error: unclosed group
-  --> $DIR/regex.rs:28:33
+  --> $DIR/regex.rs:29:33
    |
 LL |     let some_regex = Regex::new(OPENING_PAREN);
    |                                 ^^^^^^^^^^^^^
 
 error: trivial regex
-  --> $DIR/regex.rs:30:53
+  --> $DIR/regex.rs:31:53
    |
 LL |     let binary_pipe_in_wrong_position = BRegex::new("|");
    |                                                     ^^^
@@ -52,7 +52,7 @@ error: regex parse error:
            (
            ^
        error: unclosed group
-  --> $DIR/regex.rs:32:41
+  --> $DIR/regex.rs:33:41
    |
 LL |     let some_binary_regex = BRegex::new(OPENING_PAREN);
    |                                         ^^^^^^^^^^^^^
@@ -61,7 +61,7 @@ error: regex parse error:
            (
            ^
        error: unclosed group
-  --> $DIR/regex.rs:33:56
+  --> $DIR/regex.rs:34:56
    |
 LL |     let some_binary_regex_builder = BRegexBuilder::new(OPENING_PAREN);
    |                                                        ^^^^^^^^^^^^^
@@ -70,7 +70,7 @@ error: regex parse error:
            (
            ^
        error: unclosed group
-  --> $DIR/regex.rs:45:37
+  --> $DIR/regex.rs:46:37
    |
 LL |     let set_error = RegexSet::new(&[OPENING_PAREN, r"[a-z]+\.(com|org|net)"]);
    |                                     ^^^^^^^^^^^^^
@@ -79,7 +79,7 @@ error: regex parse error:
            (
            ^
        error: unclosed group
-  --> $DIR/regex.rs:46:39
+  --> $DIR/regex.rs:47:39
    |
 LL |     let bset_error = BRegexSet::new(&[OPENING_PAREN, r"[a-z]+\.(com|org|net)"]);
    |                                       ^^^^^^^^^^^^^
@@ -88,7 +88,7 @@ error: regex parse error:
            \b\c
              ^^
        error: unrecognized escape sequence
-  --> $DIR/regex.rs:53:42
+  --> $DIR/regex.rs:54:42
    |
 LL |     let escaped_string_span = Regex::new("\\b\\c");
    |                                          ^^^^^^^^
@@ -96,19 +96,19 @@ LL |     let escaped_string_span = Regex::new("\\b\\c");
    = help: consider using a raw string literal: `r".."`
 
 error: regex syntax error: duplicate flag
-  --> $DIR/regex.rs:55:34
+  --> $DIR/regex.rs:56:34
    |
 LL |     let aux_span = Regex::new("(?ixi)");
    |                                  ^ ^
 
 error: regex syntax error: pattern can match invalid UTF-8
-  --> $DIR/regex.rs:61:53
+  --> $DIR/regex.rs:62:53
    |
 LL |     let invalid_utf8_should_lint = Regex::new("(?-u).");
    |                                                     ^
 
 error: trivial regex
-  --> $DIR/regex.rs:66:33
+  --> $DIR/regex.rs:67:33
    |
 LL |     let trivial_eq = Regex::new("^foobar$");
    |                                 ^^^^^^^^^^
@@ -116,7 +116,7 @@ LL |     let trivial_eq = Regex::new("^foobar$");
    = help: consider using `==` on `str`s
 
 error: trivial regex
-  --> $DIR/regex.rs:69:48
+  --> $DIR/regex.rs:70:48
    |
 LL |     let trivial_eq_builder = RegexBuilder::new("^foobar$");
    |                                                ^^^^^^^^^^
@@ -124,7 +124,7 @@ LL |     let trivial_eq_builder = RegexBuilder::new("^foobar$");
    = help: consider using `==` on `str`s
 
 error: trivial regex
-  --> $DIR/regex.rs:72:42
+  --> $DIR/regex.rs:73:42
    |
 LL |     let trivial_starts_with = Regex::new("^foobar");
    |                                          ^^^^^^^^^
@@ -132,7 +132,7 @@ LL |     let trivial_starts_with = Regex::new("^foobar");
    = help: consider using `str::starts_with`
 
 error: trivial regex
-  --> $DIR/regex.rs:75:40
+  --> $DIR/regex.rs:76:40
    |
 LL |     let trivial_ends_with = Regex::new("foobar$");
    |                                        ^^^^^^^^^
@@ -140,7 +140,7 @@ LL |     let trivial_ends_with = Regex::new("foobar$");
    = help: consider using `str::ends_with`
 
 error: trivial regex
-  --> $DIR/regex.rs:78:39
+  --> $DIR/regex.rs:79:39
    |
 LL |     let trivial_contains = Regex::new("foobar");
    |                                       ^^^^^^^^
@@ -148,7 +148,7 @@ LL |     let trivial_contains = Regex::new("foobar");
    = help: consider using `str::contains`
 
 error: trivial regex
-  --> $DIR/regex.rs:81:39
+  --> $DIR/regex.rs:82:39
    |
 LL |     let trivial_contains = Regex::new(NOT_A_REAL_REGEX);
    |                                       ^^^^^^^^^^^^^^^^
@@ -156,7 +156,7 @@ LL |     let trivial_contains = Regex::new(NOT_A_REAL_REGEX);
    = help: consider using `str::contains`
 
 error: trivial regex
-  --> $DIR/regex.rs:84:40
+  --> $DIR/regex.rs:85:40
    |
 LL |     let trivial_backslash = Regex::new("a\\.b");
    |                                        ^^^^^^^
@@ -164,7 +164,7 @@ LL |     let trivial_backslash = Regex::new("a\\.b");
    = help: consider using `str::contains`
 
 error: trivial regex
-  --> $DIR/regex.rs:88:36
+  --> $DIR/regex.rs:89:36
    |
 LL |     let trivial_empty = Regex::new("");
    |                                    ^^
@@ -172,7 +172,7 @@ LL |     let trivial_empty = Regex::new("");
    = help: the regex is unlikely to be useful as it is
 
 error: trivial regex
-  --> $DIR/regex.rs:91:36
+  --> $DIR/regex.rs:92:36
    |
 LL |     let trivial_empty = Regex::new("^");
    |                                    ^^^
@@ -180,7 +180,7 @@ LL |     let trivial_empty = Regex::new("^");
    = help: the regex is unlikely to be useful as it is
 
 error: trivial regex
-  --> $DIR/regex.rs:94:36
+  --> $DIR/regex.rs:95:36
    |
 LL |     let trivial_empty = Regex::new("^$");
    |                                    ^^^^
@@ -188,7 +188,7 @@ LL |     let trivial_empty = Regex::new("^$");
    = help: consider using `str::is_empty`
 
 error: trivial regex
-  --> $DIR/regex.rs:97:44
+  --> $DIR/regex.rs:98:44
    |
 LL |     let binary_trivial_empty = BRegex::new("^$");
    |                                            ^^^^
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs
index a4dfc8f293d..62798b6d3d6 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_unfixable.rs
@@ -1,6 +1,6 @@
 #![warn(clippy::result_map_unit_fn)]
 #![feature(never_type)]
-#![allow(unused)]
+#![allow(unused, clippy::unnecessary_map_on_constructor)]
 //@no-rustfix
 struct HasResult {
     field: Result<usize, usize>,
diff --git a/src/tools/clippy/tests/ui/transmute_null_to_fn.rs b/src/tools/clippy/tests/ui/transmute_null_to_fn.rs
index 7d780c803ff..b07851e864f 100644
--- a/src/tools/clippy/tests/ui/transmute_null_to_fn.rs
+++ b/src/tools/clippy/tests/ui/transmute_null_to_fn.rs
@@ -25,6 +25,17 @@ fn transmute_const() {
     }
 }
 
+fn issue_11485() {
+    unsafe {
+        let _: fn() = std::mem::transmute(0 as *const u8 as *const ());
+        //~^ ERROR: transmuting a known null pointer into a function pointer
+        let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);
+        //~^ ERROR: transmuting a known null pointer into a function pointer
+        let _: fn() = std::mem::transmute(ZPTR as *const u8);
+        //~^ ERROR: transmuting a known null pointer into a function pointer
+    }
+}
+
 fn main() {
     one_liners();
     transmute_const();
diff --git a/src/tools/clippy/tests/ui/transmute_null_to_fn.stderr b/src/tools/clippy/tests/ui/transmute_null_to_fn.stderr
index ab0ac0dd480..9073080cbf3 100644
--- a/src/tools/clippy/tests/ui/transmute_null_to_fn.stderr
+++ b/src/tools/clippy/tests/ui/transmute_null_to_fn.stderr
@@ -24,5 +24,29 @@ LL |         let _: fn() = std::mem::transmute(ZPTR);
    |
    = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
 
-error: aborting due to 3 previous errors
+error: transmuting a known null pointer into a function pointer
+  --> $DIR/transmute_null_to_fn.rs:30:23
+   |
+LL |         let _: fn() = std::mem::transmute(0 as *const u8 as *const ());
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
+   |
+   = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
+
+error: transmuting a known null pointer into a function pointer
+  --> $DIR/transmute_null_to_fn.rs:32:23
+   |
+LL |         let _: fn() = std::mem::transmute(std::ptr::null::<()>() as *const u8);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
+   |
+   = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
+
+error: transmuting a known null pointer into a function pointer
+  --> $DIR/transmute_null_to_fn.rs:34:23
+   |
+LL |         let _: fn() = std::mem::transmute(ZPTR as *const u8);
+   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ this transmute results in undefined behavior
+   |
+   = help: try wrapping your function pointer type in `Option<T>` instead, and using `None` as a null pointer value
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
deleted file mode 100644
index f4e7f1943ae..00000000000
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
+++ /dev/null
@@ -1,534 +0,0 @@
-//@aux-build:proc_macro_unsafe.rs
-
-#![warn(clippy::undocumented_unsafe_blocks, clippy::unnecessary_safety_comment)]
-#![allow(clippy::let_unit_value, clippy::missing_safety_doc)]
-
-extern crate proc_macro_unsafe;
-
-// Valid comments
-
-fn nested_local() {
-    let _ = {
-        let _ = {
-            // SAFETY:
-            let _ = unsafe {};
-        };
-    };
-}
-
-fn deep_nest() {
-    let _ = {
-        let _ = {
-            // SAFETY:
-            let _ = unsafe {};
-
-            // Safety:
-            unsafe {};
-
-            let _ = {
-                let _ = {
-                    let _ = {
-                        let _ = {
-                            let _ = {
-                                // Safety:
-                                let _ = unsafe {};
-
-                                // SAFETY:
-                                unsafe {};
-                            };
-                        };
-                    };
-
-                    // Safety:
-                    unsafe {};
-                };
-            };
-        };
-
-        // Safety:
-        unsafe {};
-    };
-
-    // SAFETY:
-    unsafe {};
-}
-
-fn local_tuple_expression() {
-    // Safety:
-    let _ = (42, unsafe {});
-}
-
-fn line_comment() {
-    // Safety:
-    unsafe {}
-}
-
-fn line_comment_newlines() {
-    // SAFETY:
-
-    unsafe {}
-}
-
-fn line_comment_empty() {
-    // Safety:
-    //
-    //
-    //
-    unsafe {}
-}
-
-fn line_comment_with_extras() {
-    // This is a description
-    // Safety:
-    unsafe {}
-}
-
-fn block_comment() {
-    /* Safety: */
-    unsafe {}
-}
-
-fn block_comment_newlines() {
-    /* SAFETY: */
-
-    unsafe {}
-}
-
-fn block_comment_with_extras() {
-    /* This is a description
-     * SAFETY:
-     */
-    unsafe {}
-}
-
-fn block_comment_terminator_same_line() {
-    /* This is a description
-     * Safety: */
-    unsafe {}
-}
-
-fn buried_safety() {
-    // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
-    // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
-    // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
-    // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
-    // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
-    // laborum. Safety:
-    // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi
-    // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio
-    // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl
-    // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus.
-    unsafe {}
-}
-
-fn safety_with_prepended_text() {
-    // This is a test. safety:
-    unsafe {}
-}
-
-fn local_line_comment() {
-    // Safety:
-    let _ = unsafe {};
-}
-
-fn local_block_comment() {
-    /* SAFETY: */
-    let _ = unsafe {};
-}
-
-fn comment_array() {
-    // Safety:
-    let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
-}
-
-fn comment_tuple() {
-    // sAFETY:
-    let _ = (42, unsafe {}, "test", unsafe {});
-}
-
-fn comment_unary() {
-    // SAFETY:
-    let _ = *unsafe { &42 };
-}
-
-#[allow(clippy::match_single_binding)]
-fn comment_match() {
-    // SAFETY:
-    let _ = match unsafe {} {
-        _ => {},
-    };
-}
-
-fn comment_addr_of() {
-    // Safety:
-    let _ = &unsafe {};
-}
-
-fn comment_repeat() {
-    // Safety:
-    let _ = [unsafe {}; 5];
-}
-
-fn comment_macro_call() {
-    macro_rules! t {
-        ($b:expr) => {
-            $b
-        };
-    }
-
-    t!(
-        // SAFETY:
-        unsafe {}
-    );
-}
-
-fn comment_macro_def() {
-    macro_rules! t {
-        () => {
-            // Safety:
-            unsafe {}
-        };
-    }
-
-    t!();
-}
-
-fn non_ascii_comment() {
-    // ॐ᧻໒ SaFeTy: ௵∰
-    unsafe {};
-}
-
-fn local_commented_block() {
-    let _ =
-        // safety:
-        unsafe {};
-}
-
-fn local_nest() {
-    // safety:
-    let _ = [(42, unsafe {}, unsafe {}), (52, unsafe {}, unsafe {})];
-}
-
-fn in_fn_call(x: *const u32) {
-    fn f(x: u32) {}
-
-    // Safety: reason
-    f(unsafe { *x });
-}
-
-fn multi_in_fn_call(x: *const u32) {
-    fn f(x: u32, y: u32) {}
-
-    // Safety: reason
-    f(unsafe { *x }, unsafe { *x });
-}
-
-fn in_multiline_fn_call(x: *const u32) {
-    fn f(x: u32, y: u32) {}
-
-    f(
-        // Safety: reason
-        unsafe { *x },
-        0,
-    );
-}
-
-fn in_macro_call(x: *const u32) {
-    // Safety: reason
-    println!("{}", unsafe { *x });
-}
-
-fn in_multiline_macro_call(x: *const u32) {
-    println!(
-        "{}",
-        // Safety: reason
-        unsafe { *x },
-    );
-}
-
-fn from_proc_macro() {
-    proc_macro_unsafe::unsafe_block!(token);
-}
-
-fn in_closure(x: *const u32) {
-    // Safety: reason
-    let _ = || unsafe { *x };
-}
-
-// Invalid comments
-
-#[rustfmt::skip]
-fn inline_block_comment() {
-    /* Safety: */ unsafe {}
-}
-
-fn no_comment() {
-    unsafe {}
-}
-
-fn no_comment_array() {
-    let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
-}
-
-fn no_comment_tuple() {
-    let _ = (42, unsafe {}, "test", unsafe {});
-}
-
-fn no_comment_unary() {
-    let _ = *unsafe { &42 };
-}
-
-#[allow(clippy::match_single_binding)]
-fn no_comment_match() {
-    let _ = match unsafe {} {
-        _ => {},
-    };
-}
-
-fn no_comment_addr_of() {
-    let _ = &unsafe {};
-}
-
-fn no_comment_repeat() {
-    let _ = [unsafe {}; 5];
-}
-
-fn local_no_comment() {
-    let _ = unsafe {};
-}
-
-fn no_comment_macro_call() {
-    macro_rules! t {
-        ($b:expr) => {
-            $b
-        };
-    }
-
-    t!(unsafe {});
-}
-
-fn no_comment_macro_def() {
-    macro_rules! t {
-        () => {
-            unsafe {}
-        };
-    }
-
-    t!();
-}
-
-fn trailing_comment() {
-    unsafe {} // SAFETY:
-}
-
-fn internal_comment() {
-    unsafe {
-        // SAFETY:
-    }
-}
-
-fn interference() {
-    // SAFETY
-
-    let _ = 42;
-
-    unsafe {};
-}
-
-pub fn print_binary_tree() {
-    println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
-}
-
-mod unsafe_impl_smoke_test {
-    unsafe trait A {}
-
-    // error: no safety comment
-    unsafe impl A for () {}
-
-    // Safety: ok
-    unsafe impl A for (i32) {}
-
-    mod sub_mod {
-        // error:
-        unsafe impl B for (u32) {}
-        unsafe trait B {}
-    }
-
-    #[rustfmt::skip]
-    mod sub_mod2 {
-        //
-        // SAFETY: ok
-        //
-
-        unsafe impl B for (u32) {}
-        unsafe trait B {}
-    }
-}
-
-mod unsafe_impl_from_macro {
-    unsafe trait T {}
-
-    // error
-    macro_rules! no_safety_comment {
-        ($t:ty) => {
-            unsafe impl T for $t {}
-        };
-    }
-
-    // ok
-    no_safety_comment!(());
-
-    // ok
-    macro_rules! with_safety_comment {
-        ($t:ty) => {
-            // SAFETY:
-            unsafe impl T for $t {}
-        };
-    }
-
-    // ok
-    with_safety_comment!((i32));
-}
-
-mod unsafe_impl_macro_and_not_macro {
-    unsafe trait T {}
-
-    // error
-    macro_rules! no_safety_comment {
-        ($t:ty) => {
-            unsafe impl T for $t {}
-        };
-    }
-
-    // ok
-    no_safety_comment!(());
-
-    // error
-    unsafe impl T for (i32) {}
-
-    // ok
-    no_safety_comment!(u32);
-
-    // error
-    unsafe impl T for (bool) {}
-}
-
-#[rustfmt::skip]
-mod unsafe_impl_valid_comment {
-    unsafe trait SaFety {}
-    // SaFety:
-    unsafe impl SaFety for () {}
-
-    unsafe trait MultiLineComment {}
-    // The following impl is safe
-    // ...
-    // Safety: reason
-    unsafe impl MultiLineComment for () {}
-
-    unsafe trait NoAscii {}
-    // 安全 SAFETY: 以下のコードは安全です
-    unsafe impl NoAscii for () {}
-
-    unsafe trait InlineAndPrecedingComment {}
-    // SAFETY:
-    /* comment */ unsafe impl InlineAndPrecedingComment for () {}
-
-    unsafe trait BuriedSafety {}
-    // Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor
-    // incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation
-    // ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
-    // reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
-    // occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est
-    // laborum. Safety:
-    // Tellus elementum sagittis vitae et leo duis ut diam quam. Sit amet nulla facilisi
-    // morbi tempus iaculis urna. Amet luctus venenatis lectus magna. At quis risus sed vulputate odio
-    // ut. Luctus venenatis lectus magna fringilla urna. Tortor id aliquet lectus proin nibh nisl
-    // condimentum id venenatis. Vulputate dignissim suspendisse in est ante in nibh mauris cursus.
-    unsafe impl BuriedSafety for () {}
-
-    unsafe trait MultiLineBlockComment {}
-    /* This is a description
-     * Safety: */
-    unsafe impl MultiLineBlockComment for () {}
-}
-
-#[rustfmt::skip]
-mod unsafe_impl_invalid_comment {
-    unsafe trait NoComment {}
-
-    unsafe impl NoComment for () {}
-
-    unsafe trait InlineComment {}
-
-    /* SAFETY: */ unsafe impl InlineComment for () {}
-
-    unsafe trait TrailingComment {}
-
-    unsafe impl TrailingComment for () {} // SAFETY:
-
-    unsafe trait Interference {}
-    // SAFETY:
-    const BIG_NUMBER: i32 = 1000000;
-    unsafe impl Interference for () {}
-}
-
-unsafe trait ImplInFn {}
-
-fn impl_in_fn() {
-    // error
-    unsafe impl ImplInFn for () {}
-
-    // SAFETY: ok
-    unsafe impl ImplInFn for (i32) {}
-}
-
-unsafe trait CrateRoot {}
-
-// error
-unsafe impl CrateRoot for () {}
-
-// SAFETY: ok
-unsafe impl CrateRoot for (i32) {}
-
-fn issue_9142() {
-    // SAFETY: ok
-    let _ =
-        // we need this comment to avoid rustfmt putting
-        // it all on one line
-        unsafe {};
-
-    // SAFETY: this is more than one level away, so it should warn
-    let _ = {
-        if unsafe { true } {
-            todo!();
-        } else {
-            let bar = unsafe {};
-            todo!();
-            bar
-        }
-    };
-}
-
-pub unsafe fn a_function_with_a_very_long_name_to_break_the_line() -> u32 {
-    1
-}
-
-pub const unsafe fn a_const_function_with_a_very_long_name_to_break_the_line() -> u32 {
-    2
-}
-
-fn issue_10832() {
-    // Safety: A safety comment. But it will warn anyways
-    let _some_variable_with_a_very_long_name_to_break_the_line =
-        unsafe { a_function_with_a_very_long_name_to_break_the_line() };
-
-    // Safety: Another safety comment. But it will warn anyways
-    const _SOME_CONST_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
-        unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
-
-    // Safety: Yet another safety comment. But it will warn anyways
-    static _SOME_STATIC_WITH_A_VERY_LONG_NAME_TO_BREAK_THE_LINE: u32 =
-        unsafe { a_const_function_with_a_very_long_name_to_break_the_line() };
-}
-
-fn main() {}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.fixed b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.fixed
new file mode 100644
index 00000000000..d0ba7ed749e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.fixed
@@ -0,0 +1,56 @@
+#![allow(unused)]
+#![warn(clippy::unnecessary_map_on_constructor)]
+
+use std::ffi::OsStr;
+
+fn fun(t: i32) -> i32 {
+    t
+}
+
+fn notfun(e: SimpleError) -> SimpleError {
+    e
+}
+macro_rules! expands_to_fun {
+    () => {
+        fun
+    };
+}
+
+#[derive(Copy, Clone)]
+struct SimpleError {}
+
+type SimpleResult = std::result::Result<i32, SimpleError>;
+
+fn main() {
+    let x: i32 = 4;
+
+    let err = SimpleError {};
+    let a = Some(x);
+    let b: SimpleResult = Ok(x);
+    let c: SimpleResult = Err(err);
+
+    let a = Some(fun(x));
+    let b: SimpleResult = Ok(fun(x));
+    let c: SimpleResult = Err(notfun(err));
+
+    let a = Option::Some(fun(x));
+    let b: SimpleResult = SimpleResult::Ok(fun(x));
+    let c: SimpleResult = SimpleResult::Err(notfun(err));
+    let b: std::result::Result<i32, SimpleError> = Ok(fun(x));
+    let c: std::result::Result<i32, SimpleError> = Err(notfun(err));
+
+    let a = Some(fun(x));
+    let b: SimpleResult = Ok(fun(x));
+    let c: SimpleResult = Err(notfun(err));
+
+    // Should not trigger warning
+    a.map(fun);
+    b.map(fun);
+    c.map_err(notfun);
+
+    b.map_err(notfun); // Ok(_).map_err
+    c.map(fun); // Err(_).map()
+
+    option_env!("PATH").map(OsStr::new);
+    Some(x).map(expands_to_fun!());
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.rs b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.rs
new file mode 100644
index 00000000000..e89e7aad4c4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.rs
@@ -0,0 +1,56 @@
+#![allow(unused)]
+#![warn(clippy::unnecessary_map_on_constructor)]
+
+use std::ffi::OsStr;
+
+fn fun(t: i32) -> i32 {
+    t
+}
+
+fn notfun(e: SimpleError) -> SimpleError {
+    e
+}
+macro_rules! expands_to_fun {
+    () => {
+        fun
+    };
+}
+
+#[derive(Copy, Clone)]
+struct SimpleError {}
+
+type SimpleResult = std::result::Result<i32, SimpleError>;
+
+fn main() {
+    let x: i32 = 4;
+
+    let err = SimpleError {};
+    let a = Some(x);
+    let b: SimpleResult = Ok(x);
+    let c: SimpleResult = Err(err);
+
+    let a = Some(x).map(fun);
+    let b: SimpleResult = Ok(x).map(fun);
+    let c: SimpleResult = Err(err).map_err(notfun);
+
+    let a = Option::Some(x).map(fun);
+    let b: SimpleResult = SimpleResult::Ok(x).map(fun);
+    let c: SimpleResult = SimpleResult::Err(err).map_err(notfun);
+    let b: std::result::Result<i32, SimpleError> = Ok(x).map(fun);
+    let c: std::result::Result<i32, SimpleError> = Err(err).map_err(notfun);
+
+    let a = Some(fun(x));
+    let b: SimpleResult = Ok(fun(x));
+    let c: SimpleResult = Err(notfun(err));
+
+    // Should not trigger warning
+    a.map(fun);
+    b.map(fun);
+    c.map_err(notfun);
+
+    b.map_err(notfun); // Ok(_).map_err
+    c.map(fun); // Err(_).map()
+
+    option_env!("PATH").map(OsStr::new);
+    Some(x).map(expands_to_fun!());
+}
diff --git a/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.stderr b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.stderr
new file mode 100644
index 00000000000..d522b68d872
--- /dev/null
+++ b/src/tools/clippy/tests/ui/unnecessary_map_on_constructor.stderr
@@ -0,0 +1,53 @@
+error: unnecessary map on constructor Some(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:32:13
+   |
+LL |     let a = Some(x).map(fun);
+   |             ^^^^^^^^^^^^^^^^ help: try: `Some(fun(x))`
+   |
+   = note: `-D clippy::unnecessary-map-on-constructor` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::unnecessary_map_on_constructor)]`
+
+error: unnecessary map on constructor Ok(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:33:27
+   |
+LL |     let b: SimpleResult = Ok(x).map(fun);
+   |                           ^^^^^^^^^^^^^^ help: try: `Ok(fun(x))`
+
+error: unnecessary map_err on constructor Err(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:34:27
+   |
+LL |     let c: SimpleResult = Err(err).map_err(notfun);
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Err(notfun(err))`
+
+error: unnecessary map on constructor Option::Some(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:36:13
+   |
+LL |     let a = Option::Some(x).map(fun);
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Option::Some(fun(x))`
+
+error: unnecessary map on constructor SimpleResult::Ok(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:37:27
+   |
+LL |     let b: SimpleResult = SimpleResult::Ok(x).map(fun);
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `SimpleResult::Ok(fun(x))`
+
+error: unnecessary map_err on constructor SimpleResult::Err(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:38:27
+   |
+LL |     let c: SimpleResult = SimpleResult::Err(err).map_err(notfun);
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `SimpleResult::Err(notfun(err))`
+
+error: unnecessary map on constructor Ok(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:39:52
+   |
+LL |     let b: std::result::Result<i32, SimpleError> = Ok(x).map(fun);
+   |                                                    ^^^^^^^^^^^^^^ help: try: `Ok(fun(x))`
+
+error: unnecessary map_err on constructor Err(_)
+  --> $DIR/unnecessary_map_on_constructor.rs:40:52
+   |
+LL |     let c: std::result::Result<i32, SimpleError> = Err(err).map_err(notfun);
+   |                                                    ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Err(notfun(err))`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
index 7b662ca92d2..67faabc53cb 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.fixed
@@ -1,4 +1,4 @@
-#![allow(clippy::needless_borrow, clippy::ptr_arg)]
+#![allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::ptr_arg)]
 #![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
 
 use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
index d79778a6a2e..99f9136427d 100644
--- a/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_to_owned.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::needless_borrow, clippy::ptr_arg)]
+#![allow(clippy::needless_borrow, clippy::needless_borrows_for_generic_args, clippy::ptr_arg)]
 #![warn(clippy::unnecessary_to_owned, clippy::redundant_clone)]
 
 use std::borrow::Cow;
diff --git a/src/tools/clippy/tests/ui/used_underscore_binding.rs b/src/tools/clippy/tests/ui/used_underscore_binding.rs
index c672eff1c27..a8f404b1400 100644
--- a/src/tools/clippy/tests/ui/used_underscore_binding.rs
+++ b/src/tools/clippy/tests/ui/used_underscore_binding.rs
@@ -1,6 +1,5 @@
 //@aux-build:proc_macro_derive.rs
-#![feature(rustc_private)]
-#![warn(clippy::all)]
+#![feature(rustc_private, lint_reasons)]
 #![warn(clippy::used_underscore_binding)]
 #![allow(clippy::disallowed_names, clippy::eq_op, clippy::uninlined_format_args)]
 
@@ -107,6 +106,31 @@ async fn await_desugaring() {
     .await
 }
 
+struct PhantomField<T> {
+    _marker: std::marker::PhantomData<T>,
+}
+
+impl<T> std::fmt::Debug for PhantomField<T> {
+    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
+        f.debug_struct("PhantomField").field("_marker", &self._marker).finish()
+    }
+}
+
+struct AllowedField {
+    #[allow(clippy::used_underscore_binding)]
+    _allowed: usize,
+}
+
+struct ExpectedField {
+    #[expect(clippy::used_underscore_binding)]
+    _expected: usize,
+}
+
+fn lint_levels(allowed: AllowedField, expected: ExpectedField) {
+    let _ = allowed._allowed;
+    let _ = expected._expected;
+}
+
 fn main() {
     let foo = 0u32;
     // tests of unused_underscore lint
diff --git a/src/tools/clippy/tests/ui/used_underscore_binding.stderr b/src/tools/clippy/tests/ui/used_underscore_binding.stderr
index 289519b172e..78d8279810c 100644
--- a/src/tools/clippy/tests/ui/used_underscore_binding.stderr
+++ b/src/tools/clippy/tests/ui/used_underscore_binding.stderr
@@ -1,41 +1,76 @@
 error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:24:5
+  --> $DIR/used_underscore_binding.rs:23:5
    |
 LL |     _foo + 1
    |     ^^^^
    |
+note: `_foo` is defined here
+  --> $DIR/used_underscore_binding.rs:22:22
+   |
+LL | fn prefix_underscore(_foo: u32) -> u32 {
+   |                      ^^^^
    = note: `-D clippy::used-underscore-binding` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::used_underscore_binding)]`
 
 error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:29:20
+  --> $DIR/used_underscore_binding.rs:28:20
    |
 LL |     println!("{}", _foo);
    |                    ^^^^
+   |
+note: `_foo` is defined here
+  --> $DIR/used_underscore_binding.rs:27:24
+   |
+LL | fn in_macro_or_desugar(_foo: u32) {
+   |                        ^^^^
 
 error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:30:16
+  --> $DIR/used_underscore_binding.rs:29:16
    |
 LL |     assert_eq!(_foo, _foo);
    |                ^^^^
+   |
+note: `_foo` is defined here
+  --> $DIR/used_underscore_binding.rs:27:24
+   |
+LL | fn in_macro_or_desugar(_foo: u32) {
+   |                        ^^^^
 
 error: used binding `_foo` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:30:22
+  --> $DIR/used_underscore_binding.rs:29:22
    |
 LL |     assert_eq!(_foo, _foo);
    |                      ^^^^
+   |
+note: `_foo` is defined here
+  --> $DIR/used_underscore_binding.rs:27:24
+   |
+LL | fn in_macro_or_desugar(_foo: u32) {
+   |                        ^^^^
 
 error: used binding `_underscore_field` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:43:5
+  --> $DIR/used_underscore_binding.rs:42:5
    |
 LL |     s._underscore_field += 1;
    |     ^^^^^^^^^^^^^^^^^^^
+   |
+note: `_underscore_field` is defined here
+  --> $DIR/used_underscore_binding.rs:36:5
+   |
+LL |     _underscore_field: u32,
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: used binding `_i` which is prefixed with an underscore. A leading underscore signals that a binding will not be used
-  --> $DIR/used_underscore_binding.rs:104:16
+  --> $DIR/used_underscore_binding.rs:103:16
    |
 LL |         uses_i(_i);
    |                ^^
+   |
+note: `_i` is defined here
+  --> $DIR/used_underscore_binding.rs:102:13
+   |
+LL |         let _i = 5;
+   |             ^^
 
 error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/useless_conversion.fixed b/src/tools/clippy/tests/ui/useless_conversion.fixed
index 52591959905..ed8387b7eb2 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.fixed
+++ b/src/tools/clippy/tests/ui/useless_conversion.fixed
@@ -151,6 +151,8 @@ fn main() {
     let _ = s3;
     let s4: Foo<'a'> = Foo;
     let _ = vec![s4, s4, s4].into_iter();
+
+    issue11300::bar();
 }
 
 #[allow(dead_code)]
@@ -196,6 +198,95 @@ fn explicit_into_iter_fn_arg() {
     b(macro_generated!());
 }
 
+mod issue11300 {
+    pub fn foo<I>(i: I)
+    where
+        I: IntoIterator<Item = i32> + ExactSizeIterator,
+    {
+        assert_eq!(i.len(), 3);
+    }
+
+    trait Helper<T: ?Sized> {}
+    impl Helper<i32> for [i32; 3] {}
+    impl Helper<i32> for std::array::IntoIter<i32, 3> {}
+    impl Helper<()> for std::array::IntoIter<i32, 3> {}
+
+    fn foo2<X: ?Sized, I>(_: I)
+    where
+        I: IntoIterator<Item = i32> + Helper<X>,
+    {
+    }
+
+    trait Helper2<T> {}
+    impl Helper2<std::array::IntoIter<i32, 3>> for i32 {}
+    impl Helper2<[i32; 3]> for i32 {}
+    fn foo3<I>(_: I)
+    where
+        I: IntoIterator<Item = i32>,
+        i32: Helper2<I>,
+    {
+    }
+
+    pub fn bar() {
+        // This should not trigger the lint:
+        // `[i32, 3]` does not satisfy the `ExactSizeIterator` bound, so the into_iter call cannot be
+        // removed and is not useless.
+        foo([1, 2, 3].into_iter());
+
+        // This should trigger the lint, receiver type [i32; 3] also implements `Helper`
+        foo2::<i32, _>([1, 2, 3]);
+
+        // This again should *not* lint, since X = () and I = std::array::IntoIter<i32, 3>,
+        // and `[i32; 3]: Helper<()>` is not true (only `std::array::IntoIter<i32, 3>: Helper<()>` is).
+        foo2::<(), _>([1, 2, 3].into_iter());
+
+        // This should lint. Removing the `.into_iter()` means that `I` gets substituted with `[i32; 3]`,
+        // and `i32: Helper2<[i32, 3]>` is true, so this call is indeed unncessary.
+        foo3([1, 2, 3]);
+    }
+
+    fn ice() {
+        struct S1;
+        impl S1 {
+            pub fn foo<I: IntoIterator>(&self, _: I) {}
+        }
+
+        S1.foo([1, 2]);
+
+        // ICE that occured in itertools
+        trait Itertools {
+            fn interleave_shortest<J>(self, other: J)
+            where
+                J: IntoIterator,
+                Self: Sized;
+        }
+        impl<I: Iterator> Itertools for I {
+            fn interleave_shortest<J>(self, other: J)
+            where
+                J: IntoIterator,
+                Self: Sized,
+            {
+            }
+        }
+        let v0: Vec<i32> = vec![0, 2, 4];
+        let v1: Vec<i32> = vec![1, 3, 5, 7];
+        v0.into_iter().interleave_shortest(v1);
+
+        trait TraitWithLifetime<'a> {}
+        impl<'a> TraitWithLifetime<'a> for std::array::IntoIter<&'a i32, 2> {}
+
+        struct Helper;
+        impl<'a> Helper {
+            fn with_lt<I>(&self, _: I)
+            where
+                I: IntoIterator + TraitWithLifetime<'a>,
+            {
+            }
+        }
+        Helper.with_lt([&1, &2].into_iter());
+    }
+}
+
 #[derive(Copy, Clone)]
 struct Foo<const C: char>;
 
diff --git a/src/tools/clippy/tests/ui/useless_conversion.rs b/src/tools/clippy/tests/ui/useless_conversion.rs
index befb2f9a5c3..991a7762fc6 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.rs
+++ b/src/tools/clippy/tests/ui/useless_conversion.rs
@@ -151,6 +151,8 @@ fn main() {
     let _ = Foo::<'a'>::from(s3);
     let s4: Foo<'a'> = Foo;
     let _ = vec![s4, s4, s4].into_iter().into_iter();
+
+    issue11300::bar();
 }
 
 #[allow(dead_code)]
@@ -196,6 +198,95 @@ fn explicit_into_iter_fn_arg() {
     b(macro_generated!());
 }
 
+mod issue11300 {
+    pub fn foo<I>(i: I)
+    where
+        I: IntoIterator<Item = i32> + ExactSizeIterator,
+    {
+        assert_eq!(i.len(), 3);
+    }
+
+    trait Helper<T: ?Sized> {}
+    impl Helper<i32> for [i32; 3] {}
+    impl Helper<i32> for std::array::IntoIter<i32, 3> {}
+    impl Helper<()> for std::array::IntoIter<i32, 3> {}
+
+    fn foo2<X: ?Sized, I>(_: I)
+    where
+        I: IntoIterator<Item = i32> + Helper<X>,
+    {
+    }
+
+    trait Helper2<T> {}
+    impl Helper2<std::array::IntoIter<i32, 3>> for i32 {}
+    impl Helper2<[i32; 3]> for i32 {}
+    fn foo3<I>(_: I)
+    where
+        I: IntoIterator<Item = i32>,
+        i32: Helper2<I>,
+    {
+    }
+
+    pub fn bar() {
+        // This should not trigger the lint:
+        // `[i32, 3]` does not satisfy the `ExactSizeIterator` bound, so the into_iter call cannot be
+        // removed and is not useless.
+        foo([1, 2, 3].into_iter());
+
+        // This should trigger the lint, receiver type [i32; 3] also implements `Helper`
+        foo2::<i32, _>([1, 2, 3].into_iter());
+
+        // This again should *not* lint, since X = () and I = std::array::IntoIter<i32, 3>,
+        // and `[i32; 3]: Helper<()>` is not true (only `std::array::IntoIter<i32, 3>: Helper<()>` is).
+        foo2::<(), _>([1, 2, 3].into_iter());
+
+        // This should lint. Removing the `.into_iter()` means that `I` gets substituted with `[i32; 3]`,
+        // and `i32: Helper2<[i32, 3]>` is true, so this call is indeed unncessary.
+        foo3([1, 2, 3].into_iter());
+    }
+
+    fn ice() {
+        struct S1;
+        impl S1 {
+            pub fn foo<I: IntoIterator>(&self, _: I) {}
+        }
+
+        S1.foo([1, 2].into_iter());
+
+        // ICE that occured in itertools
+        trait Itertools {
+            fn interleave_shortest<J>(self, other: J)
+            where
+                J: IntoIterator,
+                Self: Sized;
+        }
+        impl<I: Iterator> Itertools for I {
+            fn interleave_shortest<J>(self, other: J)
+            where
+                J: IntoIterator,
+                Self: Sized,
+            {
+            }
+        }
+        let v0: Vec<i32> = vec![0, 2, 4];
+        let v1: Vec<i32> = vec![1, 3, 5, 7];
+        v0.into_iter().interleave_shortest(v1.into_iter());
+
+        trait TraitWithLifetime<'a> {}
+        impl<'a> TraitWithLifetime<'a> for std::array::IntoIter<&'a i32, 2> {}
+
+        struct Helper;
+        impl<'a> Helper {
+            fn with_lt<I>(&self, _: I)
+            where
+                I: IntoIterator + TraitWithLifetime<'a>,
+            {
+            }
+        }
+        Helper.with_lt([&1, &2].into_iter());
+    }
+}
+
 #[derive(Copy, Clone)]
 struct Foo<const C: char>;
 
diff --git a/src/tools/clippy/tests/ui/useless_conversion.stderr b/src/tools/clippy/tests/ui/useless_conversion.stderr
index 28e7bb61098..c1f8b6b4aa9 100644
--- a/src/tools/clippy/tests/ui/useless_conversion.stderr
+++ b/src/tools/clippy/tests/ui/useless_conversion.stderr
@@ -119,64 +119,112 @@ LL |     let _ = vec![s4, s4, s4].into_iter().into_iter();
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing `.into_iter()`: `vec![s4, s4, s4].into_iter()`
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> $DIR/useless_conversion.rs:183:7
+  --> $DIR/useless_conversion.rs:185:7
    |
 LL |     b(vec![1, 2].into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> $DIR/useless_conversion.rs:173:13
+  --> $DIR/useless_conversion.rs:175:13
    |
 LL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> $DIR/useless_conversion.rs:184:7
+  --> $DIR/useless_conversion.rs:186:7
    |
 LL |     c(vec![1, 2].into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> $DIR/useless_conversion.rs:174:18
+  --> $DIR/useless_conversion.rs:176:18
    |
 LL |     fn c(_: impl IntoIterator<Item = i32>) {}
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> $DIR/useless_conversion.rs:185:7
+  --> $DIR/useless_conversion.rs:187:7
    |
 LL |     d(vec![1, 2].into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> $DIR/useless_conversion.rs:177:12
+  --> $DIR/useless_conversion.rs:179:12
    |
 LL |         T: IntoIterator<Item = i32>,
    |            ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> $DIR/useless_conversion.rs:188:7
+  --> $DIR/useless_conversion.rs:190:7
    |
 LL |     b(vec![1, 2].into_iter().into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> $DIR/useless_conversion.rs:173:13
+  --> $DIR/useless_conversion.rs:175:13
    |
 LL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
-  --> $DIR/useless_conversion.rs:189:7
+  --> $DIR/useless_conversion.rs:191:7
    |
 LL |     b(vec![1, 2].into_iter().into_iter().into_iter());
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`s: `vec![1, 2]`
    |
 note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
-  --> $DIR/useless_conversion.rs:173:13
+  --> $DIR/useless_conversion.rs:175:13
    |
 LL |     fn b<T: IntoIterator<Item = i32>>(_: T) {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 24 previous errors
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+  --> $DIR/useless_conversion.rs:237:24
+   |
+LL |         foo2::<i32, _>([1, 2, 3].into_iter());
+   |                        ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]`
+   |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+  --> $DIR/useless_conversion.rs:216:12
+   |
+LL |         I: IntoIterator<Item = i32> + Helper<X>,
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+  --> $DIR/useless_conversion.rs:245:14
+   |
+LL |         foo3([1, 2, 3].into_iter());
+   |              ^^^^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2, 3]`
+   |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+  --> $DIR/useless_conversion.rs:225:12
+   |
+LL |         I: IntoIterator<Item = i32>,
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+  --> $DIR/useless_conversion.rs:254:16
+   |
+LL |         S1.foo([1, 2].into_iter());
+   |                ^^^^^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `[1, 2]`
+   |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+  --> $DIR/useless_conversion.rs:251:27
+   |
+LL |             pub fn foo<I: IntoIterator>(&self, _: I) {}
+   |                           ^^^^^^^^^^^^
+
+error: explicit call to `.into_iter()` in function argument accepting `IntoIterator`
+  --> $DIR/useless_conversion.rs:273:44
+   |
+LL |         v0.into_iter().interleave_shortest(v1.into_iter());
+   |                                            ^^^^^^^^^^^^^^ help: consider removing the `.into_iter()`: `v1`
+   |
+note: this parameter accepts any `IntoIterator`, so you don't need to call `.into_iter()`
+  --> $DIR/useless_conversion.rs:260:20
+   |
+LL |                 J: IntoIterator,
+   |                    ^^^^^^^^^^^^
+
+error: aborting due to 28 previous errors
 
diff --git a/src/tools/clippy/tests/ui/vec_box_sized.fixed b/src/tools/clippy/tests/ui/vec_box_sized.fixed
index 4a5ef83856a..4363d2224af 100644
--- a/src/tools/clippy/tests/ui/vec_box_sized.fixed
+++ b/src/tools/clippy/tests/ui/vec_box_sized.fixed
@@ -49,4 +49,9 @@ mod inner_mod {
     }
 }
 
+// https://github.com/rust-lang/rust-clippy/issues/11417
+fn in_closure() {
+    let _ = |_: Vec<Box<dyn ToString>>| {};
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/vec_box_sized.rs b/src/tools/clippy/tests/ui/vec_box_sized.rs
index ea020405a30..f4e27fe4bd5 100644
--- a/src/tools/clippy/tests/ui/vec_box_sized.rs
+++ b/src/tools/clippy/tests/ui/vec_box_sized.rs
@@ -49,4 +49,9 @@ mod inner_mod {
     }
 }
 
+// https://github.com/rust-lang/rust-clippy/issues/11417
+fn in_closure() {
+    let _ = |_: Vec<Box<dyn ToString>>| {};
+}
+
 fn main() {}
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index ba273489eb8..0e1bf0c6c2d 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -580,6 +580,8 @@ pub struct TargetCfg {
     pub(crate) sanitizers: Vec<Sanitizer>,
     #[serde(rename = "supports-xray", default)]
     pub(crate) xray: bool,
+    #[serde(default = "default_reloc_model")]
+    pub(crate) relocation_model: String,
 }
 
 impl TargetCfg {
@@ -592,6 +594,10 @@ fn default_os() -> String {
     "none".into()
 }
 
+fn default_reloc_model() -> String {
+    "pic".into()
+}
+
 #[derive(Eq, PartialEq, Clone, Debug, Default, serde::Deserialize)]
 #[serde(rename_all = "kebab-case")]
 pub enum Endian {
diff --git a/src/tools/compiletest/src/header/needs.rs b/src/tools/compiletest/src/header/needs.rs
index 1113721fff6..2b7a4387ceb 100644
--- a/src/tools/compiletest/src/header/needs.rs
+++ b/src/tools/compiletest/src/header/needs.rs
@@ -134,6 +134,11 @@ pub(super) fn handle_needs(
             condition: config.target_cfg().dynamic_linking,
             ignore_reason: "ignored on targets without dynamic linking",
         },
+        Need {
+            name: "needs-relocation-model-pic",
+            condition: config.target_cfg().relocation_model == "pic",
+            ignore_reason: "ignored on targets without PIC relocation model",
+        },
     ];
 
     let (name, comment) = match ln.split_once([':', ' ']) {
diff --git a/src/tools/generate-windows-sys/Cargo.toml b/src/tools/generate-windows-sys/Cargo.toml
index 23e88844bd0..9821677a122 100644
--- a/src/tools/generate-windows-sys/Cargo.toml
+++ b/src/tools/generate-windows-sys/Cargo.toml
@@ -4,4 +4,4 @@ version = "0.1.0"
 edition = "2021"
 
 [dependencies.windows-bindgen]
-version = "0.49"
+version = "0.51.1"
diff --git a/src/tools/generate-windows-sys/src/main.rs b/src/tools/generate-windows-sys/src/main.rs
index 91d981462e8..dff2c5e467a 100644
--- a/src/tools/generate-windows-sys/src/main.rs
+++ b/src/tools/generate-windows-sys/src/main.rs
@@ -1,5 +1,7 @@
+use std::env;
+use std::error::Error;
 use std::fs;
-use std::io::{self, Write};
+use std::io::{self, Read, Seek, Write};
 use std::path::PathBuf;
 
 /// This is printed to the file before the rest of the contents.
@@ -11,25 +13,20 @@ const PRELUDE: &str = r#"// This file is autogenerated.
 // ignore-tidy-filelength
 "#;
 
-fn main() -> io::Result<()> {
+fn main() -> Result<(), Box<dyn Error>> {
     let mut path: PathBuf =
-        std::env::args_os().nth(1).expect("a path to the rust repository is required").into();
-    path.push("library/std/src/sys/windows/c/windows_sys.lst");
+        env::args_os().nth(1).expect("a path to the rust repository is required").into();
+    path.push("library/std/src/sys/windows/c");
+    env::set_current_dir(&path)?;
 
-    // Load the list of APIs
-    let buffer = fs::read_to_string(&path)?;
-    let names: Vec<&str> = buffer
-        .lines()
-        .filter_map(|line| {
-            let line = line.trim();
-            if line.is_empty() || line.starts_with("//") { None } else { Some(line) }
-        })
-        .collect();
+    let info = windows_bindgen::bindgen(["--etc", "windows_sys.lst"])?;
+    println!("{info}");
 
-    // Write the bindings to windows-sys.rs
-    let bindings = windows_bindgen::standalone_std(&names);
-    path.set_extension("rs");
-    let mut f = std::fs::File::create(&path)?;
+    // add some gunk to the output file.
+    let mut f = fs::File::options().read(true).write(true).open("windows_sys.rs")?;
+    let mut bindings = String::new();
+    f.read_to_string(&mut bindings)?;
+    f.seek(io::SeekFrom::Start(0))?;
     f.write_all(PRELUDE.as_bytes())?;
     f.write_all(bindings.as_bytes())?;
 
diff --git a/src/tools/miri/.github/workflows/ci.yml b/src/tools/miri/.github/workflows/ci.yml
index bcbd44a5f38..f026b7fd104 100644
--- a/src/tools/miri/.github/workflows/ci.yml
+++ b/src/tools/miri/.github/workflows/ci.yml
@@ -10,7 +10,7 @@ on:
     branches:
       - 'master'
   schedule:
-    - cron: '11 5 * * *' # At 5:11 UTC every day.
+    - cron: '44 4 * * *' # At 4:44 UTC every day.
 
 defaults:
   run:
@@ -208,7 +208,7 @@ jobs:
           git push -u origin $BRANCH
       - name: Create Pull Request
         run: |
-          PR=$(gh pr create -B master --title 'Automatic sync from rustc' --body '' --label subtree-sync)
+          PR=$(gh pr create -B master --title 'Automatic sync from rustc' --body '')
           ~/.local/bin/zulip-send --user $ZULIP_BOT_EMAIL --api-key $ZULIP_API_TOKEN --site https://rust-lang.zulipchat.com \
             --stream miri --subject "Cron Job Failure (miri, $(date -u +%Y-%m))" \
             --message "A PR doing a rustc-pull [has been automatically created]($PR) for your convenience."
diff --git a/src/tools/miri/Cargo.lock b/src/tools/miri/Cargo.lock
index ca5b6d22515..d236e4bbcb4 100644
--- a/src/tools/miri/Cargo.lock
+++ b/src/tools/miri/Cargo.lock
@@ -27,23 +27,31 @@ dependencies = [
 ]
 
 [[package]]
-name = "anyhow"
-version = "1.0.71"
+name = "annotate-snippets"
+version = "0.9.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
+checksum = "c3b9d411ecbaf79885c6df4d75fff75858d5995ff25385657a28af47e82f9c36"
+dependencies = [
+ "unicode-width",
+ "yansi-term",
+]
 
 [[package]]
-name = "atty"
-version = "0.2.14"
+name = "ansi_term"
+version = "0.12.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
+checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
 dependencies = [
- "hermit-abi 0.1.19",
- "libc",
  "winapi",
 ]
 
 [[package]]
+name = "anyhow"
+version = "1.0.71"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9c7d0618f0e0b7e8ff11427422b64564d5fb0be1940354bfe2e0529b18a9d9b8"
+
+[[package]]
 name = "autocfg"
 version = "1.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -71,6 +79,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 [[package]]
+name = "bitflags"
+version = "2.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635"
+
+[[package]]
 name = "bstr"
 version = "1.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -155,13 +169,32 @@ dependencies = [
 
 [[package]]
 name = "colored"
-version = "2.0.0"
+version = "2.0.4"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "b3616f750b84d8f0de8a58bda93e08e2a81ad3f523089b05f1dffecab48c6cbd"
+checksum = "2674ec482fbc38012cf31e6c42ba0177b431a0cb6f15fe40efa5aab1bda516f6"
 dependencies = [
- "atty",
+ "is-terminal",
  "lazy_static",
- "winapi",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "comma"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "55b672471b4e9f9e95499ea597ff64941a309b2cdbffcc46f2cc5e2d971fd335"
+
+[[package]]
+name = "console"
+version = "0.15.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c926e00cc70edefdc64d3a5ff31cc65bb97a3460097762bd23afb4d8145fccf8"
+dependencies = [
+ "encode_unicode",
+ "lazy_static",
+ "libc",
+ "unicode-width",
+ "windows-sys 0.45.0",
 ]
 
 [[package]]
@@ -194,19 +227,19 @@ dependencies = [
 ]
 
 [[package]]
-name = "diff"
-version = "0.1.13"
+name = "encode_unicode"
+version = "0.3.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "56254986775e3233ffa9c4d7d3faaf6d36a2c09d30b20687e9f88bc8bafc16c8"
+checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f"
 
 [[package]]
 name = "env_logger"
-version = "0.9.3"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "a12e6657c4c97ebab115a42dcee77225f7f482cdd841cf7088c657a42e9e00e7"
+checksum = "85cdab6a89accf66733ad5a1693a4dcced6aeff64602b634530dd73c1f3ee9f0"
 dependencies = [
- "atty",
  "humantime",
+ "is-terminal",
  "log",
  "regex",
  "termcolor",
@@ -271,15 +304,6 @@ checksum = "ad0a93d233ebf96623465aad4046a8d3aa4da22d4f4beba5388838c8a434bbb4"
 
 [[package]]
 name = "hermit-abi"
-version = "0.1.19"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
-dependencies = [
- "libc",
-]
-
-[[package]]
-name = "hermit-abi"
 version = "0.3.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
@@ -297,6 +321,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ce23b50ad8242c51a442f3ff322d56b02f08852c77e4c0b4d3fd684abc89c683"
 
 [[package]]
+name = "indicatif"
+version = "0.17.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fb28741c9db9a713d93deb3bb9515c20788cef5815265bee4980e87bde7e0f25"
+dependencies = [
+ "console",
+ "instant",
+ "number_prefix",
+ "portable-atomic",
+ "unicode-width",
+]
+
+[[package]]
 name = "instant"
 version = "0.1.12"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -311,12 +348,23 @@ version = "1.0.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "9c66c74d2ae7e79a5a8f7ac924adbe38ee42a859c6539ad869eb51f0b52dc220"
 dependencies = [
- "hermit-abi 0.3.1",
+ "hermit-abi",
  "libc",
  "windows-sys 0.48.0",
 ]
 
 [[package]]
+name = "is-terminal"
+version = "0.4.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b"
+dependencies = [
+ "hermit-abi",
+ "rustix 0.38.14",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
 name = "itoa"
 version = "1.0.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -329,10 +377,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
 
 [[package]]
+name = "levenshtein"
+version = "1.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "db13adb97ab515a3691f56e4dbab09283d0b86cb45abd991d8634a9d6f501760"
+
+[[package]]
 name = "libc"
-version = "0.2.142"
+version = "0.2.148"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "6a987beff54b60ffa6d51982e1aa1146bc42f19bd26be28b0586f252fccf5317"
+checksum = "9cdc71e17332e86d2e1d38c1f99edcb6288ee11b815fb1a4b049eaa2114d369b"
 
 [[package]]
 name = "libffi"
@@ -370,6 +424,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ece97ea872ece730aed82664c424eb4c8291e1ff2480247ccf7409044bc6479f"
 
 [[package]]
+name = "linux-raw-sys"
+version = "0.4.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
+
+[[package]]
 name = "lock_api"
 version = "0.4.9"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -454,13 +514,19 @@ version = "0.26.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bfdda3d196821d6af13126e40375cdf7da646a96114af134d5f417a9a1dc8e1a"
 dependencies = [
- "bitflags",
+ "bitflags 1.3.2",
  "cfg-if",
  "libc",
  "static_assertions",
 ]
 
 [[package]]
+name = "number_prefix"
+version = "0.4.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "830b246a0e5f20af87141b25c173cd1b609bd7779a4617d6ec582abaf90870f3"
+
+[[package]]
 name = "object"
 version = "0.30.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -482,6 +548,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "c1b04fb49957986fdce4d6ee7a65027d55d4b6d2265e5848bbb507b58ccfdb6f"
 
 [[package]]
+name = "pad"
+version = "0.1.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d2ad9b889f1b12e0b9ee24db044b5129150d5eada288edc800f789928dc8c0e3"
+dependencies = [
+ "unicode-width",
+]
+
+[[package]]
 name = "parking_lot"
 version = "0.11.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -522,12 +597,28 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e0a7ae3ac2f1173085d398531c705756c94a4c56843785df85a60c1a0afac116"
 
 [[package]]
+name = "portable-atomic"
+version = "1.4.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "31114a898e107c51bb1609ffaf55a0e011cf6a4d7f1170d0015a165082c0338b"
+
+[[package]]
 name = "ppv-lite86"
 version = "0.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de"
 
 [[package]]
+name = "prettydiff"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8ff1fec61082821f8236cf6c0c14e8172b62ce8a72a0eedc30d3b247bb68dc11"
+dependencies = [
+ "ansi_term",
+ "pad",
+]
+
+[[package]]
 name = "proc-macro2"
 version = "1.0.66"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -581,7 +672,7 @@ version = "0.2.16"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a"
 dependencies = [
- "bitflags",
+ "bitflags 1.3.2",
 ]
 
 [[package]]
@@ -590,7 +681,7 @@ version = "0.3.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "567664f262709473930a4bf9e51bf2ebf3348f2e748ccc50dea20646858f8f29"
 dependencies = [
- "bitflags",
+ "bitflags 1.3.2",
 ]
 
 [[package]]
@@ -655,11 +746,24 @@ version = "0.37.19"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "acf8729d8542766f1b2cf77eb034d52f40d375bb8b615d0b147089946e16613d"
 dependencies = [
- "bitflags",
+ "bitflags 1.3.2",
  "errno",
  "io-lifetimes",
  "libc",
- "linux-raw-sys",
+ "linux-raw-sys 0.3.7",
+ "windows-sys 0.48.0",
+]
+
+[[package]]
+name = "rustix"
+version = "0.38.14"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "747c788e9ce8e92b12cd485c49ddf90723550b654b32508f979b71a7b1ecda4f"
+dependencies = [
+ "bitflags 2.4.0",
+ "errno",
+ "libc",
+ "linux-raw-sys 0.4.7",
  "windows-sys 0.48.0",
 ]
 
@@ -756,7 +860,7 @@ dependencies = [
  "cfg-if",
  "fastrand",
  "redox_syscall 0.3.5",
- "rustix",
+ "rustix 0.37.19",
  "windows-sys 0.45.0",
 ]
 
@@ -843,18 +947,23 @@ dependencies = [
 
 [[package]]
 name = "ui_test"
-version = "0.11.7"
+version = "0.21.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c21899b59f53717dfad29e4f46e5b21a200a1b6888ab86532a07cfc8b48dd78c"
+checksum = "accffe020b57a6dd50014d457b5842c5a2ca73cd84f07d86d0a19c460a6509ae"
 dependencies = [
+ "annotate-snippets",
+ "anyhow",
  "bstr",
  "cargo-platform",
  "cargo_metadata",
  "color-eyre",
  "colored",
+ "comma",
  "crossbeam-channel",
- "diff",
+ "indicatif",
  "lazy_static",
+ "levenshtein",
+ "prettydiff",
  "regex",
  "rustc_version",
  "rustfix",
@@ -870,6 +979,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4"
 
 [[package]]
+name = "unicode-width"
+version = "0.1.11"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"
+
+[[package]]
 name = "valuable"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1043,3 +1158,12 @@ name = "windows_x86_64_msvc"
 version = "0.48.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a"
+
+[[package]]
+name = "yansi-term"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fe5c30ade05e61656247b2e334a031dfd0cc466fadef865bdcdea8d537951bf1"
+dependencies = [
+ "winapi",
+]
diff --git a/src/tools/miri/Cargo.toml b/src/tools/miri/Cargo.toml
index 2ae6f922e3a..0df2c160e2f 100644
--- a/src/tools/miri/Cargo.toml
+++ b/src/tools/miri/Cargo.toml
@@ -36,7 +36,7 @@ libloading = "0.7"
 
 [dev-dependencies]
 colored = "2"
-ui_test = "0.11.7"
+ui_test = "0.21.1"
 rustc_version = "0.4"
 # Features chosen to match those required by env_logger, to avoid rebuilds
 regex = { version = "1.5.5", default-features = false, features = ["perf", "std"] }
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index cedc558ebb8..6127eada222 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -362,7 +362,7 @@ Some of these are **unsound**, which means they can lead
 to Miri failing to detect cases of undefined behavior in a program.
 
 * `-Zmiri-disable-abi-check` disables checking [function ABI]. Using this flag
-  is **unsound**.
+  is **unsound**. This flag is **deprecated**.
 * `-Zmiri-disable-alignment-check` disables checking pointer alignment, so you
   can focus on other failures, but it means Miri can miss bugs in your program.
   Using this flag is **unsound**.
@@ -478,6 +478,8 @@ Moreover, Miri recognizes some environment variables:
 * `MIRI_TEST_TARGET` (recognized by the test suite and the `./miri` script) indicates which target
   architecture to test against.  `miri` and `cargo miri` accept the `--target` flag for the same
   purpose.
+* `MIRI_TEST_THREADS` (recognized by the test suite): set the number of threads to use for running tests.
+  By default the number of cores is used.
 * `MIRI_NO_STD` (recognized by `cargo miri` and the test suite) makes sure that the target's
   sysroot is built without libstd. This allows testing and running no_std programs.
 * `RUSTC_BLESS` (recognized by the test suite and `cargo-miri-test/run-test.py`): overwrite all
diff --git a/src/tools/miri/bench-cargo-miri/invalidate/Cargo.lock b/src/tools/miri/bench-cargo-miri/invalidate/Cargo.lock
new file mode 100644
index 00000000000..7bf23225ea5
--- /dev/null
+++ b/src/tools/miri/bench-cargo-miri/invalidate/Cargo.lock
@@ -0,0 +1,7 @@
+# This file is automatically @generated by Cargo.
+# It is not intended for manual editing.
+version = 3
+
+[[package]]
+name = "invalidate"
+version = "0.1.0"
diff --git a/src/tools/miri/bench-cargo-miri/invalidate/Cargo.toml b/src/tools/miri/bench-cargo-miri/invalidate/Cargo.toml
new file mode 100644
index 00000000000..14cf0882f0b
--- /dev/null
+++ b/src/tools/miri/bench-cargo-miri/invalidate/Cargo.toml
@@ -0,0 +1,8 @@
+[package]
+name = "invalidate"
+version = "0.1.0"
+edition = "2021"
+
+# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
+
+[dependencies]
diff --git a/src/tools/miri/bench-cargo-miri/invalidate/src/main.rs b/src/tools/miri/bench-cargo-miri/invalidate/src/main.rs
new file mode 100644
index 00000000000..fa8deb851c3
--- /dev/null
+++ b/src/tools/miri/bench-cargo-miri/invalidate/src/main.rs
@@ -0,0 +1,4 @@
+fn main() {
+    // The end of the range is just chosen to make the benchmark run for a few seconds.
+    for _ in 0..200_000 {}
+}
diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs
index 80ce6325582..d655df6d994 100644
--- a/src/tools/miri/cargo-miri/src/phases.rs
+++ b/src/tools/miri/cargo-miri/src/phases.rs
@@ -10,7 +10,7 @@ use rustc_version::VersionMeta;
 
 use crate::{setup::*, util::*};
 
-const CARGO_MIRI_HELP: &str = r#"Runs binary crates and tests in Miri
+const CARGO_MIRI_HELP: &str = r"Runs binary crates and tests in Miri
 
 Usage:
     cargo miri [subcommand] [<cargo options>...] [--] [<program/test suite options>...]
@@ -31,7 +31,7 @@ Examples:
         This will print the path to the generated sysroot (and nothing else) on stdout.
         stderr will still contain progress information about how the build is doing.
 
-"#;
+";
 
 fn show_help() {
     println!("{CARGO_MIRI_HELP}");
diff --git a/src/tools/miri/miri-script/src/commands.rs b/src/tools/miri/miri-script/src/commands.rs
index 124acc95098..de80777a689 100644
--- a/src/tools/miri/miri-script/src/commands.rs
+++ b/src/tools/miri/miri-script/src/commands.rs
@@ -339,9 +339,9 @@ impl Command {
             "Confirmed that the push round-trips back to Miri properly. Please create a rustc PR:"
         );
         println!(
-            // Open PR with `subtree-sync` label to satisfy the `no-merges` triagebot check
+            // Open PR with `subtree update` title to silence the `no-merges` triagebot check
             // See https://github.com/rust-lang/rust/pull/114157
-            "    https://github.com/rust-lang/rust/compare/{github_user}:{branch}?quick_pull=1&labels=subtree-sync"
+            "    https://github.com/rust-lang/rust/compare/{github_user}:{branch}?quick_pull=1&title=Miri+subtree+update"
         );
 
         drop(josh);
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index ab73f33497e..07dd52ce941 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-366dab13f711df90a6891411458544199d159cbc
+2ba4eb2d49e774b5fbc2a06258ac7b0f60b92b7e
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 50f09584475..fc6151772a0 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -28,9 +28,9 @@ use rustc_middle::{
     middle::exported_symbols::{
         ExportedSymbol, SymbolExportInfo, SymbolExportKind, SymbolExportLevel,
     },
-    query::{LocalCrate},
-    util::Providers,
+    query::LocalCrate,
     ty::TyCtxt,
+    util::Providers,
 };
 use rustc_session::config::{CrateType, ErrorOutputType, OptLevel};
 use rustc_session::search_paths::PathKind;
@@ -359,6 +359,10 @@ fn main() {
                         since it is now enabled by default"
             );
         } else if arg == "-Zmiri-disable-abi-check" {
+            eprintln!(
+                "WARNING: the flag `-Zmiri-disable-abi-check` is deprecated and planned to be removed.\n\
+                If you have a use-case for it, please file an issue."
+            );
             miri_config.check_abi = false;
         } else if arg == "-Zmiri-disable-isolation" {
             if matches!(isolation_enabled, Some(true)) {
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs
index 9b0f13dd62c..1ef30cb9fad 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs
@@ -1,6 +1,7 @@
 use smallvec::SmallVec;
 use std::fmt;
 
+use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::mir::interpret::{alloc_range, AllocId, AllocRange, InterpError};
 use rustc_span::{Span, SpanData};
 use rustc_target::abi::Size;
@@ -233,6 +234,12 @@ impl AllocHistory {
             protectors: SmallVec::new(),
         }
     }
+
+    pub fn retain(&mut self, live_tags: &FxHashSet<BorTag>) {
+        self.invalidations.retain(|event| live_tags.contains(&event.tag));
+        self.creations.retain(|event| live_tags.contains(&event.retag.new_tag));
+        self.protectors.retain(|event| live_tags.contains(&event.tag));
+    }
 }
 
 impl<'history, 'ecx, 'mir, 'tcx> DiagnosticCx<'history, 'ecx, 'mir, 'tcx> {
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
index a54bd32cd40..e670dcef330 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/mod.rs
@@ -456,6 +456,7 @@ impl Stacks {
                     stack.retain(live_tags);
                 }
             }
+            self.history.retain(live_tags);
             self.modified_since_last_gc = false;
         }
     }
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/exhaustive.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/exhaustive.rs
new file mode 100644
index 00000000000..daf3590358f
--- /dev/null
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/exhaustive.rs
@@ -0,0 +1,111 @@
+//! Exhaustive testing utilities.
+//! (These are used in Tree Borrows `#[test]`s for thorough verification
+//! of the behavior of the state machine of permissions,
+//! but the contents of this file are extremely generic)
+#![cfg(test)]
+
+pub trait Exhaustive: Sized {
+    fn exhaustive() -> Box<dyn Iterator<Item = Self>>;
+}
+
+macro_rules! precondition {
+    ($cond:expr) => {
+        if !$cond {
+            continue;
+        }
+    };
+}
+pub(crate) use precondition;
+
+// Trivial impls of `Exhaustive` for the standard types with 0, 1 and 2 elements respectively.
+
+impl Exhaustive for ! {
+    fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+        Box::new(std::iter::empty())
+    }
+}
+
+impl Exhaustive for () {
+    fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+        Box::new(std::iter::once(()))
+    }
+}
+
+impl Exhaustive for bool {
+    fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+        Box::new(vec![true, false].into_iter())
+    }
+}
+
+// Some container impls for `Exhaustive`.
+
+impl<T> Exhaustive for Option<T>
+where
+    T: Exhaustive + 'static,
+{
+    fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+        Box::new(std::iter::once(None).chain(T::exhaustive().map(Some)))
+    }
+}
+
+impl<T1, T2> Exhaustive for (T1, T2)
+where
+    T1: Exhaustive + Clone + 'static,
+    T2: Exhaustive + 'static,
+{
+    fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+        Box::new(T1::exhaustive().flat_map(|t1| T2::exhaustive().map(move |t2| (t1.clone(), t2))))
+    }
+}
+
+impl<T> Exhaustive for [T; 1]
+where
+    T: Exhaustive + 'static,
+{
+    fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+        Box::new(T::exhaustive().map(|t| [t]))
+    }
+}
+
+impl<T> Exhaustive for [T; 2]
+where
+    T: Exhaustive + Clone + 'static,
+{
+    fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+        Box::new(T::exhaustive().flat_map(|t1| T::exhaustive().map(move |t2| [t1.clone(), t2])))
+    }
+}
+
+impl<T> Exhaustive for [T; 3]
+where
+    T: Exhaustive + Clone + 'static,
+{
+    fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+        Box::new(
+            <[T; 2]>::exhaustive()
+                .flat_map(|[t1, t2]| T::exhaustive().map(move |t3| [t1.clone(), t2.clone(), t3])),
+        )
+    }
+}
+
+impl<T> Exhaustive for [T; 4]
+where
+    T: Exhaustive + Clone + 'static,
+{
+    fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+        Box::new(<[T; 2]>::exhaustive().flat_map(|[t1, t2]| {
+            <[T; 2]>::exhaustive().map(move |[t3, t4]| [t1.clone(), t2.clone(), t3, t4])
+        }))
+    }
+}
+
+impl<T> Exhaustive for [T; 5]
+where
+    T: Exhaustive + Clone + 'static,
+{
+    fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+        Box::new(<[T; 2]>::exhaustive().flat_map(|[t1, t2]| {
+            <[T; 3]>::exhaustive().map(move |[t3, t4, t5]| [t1.clone(), t2.clone(), t3, t4, t5])
+        }))
+    }
+}
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
index 8dd925a0ad8..924e0de38c9 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/mod.rs
@@ -15,6 +15,10 @@ pub mod diagnostics;
 mod perms;
 mod tree;
 mod unimap;
+
+#[cfg(test)]
+mod exhaustive;
+
 use perms::Permission;
 pub use tree::Tree;
 
@@ -271,6 +275,10 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
             diagnostics::AccessCause::Reborrow,
         )?;
         // Record the parent-child pair in the tree.
+        // FIXME: We should eventually ensure that the following `assert` holds, because
+        // some "exhaustive" tests consider only the initial configurations that satisfy it.
+        // The culprit is `Permission::new_active` in `tb_protect_place`.
+        //assert!(new_perm.initial_state.is_initial());
         tree_borrows.new_child(orig_tag, new_tag, new_perm.initial_state, range, span)?;
         drop(tree_borrows);
 
@@ -283,7 +291,7 @@ trait EvalContextPrivExt<'mir: 'ecx, 'tcx: 'mir, 'ecx>: crate::MiriInterpCxExt<'
                 // interleaving, but wether UB happens can depend on whether a write occurs in the
                 // future...
                 let is_write = new_perm.initial_state.is_active()
-                    || (new_perm.initial_state.is_reserved() && new_perm.protector.is_some());
+                    || (new_perm.initial_state.is_reserved(None) && new_perm.protector.is_some());
                 if is_write {
                     // Need to get mutable access to alloc_extra.
                     // (Cannot always do this as we can do read-only reborrowing on read-only allocations.)
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
index dab216bc5b1..16bad13e28f 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/perms.rs
@@ -6,7 +6,7 @@ use crate::borrow_tracker::tree_borrows::tree::AccessRelatedness;
 use crate::borrow_tracker::AccessKind;
 
 /// The activation states of a pointer.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 enum PermissionPriv {
     /// represents: a local reference that has not yet been written to;
     /// allows: child reads, foreign reads, foreign writes if type is freeze;
@@ -48,6 +48,13 @@ impl PartialOrd for PermissionPriv {
     }
 }
 
+impl PermissionPriv {
+    /// Check if `self` can be the initial state of a pointer.
+    fn is_initial(&self) -> bool {
+        matches!(self, Reserved { ty_is_freeze: _ } | Frozen)
+    }
+}
+
 /// This module controls how each permission individually reacts to an access.
 /// Although these functions take `protected` as an argument, this is NOT because
 /// we check protector violations here, but because some permissions behave differently
@@ -66,7 +73,6 @@ mod transition {
 
     /// A non-child node was read-accessed: noop on non-protected Reserved, advance to Frozen otherwise.
     fn foreign_read(state: PermissionPriv, protected: bool) -> Option<PermissionPriv> {
-        use Option::*;
         Some(match state {
             // Non-writeable states just ignore foreign reads.
             non_writeable @ (Frozen | Disabled) => non_writeable,
@@ -134,7 +140,7 @@ mod transition {
 
 /// Public interface to the state machine that controls read-write permissions.
 /// This is the "private `enum`" pattern.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd)]
 pub struct Permission {
     inner: PermissionPriv,
 }
@@ -147,6 +153,11 @@ pub struct PermTransition {
 }
 
 impl Permission {
+    /// Check if `self` can be the initial state of a pointer.
+    pub fn is_initial(&self) -> bool {
+        self.inner.is_initial()
+    }
+
     /// Default initial permission of the root of a new tree.
     pub fn new_active() -> Self {
         Self { inner: Active }
@@ -166,14 +177,24 @@ impl Permission {
         matches!(self.inner, Active)
     }
 
-    pub fn is_reserved(self) -> bool {
-        matches!(self.inner, Reserved { .. })
+    // Leave `interior_mut` as `None` if interior mutability
+    // is irrelevant.
+    pub fn is_reserved(self, interior_mut: Option<bool>) -> bool {
+        match (interior_mut, self.inner) {
+            (None, Reserved { .. }) => true,
+            (Some(b1), Reserved { ty_is_freeze: b2 }) => b1 == b2,
+            _ => false,
+        }
     }
 
     pub fn is_frozen(self) -> bool {
         matches!(self.inner, Frozen)
     }
 
+    pub fn is_disabled(self) -> bool {
+        matches!(self.inner, Disabled)
+    }
+
     /// Apply the transition to the inner PermissionPriv.
     pub fn perform_access(
         kind: AccessKind,
@@ -229,7 +250,8 @@ pub mod diagnostics {
                 f,
                 "{}",
                 match self {
-                    Reserved { .. } => "Reserved",
+                    Reserved { ty_is_freeze: true } => "Reserved",
+                    Reserved { ty_is_freeze: false } => "Reserved (interior mutable)",
                     Active => "Active",
                     Frozen => "Frozen",
                     Disabled => "Disabled",
@@ -397,43 +419,35 @@ pub mod diagnostics {
 #[cfg(test)]
 mod propagation_optimization_checks {
     pub use super::*;
-
-    mod util {
-        pub use super::*;
-        impl PermissionPriv {
-            /// Enumerate all states
-            pub fn all() -> impl Iterator<Item = Self> {
-                vec![
-                    Active,
-                    Reserved { ty_is_freeze: true },
-                    Reserved { ty_is_freeze: false },
-                    Frozen,
-                    Disabled,
-                ]
-                .into_iter()
-            }
+    use crate::borrow_tracker::tree_borrows::exhaustive::{precondition, Exhaustive};
+
+    impl Exhaustive for PermissionPriv {
+        fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+            Box::new(
+                vec![Active, Frozen, Disabled]
+                    .into_iter()
+                    .chain(bool::exhaustive().map(|ty_is_freeze| Reserved { ty_is_freeze })),
+            )
         }
+    }
 
-        impl Permission {
-            pub fn all() -> impl Iterator<Item = Self> {
-                PermissionPriv::all().map(|inner| Self { inner })
-            }
+    impl Exhaustive for Permission {
+        fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+            Box::new(PermissionPriv::exhaustive().map(|inner| Self { inner }))
         }
+    }
 
-        impl AccessKind {
-            /// Enumerate all AccessKind.
-            pub fn all() -> impl Iterator<Item = Self> {
-                use AccessKind::*;
-                [Read, Write].into_iter()
-            }
+    impl Exhaustive for AccessKind {
+        fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+            use AccessKind::*;
+            Box::new(vec![Read, Write].into_iter())
         }
+    }
 
-        impl AccessRelatedness {
-            /// Enumerate all relative positions
-            pub fn all() -> impl Iterator<Item = Self> {
-                use AccessRelatedness::*;
-                [This, StrictChildAccess, AncestorAccess, DistantAccess].into_iter()
-            }
+    impl Exhaustive for AccessRelatedness {
+        fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+            use AccessRelatedness::*;
+            Box::new(vec![This, StrictChildAccess, AncestorAccess, DistantAccess].into_iter())
         }
     }
 
@@ -442,16 +456,22 @@ mod propagation_optimization_checks {
     // Even if the protector has disappeared.
     fn all_transitions_idempotent() {
         use transition::*;
-        for old in PermissionPriv::all() {
-            for (old_protected, new_protected) in [(true, true), (true, false), (false, false)] {
-                for access in AccessKind::all() {
-                    for rel_pos in AccessRelatedness::all() {
-                        if let Some(new) = perform_access(access, rel_pos, old, old_protected) {
-                            assert_eq!(
-                                new,
-                                perform_access(access, rel_pos, new, new_protected).unwrap()
-                            );
-                        }
+        for old in PermissionPriv::exhaustive() {
+            for (old_protected, new_protected) in <(bool, bool)>::exhaustive() {
+                // Protector can't appear out of nowhere: either the permission was
+                // created with a protector (`old_protected = true`) and it then may
+                // or may not lose it (`new_protected = false`, resp. `new_protected = true`),
+                // or it didn't have one upon creation and never will
+                // (`old_protected = new_protected = false`).
+                // We thus eliminate from this test and all other tests
+                // the case where the tag is initially unprotected and later becomes protected.
+                precondition!(old_protected || !new_protected);
+                for (access, rel_pos) in <(AccessKind, AccessRelatedness)>::exhaustive() {
+                    if let Some(new) = perform_access(access, rel_pos, old, old_protected) {
+                        assert_eq!(
+                            new,
+                            perform_access(access, rel_pos, new, new_protected).unwrap()
+                        );
                     }
                 }
             }
@@ -459,13 +479,16 @@ mod propagation_optimization_checks {
     }
 
     #[test]
+    #[rustfmt::skip]
     fn foreign_read_is_noop_after_foreign_write() {
         use transition::*;
         let old_access = AccessKind::Write;
         let new_access = AccessKind::Read;
-        for old in PermissionPriv::all() {
-            for (old_protected, new_protected) in [(true, true), (true, false), (false, false)] {
-                for rel_pos in AccessRelatedness::all().filter(|rel| rel.is_foreign()) {
+        for old in PermissionPriv::exhaustive() {
+            for [old_protected, new_protected] in <[bool; 2]>::exhaustive() {
+                precondition!(old_protected || !new_protected);
+                for rel_pos in AccessRelatedness::exhaustive() {
+                    precondition!(rel_pos.is_foreign());
                     if let Some(new) = perform_access(old_access, rel_pos, old, old_protected) {
                         assert_eq!(
                             new,
@@ -480,18 +503,44 @@ mod propagation_optimization_checks {
     #[test]
     // Check that all transitions are consistent with the order on PermissionPriv,
     // i.e. Reserved -> Active -> Frozen -> Disabled
-    fn access_transitions_progress_increasing() {
-        use transition::*;
-        for old in PermissionPriv::all() {
-            for protected in [true, false] {
-                for access in AccessKind::all() {
-                    for rel_pos in AccessRelatedness::all() {
-                        if let Some(new) = perform_access(access, rel_pos, old, protected) {
-                            assert!(old <= new);
+    fn permissionpriv_partialord_is_reachability() {
+        let reach = {
+            let mut reach = rustc_data_structures::fx::FxHashSet::default();
+            // One-step transitions + reflexivity
+            for start in PermissionPriv::exhaustive() {
+                reach.insert((start, start));
+                for (access, rel) in <(AccessKind, AccessRelatedness)>::exhaustive() {
+                    for prot in bool::exhaustive() {
+                        if let Some(end) = transition::perform_access(access, rel, start, prot) {
+                            reach.insert((start, end));
                         }
                     }
                 }
             }
+            // Transitive closure
+            let mut finished = false;
+            while !finished {
+                finished = true;
+                for [start, mid, end] in <[PermissionPriv; 3]>::exhaustive() {
+                    if reach.contains(&(start, mid))
+                        && reach.contains(&(mid, end))
+                        && !reach.contains(&(start, end))
+                    {
+                        finished = false;
+                        reach.insert((start, end));
+                    }
+                }
+            }
+            reach
+        };
+        // Check that it matches `<`
+        for [p1, p2] in <[PermissionPriv; 2]>::exhaustive() {
+            let le12 = p1 <= p2;
+            let reach12 = reach.contains(&(p1, p2));
+            assert!(
+                le12 == reach12,
+                "`{p1} reach {p2}` ({reach12}) does not match `{p1} <= {p2}` ({le12})"
+            );
         }
     }
 }
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
index 5abf13229bb..eb466f89a84 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
@@ -10,6 +10,8 @@
 //!   and the relative position of the access;
 //! - idempotency properties asserted in `perms.rs` (for optimizations)
 
+use std::fmt;
+
 use smallvec::SmallVec;
 
 use rustc_const_eval::interpret::InterpResult;
@@ -26,8 +28,10 @@ use crate::borrow_tracker::tree_borrows::{
 use crate::borrow_tracker::{AccessKind, GlobalState, ProtectorKind};
 use crate::*;
 
+mod tests;
+
 /// Data for a single *location*.
-#[derive(Debug, Clone, Copy, PartialEq, Eq)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
 pub(super) struct LocationState {
     /// A location is initialized when it is child-accessed for the first time (and the initial
     /// retag initializes the location for the range covered by the type), and it then stays
@@ -65,10 +69,25 @@ impl LocationState {
         self
     }
 
+    /// Check if the location has been initialized, i.e. if it has
+    /// ever been accessed through a child pointer.
     pub fn is_initialized(&self) -> bool {
         self.initialized
     }
 
+    /// Check if the state can exist as the initial permission of a pointer.
+    ///
+    /// Do not confuse with `is_initialized`, the two are almost orthogonal
+    /// as apart from `Active` which is not initial and must be initialized,
+    /// any other permission can have an arbitrary combination of being
+    /// initial/initialized.
+    /// FIXME: when the corresponding `assert` in `tree_borrows/mod.rs` finally
+    /// passes and can be uncommented, remove this `#[allow(dead_code)]`.
+    #[cfg_attr(not(test), allow(dead_code))]
+    pub fn is_initial(&self) -> bool {
+        self.permission.is_initial()
+    }
+
     pub fn permission(&self) -> Permission {
         self.permission
     }
@@ -172,6 +191,16 @@ impl LocationState {
     }
 }
 
+impl fmt::Display for LocationState {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        write!(f, "{}", self.permission)?;
+        if !self.initialized {
+            write!(f, "?")?;
+        }
+        Ok(())
+    }
+}
+
 /// Tree structure with both parents and children since we want to be
 /// able to traverse the tree efficiently in both directions.
 #[derive(Clone, Debug)]
@@ -665,87 +694,3 @@ impl AccessRelatedness {
         }
     }
 }
-
-#[cfg(test)]
-mod commutation_tests {
-    use super::*;
-    impl LocationState {
-        pub fn all() -> impl Iterator<Item = Self> {
-            // We keep `latest_foreign_access` at `None` as that's just a cache.
-            Permission::all().flat_map(|permission| {
-                [false, true].into_iter().map(move |initialized| {
-                    Self { permission, initialized, latest_foreign_access: None }
-                })
-            })
-        }
-    }
-
-    #[test]
-    #[rustfmt::skip]
-    // Exhaustive check that for any starting configuration loc,
-    // for any two read accesses r1 and r2, if `loc + r1 + r2` is not UB
-    // and results in `loc'`, then `loc + r2 + r1` is also not UB and results
-    // in the same final state `loc'`.
-    // This lets us justify arbitrary read-read reorderings.
-    fn all_read_accesses_commute() {
-        let kind = AccessKind::Read;
-        // Two of the four combinations of `AccessRelatedness` are trivial,
-        // but we might as well check them all.
-        for rel1 in AccessRelatedness::all() {
-            for rel2 in AccessRelatedness::all() {
-                // Any protector state works, but we can't move reads across function boundaries
-                // so the two read accesses occur under the same protector.
-                for &protected in &[true, false] {
-                    for loc in LocationState::all() {
-                        // Apply 1 then 2. Failure here means that there is UB in the source
-                        // and we skip the check in the target.
-                        let mut loc12 = loc;
-                        let Ok(_) = loc12.perform_access(kind, rel1, protected) else { continue };
-                        let Ok(_) = loc12.perform_access(kind, rel2, protected) else { continue };
-
-                        // If 1 followed by 2 succeeded, then 2 followed by 1 must also succeed...
-                        let mut loc21 = loc;
-                        loc21.perform_access(kind, rel2, protected).unwrap();
-                        loc21.perform_access(kind, rel1, protected).unwrap();
-
-                        // ... and produce the same final result.
-                        assert_eq!(
-                            loc12, loc21,
-                            "Read accesses {:?} followed by {:?} do not commute !",
-                            rel1, rel2
-                        );
-                    }
-                }
-            }
-        }
-    }
-
-    #[test]
-    #[rustfmt::skip]
-    // Ensure that of 2 accesses happen, one foreign and one a child, and we are protected, that we
-    // get UB unless they are both reads.
-    fn protected_enforces_noalias() {
-        for rel1 in AccessRelatedness::all() {
-            for rel2 in AccessRelatedness::all() {
-                if rel1.is_foreign() == rel2.is_foreign() {
-                    // We want to check pairs of accesses where one is foreign and one is not.
-                    continue;
-                }
-                for kind1 in AccessKind::all() {
-                    for kind2 in AccessKind::all() {
-                        for mut state in LocationState::all() {
-                            let protected = true;
-                            let Ok(_) = state.perform_access(kind1, rel1, protected) else { continue };
-                            let Ok(_) = state.perform_access(kind2, rel2, protected) else { continue };
-                            // If these were both allowed, it must have been two reads.
-                            assert!(
-                                kind1 == AccessKind::Read && kind2 == AccessKind::Read,
-                                "failed to enforce noalias between two accesses that are not both reads"
-                            );
-                        }
-                    }
-                }
-            }
-        }
-    }
-}
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs
new file mode 100644
index 00000000000..11c06d0b763
--- /dev/null
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree/tests.rs
@@ -0,0 +1,658 @@
+//! Tests for the tree
+#![cfg(test)]
+
+use super::*;
+use crate::borrow_tracker::tree_borrows::exhaustive::{precondition, Exhaustive};
+use std::fmt;
+
+impl Exhaustive for LocationState {
+    fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+        // We keep `latest_foreign_access` at `None` as that's just a cache.
+        Box::new(<(Permission, bool)>::exhaustive().map(|(permission, initialized)| {
+            Self { permission, initialized, latest_foreign_access: None }
+        }))
+    }
+}
+
+#[test]
+#[rustfmt::skip]
+// Exhaustive check that for any starting configuration loc,
+// for any two read accesses r1 and r2, if `loc + r1 + r2` is not UB
+// and results in `loc'`, then `loc + r2 + r1` is also not UB and results
+// in the same final state `loc'`.
+// This lets us justify arbitrary read-read reorderings.
+fn all_read_accesses_commute() {
+    let kind = AccessKind::Read;
+    // Two of the four combinations of `AccessRelatedness` are trivial,
+    // but we might as well check them all.
+    for [rel1, rel2] in <[AccessRelatedness; 2]>::exhaustive() {
+        // Any protector state works, but we can't move reads across function boundaries
+        // so the two read accesses occur under the same protector.
+        for protected in bool::exhaustive() {
+            for loc in LocationState::exhaustive() {
+                // Apply 1 then 2. Failure here means that there is UB in the source
+                // and we skip the check in the target.
+                let mut loc12 = loc;
+                precondition!(loc12.perform_access(kind, rel1, protected).is_ok());
+                precondition!(loc12.perform_access(kind, rel2, protected).is_ok());
+
+                // If 1 followed by 2 succeeded, then 2 followed by 1 must also succeed...
+                let mut loc21 = loc;
+                loc21.perform_access(kind, rel2, protected).unwrap();
+                loc21.perform_access(kind, rel1, protected).unwrap();
+
+                // ... and produce the same final result.
+                assert_eq!(
+                    loc12, loc21,
+                    "Read accesses {:?} followed by {:?} do not commute !",
+                    rel1, rel2
+                );
+            }
+        }
+    }
+}
+
+#[test]
+#[rustfmt::skip]
+// Ensure that of 2 accesses happen, one foreign and one a child, and we are protected, that we
+// get UB unless they are both reads.
+fn protected_enforces_noalias() {
+    for [rel1, rel2] in <[AccessRelatedness; 2]>::exhaustive() {
+        // We want to check pairs of accesses where one is foreign and one is not.
+        precondition!(rel1.is_foreign() != rel2.is_foreign());
+        for [kind1, kind2] in <[AccessKind; 2]>::exhaustive() {
+            for mut state in LocationState::exhaustive() {
+                let protected = true;
+                precondition!(state.perform_access(kind1, rel1, protected).is_ok());
+                precondition!(state.perform_access(kind2, rel2, protected).is_ok());
+                // If these were both allowed, it must have been two reads.
+                assert!(
+                    kind1 == AccessKind::Read && kind2 == AccessKind::Read,
+                    "failed to enforce noalias between two accesses that are not both reads"
+                );
+            }
+        }
+    }
+}
+
+/// We are going to exhaustively test the possibily of inserting
+/// a spurious read in some code.
+///
+/// We choose some pointer `x` through which we want a spurious read to be inserted.
+/// `x` must thus be reborrowed, not have any children, and initially start protected.
+///
+/// To check if inserting a spurious read is possible, we observe the behavior
+/// of some pointer `y` different from `x` (possibly from a different thread, thus
+/// the protectors on `x` and `y` are not necessarily well-nested).
+/// It must be the case that no matter the context, the insertion of a spurious read
+/// through `x` does not introduce UB in code that did not already have UB.
+///
+/// Testing this will need some setup to simulate the evolution of the permissions
+/// of `x` and `y` under arbitrary code. This arbitrary code of course includes
+/// read and write accesses through `x` and `y`, but it must also consider
+/// the less obvious:
+/// - accesses through pointers that are *neither* `x` nor `y`,
+/// - retags of `y` that change its relative position to `x`.
+///
+///
+/// The general code pattern thus looks like
+///     [thread 1]             || [thread 2]
+///                            || y exists
+///     retag x (protect)      ||
+///                      arbitrary code
+///                           read/write x/y/other
+///                        or retag y
+///                        or unprotect y
+///     <spurious read x>      ||
+///                      arbitrary code
+///                           read/write x/y/other
+///                        or retag y
+///                        or unprotect y
+///                        or unprotect x
+///
+/// `x` must still be protected at the moment the spurious read is inserted
+/// because spurious reads are impossible in general on unprotected tags.
+mod spurious_read {
+    use super::*;
+
+    /// Accessed pointer.
+    #[derive(Debug, Clone, Copy, PartialEq, Eq)]
+    enum PtrSelector {
+        X,
+        Y,
+        Other,
+    }
+
+    /// Relative position of `x` and `y`.
+    /// `y` cannot be a child of `x` because `x` gets retagged as the first
+    /// thing in the pattern, so it cannot have children.
+    #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+    enum RelPosXY {
+        MutuallyForeign,
+        /// X is a child of Y.
+        XChildY,
+    }
+
+    impl Exhaustive for PtrSelector {
+        fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+            use PtrSelector::*;
+            Box::new(vec![X, Y, Other].into_iter())
+        }
+    }
+
+    impl fmt::Display for PtrSelector {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            match self {
+                PtrSelector::X => write!(f, "x"),
+                PtrSelector::Y => write!(f, "y"),
+                PtrSelector::Other => write!(f, "z"),
+            }
+        }
+    }
+
+    impl Exhaustive for RelPosXY {
+        fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+            use RelPosXY::*;
+            Box::new(vec![MutuallyForeign, XChildY].into_iter())
+        }
+    }
+
+    impl fmt::Display for RelPosXY {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            match self {
+                RelPosXY::MutuallyForeign => write!(f, "x and y are mutually foreign"),
+                RelPosXY::XChildY => write!(f, "x is a child of y"),
+            }
+        }
+    }
+
+    impl PtrSelector {
+        /// Knowing the relative position of `x` to `y`, determine the relative
+        /// position of the accessed pointer defined by `self` relative to each `x`
+        /// and `y`.
+        ///
+        /// The output is not necessarily well-defined in general, but it
+        /// is unique when considered up to equivalence by `AccessRelatedness::is_foreign`
+        /// (e.g. having `RelPosXY::XChildY` and `PtrSelector::Other`, strictly
+        /// speaking it is impossible to determine if `Other` is a `DistantAccess`
+        /// or an `AncestorAccess` relative to `y`, but it doesn't really matter
+        /// because `DistantAccess.is_foreign() == AncestorAccess.is_foreign()`).
+        fn rel_pair(self, xy_rel: RelPosXY) -> (AccessRelatedness, AccessRelatedness) {
+            use AccessRelatedness::*;
+            match xy_rel {
+                RelPosXY::MutuallyForeign =>
+                    match self {
+                        PtrSelector::X => (This, DistantAccess),
+                        PtrSelector::Y => (DistantAccess, This),
+                        PtrSelector::Other => (DistantAccess, DistantAccess),
+                    },
+                RelPosXY::XChildY =>
+                    match self {
+                        PtrSelector::X => (This, StrictChildAccess),
+                        PtrSelector::Y => (AncestorAccess, This),
+                        PtrSelector::Other => (DistantAccess, DistantAccess),
+                    },
+            }
+        }
+    }
+
+    /// Arbitrary access parametrized by the relative position of `x` and `y`
+    /// to each other.
+    #[derive(Debug, Clone, Copy)]
+    struct TestAccess {
+        ptr: PtrSelector,
+        kind: AccessKind,
+    }
+
+    impl Exhaustive for TestAccess {
+        fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+            Box::new(
+                <(PtrSelector, AccessKind)>::exhaustive()
+                    .map(|(ptr, kind)| TestAccess { ptr, kind }),
+            )
+        }
+    }
+
+    impl fmt::Display for TestAccess {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            let kind_text = match self.kind {
+                AccessKind::Read => "read",
+                AccessKind::Write => "write",
+            };
+            write!(f, "{kind_text} {}", self.ptr)
+        }
+    }
+
+    type AllowRet = ();
+    type NoRet = !;
+    #[derive(Clone)]
+    /// Events relevant to the evolution of 2 pointers are
+    /// - any access to the same location
+    /// - end of one of them being protected
+    /// - a retag that would change their relative position
+    /// The type `TestEvent` models these kinds of events.
+    ///
+    /// In order to prevent `x` or `y` from losing their protector,
+    /// choose a type `RetX` or `RetY` that is not inhabited.
+    /// e.g.
+    /// - `TestEvent<AllowRet, AllowRet>` is any event including end of protector on either `x` or `y`
+    /// - `TestEvent<NoRet, NoRet>` is any access
+    /// - `TestEvent<NoRet, AllowRet>` allows for `y` to lose its protector but not `x`
+    enum TestEvent<RetX, RetY> {
+        Access(TestAccess),
+        RetX(RetX),
+        RetY(RetY),
+        /// The inner `LocStateProt` must be an initial state (as per the `is_initial` function)
+        RetagY(LocStateProt),
+    }
+
+    impl<RetX, RetY> Exhaustive for TestEvent<RetX, RetY>
+    where
+        RetX: Exhaustive + 'static,
+        RetY: Exhaustive + 'static,
+    {
+        fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+            Box::new(
+                <TestAccess>::exhaustive()
+                    .map(|acc| Self::Access(acc))
+                    .chain(RetX::exhaustive().map(|retx| Self::RetX(retx)))
+                    .chain(RetY::exhaustive().map(|rety| Self::RetY(rety)))
+                    .chain(
+                        LocStateProt::exhaustive()
+                            .filter_map(|s| s.is_initial().then_some(Self::RetagY(s))),
+                    ),
+            )
+        }
+    }
+
+    impl<RetX, RetY> fmt::Display for TestEvent<RetX, RetY> {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            match self {
+                TestEvent::Access(acc) => write!(f, "{acc}"),
+                // The fields of the `Ret` variants just serve to make them
+                // impossible to instanciate via the `RetX = NoRet` type; we can
+                // always ignore their value.
+                TestEvent::RetX(_) => write!(f, "ret x"),
+                TestEvent::RetY(_) => write!(f, "ret y"),
+                TestEvent::RetagY(newp) => write!(f, "retag y ({newp})"),
+            }
+        }
+    }
+
+    #[derive(Clone, PartialEq, Eq, Hash)]
+    /// The state of a pointer on a location, including the protector.
+    /// It is represented here with the protector bound to the `LocationState` rather
+    /// than the `Map<Location, LocationState>` as is normally the case,
+    /// but since all our exhaustive tests look at a  single location
+    /// there's no risk of `prot` for different locations of the same tag getting
+    /// out of sync.
+    struct LocStateProt {
+        state: LocationState,
+        prot: bool,
+    }
+
+    impl LocStateProt {
+        fn is_initial(&self) -> bool {
+            self.state.is_initial()
+        }
+
+        fn perform_access(&self, kind: AccessKind, rel: AccessRelatedness) -> Result<Self, ()> {
+            let mut state = self.state;
+            state.perform_access(kind, rel, self.prot).map_err(|_| ())?;
+            Ok(Self { state, prot: self.prot })
+        }
+
+        fn end_protector(&self) -> Self {
+            Self { prot: false, state: self.state }
+        }
+    }
+
+    impl Exhaustive for LocStateProt {
+        fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+            Box::new(
+                <(LocationState, bool)>::exhaustive().map(|(state, prot)| Self { state, prot }),
+            )
+        }
+    }
+
+    impl fmt::Display for LocStateProt {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            write!(f, "{}", self.state)?;
+            if self.prot {
+                write!(f, ", protect")?;
+            }
+            Ok(())
+        }
+    }
+
+    #[derive(Clone, PartialEq, Eq, Hash)]
+    /// The states of two pointers to the same location,
+    /// and their relationship to each other in the tree.
+    ///
+    /// Note that the two states interact: using one pointer can have
+    /// an impact on the other.
+    /// This makes `LocStateProtPair` more meaningful than a simple
+    /// `(LocStateProt, LocStateProt)` where the two states are not guaranteed
+    /// to be updated at the same time.
+    /// Some `LocStateProtPair` may be unreachable through normal means
+    /// such as `x: Active, y: Active` in the case of mutually foreign pointers.
+    struct LocStateProtPair {
+        xy_rel: RelPosXY,
+        x: LocStateProt,
+        y: LocStateProt,
+    }
+
+    impl LocStateProtPair {
+        fn perform_test_access(self, acc: &TestAccess) -> Result<Self, ()> {
+            let (xrel, yrel) = acc.ptr.rel_pair(self.xy_rel);
+            let x = self.x.perform_access(acc.kind, xrel)?;
+            let y = self.y.perform_access(acc.kind, yrel)?;
+            Ok(Self { x, y, ..self })
+        }
+
+        /// Perform a read on the given pointer if its state is `initialized`.
+        /// Must be called just after reborrowing a pointer.
+        fn read_if_initialized(self, ptr: PtrSelector) -> Result<Self, ()> {
+            let initialized = match ptr {
+                PtrSelector::X => self.x.state.initialized,
+                PtrSelector::Y => self.y.state.initialized,
+                PtrSelector::Other =>
+                    panic!(
+                        "the `initialized` status of `PtrSelector::Other` is unknown, do not pass it to `read_if_initialized`"
+                    ),
+            };
+            if initialized {
+                self.perform_test_access(&TestAccess { ptr, kind: AccessKind::Read })
+            } else {
+                Ok(self)
+            }
+        }
+
+        fn end_protector_x(self) -> Result<Self, ()> {
+            let x = self.x.end_protector();
+            Ok(Self { x, ..self })
+        }
+
+        fn end_protector_y(self) -> Result<Self, ()> {
+            let y = self.y.end_protector();
+            Ok(Self { y, ..self })
+        }
+
+        fn retag_y(self, new_y: LocStateProt) -> Result<Self, ()> {
+            assert!(new_y.is_initial());
+            // `xy_rel` changes to "mutually foreign" now: `y` can no longer be a parent of `x`.
+            Self { y: new_y, xy_rel: RelPosXY::MutuallyForeign, ..self }
+                .read_if_initialized(PtrSelector::Y)
+        }
+
+        fn perform_test_event<RetX, RetY>(self, evt: &TestEvent<RetX, RetY>) -> Result<Self, ()> {
+            match evt {
+                TestEvent::Access(acc) => self.perform_test_access(acc),
+                // The fields of the `Ret` variants just serve to make them
+                // impossible to instanciate via the `RetX = NoRet` type; we can
+                // always ignore their value.
+                TestEvent::RetX(_) => self.end_protector_x(),
+                TestEvent::RetY(_) => self.end_protector_y(),
+                TestEvent::RetagY(newp) => self.retag_y(newp.clone()),
+            }
+        }
+    }
+
+    impl Exhaustive for LocStateProtPair {
+        fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+            Box::new(<[LocStateProt; 2]>::exhaustive().flat_map(|[x, y]| {
+                RelPosXY::exhaustive()
+                    .map(move |xy_rel| Self { x: x.clone(), y: y.clone(), xy_rel })
+            }))
+        }
+    }
+
+    impl fmt::Display for LocStateProtPair {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            write!(f, "x:{}, y:{}", self.x, self.y)
+        }
+    }
+
+    /// Arbitrary sequence of events, as experienced by two mutually foreign pointers
+    /// to the same location.
+    #[derive(Clone)]
+    struct OpaqueCode<RetX, RetY> {
+        events: Vec<TestEvent<RetX, RetY>>,
+    }
+
+    impl<RetX, RetY> fmt::Display for OpaqueCode<RetX, RetY> {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            for evt in &self.events {
+                write!(f, "{evt}; ")?;
+            }
+            Ok(())
+        }
+    }
+
+    impl LocStateProtPair {
+        /// List all sequences of operations that start at `self` and do not cause UB
+        /// There are no duplicates: all sequences returned lead to distinct final states
+        /// (though the sequence is not guaranteed to be the shortest possible sequence of events).
+        /// Yields the states it reaches, and the sequence of operations that got us there.
+        fn all_states_reachable_via_opaque_code<RetX, RetY>(
+            self,
+        ) -> impl Iterator<Item = (Self, OpaqueCode<RetX, RetY>)>
+        where
+            RetX: Exhaustive + Clone + 'static,
+            RetY: Exhaustive + Clone + 'static,
+        {
+            // We compute the reachable set of `Self` from `self` by non-UB `OpaqueCode`.
+            // Configurations are `(reach: Self, code: OpaqueCode)` tuples
+            // for which `code` applied to `self` returns `Ok(reach)`.
+
+            // Stack of all configurations left to handle.
+            let mut handle: Vec<(Self, OpaqueCode<_, _>)> =
+                vec![(self, OpaqueCode { events: Vec::new() })];
+            // Code that can be applied to `self`, and final state.
+            let mut paths: Vec<(Self, OpaqueCode<_, _>)> = Default::default();
+            // Already explored states reachable from `self`
+            let mut seen: FxHashSet<Self> = Default::default();
+            // This is essentially just computing the transitive closure by `perform_test_event`,
+            // most of the work lies in remembering the path up to the current state.
+            while let Some((state, path)) = handle.pop() {
+                for evt in <TestEvent<RetX, RetY>>::exhaustive() {
+                    if let Ok(next) = state.clone().perform_test_event(&evt) {
+                        if seen.insert(next.clone()) {
+                            let mut evts = path.clone();
+                            evts.events.push(evt);
+                            paths.push((next.clone(), evts.clone()));
+                            handle.push((next, evts));
+                        }
+                    }
+                }
+            }
+            paths.into_iter()
+        }
+    }
+
+    impl LocStateProtPair {
+        #[rustfmt::skip]
+        /// Two states (by convention `self` is the source and `other` is the target)
+        /// are "distinguishable" if there exists a sequence of instructions
+        /// that causes UB in the target but not in the source.
+        /// This implementation simply explores the reachable space
+        /// by all sequences of `TestEvent`.
+        /// This function can be instanciated with `RetX` and `RetY`
+        /// among `NoRet` or `AllowRet` to resp. forbid/allow `x`/`y` to lose their
+        /// protector.
+        fn distinguishable<RetX, RetY>(&self, other: &Self) -> bool
+        where
+            RetX: Exhaustive + 'static,
+            RetY: Exhaustive + 'static,
+        {
+            if self == other { return false; }
+            let mut states = vec![(self.clone(), other.clone())];
+            let mut seen = FxHashSet::default();
+            while let Some(state) = states.pop() {
+                if !seen.insert(state.clone()) { continue; };
+                let (source, target) = state;
+                for evt in <TestEvent<RetX, RetY>>::exhaustive() {
+                    // Generate successor states through events (accesses and protector ends)
+                    let Ok(new_source) = source.clone().perform_test_event(&evt) else { continue; };
+                    let Ok(new_target) = target.clone().perform_test_event(&evt) else { return true; };
+                    if new_source == new_target { continue; }
+                    states.push((new_source, new_target));
+                }
+            }
+            false
+        }
+    }
+
+    #[test]
+    #[should_panic]
+    // This is why `Reserved -> Frozen` on foreign read for protected references
+    // prevents the insertion of spurious reads: the transition can cause UB in the target
+    // later down the line.
+    fn reserved_frozen_protected_distinguishable() {
+        let source = LocStateProtPair {
+            xy_rel: RelPosXY::MutuallyForeign,
+            x: LocStateProt {
+                state: LocationState::new(Permission::new_frozen()).with_access(),
+                prot: true,
+            },
+            y: LocStateProt {
+                state: LocationState::new(Permission::new_reserved(false)),
+                prot: true,
+            },
+        };
+        let acc = TestAccess { ptr: PtrSelector::X, kind: AccessKind::Read };
+        let target = source.clone().perform_test_access(&acc).unwrap();
+        assert!(source.y.state.permission.is_reserved(None));
+        assert!(target.y.state.permission.is_frozen());
+        assert!(!source.distinguishable::<(), ()>(&target))
+    }
+
+    #[derive(Clone, Debug)]
+    struct Pattern {
+        /// The relative position of `x` and `y` at the beginning of the arbitrary
+        /// code (i.e., just after `x` got created).
+        /// Might change during the execution if said arbitrary code contains any `retag y`.
+        xy_rel: RelPosXY,
+        /// Permission that `x` will be created as
+        /// (always protected until a possible `ret x` in the second phase).
+        /// This one should be initial (as per `is_initial`).
+        x_retag_perm: LocationState,
+        /// Permission that `y` has at the beginning of the pattern.
+        /// Can be any state, not necessarily initial
+        /// (since `y` exists already before the pattern starts).
+        /// This state might be reset during the execution if the opaque code
+        /// contains any `retag y`, but only to an initial state this time.
+        y_current_perm: LocationState,
+        /// Whether `y` starts with a protector.
+        /// Might change if the opaque code contains any `ret y`.
+        y_protected: bool,
+    }
+
+    impl Exhaustive for Pattern {
+        fn exhaustive() -> Box<dyn Iterator<Item = Self>> {
+            let mut v = Vec::new();
+            for xy_rel in RelPosXY::exhaustive() {
+                for (x_retag_perm, y_current_perm) in <(LocationState, LocationState)>::exhaustive()
+                {
+                    // We can only do spurious reads for initialized locations anyway.
+                    precondition!(x_retag_perm.initialized);
+                    // And `x` just got retagged, so it must be initial.
+                    precondition!(x_retag_perm.permission.is_initial());
+                    for y_protected in bool::exhaustive() {
+                        v.push(Pattern { xy_rel, x_retag_perm, y_current_perm, y_protected });
+                    }
+                }
+            }
+            Box::new(v.into_iter())
+        }
+    }
+
+    impl fmt::Display for Pattern {
+        fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+            let (x, y) = self.retag_permissions();
+            write!(f, "{}; ", self.xy_rel)?;
+            write!(f, "y: ({}); ", y,)?;
+            write!(f, "retag x ({}); ", x)?;
+
+            write!(f, "<arbitrary code>; <spurious read x>;")?;
+            Ok(())
+        }
+    }
+
+    impl Pattern {
+        /// Return the permission that `y` starts as, and the permission that we
+        /// will retag `x` with.
+        /// This does not yet include a possible read-on-reborrow through `x`.
+        fn retag_permissions(&self) -> (LocStateProt, LocStateProt) {
+            let x = LocStateProt { state: self.x_retag_perm, prot: true };
+            let y = LocStateProt { state: self.y_current_perm, prot: self.y_protected };
+            (x, y)
+        }
+
+        /// State that the pattern deterministically produces immediately after
+        /// the retag of `x`.
+        fn initial_state(&self) -> Result<LocStateProtPair, ()> {
+            let (x, y) = self.retag_permissions();
+            let state = LocStateProtPair { xy_rel: self.xy_rel, x, y };
+            state.read_if_initialized(PtrSelector::X)
+        }
+    }
+
+    #[test]
+    #[should_panic]
+    /// For each of the patterns described above, execute it once
+    /// as-is, and once with a spurious read inserted. Report any UB
+    /// in the target but not in the source.
+    fn test_all_patterns() {
+        let mut ok = 0;
+        let mut err = 0;
+        for pat in Pattern::exhaustive() {
+            let Ok(initial_source) = pat.initial_state() else {
+                // Failed to retag `x` in the source (e.g. `y` was protected Active)
+                continue;
+            };
+            // `x` must stay protected, but the function protecting `y` might return here
+            for (final_source, opaque) in
+                initial_source.all_states_reachable_via_opaque_code::</*X*/ NoRet, /*Y*/ AllowRet>()
+            {
+                // Both executions are identical up to here.
+                // Now we do nothing in the source and in the target we do a spurious read.
+                // Then we check if the resulting states are distinguishable.
+                let distinguishable = {
+                    assert!(final_source.x.prot);
+                    let spurious_read = TestAccess { ptr: PtrSelector::X, kind: AccessKind::Read };
+                    if let Ok(final_target) =
+                        final_source.clone().perform_test_access(&spurious_read)
+                    {
+                        // Only after the spurious read has been executed can `x` lose its
+                        // protector.
+                        final_source
+                            .distinguishable::</*X*/ AllowRet, /*Y*/ AllowRet>(&final_target)
+                            .then_some(format!("{}", final_target))
+                    } else {
+                        Some(format!("UB"))
+                    }
+                };
+                if let Some(final_target) = distinguishable {
+                    eprintln!(
+                        "For pattern '{}', inserting a spurious read through x makes the final state '{}' instead of '{}' which is observable",
+                        pat, final_target, final_source
+                    );
+                    eprintln!("  (arbitrary code instanciated with '{}')", opaque);
+                    err += 1;
+                    // We found an instanciation of the opaque code that makes this Pattern
+                    // fail, we don't really need to check the rest.
+                    break;
+                }
+                ok += 1;
+            }
+        }
+        if err > 0 {
+            panic!(
+                "Test failed after {}/{} patterns had UB in the target but not the source",
+                err,
+                ok + err
+            )
+        }
+    }
+}
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 537c767065d..fd9d57c487c 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -1,5 +1,3 @@
-pub mod convert;
-
 use std::cmp;
 use std::iter;
 use std::num::NonZeroUsize;
@@ -1033,7 +1031,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 ) {
                     // Floating point value is NaN (flagged with INVALID_OP) or outside the range
                     // of values of the integer type (flagged with OVERFLOW or UNDERFLOW).
-                    return None
+                    return None;
                 } else {
                     // Floating point value can be represented by the integer type after rounding.
                     // The INEXACT flag is ignored on purpose to allow rounding.
@@ -1051,7 +1049,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 ) {
                     // Floating point value is NaN (flagged with INVALID_OP) or outside the range
                     // of values of the integer type (flagged with OVERFLOW or UNDERFLOW).
-                    return None
+                    return None;
                 } else {
                     // Floating point value can be represented by the integer type after rounding.
                     // The INEXACT flag is ignored on purpose to allow rounding.
diff --git a/src/tools/miri/src/helpers/convert.rs b/src/tools/miri/src/helpers/convert.rs
deleted file mode 100644
index 4506fe47495..00000000000
--- a/src/tools/miri/src/helpers/convert.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-use implementations::NarrowerThan;
-
-/// Replacement for `as` casts going from wide integer to narrower integer.
-///
-/// # Example
-///
-/// ```ignore
-/// let x = 99_u64;
-/// let lo = x.truncate::<u16>();
-/// // lo is of type u16, equivalent to `x as u16`.
-/// ```
-pub(crate) trait Truncate: Sized {
-    fn truncate<To>(self) -> To
-    where
-        To: NarrowerThan<Self>,
-    {
-        NarrowerThan::truncate_from(self)
-    }
-}
-
-impl Truncate for u16 {}
-impl Truncate for u32 {}
-impl Truncate for u64 {}
-impl Truncate for u128 {}
-
-mod implementations {
-    pub(crate) trait NarrowerThan<T> {
-        fn truncate_from(wide: T) -> Self;
-    }
-
-    macro_rules! impl_narrower_than {
-        ($(NarrowerThan<{$($ty:ty),*}> for $self:ty)*) => {
-            $($(
-                impl NarrowerThan<$ty> for $self {
-                    fn truncate_from(wide: $ty) -> Self {
-                        wide as Self
-                    }
-                }
-            )*)*
-        };
-    }
-
-    impl_narrower_than! {
-        NarrowerThan<{u128, u64, u32, u16}> for u8
-        NarrowerThan<{u128, u64, u32}> for u16
-        NarrowerThan<{u128, u64}> for u32
-        NarrowerThan<{u128}> for u64
-    }
-}
diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs
index 27fe7374ea5..1faf8f9fc12 100644
--- a/src/tools/miri/src/operator.rs
+++ b/src/tools/miri/src/operator.rs
@@ -65,12 +65,16 @@ impl<'mir, 'tcx> EvalContextExt<'tcx> for super::MiriInterpCx<'mir, 'tcx> {
                     right.to_scalar().to_target_usize(self)?,
                     self.machine.layouts.usize,
                 );
-                let (result, overflowing) =
-                    self.overflowing_binary_op(bin_op, &left, &right)?;
+                let (result, overflowing) = self.overflowing_binary_op(bin_op, &left, &right)?;
                 // Construct a new pointer with the provenance of `ptr` (the LHS).
-                let result_ptr =
-                    Pointer::new(ptr.provenance, Size::from_bytes(result.to_scalar().to_target_usize(self)?));
-                (ImmTy::from_scalar(Scalar::from_maybe_pointer(result_ptr, self), left.layout), overflowing)
+                let result_ptr = Pointer::new(
+                    ptr.provenance,
+                    Size::from_bytes(result.to_scalar().to_target_usize(self)?),
+                );
+                (
+                    ImmTy::from_scalar(Scalar::from_maybe_pointer(result_ptr, self), left.layout),
+                    overflowing,
+                )
             }
 
             _ => span_bug!(self.cur_span(), "Invalid operator on pointers: {:?}", bin_op),
diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs
index 836cab3ac9d..ee2edd462d1 100644
--- a/src/tools/miri/src/shims/backtrace.rs
+++ b/src/tools/miri/src/shims/backtrace.rs
@@ -88,10 +88,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     this.write_pointer(ptr, &place)?;
                 }
 
-                this.write_immediate(
-                    Immediate::new_slice(alloc.ptr(), len, this),
-                    dest,
-                )?;
+                this.write_immediate(Immediate::new_slice(alloc.ptr(), len, this), dest)?;
             }
             // storage for pointers is allocated by the caller
             1 => {
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 0e8eaf450e4..0c92ede40fd 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -22,7 +22,7 @@ use rustc_target::{
 };
 
 use super::backtrace::EvalContextExt as _;
-use crate::helpers::{convert::Truncate, target_os_is_unix};
+use crate::helpers::target_os_is_unix;
 use crate::*;
 
 /// Returned by `emulate_foreign_item_by_name`.
@@ -981,30 +981,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     throw_unsup_format!("unsupported `llvm.prefetch` type argument: {}", ty);
                 }
             }
-            "llvm.x86.addcarry.64" if this.tcx.sess.target.arch == "x86_64" => {
-                // Computes u8+u64+u64, returning tuple (u8,u64) comprising the output carry and truncated sum.
-                let [c_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
-                let c_in = this.read_scalar(c_in)?.to_u8()?;
-                let a = this.read_scalar(a)?.to_u64()?;
-                let b = this.read_scalar(b)?.to_u64()?;
-
-                #[allow(clippy::arithmetic_side_effects)]
-                // adding two u64 and a u8 cannot wrap in a u128
-                let wide_sum = u128::from(c_in) + u128::from(a) + u128::from(b);
-                #[allow(clippy::arithmetic_side_effects)] // it's a u128, we can shift by 64
-                let (c_out, sum) = ((wide_sum >> 64).truncate::<u8>(), wide_sum.truncate::<u64>());
-
-                let c_out_field = this.project_field(dest, 0)?;
-                this.write_scalar(Scalar::from_u8(c_out), &c_out_field)?;
-                let sum_field = this.project_field(dest, 1)?;
-                this.write_scalar(Scalar::from_u64(sum), &sum_field)?;
-            }
-            "llvm.x86.sse2.pause"
-                if this.tcx.sess.target.arch == "x86" || this.tcx.sess.target.arch == "x86_64" =>
-            {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
-                this.yield_active_thread();
-            }
+            // FIXME: Move these to an `arm` submodule.
             "llvm.aarch64.isb" if this.tcx.sess.target.arch == "aarch64" => {
                 let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
                 let arg = this.read_scalar(arg)?.to_i32()?;
@@ -1032,13 +1009,34 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 }
             }
 
-            name if name.starts_with("llvm.x86.sse.") => {
-                return shims::x86::sse::EvalContextExt::emulate_x86_sse_intrinsic(
-                    this, link_name, abi, args, dest,
-                );
+            // Used to implement the x86 `_mm{,256,512}_popcnt_epi{8,16,32,64}` and wasm
+            // `{i,u}8x16_popcnt` functions.
+            name if name.starts_with("llvm.ctpop.v") => {
+                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+
+                let (op, op_len) = this.operand_to_simd(op)?;
+                let (dest, dest_len) = this.place_to_simd(dest)?;
+
+                assert_eq!(dest_len, op_len);
+
+                for i in 0..dest_len {
+                    let op = this.read_immediate(&this.project_index(&op, i)?)?;
+                    // Use `to_uint` to get a zero-extended `u128`. Those
+                    // extra zeros will not affect `count_ones`.
+                    let res = op.to_scalar().to_uint(op.layout.size)?.count_ones();
+
+                    this.write_scalar(
+                        Scalar::from_uint(res, op.layout.size),
+                        &this.project_index(&dest, i)?,
+                    )?;
+                }
             }
-            name if name.starts_with("llvm.x86.sse2.") => {
-                return shims::x86::sse2::EvalContextExt::emulate_x86_sse2_intrinsic(
+
+            name if name.starts_with("llvm.x86.")
+                && (this.tcx.sess.target.arch == "x86"
+                    || this.tcx.sess.target.arch == "x86_64") =>
+            {
+                return shims::x86::EvalContextExt::emulate_x86_intrinsic(
                     this, link_name, abi, args, dest,
                 );
             }
diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs
index d54145dbdc7..063f74f989d 100644
--- a/src/tools/miri/src/shims/intrinsics/mod.rs
+++ b/src/tools/miri/src/shims/intrinsics/mod.rs
@@ -60,7 +60,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         }
 
         // The rest jumps to `ret` immediately.
-        this.emulate_intrinsic_by_name(intrinsic_name, args, dest)?;
+        this.emulate_intrinsic_by_name(intrinsic_name, instance.args, args, dest)?;
 
         trace!("{:?}", this.dump_place(dest));
         this.go_to_block(ret);
@@ -71,6 +71,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     fn emulate_intrinsic_by_name(
         &mut self,
         intrinsic_name: &str,
+        generic_args: ty::GenericArgsRef<'tcx>,
         args: &[OpTy<'tcx, Provenance>],
         dest: &PlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx> {
@@ -80,7 +81,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             return this.emulate_atomic_intrinsic(name, args, dest);
         }
         if let Some(name) = intrinsic_name.strip_prefix("simd_") {
-            return this.emulate_simd_intrinsic(name, args, dest);
+            return this.emulate_simd_intrinsic(name, generic_args, args, dest);
         }
 
         match intrinsic_name {
diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs
index 49ba7e5556e..5e488679b81 100644
--- a/src/tools/miri/src/shims/intrinsics/simd.rs
+++ b/src/tools/miri/src/shims/intrinsics/simd.rs
@@ -12,6 +12,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     fn emulate_simd_intrinsic(
         &mut self,
         intrinsic_name: &str,
+        generic_args: ty::GenericArgsRef<'tcx>,
         args: &[OpTy<'tcx, Provenance>],
         dest: &PlaceTy<'tcx, Provenance>,
     ) -> InterpResult<'tcx> {
@@ -458,7 +459,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                                         dest.layout.ty
                                     )
                                 })?
-                                .into()
                         }
                         (ty::Float(FloatTy::F64), ty::Int(_) | ty::Uint(_)) if unsafe_cast => {
                             let f = op.to_scalar().to_f64()?;
@@ -469,7 +469,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                                         dest.layout.ty
                                     )
                                 })?
-                                .into()
                         }
                         // Ptr-to-ptr cast
                         (ty::RawPtr(..), ty::RawPtr(..)) if ptr_cast =>
@@ -490,6 +489,38 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     this.write_immediate(*val, &dest)?;
                 }
             }
+            "shuffle_generic" => {
+                let [left, right] = check_arg_count(args)?;
+                let (left, left_len) = this.operand_to_simd(left)?;
+                let (right, right_len) = this.operand_to_simd(right)?;
+                let (dest, dest_len) = this.place_to_simd(dest)?;
+
+                let index = generic_args[2].expect_const().eval(*this.tcx, this.param_env(), Some(this.tcx.span)).unwrap().unwrap_branch();
+                let index_len = index.len();
+
+                assert_eq!(left_len, right_len);
+                assert_eq!(index_len as u64, dest_len);
+
+                for i in 0..dest_len {
+                    let src_index: u64 = index[i as usize].unwrap_leaf()
+                        .try_to_u32().unwrap()
+                        .into();
+                    let dest = this.project_index(&dest, i)?;
+
+                    let val = if src_index < left_len {
+                        this.read_immediate(&this.project_index(&left, src_index)?)?
+                    } else if src_index < left_len.checked_add(right_len).unwrap() {
+                        let right_idx = src_index.checked_sub(left_len).unwrap();
+                        this.read_immediate(&this.project_index(&right, right_idx)?)?
+                    } else {
+                        span_bug!(
+                            this.cur_span(),
+                            "simd_shuffle index {src_index} is out of bounds for 2 vectors of size {left_len}",
+                        );
+                    };
+                    this.write_immediate(*val, &dest)?;
+                }
+            }
             "shuffle" => {
                 let [left, right, index] = check_arg_count(args)?;
                 let (left, left_len) = this.operand_to_simd(left)?;
diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs
index cbdc500be78..fbfe00e03db 100644
--- a/src/tools/miri/src/shims/x86/mod.rs
+++ b/src/tools/miri/src/shims/x86/mod.rs
@@ -1,11 +1,98 @@
 use rustc_middle::mir;
+use rustc_span::Symbol;
 use rustc_target::abi::Size;
+use rustc_target::spec::abi::Abi;
 
 use crate::*;
 use helpers::bool_to_simd_element;
+use shims::foreign_items::EmulateByNameResult;
 
-pub(super) mod sse;
-pub(super) mod sse2;
+mod sse;
+mod sse2;
+
+impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
+pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
+    crate::MiriInterpCxExt<'mir, 'tcx>
+{
+    fn emulate_x86_intrinsic(
+        &mut self,
+        link_name: Symbol,
+        abi: Abi,
+        args: &[OpTy<'tcx, Provenance>],
+        dest: &PlaceTy<'tcx, Provenance>,
+    ) -> InterpResult<'tcx, EmulateByNameResult<'mir, 'tcx>> {
+        let this = self.eval_context_mut();
+        // Prefix should have already been checked.
+        let unprefixed_name = link_name.as_str().strip_prefix("llvm.x86.").unwrap();
+        match unprefixed_name {
+            // Used to implement the `_addcarry_u32` and `_addcarry_u64` functions.
+            // Computes a + b with input and output carry. The input carry is an 8-bit
+            // value, which is interpreted as 1 if it is non-zero. The output carry is
+            // an 8-bit value that will be 0 or 1.
+            // https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/addcarry-u32-addcarry-u64.html
+            "addcarry.32" | "addcarry.64" => {
+                if unprefixed_name == "addcarry.64" && this.tcx.sess.target.arch != "x86_64" {
+                    return Ok(EmulateByNameResult::NotSupported);
+                }
+
+                let [c_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
+                let c_in = this.read_scalar(c_in)?.to_u8()? != 0;
+                let a = this.read_immediate(a)?;
+                let b = this.read_immediate(b)?;
+
+                let (sum, overflow1) = this.overflowing_binary_op(mir::BinOp::Add, &a, &b)?;
+                let (sum, overflow2) = this.overflowing_binary_op(
+                    mir::BinOp::Add,
+                    &sum,
+                    &ImmTy::from_uint(c_in, a.layout),
+                )?;
+                let c_out = overflow1 | overflow2;
+
+                this.write_scalar(Scalar::from_u8(c_out.into()), &this.project_field(dest, 0)?)?;
+                this.write_immediate(*sum, &this.project_field(dest, 1)?)?;
+            }
+            // Used to implement the `_subborrow_u32` and `_subborrow_u64` functions.
+            // Computes a - b with input and output borrow. The input borrow is an 8-bit
+            // value, which is interpreted as 1 if it is non-zero. The output borrow is
+            // an 8-bit value that will be 0 or 1.
+            // https://www.intel.com/content/www/us/en/docs/cpp-compiler/developer-guide-reference/2021-8/subborrow-u32-subborrow-u64.html
+            "subborrow.32" | "subborrow.64" => {
+                if unprefixed_name == "subborrow.64" && this.tcx.sess.target.arch != "x86_64" {
+                    return Ok(EmulateByNameResult::NotSupported);
+                }
+
+                let [b_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
+                let b_in = this.read_scalar(b_in)?.to_u8()? != 0;
+                let a = this.read_immediate(a)?;
+                let b = this.read_immediate(b)?;
+
+                let (sub, overflow1) = this.overflowing_binary_op(mir::BinOp::Sub, &a, &b)?;
+                let (sub, overflow2) = this.overflowing_binary_op(
+                    mir::BinOp::Sub,
+                    &sub,
+                    &ImmTy::from_uint(b_in, a.layout),
+                )?;
+                let b_out = overflow1 | overflow2;
+
+                this.write_scalar(Scalar::from_u8(b_out.into()), &this.project_field(dest, 0)?)?;
+                this.write_immediate(*sub, &this.project_field(dest, 1)?)?;
+            }
+
+            name if name.starts_with("sse.") => {
+                return sse::EvalContextExt::emulate_x86_sse_intrinsic(
+                    this, link_name, abi, args, dest,
+                );
+            }
+            name if name.starts_with("sse2.") => {
+                return sse2::EvalContextExt::emulate_x86_sse2_intrinsic(
+                    this, link_name, abi, args, dest,
+                );
+            }
+            _ => return Ok(EmulateByNameResult::NotSupported),
+        }
+        Ok(EmulateByNameResult::NeedsJumping)
+    }
+}
 
 /// Floating point comparison operation
 ///
diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs
index b6b994b45ac..de1e695b6d1 100644
--- a/src/tools/miri/src/shims/x86/sse.rs
+++ b/src/tools/miri/src/shims/x86/sse.rs
@@ -10,7 +10,9 @@ use crate::*;
 use shims::foreign_items::EmulateByNameResult;
 
 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
-pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
+pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
+    crate::MiriInterpCxExt<'mir, 'tcx>
+{
     fn emulate_x86_sse_intrinsic(
         &mut self,
         link_name: Symbol,
diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs
index 7e10d1d3726..2ca882167bf 100644
--- a/src/tools/miri/src/shims/x86/sse2.rs
+++ b/src/tools/miri/src/shims/x86/sse2.rs
@@ -13,7 +13,9 @@ use crate::*;
 use shims::foreign_items::EmulateByNameResult;
 
 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
-pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
+pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
+    crate::MiriInterpCxExt<'mir, 'tcx>
+{
     fn emulate_x86_sse2_intrinsic(
         &mut self,
         link_name: Symbol,
@@ -61,11 +63,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     let right = this.int_to_int_or_float(&right, twice_wide)?;
 
                     // Calculate left + right + 1
-                    let added = this.wrapping_binary_op(
-                        mir::BinOp::Add,
-                        &left,
-                        &right,
-                    )?;
+                    let added = this.wrapping_binary_op(mir::BinOp::Add, &left, &right)?;
                     let added = this.wrapping_binary_op(
                         mir::BinOp::Add,
                         &added,
@@ -80,10 +78,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     )?;
 
                     // Narrow back to the original type
-                    let res = this.int_to_int_or_float(
-                        &divided,
-                        dest.layout,
-                    )?;
+                    let res = this.int_to_int_or_float(&divided, dest.layout)?;
                     this.write_immediate(*res, &dest)?;
                 }
             }
@@ -110,11 +105,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     let right = this.int_to_int_or_float(&right, twice_wide)?;
 
                     // Multiply
-                    let multiplied = this.wrapping_binary_op(
-                        mir::BinOp::Mul,
-                        &left,
-                        &right,
-                    )?;
+                    let multiplied = this.wrapping_binary_op(mir::BinOp::Mul, &left, &right)?;
                     // Keep the high half
                     let high = this.wrapping_binary_op(
                         mir::BinOp::Shr,
@@ -123,10 +114,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     )?;
 
                     // Narrow back to the original type
-                    let res = this.int_to_int_or_float(
-                        &high,
-                        dest.layout,
-                    )?;
+                    let res = this.int_to_int_or_float(&high, dest.layout)?;
                     this.write_immediate(*res, &dest)?;
                 }
             }
@@ -424,8 +412,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     let right_res =
                         i8::try_from(right).unwrap_or(if right < 0 { i8::MIN } else { i8::MAX });
 
-                    this.write_scalar(Scalar::from_i8(left_res.try_into().unwrap()), &left_dest)?;
-                    this.write_scalar(Scalar::from_i8(right_res.try_into().unwrap()), &right_dest)?;
+                    this.write_scalar(Scalar::from_i8(left_res), &left_dest)?;
+                    this.write_scalar(Scalar::from_i8(right_res), &right_dest)?;
                 }
             }
             // Used to implement the _mm_packus_epi16 function.
@@ -485,11 +473,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     let right_res =
                         i16::try_from(right).unwrap_or(if right < 0 { i16::MIN } else { i16::MAX });
 
-                    this.write_scalar(Scalar::from_i16(left_res.try_into().unwrap()), &left_dest)?;
-                    this.write_scalar(
-                        Scalar::from_i16(right_res.try_into().unwrap()),
-                        &right_dest,
-                    )?;
+                    this.write_scalar(Scalar::from_i16(left_res), &left_dest)?;
+                    this.write_scalar(Scalar::from_i16(right_res), &right_dest)?;
                 }
             }
             // Used to implement _mm_min_sd and _mm_max_sd functions.
@@ -770,6 +755,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
                 this.write_scalar(Scalar::from_u32(res.try_into().unwrap()), dest)?;
             }
+            // Used to implement the `_mm_pause` function.
+            // The intrinsic is used to hint the processor that the code is in a spin-loop.
+            "pause" => {
+                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                this.yield_active_thread();
+            }
             _ => return Ok(EmulateByNameResult::NotSupported),
         }
         Ok(EmulateByNameResult::NeedsJumping)
diff --git a/src/tools/miri/tests/compiletest.rs b/src/tools/miri/tests/compiletest.rs
index 78dd3df01ec..035846f0ef9 100644
--- a/src/tools/miri/tests/compiletest.rs
+++ b/src/tools/miri/tests/compiletest.rs
@@ -1,10 +1,11 @@
 use colored::*;
 use regex::bytes::Regex;
 use std::ffi::OsString;
+use std::num::NonZeroUsize;
 use std::path::{Path, PathBuf};
 use std::{env, process::Command};
 use ui_test::{color_eyre::Result, Config, Match, Mode, OutputConflictHandling};
-use ui_test::{status_emitter, CommandBuilder};
+use ui_test::{status_emitter, CommandBuilder, Format, RustfixMode};
 
 fn miri_path() -> PathBuf {
     PathBuf::from(option_env!("MIRI").unwrap_or(env!("CARGO_BIN_EXE_miri")))
@@ -78,26 +79,18 @@ fn test_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) ->
         program.args.push(flag);
     }
 
-    let bless = env::var_os("RUSTC_BLESS").is_some_and(|v| v != "0");
-    let skip_ui_checks = env::var_os("MIRI_SKIP_UI_CHECKS").is_some();
-
-    let output_conflict_handling = match (bless, skip_ui_checks) {
-        (false, false) => OutputConflictHandling::Error("./miri test --bless".into()),
-        (true, false) => OutputConflictHandling::Bless,
-        (false, true) => OutputConflictHandling::Ignore,
-        (true, true) => panic!("cannot use RUSTC_BLESS and MIRI_SKIP_UI_CHECKS at the same time"),
-    };
-
     let mut config = Config {
         target: Some(target.to_owned()),
         stderr_filters: STDERR.clone(),
         stdout_filters: STDOUT.clone(),
         mode,
         program,
-        output_conflict_handling,
         out_dir: PathBuf::from(std::env::var_os("CARGO_TARGET_DIR").unwrap()).join("ui"),
         edition: Some("2021".into()),
-        ..Config::rustc(path.into())
+        threads: std::env::var("MIRI_TEST_THREADS")
+            .ok()
+            .map(|threads| NonZeroUsize::new(threads.parse().unwrap()).unwrap()),
+        ..Config::rustc(path)
     };
 
     let use_std = env::var_os("MIRI_NO_STD").is_none();
@@ -120,51 +113,32 @@ fn test_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) ->
 }
 
 fn run_tests(mode: Mode, path: &str, target: &str, with_dependencies: bool) -> Result<()> {
-    let config = test_config(target, path, mode, with_dependencies);
+    let mut config = test_config(target, path, mode, with_dependencies);
 
     // Handle command-line arguments.
-    let mut after_dashdash = false;
-    let mut quiet = false;
-    let filters = std::env::args()
-        .skip(1)
-        .filter(|arg| {
-            if after_dashdash {
-                // Just propagate everything.
-                return true;
-            }
-            match &**arg {
-                "--quiet" => {
-                    quiet = true;
-                    false
-                }
-                "--" => {
-                    after_dashdash = true;
-                    false
-                }
-                s if s.starts_with('-') => {
-                    panic!("unknown compiletest flag `{s}`");
-                }
-                _ => true,
-            }
-        })
-        .collect::<Vec<_>>();
+    let args = ui_test::Args::test()?;
+    let default_bless = env::var_os("RUSTC_BLESS").is_some_and(|v| v != "0");
+    config.with_args(&args, default_bless);
+    if let OutputConflictHandling::Error(msg) = &mut config.output_conflict_handling {
+        *msg = "./miri test --bless".into();
+    }
+    if env::var_os("MIRI_SKIP_UI_CHECKS").is_some() {
+        assert!(!default_bless, "cannot use RUSTC_BLESS and MIRI_SKIP_UI_CHECKS at the same time");
+        config.output_conflict_handling = OutputConflictHandling::Ignore;
+    }
     eprintln!("   Compiler: {}", config.program.display());
     ui_test::run_tests_generic(
-        config,
+        // Only run one test suite. In the future we can add all test suites to one `Vec` and run
+        // them all at once, making best use of systems with high parallelism.
+        vec![config],
         // The files we're actually interested in (all `.rs` files).
-        |path| {
-            path.extension().is_some_and(|ext| ext == "rs")
-                && (filters.is_empty()
-                    || filters.iter().any(|f| path.display().to_string().contains(f)))
-        },
+        ui_test::default_file_filter,
         // This could be used to overwrite the `Config` on a per-test basis.
-        |_, _| None,
+        |_, _, _| {},
         (
-            if quiet {
-                Box::<status_emitter::Quiet>::default()
-                    as Box<dyn status_emitter::StatusEmitter + Send>
-            } else {
-                Box::new(status_emitter::Text)
+            match args.format {
+                Format::Terse => status_emitter::Text::quiet(),
+                Format::Pretty => status_emitter::Text::verbose(),
             },
             status_emitter::Gha::</* GHA Actions groups*/ false> {
                 name: format!("{mode:?} {path} ({target})"),
@@ -205,8 +179,6 @@ regexes! {
     r" +at (.*\.rs)"                 => " at $1",
     // erase generics in backtraces
     "([0-9]+: .*)::<.*>"             => "$1",
-    // erase addresses in backtraces
-    "([0-9]+: ) +0x[0-9a-f]+ - (.*)" => "$1$2",
     // erase long hexadecimals
     r"0x[0-9a-fA-F]+[0-9a-fA-F]{2,2}" => "$$HEX",
     // erase specific alignments
@@ -218,7 +190,7 @@ regexes! {
     // Windows file paths
     r"\\"                           => "/",
     // erase Rust stdlib path
-    "[^ `]*/(rust[^/]*|checkout)/library/" => "RUSTLIB/",
+    "[^ \n`]*/(rust[^/]*|checkout)/library/" => "RUSTLIB/",
     // erase platform file paths
     "sys/[a-z]+/"                    => "sys/PLATFORM/",
     // erase paths into the crate registry
@@ -269,11 +241,22 @@ fn main() -> Result<()> {
     ui(Mode::Pass, "tests/pass", &target, WithoutDependencies)?;
     ui(Mode::Pass, "tests/pass-dep", &target, WithDependencies)?;
     ui(Mode::Panic, "tests/panic", &target, WithDependencies)?;
-    ui(Mode::Fail { require_patterns: true }, "tests/fail", &target, WithDependencies)?;
+    ui(
+        Mode::Fail { require_patterns: true, rustfix: RustfixMode::Disabled },
+        "tests/fail",
+        &target,
+        WithoutDependencies,
+    )?;
+    ui(
+        Mode::Fail { require_patterns: true, rustfix: RustfixMode::Disabled },
+        "tests/fail-dep",
+        &target,
+        WithDependencies,
+    )?;
     if cfg!(target_os = "linux") {
         ui(Mode::Pass, "tests/extern-so/pass", &target, WithoutDependencies)?;
         ui(
-            Mode::Fail { require_patterns: true },
+            Mode::Fail { require_patterns: true, rustfix: RustfixMode::Disabled },
             "tests/extern-so/fail",
             &target,
             WithoutDependencies,
@@ -285,11 +268,17 @@ fn main() -> Result<()> {
 
 fn run_dep_mode(target: String, mut args: impl Iterator<Item = OsString>) -> Result<()> {
     let path = args.next().expect("./miri run-dep must be followed by a file name");
-    let mut config = test_config(&target, "", Mode::Yolo, /* with dependencies */ true);
+    let mut config = test_config(
+        &target,
+        "",
+        Mode::Yolo { rustfix: RustfixMode::Disabled },
+        /* with dependencies */ true,
+    );
     config.program.args.clear(); // We want to give the user full control over flags
-    config.build_dependencies_and_link_them()?;
+    let dep_args = config.build_dependencies()?;
 
     let mut cmd = config.program.build(&config.out_dir);
+    cmd.args(dep_args);
 
     cmd.arg(path);
 
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.rs
index 7e6f490bb3d..7e6f490bb3d 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.rs
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.stderr
index c5093c0e601..c5093c0e601 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_main_terminate.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_main_terminate.stderr
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs
index e1d3704af7c..e1d3704af7c 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.rs
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr
index c2de4afd68f..c2de4afd68f 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_few_args.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_few_args.stderr
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs
index 7408634db52..7408634db52 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.rs
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr
index 85ae930d439..85ae930d439 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_create_too_many_args.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_create_too_many_args.stderr
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_detached.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.rs
index 0b810dc8c72..0b810dc8c72 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_detached.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.rs
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_detached.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.stderr
index 763e0d3665d..763e0d3665d 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_detached.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_detached.stderr
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_joined.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.rs
index 04ca4bbb3f6..04ca4bbb3f6 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_joined.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.rs
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_joined.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.stderr
index a3253e2ef93..a3253e2ef93 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_joined.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_joined.stderr
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_main.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.rs
index 75765182163..75765182163 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_main.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.rs
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_main.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr
index 09e14d46a96..09e14d46a96 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_main.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_main.stderr
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_multiple.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.rs
index 966f416eeac..966f416eeac 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_multiple.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.rs
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_multiple.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr
index db5d7bfd5da..db5d7bfd5da 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_multiple.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_multiple.stderr
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_self.rs b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.rs
index 0c25c690f37..0c25c690f37 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_self.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.rs
diff --git a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_self.stderr b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr
index 8db4a83f9ce..8db4a83f9ce 100644
--- a/src/tools/miri/tests/fail/concurrency/libc_pthread_join_self.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/libc_pthread_join_self.stderr
diff --git a/src/tools/miri/tests/fail/concurrency/unwind_top_of_stack.rs b/src/tools/miri/tests/fail-dep/concurrency/unwind_top_of_stack.rs
index 4704cfed039..4704cfed039 100644
--- a/src/tools/miri/tests/fail/concurrency/unwind_top_of_stack.rs
+++ b/src/tools/miri/tests/fail-dep/concurrency/unwind_top_of_stack.rs
diff --git a/src/tools/miri/tests/fail/concurrency/unwind_top_of_stack.stderr b/src/tools/miri/tests/fail-dep/concurrency/unwind_top_of_stack.stderr
index ceb5955922a..fccd3fbbc9d 100644
--- a/src/tools/miri/tests/fail/concurrency/unwind_top_of_stack.stderr
+++ b/src/tools/miri/tests/fail-dep/concurrency/unwind_top_of_stack.stderr
@@ -1,3 +1,5 @@
+WARNING: the flag `-Zmiri-disable-abi-check` is deprecated and planned to be removed.
+If you have a use-case for it, please file an issue.
 thread '<unnamed>' panicked at $DIR/unwind_top_of_stack.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/src/tools/miri/tests/fail/shims/fs/close_stdout.rs b/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.rs
index 09da8509af4..09da8509af4 100644
--- a/src/tools/miri/tests/fail/shims/fs/close_stdout.rs
+++ b/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.rs
diff --git a/src/tools/miri/tests/fail/shims/fs/close_stdout.stderr b/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr
index 02f1eee97fc..02f1eee97fc 100644
--- a/src/tools/miri/tests/fail/shims/fs/close_stdout.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/fs/close_stdout.stderr
diff --git a/src/tools/miri/tests/fail/shims/fs/isolated_stdin.rs b/src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.rs
index a45f805696d..a45f805696d 100644
--- a/src/tools/miri/tests/fail/shims/fs/isolated_stdin.rs
+++ b/src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.rs
diff --git a/src/tools/miri/tests/fail/shims/fs/isolated_stdin.stderr b/src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.stderr
index ed826147e3b..ed826147e3b 100644
--- a/src/tools/miri/tests/fail/shims/fs/isolated_stdin.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/fs/isolated_stdin.stderr
diff --git a/src/tools/miri/tests/fail/shims/fs/mkstemp_immutable_arg.rs b/src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.rs
index ba9f404d7c9..ba9f404d7c9 100644
--- a/src/tools/miri/tests/fail/shims/fs/mkstemp_immutable_arg.rs
+++ b/src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.rs
diff --git a/src/tools/miri/tests/fail/shims/fs/mkstemp_immutable_arg.stderr b/src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.stderr
index 35ff1926b06..35ff1926b06 100644
--- a/src/tools/miri/tests/fail/shims/fs/mkstemp_immutable_arg.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/fs/mkstemp_immutable_arg.stderr
diff --git a/src/tools/miri/tests/fail/shims/fs/read_from_stdout.rs b/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.rs
index 073fca4712e..073fca4712e 100644
--- a/src/tools/miri/tests/fail/shims/fs/read_from_stdout.rs
+++ b/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.rs
diff --git a/src/tools/miri/tests/fail/shims/fs/read_from_stdout.stderr b/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr
index bcece7ad4e5..bcece7ad4e5 100644
--- a/src/tools/miri/tests/fail/shims/fs/read_from_stdout.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/fs/read_from_stdout.stderr
diff --git a/src/tools/miri/tests/fail/shims/fs/unix_open_missing_required_mode.rs b/src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.rs
index ae231d4be66..ae231d4be66 100644
--- a/src/tools/miri/tests/fail/shims/fs/unix_open_missing_required_mode.rs
+++ b/src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.rs
diff --git a/src/tools/miri/tests/fail/shims/fs/unix_open_missing_required_mode.stderr b/src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.stderr
index 5a8e7352c76..5a8e7352c76 100644
--- a/src/tools/miri/tests/fail/shims/fs/unix_open_missing_required_mode.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/fs/unix_open_missing_required_mode.stderr
diff --git a/src/tools/miri/tests/fail/shims/fs/write_to_stdin.rs b/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.rs
index d039ad718d3..d039ad718d3 100644
--- a/src/tools/miri/tests/fail/shims/fs/write_to_stdin.rs
+++ b/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.rs
diff --git a/src/tools/miri/tests/fail/shims/fs/write_to_stdin.stderr b/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr
index d4a38e1ca96..d4a38e1ca96 100644
--- a/src/tools/miri/tests/fail/shims/fs/write_to_stdin.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/fs/write_to_stdin.stderr
diff --git a/src/tools/miri/tests/fail/shims/memchr_null.rs b/src/tools/miri/tests/fail-dep/shims/memchr_null.rs
index 6bc7af7e6bf..6bc7af7e6bf 100644
--- a/src/tools/miri/tests/fail/shims/memchr_null.rs
+++ b/src/tools/miri/tests/fail-dep/shims/memchr_null.rs
diff --git a/src/tools/miri/tests/fail/shims/memchr_null.stderr b/src/tools/miri/tests/fail-dep/shims/memchr_null.stderr
index 54b58f22c6c..54b58f22c6c 100644
--- a/src/tools/miri/tests/fail/shims/memchr_null.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/memchr_null.stderr
diff --git a/src/tools/miri/tests/fail/shims/memcmp_null.rs b/src/tools/miri/tests/fail-dep/shims/memcmp_null.rs
index a4e0034c40b..a4e0034c40b 100644
--- a/src/tools/miri/tests/fail/shims/memcmp_null.rs
+++ b/src/tools/miri/tests/fail-dep/shims/memcmp_null.rs
diff --git a/src/tools/miri/tests/fail/shims/memcmp_null.stderr b/src/tools/miri/tests/fail-dep/shims/memcmp_null.stderr
index 8b2882fc243..8b2882fc243 100644
--- a/src/tools/miri/tests/fail/shims/memcmp_null.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/memcmp_null.stderr
diff --git a/src/tools/miri/tests/fail/shims/memcmp_zero.rs b/src/tools/miri/tests/fail-dep/shims/memcmp_zero.rs
index f2ddc200563..f2ddc200563 100644
--- a/src/tools/miri/tests/fail/shims/memcmp_zero.rs
+++ b/src/tools/miri/tests/fail-dep/shims/memcmp_zero.rs
diff --git a/src/tools/miri/tests/fail/shims/memcmp_zero.stderr b/src/tools/miri/tests/fail-dep/shims/memcmp_zero.stderr
index e21b9b06008..e21b9b06008 100644
--- a/src/tools/miri/tests/fail/shims/memcmp_zero.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/memcmp_zero.stderr
diff --git a/src/tools/miri/tests/fail/shims/memcpy_zero.rs b/src/tools/miri/tests/fail-dep/shims/memcpy_zero.rs
index 5283fea4cb9..5283fea4cb9 100644
--- a/src/tools/miri/tests/fail/shims/memcpy_zero.rs
+++ b/src/tools/miri/tests/fail-dep/shims/memcpy_zero.rs
diff --git a/src/tools/miri/tests/fail/shims/memcpy_zero.stderr b/src/tools/miri/tests/fail-dep/shims/memcpy_zero.stderr
index 7c1c3fe20c4..7c1c3fe20c4 100644
--- a/src/tools/miri/tests/fail/shims/memcpy_zero.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/memcpy_zero.stderr
diff --git a/src/tools/miri/tests/fail/shims/memrchr_null.rs b/src/tools/miri/tests/fail-dep/shims/memrchr_null.rs
index b6707d558d8..b6707d558d8 100644
--- a/src/tools/miri/tests/fail/shims/memrchr_null.rs
+++ b/src/tools/miri/tests/fail-dep/shims/memrchr_null.rs
diff --git a/src/tools/miri/tests/fail/shims/memrchr_null.stderr b/src/tools/miri/tests/fail-dep/shims/memrchr_null.stderr
index cc11ba89f8f..cc11ba89f8f 100644
--- a/src/tools/miri/tests/fail/shims/memrchr_null.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/memrchr_null.stderr
diff --git a/src/tools/miri/tests/fail/shims/mmap_invalid_dealloc.rs b/src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.rs
index 70f7a6a7cef..70f7a6a7cef 100644
--- a/src/tools/miri/tests/fail/shims/mmap_invalid_dealloc.rs
+++ b/src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.rs
diff --git a/src/tools/miri/tests/fail/shims/mmap_invalid_dealloc.stderr b/src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.stderr
index 54e0cd5275d..54e0cd5275d 100644
--- a/src/tools/miri/tests/fail/shims/mmap_invalid_dealloc.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/mmap_invalid_dealloc.stderr
diff --git a/src/tools/miri/tests/fail/shims/mmap_use_after_munmap.rs b/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.rs
index c97b013ba5a..c97b013ba5a 100644
--- a/src/tools/miri/tests/fail/shims/mmap_use_after_munmap.rs
+++ b/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.rs
diff --git a/src/tools/miri/tests/fail/shims/mmap_use_after_munmap.stderr b/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.stderr
index 44e122330bc..44e122330bc 100644
--- a/src/tools/miri/tests/fail/shims/mmap_use_after_munmap.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/mmap_use_after_munmap.stderr
diff --git a/src/tools/miri/tests/fail/shims/munmap.rs b/src/tools/miri/tests/fail-dep/shims/munmap.rs
index 453437a06cf..453437a06cf 100644
--- a/src/tools/miri/tests/fail/shims/munmap.rs
+++ b/src/tools/miri/tests/fail-dep/shims/munmap.rs
diff --git a/src/tools/miri/tests/fail/shims/munmap.stderr b/src/tools/miri/tests/fail-dep/shims/munmap.stderr
index cb47769c063..cb47769c063 100644
--- a/src/tools/miri/tests/fail/shims/munmap.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/munmap.stderr
diff --git a/src/tools/miri/tests/fail/shims/munmap_partial.rs b/src/tools/miri/tests/fail-dep/shims/munmap_partial.rs
index 938850ee286..938850ee286 100644
--- a/src/tools/miri/tests/fail/shims/munmap_partial.rs
+++ b/src/tools/miri/tests/fail-dep/shims/munmap_partial.rs
diff --git a/src/tools/miri/tests/fail/shims/munmap_partial.stderr b/src/tools/miri/tests/fail-dep/shims/munmap_partial.stderr
index 9a084c50437..9a084c50437 100644
--- a/src/tools/miri/tests/fail/shims/munmap_partial.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/munmap_partial.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_cond_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.rs
index 94ca3496ed9..94ca3496ed9 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_cond_double_destroy.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_cond_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.stderr
index ecfedf75370..ecfedf75370 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_cond_double_destroy.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_cond_double_destroy.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_condattr_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.rs
index 13e639a867d..13e639a867d 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_condattr_double_destroy.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_condattr_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.stderr
index f39d909adbd..f39d909adbd 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_condattr_double_destroy.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_condattr_double_destroy.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_NULL_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.rs
index 8b251073383..8b251073383 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_NULL_deadlock.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_NULL_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.stderr
index 4a138e6f8a2..4a138e6f8a2 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_NULL_deadlock.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_NULL_deadlock.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.rs
index 6c3cb738e29..6c3cb738e29 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_deadlock.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.stderr
index 599655a8692..599655a8692 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_deadlock.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_deadlock.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_default_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.rs
index f443768819f..f443768819f 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_default_deadlock.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_default_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.stderr
index 8aea3f5c693..8aea3f5c693 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_default_deadlock.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_default_deadlock.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_destroy_locked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.rs
index ec3965c7574..ec3965c7574 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_destroy_locked.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_destroy_locked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.stderr
index a8ab948116e..a8ab948116e 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_destroy_locked.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_destroy_locked.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.rs
index 622c3eaeae3..622c3eaeae3 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_double_destroy.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.stderr
index 9620fdbd18b..9620fdbd18b 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_double_destroy.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_double_destroy.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.rs
index 5ea09fa5aac..5ea09fa5aac 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_deadlock.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.stderr
index b7877d3aa39..b7877d3aa39 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_deadlock.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_deadlock.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.rs
index 8ce7542edb8..8ce7542edb8 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.stderr
index 754137b85b9..754137b85b9 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_normal_unlock_unlocked.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_wrong_owner.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.rs
index b56775252e4..b56775252e4 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_wrong_owner.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.stderr
index aa81b06fc80..aa81b06fc80 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutex_wrong_owner.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutex_wrong_owner.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutexattr_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.rs
index 474a277516d..474a277516d 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutexattr_double_destroy.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutexattr_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.stderr
index 82949047d2a..82949047d2a 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_mutexattr_double_destroy.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_mutexattr_double_destroy.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_read_locked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.rs
index 603580ff58a..603580ff58a 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_read_locked.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_read_locked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.stderr
index be73e7f1e2a..be73e7f1e2a 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_read_locked.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_read_locked.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_write_locked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.rs
index ae44f22d146..ae44f22d146 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_write_locked.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_write_locked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.stderr
index bc2713a5ffb..bc2713a5ffb 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_destroy_write_locked.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_destroy_write_locked.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_double_destroy.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.rs
index 800986f7506..800986f7506 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_double_destroy.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_double_destroy.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.stderr
index 5004f84358d..5004f84358d 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_double_destroy.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_double_destroy.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs
index 782c95b6d2e..782c95b6d2e 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr
index 075c8f0ef52..075c8f0ef52 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_write_deadlock_single_thread.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_wrong_owner.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.rs
index 1b498ad8fcd..1b498ad8fcd 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_wrong_owner.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.stderr
index 7dfa27b43d0..7dfa27b43d0 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_read_wrong_owner.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_read_wrong_owner.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_unlock_unlocked.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.rs
index 05f7e7a06c5..05f7e7a06c5 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_unlock_unlocked.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_unlock_unlocked.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.stderr
index 1c25ac2c048..1c25ac2c048 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_unlock_unlocked.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_unlock_unlocked.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.rs
index 201844615e1..201844615e1 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.stderr
index 333fb1afb91..333fb1afb91 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs
index 538f14ef89f..538f14ef89f 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr
index caab19a782f..caab19a782f 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_read_deadlock_single_thread.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.rs
index b1d7e0492e5..b1d7e0492e5 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.stderr
index 93bede54fcf..93bede54fcf 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs
index 2c963d36510..2c963d36510 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr
index 30f5f447c71..30f5f447c71 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_write_deadlock_single_thread.stderr
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_wrong_owner.rs b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.rs
index dd099474d8f..dd099474d8f 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_wrong_owner.rs
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.rs
diff --git a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_wrong_owner.stderr b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.stderr
index 5bf402c775a..5bf402c775a 100644
--- a/src/tools/miri/tests/fail/shims/sync/libc_pthread_rwlock_write_wrong_owner.stderr
+++ b/src/tools/miri/tests/fail-dep/shims/sync/libc_pthread_rwlock_write_wrong_owner.stderr
diff --git a/src/tools/miri/tests/fail/tokio/sleep.rs b/src/tools/miri/tests/fail-dep/tokio/sleep.rs
index d96d778e6ca..d96d778e6ca 100644
--- a/src/tools/miri/tests/fail/tokio/sleep.rs
+++ b/src/tools/miri/tests/fail-dep/tokio/sleep.rs
diff --git a/src/tools/miri/tests/fail/tokio/sleep.stderr b/src/tools/miri/tests/fail-dep/tokio/sleep.stderr
index ac2a984ed51..ac2a984ed51 100644
--- a/src/tools/miri/tests/fail/tokio/sleep.stderr
+++ b/src/tools/miri/tests/fail-dep/tokio/sleep.stderr
diff --git a/src/tools/miri/tests/fail/unsupported_incomplete_function.rs b/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.rs
index 6ef842c9ccb..6ef842c9ccb 100644
--- a/src/tools/miri/tests/fail/unsupported_incomplete_function.rs
+++ b/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.rs
diff --git a/src/tools/miri/tests/fail/unsupported_incomplete_function.stderr b/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr
index ec2bba61172..ec2bba61172 100644
--- a/src/tools/miri/tests/fail/unsupported_incomplete_function.stderr
+++ b/src/tools/miri/tests/fail-dep/unsupported_incomplete_function.stderr
diff --git a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr
index f181f90abd3..507b459b718 100644
--- a/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr
+++ b/src/tools/miri/tests/fail/function_calls/exported_symbol_bad_unwind1.stderr
@@ -1,3 +1,5 @@
+WARNING: the flag `-Zmiri-disable-abi-check` is deprecated and planned to be removed.
+If you have a use-case for it, please file an issue.
 thread 'main' panicked at $DIR/exported_symbol_bad_unwind1.rs:LL:CC:
 explicit panic
 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
diff --git a/src/tools/miri/tests/fail/panic/bad_miri_start_panic.stderr b/src/tools/miri/tests/fail/panic/bad_miri_start_panic.stderr
index 3bd2be03ea1..4e5a2dfba34 100644
--- a/src/tools/miri/tests/fail/panic/bad_miri_start_panic.stderr
+++ b/src/tools/miri/tests/fail/panic/bad_miri_start_panic.stderr
@@ -1,3 +1,5 @@
+WARNING: the flag `-Zmiri-disable-abi-check` is deprecated and planned to be removed.
+If you have a use-case for it, please file an issue.
 error: Undefined Behavior: unwinding past a stack frame that does not allow unwinding
   --> $DIR/bad_miri_start_panic.rs:LL:CC
    |
diff --git a/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr b/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr
index 769769d957d..998ab956e1a 100644
--- a/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr
+++ b/src/tools/miri/tests/fail/tree_borrows/reserved/cell-protected-write.stderr
@@ -16,14 +16,14 @@ LL |             *y = 1;
    |
    = help: this indicates a potential bug in the program: it performed an invalid operation, but the Tree Borrows rules it violated are still experimental
    = help: the accessed tag <TAG> (y, callee:y, caller:y) is foreign to the protected tag <TAG> (callee:x) (i.e., it is not a child)
-   = help: this foreign write access would cause the protected tag <TAG> (callee:x) (currently Reserved) to become Disabled
+   = help: this foreign write access would cause the protected tag <TAG> (callee:x) (currently Reserved (interior mutable)) to become Disabled
    = help: protected tags must never be Disabled
 help: the accessed tag <TAG> was created here
   --> $DIR/cell-protected-write.rs:LL:CC
    |
 LL |         let y = (&mut *n).get();
    |                 ^^^^^^^^^
-help: the protected tag <TAG> was created here, in the initial state Reserved
+help: the protected tag <TAG> was created here, in the initial state Reserved (interior mutable)
   --> $DIR/cell-protected-write.rs:LL:CC
    |
 LL |         unsafe fn write_second(x: &mut UnsafeCell<u8>, y: *mut u8) {
diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.rs b/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.rs
index 5cd12959ca4..8d3173da400 100644
--- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.rs
+++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.rs
@@ -41,6 +41,8 @@ fn main() {
         eprintln!("{}", out);
         // Print the 'main' frame (and everything before it) to stdout, skipping
         // the printing of internal (and possibly fragile) libstd frames.
+        // Stdout is less normalized so we see more, but it also means we can print less
+        // as platform differences would lead to test suite failures.
         if !seen_main {
             println!("{}", out);
             seen_main = name == "main";
diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stderr b/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stderr
index ee556b3e4a0..bc24d6de734 100644
--- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stderr
+++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stderr
@@ -2,4 +2,17 @@ $DIR/backtrace-api-v0.rs:LL:CC (func_d)
 $DIR/backtrace-api-v0.rs:LL:CC (func_c)
 $DIR/backtrace-api-v0.rs:LL:CC (func_b)
 $DIR/backtrace-api-v0.rs:LL:CC (func_a)
-$DIR/backtrace-api-v0.rs:LL:CC RUSTLIB/core/src/ops/function.rs:LL:CC (<fn() as std::ops::FnOnce<()>>::call_once - RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC (std::sys_common::backtrace::__rust_begin_short_backtrace)
+$DIR/backtrace-api-v0.rs:LL:CC (main)
+RUSTLIB/core/src/ops/function.rs:LL:CC (<fn() as std::ops::FnOnce<()>>::call_once - shim(fn()))
+RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC (std::sys_common::backtrace::__rust_begin_short_backtrace)
+RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start::{closure#0})
+RUSTLIB/core/src/ops/function.rs:LL:CC (std::ops::function::impls::call_once)
+RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call)
+RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try)
+RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind)
+RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal::{closure#2})
+RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call)
+RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try)
+RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind)
+RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal)
+RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start)
diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stdout b/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stdout
index 2fe31dd0e6b..c9cab268168 100644
--- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stdout
+++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v0.stdout
@@ -1,5 +1,5 @@
 $DIR/backtrace-api-v0.rs:24:14 (func_d)
 $DIR/backtrace-api-v0.rs:20:5 (func_c)
-$DIR/backtrace-api-v0.rs:9:5 (func_b)
+$DIR/backtrace-api-v0.rs:9:5 (func_b::<u8>)
 $DIR/backtrace-api-v0.rs:5:5 (func_a)
 $DIR/backtrace-api-v0.rs:29:18 (main)
diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.rs b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.rs
index 1e35574b39b..ad05271ca51 100644
--- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.rs
+++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.rs
@@ -54,6 +54,8 @@ fn main() {
         eprintln!("{}", out);
         // Print the 'main' frame (and everything before it) to stdout, skipping
         // the printing of internal (and possibly fragile) libstd frames.
+        // Stdout is less normalized so we see more, but it also means we can print less
+        // as platform differences would lead to test suite failures.
         if !seen_main {
             println!("{}", out);
             seen_main = name == "main";
diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr
index 7dc281af31d..246e54becd8 100644
--- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr
+++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stderr
@@ -2,4 +2,17 @@ $DIR/backtrace-api-v1.rs:LL:CC (func_d)
 $DIR/backtrace-api-v1.rs:LL:CC (func_c)
 $DIR/backtrace-api-v1.rs:LL:CC (func_b)
 $DIR/backtrace-api-v1.rs:LL:CC (func_a)
-$DIR/backtrace-api-v1.rs:LL:CC RUSTLIB/core/src/ops/function.rs:LL:CC (<fn() as std::ops::FnOnce<()>>::call_once - RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC (std::sys_common::backtrace::__rust_begin_short_backtrace)
+$DIR/backtrace-api-v1.rs:LL:CC (main)
+RUSTLIB/core/src/ops/function.rs:LL:CC (<fn() as std::ops::FnOnce<()>>::call_once - shim(fn()))
+RUSTLIB/std/src/sys_common/backtrace.rs:LL:CC (std::sys_common::backtrace::__rust_begin_short_backtrace)
+RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start::{closure#0})
+RUSTLIB/core/src/ops/function.rs:LL:CC (std::ops::function::impls::call_once)
+RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call)
+RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try)
+RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind)
+RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal::{closure#2})
+RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try::do_call)
+RUSTLIB/std/src/panicking.rs:LL:CC (std::panicking::r#try)
+RUSTLIB/std/src/panic.rs:LL:CC (std::panic::catch_unwind)
+RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start_internal)
+RUSTLIB/std/src/rt.rs:LL:CC (std::rt::lang_start)
diff --git a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stdout b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stdout
index 0d2ae3b516a..e145c167e88 100644
--- a/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stdout
+++ b/src/tools/miri/tests/pass/backtrace/backtrace-api-v1.stdout
@@ -1,5 +1,5 @@
 $DIR/backtrace-api-v1.rs:27:9 (func_d)
 $DIR/backtrace-api-v1.rs:20:5 (func_c)
-$DIR/backtrace-api-v1.rs:9:5 (func_b)
+$DIR/backtrace-api-v1.rs:9:5 (func_b::<u8>)
 $DIR/backtrace-api-v1.rs:5:5 (func_a)
 $DIR/backtrace-api-v1.rs:34:18 (main)
diff --git a/src/tools/miri/tests/pass/function_calls/disable_abi_check.stderr b/src/tools/miri/tests/pass/function_calls/disable_abi_check.stderr
new file mode 100644
index 00000000000..e5b84f6d709
--- /dev/null
+++ b/src/tools/miri/tests/pass/function_calls/disable_abi_check.stderr
@@ -0,0 +1,2 @@
+WARNING: the flag `-Zmiri-disable-abi-check` is deprecated and planned to be removed.
+If you have a use-case for it, please file an issue.
diff --git a/src/tools/miri/tests/pass/function_pointers.rs b/src/tools/miri/tests/pass/function_pointers.rs
index b66826e3fcd..1c99a96feda 100644
--- a/src/tools/miri/tests/pass/function_pointers.rs
+++ b/src/tools/miri/tests/pass/function_pointers.rs
@@ -23,6 +23,10 @@ fn h(i: i32, j: i32) -> i32 {
     j * i * 7
 }
 
+fn i() -> i32 {
+    73
+}
+
 fn return_fn_ptr(f: fn() -> i32) -> fn() -> i32 {
     f
 }
@@ -72,10 +76,18 @@ fn main() {
     assert_eq!(indirect3(h), 210);
     assert_eq!(indirect_mut3(h), 210);
     assert_eq!(indirect_once3(h), 210);
-    let g = f as fn() -> i32;
-    assert!(return_fn_ptr(g) == g);
-    assert!(return_fn_ptr(g) as unsafe fn() -> i32 == g as fn() -> i32 as unsafe fn() -> i32);
-    assert!(return_fn_ptr(f) != f);
+    // Check that `i` always has the same address. This is not guaranteed
+    // but Miri currently uses a fixed address for monomorphic functions.
+    assert!(return_fn_ptr(i) == i);
+    assert!(return_fn_ptr(i) as unsafe fn() -> i32 == i as fn() -> i32 as unsafe fn() -> i32);
+    // We don't check anything for `f`. Miri gives it many different addresses
+    // but mir-opts can turn them into the same address.
+    let _val = return_fn_ptr(f) != f;
+    // However, if we only turn `f` into a function pointer and use that pointer,
+    // it is equal to itself.
+    let f2 = f as fn() -> i32;
+    assert!(return_fn_ptr(f2) == f2);
+    assert!(return_fn_ptr(f2) as unsafe fn() -> i32 == f2 as fn() -> i32 as unsafe fn() -> i32);
 
     // Any non-null value is okay for function pointers.
     unsafe {
diff --git a/src/tools/miri/tests/pass/intrinsics-x86-avx512.rs b/src/tools/miri/tests/pass/intrinsics-x86-avx512.rs
new file mode 100644
index 00000000000..c38158dc797
--- /dev/null
+++ b/src/tools/miri/tests/pass/intrinsics-x86-avx512.rs
@@ -0,0 +1,217 @@
+// Ignore everything except x86 and x86_64
+// Any additional target are added to CI should be ignored here
+// (We cannot use `cfg`-based tricks here since the `target-feature` flags below only work on x86.)
+//@ignore-target-aarch64
+//@ignore-target-arm
+//@ignore-target-avr
+//@ignore-target-s390x
+//@ignore-target-thumbv7em
+//@ignore-target-wasm32
+//@compile-flags: -C target-feature=+avx512f,+avx512vl,+avx512bitalg,+avx512vpopcntdq
+
+#![feature(avx512_target_feature)]
+#![feature(stdsimd)]
+
+#[cfg(target_arch = "x86")]
+use std::arch::x86::*;
+#[cfg(target_arch = "x86_64")]
+use std::arch::x86_64::*;
+use std::mem::transmute;
+
+fn main() {
+    assert!(is_x86_feature_detected!("avx512f"));
+    assert!(is_x86_feature_detected!("avx512vl"));
+    assert!(is_x86_feature_detected!("avx512bitalg"));
+    assert!(is_x86_feature_detected!("avx512vpopcntdq"));
+
+    unsafe {
+        test_avx512bitalg();
+        test_avx512vpopcntdq();
+    }
+}
+
+// Some of the constants in the tests below are just bit patterns. They should not
+// be interpreted as integers; signedness does not make sense for them, but
+// __mXXXi happens to be defined in terms of signed integers.
+#[allow(overflowing_literals)]
+#[target_feature(enable = "avx512bitalg,avx512f,avx512vl")]
+unsafe fn test_avx512bitalg() {
+    // Mostly copied from library/stdarch/crates/core_arch/src/x86/avx512bitalg.rs
+
+    #[target_feature(enable = "avx512bitalg,avx512f")]
+    unsafe fn test_mm512_popcnt_epi16() {
+        let test_data = _mm512_set_epi16(
+            0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1_FF, 0x3_FF, 0x7_FF, 0xF_FF, 0x1F_FF,
+            0x3F_FF, 0x7F_FF, 0xFF_FF, -1, -100, 255, 256, 2, 4, 8, 16, 32, 64, 128, 256, 512,
+            1024, 2048,
+        );
+        let actual_result = _mm512_popcnt_epi16(test_data);
+        let reference_result = _mm512_set_epi16(
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 16, 12, 8, 1, 1, 1, 1, 1, 1,
+            1, 1, 1, 1, 1, 1,
+        );
+        assert_eq_m512i(actual_result, reference_result);
+    }
+    test_mm512_popcnt_epi16();
+
+    #[target_feature(enable = "avx512bitalg,avx512f,avx512vl")]
+    unsafe fn test_mm256_popcnt_epi16() {
+        let test_data = _mm256_set_epi16(
+            0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, 0x1_FF, 0x3_FF, 0x7_FF, 0xF_FF, 0x1F_FF,
+            0x3F_FF, 0x7F_FF,
+        );
+        let actual_result = _mm256_popcnt_epi16(test_data);
+        let reference_result =
+            _mm256_set_epi16(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+        assert_eq_m256i(actual_result, reference_result);
+    }
+    test_mm256_popcnt_epi16();
+
+    #[target_feature(enable = "avx512bitalg,avx512f,avx512vl")]
+    unsafe fn test_mm_popcnt_epi16() {
+        let test_data = _mm_set_epi16(0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F);
+        let actual_result = _mm_popcnt_epi16(test_data);
+        let reference_result = _mm_set_epi16(0, 1, 2, 3, 4, 5, 6, 7);
+        assert_eq_m128i(actual_result, reference_result);
+    }
+    test_mm_popcnt_epi16();
+
+    #[target_feature(enable = "avx512bitalg,avx512f")]
+    unsafe fn test_mm512_popcnt_epi8() {
+        let test_data = _mm512_set_epi8(
+            0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, -1, 2, 4, 8, 16, 32, 64, 128, 171, 206, 100,
+            217, 109, 253, 190, 177, 254, 179, 215, 230, 68, 201, 172, 183, 154, 84, 56, 227, 189,
+            140, 35, 117, 219, 169, 226, 170, 13, 22, 159, 251, 73, 121, 143, 145, 85, 91, 137, 90,
+            225, 21, 249, 211, 155, 228, 70,
+        );
+        let actual_result = _mm512_popcnt_epi8(test_data);
+        let reference_result = _mm512_set_epi8(
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 1, 1, 1, 1, 1, 1, 1, 5, 5, 3, 5, 5, 7, 6, 4, 7, 5, 6, 5,
+            2, 4, 4, 6, 4, 3, 3, 5, 6, 3, 3, 5, 6, 4, 4, 4, 3, 3, 6, 7, 3, 5, 5, 3, 4, 5, 3, 4, 4,
+            3, 6, 5, 5, 4, 3,
+        );
+        assert_eq_m512i(actual_result, reference_result);
+    }
+    test_mm512_popcnt_epi8();
+
+    #[target_feature(enable = "avx512bitalg,avx512f,avx512vl")]
+    unsafe fn test_mm256_popcnt_epi8() {
+        let test_data = _mm256_set_epi8(
+            0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, -1, 2, 4, 8, 16, 32, 64, 128, 171, 206, 100,
+            217, 109, 253, 190, 177, 254, 179, 215, 230, 68, 201, 172,
+        );
+        let actual_result = _mm256_popcnt_epi8(test_data);
+        let reference_result = _mm256_set_epi8(
+            0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 1, 1, 1, 1, 1, 1, 1, 5, 5, 3, 5, 5, 7, 6, 4, 7, 5, 6, 5,
+            2, 4, 4,
+        );
+        assert_eq_m256i(actual_result, reference_result);
+    }
+    test_mm256_popcnt_epi8();
+
+    #[target_feature(enable = "avx512bitalg,avx512f,avx512vl")]
+    unsafe fn test_mm_popcnt_epi8() {
+        let test_data =
+            _mm_set_epi8(0, 1, 3, 7, 0xF, 0x1F, 0x3F, 0x7F, 0xFF, -1, 2, 4, 8, 16, 32, 64);
+        let actual_result = _mm_popcnt_epi8(test_data);
+        let reference_result = _mm_set_epi8(0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 1, 1, 1, 1, 1, 1);
+        assert_eq_m128i(actual_result, reference_result);
+    }
+    test_mm_popcnt_epi8();
+}
+
+#[target_feature(enable = "avx512vpopcntdq,avx512f,avx512vl")]
+unsafe fn test_avx512vpopcntdq() {
+    // Mostly copied from library/stdarch/crates/core_arch/src/x86/avx512vpopcntdq.rs
+
+    #[target_feature(enable = "avx512vpopcntdq,avx512f")]
+    unsafe fn test_mm512_popcnt_epi32() {
+        let test_data = _mm512_set_epi32(
+            0,
+            1,
+            -1,
+            2,
+            7,
+            0xFF_FE,
+            0x7F_FF_FF_FF,
+            -100,
+            0x40_00_00_00,
+            103,
+            371,
+            552,
+            432_948,
+            818_826_998,
+            255,
+            256,
+        );
+        let actual_result = _mm512_popcnt_epi32(test_data);
+        let reference_result =
+            _mm512_set_epi32(0, 1, 32, 1, 3, 15, 31, 28, 1, 5, 6, 3, 10, 17, 8, 1);
+        assert_eq_m512i(actual_result, reference_result);
+    }
+    test_mm512_popcnt_epi32();
+
+    #[target_feature(enable = "avx512vpopcntdq,avx512f,avx512vl")]
+    unsafe fn test_mm256_popcnt_epi32() {
+        let test_data = _mm256_set_epi32(0, 1, -1, 2, 7, 0xFF_FE, 0x7F_FF_FF_FF, -100);
+        let actual_result = _mm256_popcnt_epi32(test_data);
+        let reference_result = _mm256_set_epi32(0, 1, 32, 1, 3, 15, 31, 28);
+        assert_eq_m256i(actual_result, reference_result);
+    }
+    test_mm256_popcnt_epi32();
+
+    #[target_feature(enable = "avx512vpopcntdq,avx512f,avx512vl")]
+    unsafe fn test_mm_popcnt_epi32() {
+        let test_data = _mm_set_epi32(0, 1, -1, -100);
+        let actual_result = _mm_popcnt_epi32(test_data);
+        let reference_result = _mm_set_epi32(0, 1, 32, 28);
+        assert_eq_m128i(actual_result, reference_result);
+    }
+    test_mm_popcnt_epi32();
+
+    #[target_feature(enable = "avx512vpopcntdq,avx512f")]
+    unsafe fn test_mm512_popcnt_epi64() {
+        let test_data = _mm512_set_epi64(0, 1, -1, 2, 7, 0xFF_FE, 0x7F_FF_FF_FF_FF_FF_FF_FF, -100);
+        let actual_result = _mm512_popcnt_epi64(test_data);
+        let reference_result = _mm512_set_epi64(0, 1, 64, 1, 3, 15, 63, 60);
+        assert_eq_m512i(actual_result, reference_result);
+    }
+    test_mm512_popcnt_epi64();
+
+    #[target_feature(enable = "avx512vpopcntdq,avx512vl")]
+    unsafe fn test_mm256_popcnt_epi64() {
+        let test_data = _mm256_set_epi64x(0, 1, -1, -100);
+        let actual_result = _mm256_popcnt_epi64(test_data);
+        let reference_result = _mm256_set_epi64x(0, 1, 64, 60);
+        assert_eq_m256i(actual_result, reference_result);
+    }
+    test_mm256_popcnt_epi64();
+
+    #[target_feature(enable = "avx512vpopcntdq,avx512vl")]
+    unsafe fn test_mm_popcnt_epi64() {
+        let test_data = _mm_set_epi64x(0, 1);
+        let actual_result = _mm_popcnt_epi64(test_data);
+        let reference_result = _mm_set_epi64x(0, 1);
+        assert_eq_m128i(actual_result, reference_result);
+        let test_data = _mm_set_epi64x(-1, -100);
+        let actual_result = _mm_popcnt_epi64(test_data);
+        let reference_result = _mm_set_epi64x(64, 60);
+        assert_eq_m128i(actual_result, reference_result);
+    }
+    test_mm_popcnt_epi64();
+}
+
+#[track_caller]
+unsafe fn assert_eq_m512i(a: __m512i, b: __m512i) {
+    assert_eq!(transmute::<_, [i32; 16]>(a), transmute::<_, [i32; 16]>(b))
+}
+
+#[track_caller]
+unsafe fn assert_eq_m256i(a: __m256i, b: __m256i) {
+    assert_eq!(transmute::<_, [u64; 4]>(a), transmute::<_, [u64; 4]>(b))
+}
+
+#[track_caller]
+unsafe fn assert_eq_m128i(a: __m128i, b: __m128i) {
+    assert_eq!(transmute::<_, [u64; 2]>(a), transmute::<_, [u64; 2]>(b))
+}
diff --git a/src/tools/miri/tests/pass/intrinsics-x86-sse.rs b/src/tools/miri/tests/pass/intrinsics-x86-sse.rs
index 9b1ded94b5d..a62a5ee3781 100644
--- a/src/tools/miri/tests/pass/intrinsics-x86-sse.rs
+++ b/src/tools/miri/tests/pass/intrinsics-x86-sse.rs
@@ -1,1094 +1,1107 @@
-// Ignore everything except x86 and x86_64
-// Any additional target are added to CI should be ignored here
-//@ignore-target-aarch64
-//@ignore-target-arm
-//@ignore-target-avr
-//@ignore-target-s390x
-//@ignore-target-thumbv7em
-//@ignore-target-wasm32
-
-#[cfg(target_arch = "x86")]
-use std::arch::x86::*;
-#[cfg(target_arch = "x86_64")]
-use std::arch::x86_64::*;
-use std::f32::NAN;
-use std::mem::transmute;
-
 fn main() {
-    assert!(is_x86_feature_detected!("sse"));
+    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+    {
+        assert!(is_x86_feature_detected!("sse"));
 
-    unsafe {
-        test_sse();
+        unsafe {
+            tests::test_sse();
+        }
     }
 }
 
-macro_rules! assert_approx_eq {
-    ($a:expr, $b:expr, $eps:expr) => {{
-        let (a, b) = (&$a, &$b);
-        assert!(
-            (*a - *b).abs() < $eps,
-            "assertion failed: `(left !== right)` \
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+mod tests {
+    #[cfg(target_arch = "x86")]
+    use std::arch::x86::*;
+    #[cfg(target_arch = "x86_64")]
+    use std::arch::x86_64::*;
+    use std::f32::NAN;
+    use std::mem::transmute;
+
+    macro_rules! assert_approx_eq {
+        ($a:expr, $b:expr, $eps:expr) => {{
+            let (a, b) = (&$a, &$b);
+            assert!(
+                (*a - *b).abs() < $eps,
+                "assertion failed: `(left !== right)` \
              (left: `{:?}`, right: `{:?}`, expect diff: `{:?}`, real diff: `{:?}`)",
-            *a,
-            *b,
-            $eps,
-            (*a - *b).abs()
-        );
-    }};
-}
-
-#[target_feature(enable = "sse")]
-unsafe fn test_sse() {
-    // Mostly copied from library/stdarch/crates/core_arch/src/x86{,_64}/sse.rs
-
-    #[target_feature(enable = "sse")]
-    unsafe fn assert_eq_m128(a: __m128, b: __m128) {
-        let r = _mm_cmpeq_ps(a, b);
-        if _mm_movemask_ps(r) != 0b1111 {
-            panic!("{:?} != {:?}", a, b);
-        }
-    }
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_add_ss() {
-        let a = _mm_set_ps(-1.0, 5.0, 0.0, -10.0);
-        let b = _mm_set_ps(-100.0, 20.0, 0.0, -5.0);
-        let r = _mm_add_ss(a, b);
-        assert_eq_m128(r, _mm_set_ps(-1.0, 5.0, 0.0, -15.0));
-    }
-    test_mm_add_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_sub_ss() {
-        let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0);
-        let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0);
-        let r = _mm_sub_ss(a, b);
-        assert_eq_m128(r, _mm_setr_ps(99.0, 5.0, 0.0, -10.0));
-    }
-    test_mm_sub_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_mul_ss() {
-        let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0);
-        let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0);
-        let r = _mm_mul_ss(a, b);
-        assert_eq_m128(r, _mm_setr_ps(100.0, 5.0, 0.0, -10.0));
-    }
-    test_mm_mul_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_div_ss() {
-        let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0);
-        let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0);
-        let r = _mm_div_ss(a, b);
-        assert_eq_m128(r, _mm_setr_ps(0.01, 5.0, 0.0, -10.0));
-    }
-    test_mm_div_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_sqrt_ss() {
-        let a = _mm_setr_ps(4.0, 13.0, 16.0, 100.0);
-        let r = _mm_sqrt_ss(a);
-        let e = _mm_setr_ps(2.0, 13.0, 16.0, 100.0);
-        assert_eq_m128(r, e);
-    }
-    test_mm_sqrt_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_sqrt_ps() {
-        let a = _mm_setr_ps(4.0, 13.0, 16.0, 100.0);
-        let r = _mm_sqrt_ps(a);
-        let e = _mm_setr_ps(2.0, 3.6055512, 4.0, 10.0);
-        assert_eq_m128(r, e);
+                *a,
+                *b,
+                $eps,
+                (*a - *b).abs()
+            );
+        }};
     }
-    test_mm_sqrt_ps();
 
     #[target_feature(enable = "sse")]
-    unsafe fn test_mm_rcp_ss() {
-        let a = _mm_setr_ps(4.0, 13.0, 16.0, 100.0);
-        let r = _mm_rcp_ss(a);
-        let e = _mm_setr_ps(0.24993896, 13.0, 16.0, 100.0);
-        let rel_err = 0.00048828125;
-
-        let r: [f32; 4] = transmute(r);
-        let e: [f32; 4] = transmute(e);
-        assert_approx_eq!(r[0], e[0], 2. * rel_err);
-        for i in 1..4 {
-            assert_eq!(r[i], e[i]);
+    pub(super) unsafe fn test_sse() {
+        // Mostly copied from library/stdarch/crates/core_arch/src/x86{,_64}/sse.rs
+
+        #[target_feature(enable = "sse")]
+        unsafe fn assert_eq_m128(a: __m128, b: __m128) {
+            let r = _mm_cmpeq_ps(a, b);
+            if _mm_movemask_ps(r) != 0b1111 {
+                panic!("{:?} != {:?}", a, b);
+            }
         }
-    }
-    test_mm_rcp_ss();
 
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_rcp_ps() {
-        let a = _mm_setr_ps(4.0, 13.0, 16.0, 100.0);
-        let r = _mm_rcp_ps(a);
-        let e = _mm_setr_ps(0.24993896, 0.0769043, 0.06248474, 0.0099983215);
-        let rel_err = 0.00048828125;
-
-        let r: [f32; 4] = transmute(r);
-        let e: [f32; 4] = transmute(e);
-        for i in 0..4 {
-            assert_approx_eq!(r[i], e[i], 2. * rel_err);
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_add_ss() {
+            let a = _mm_set_ps(-1.0, 5.0, 0.0, -10.0);
+            let b = _mm_set_ps(-100.0, 20.0, 0.0, -5.0);
+            let r = _mm_add_ss(a, b);
+            assert_eq_m128(r, _mm_set_ps(-1.0, 5.0, 0.0, -15.0));
         }
-    }
-    test_mm_rcp_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_rsqrt_ss() {
-        let a = _mm_setr_ps(4.0, 13.0, 16.0, 100.0);
-        let r = _mm_rsqrt_ss(a);
-        let e = _mm_setr_ps(0.49987793, 13.0, 16.0, 100.0);
-        let rel_err = 0.00048828125;
-
-        let r: [f32; 4] = transmute(r);
-        let e: [f32; 4] = transmute(e);
-        assert_approx_eq!(r[0], e[0], 2. * rel_err);
-        for i in 1..4 {
-            assert_eq!(r[i], e[i]);
+        test_mm_add_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_sub_ss() {
+            let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0);
+            let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0);
+            let r = _mm_sub_ss(a, b);
+            assert_eq_m128(r, _mm_setr_ps(99.0, 5.0, 0.0, -10.0));
         }
-    }
-    test_mm_rsqrt_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_rsqrt_ps() {
-        let a = _mm_setr_ps(4.0, 13.0, 16.0, 100.0);
-        let r = _mm_rsqrt_ps(a);
-        let e = _mm_setr_ps(0.49987793, 0.2772827, 0.24993896, 0.099990845);
-        let rel_err = 0.00048828125;
-
-        let r: [f32; 4] = transmute(r);
-        let e: [f32; 4] = transmute(e);
-        for i in 0..4 {
-            assert_approx_eq!(r[i], e[i], 2. * rel_err);
+        test_mm_sub_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_mul_ss() {
+            let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0);
+            let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0);
+            let r = _mm_mul_ss(a, b);
+            assert_eq_m128(r, _mm_setr_ps(100.0, 5.0, 0.0, -10.0));
         }
-    }
-    test_mm_rsqrt_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_min_ss() {
-        let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0);
-        let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0);
-        let r = _mm_min_ss(a, b);
-        assert_eq_m128(r, _mm_setr_ps(-100.0, 5.0, 0.0, -10.0));
-    }
-    test_mm_min_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_min_ps() {
-        let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0);
-        let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0);
-        let r = _mm_min_ps(a, b);
-        assert_eq_m128(r, _mm_setr_ps(-100.0, 5.0, 0.0, -10.0));
-
-        // `_mm_min_ps` can **not** be implemented using the `simd_min` rust intrinsic because
-        // the semantics of `simd_min` are different to those of `_mm_min_ps` regarding handling
-        // of `-0.0`.
-        let a = _mm_setr_ps(-0.0, 0.0, 0.0, 0.0);
-        let b = _mm_setr_ps(0.0, 0.0, 0.0, 0.0);
-        let r1: [u8; 16] = transmute(_mm_min_ps(a, b));
-        let r2: [u8; 16] = transmute(_mm_min_ps(b, a));
-        let a: [u8; 16] = transmute(a);
-        let b: [u8; 16] = transmute(b);
-        assert_eq!(r1, b);
-        assert_eq!(r2, a);
-        assert_ne!(a, b); // sanity check that -0.0 is actually present
-    }
-    test_mm_min_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_max_ss() {
-        let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0);
-        let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0);
-        let r = _mm_max_ss(a, b);
-        assert_eq_m128(r, _mm_setr_ps(-1.0, 5.0, 0.0, -10.0));
-    }
-    test_mm_max_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_max_ps() {
-        let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0);
-        let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0);
-        let r = _mm_max_ps(a, b);
-        assert_eq_m128(r, _mm_setr_ps(-1.0, 20.0, 0.0, -5.0));
-
-        // `_mm_max_ps` can **not** be implemented using the `simd_max` rust intrinsic because
-        // the semantics of `simd_max` are different to those of `_mm_max_ps` regarding handling
-        // of `-0.0`.
-        let a = _mm_setr_ps(-0.0, 0.0, 0.0, 0.0);
-        let b = _mm_setr_ps(0.0, 0.0, 0.0, 0.0);
-        let r1: [u8; 16] = transmute(_mm_max_ps(a, b));
-        let r2: [u8; 16] = transmute(_mm_max_ps(b, a));
-        let a: [u8; 16] = transmute(a);
-        let b: [u8; 16] = transmute(b);
-        assert_eq!(r1, b);
-        assert_eq!(r2, a);
-        assert_ne!(a, b); // sanity check that -0.0 is actually present
-    }
-    test_mm_max_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpeq_ss() {
-        let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
-        let b = _mm_setr_ps(-1.0, 5.0, 6.0, 7.0);
-        let r: [u32; 4] = transmute(_mm_cmpeq_ss(a, b));
-        let e: [u32; 4] = transmute(_mm_setr_ps(transmute(0u32), 2.0, 3.0, 4.0));
-        assert_eq!(r, e);
-
-        let b2 = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
-        let r2: [u32; 4] = transmute(_mm_cmpeq_ss(a, b2));
-        let e2: [u32; 4] = transmute(_mm_setr_ps(transmute(0xffffffffu32), 2.0, 3.0, 4.0));
-        assert_eq!(r2, e2);
-    }
-    test_mm_cmpeq_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmplt_ss() {
-        let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
-        let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
-        let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
-        let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
-
-        let b1 = 0u32; // a.extract(0) < b.extract(0)
-        let c1 = 0u32; // a.extract(0) < c.extract(0)
-        let d1 = !0u32; // a.extract(0) < d.extract(0)
-
-        let rb: [u32; 4] = transmute(_mm_cmplt_ss(a, b));
-        let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
-        assert_eq!(rb, eb);
-
-        let rc: [u32; 4] = transmute(_mm_cmplt_ss(a, c));
-        let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
-        assert_eq!(rc, ec);
-
-        let rd: [u32; 4] = transmute(_mm_cmplt_ss(a, d));
-        let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
-        assert_eq!(rd, ed);
-    }
-    test_mm_cmplt_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmple_ss() {
-        let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
-        let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
-        let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
-        let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
-
-        let b1 = 0u32; // a.extract(0) <= b.extract(0)
-        let c1 = !0u32; // a.extract(0) <= c.extract(0)
-        let d1 = !0u32; // a.extract(0) <= d.extract(0)
-
-        let rb: [u32; 4] = transmute(_mm_cmple_ss(a, b));
-        let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
-        assert_eq!(rb, eb);
-
-        let rc: [u32; 4] = transmute(_mm_cmple_ss(a, c));
-        let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
-        assert_eq!(rc, ec);
-
-        let rd: [u32; 4] = transmute(_mm_cmple_ss(a, d));
-        let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
-        assert_eq!(rd, ed);
-    }
-    test_mm_cmple_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpgt_ss() {
-        let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
-        let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
-        let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
-        let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
-
-        let b1 = !0u32; // a.extract(0) > b.extract(0)
-        let c1 = 0u32; // a.extract(0) > c.extract(0)
-        let d1 = 0u32; // a.extract(0) > d.extract(0)
-
-        let rb: [u32; 4] = transmute(_mm_cmpgt_ss(a, b));
-        let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
-        assert_eq!(rb, eb);
-
-        let rc: [u32; 4] = transmute(_mm_cmpgt_ss(a, c));
-        let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
-        assert_eq!(rc, ec);
-
-        let rd: [u32; 4] = transmute(_mm_cmpgt_ss(a, d));
-        let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
-        assert_eq!(rd, ed);
-    }
-    test_mm_cmpgt_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpge_ss() {
-        let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
-        let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
-        let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
-        let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
-
-        let b1 = !0u32; // a.extract(0) >= b.extract(0)
-        let c1 = !0u32; // a.extract(0) >= c.extract(0)
-        let d1 = 0u32; // a.extract(0) >= d.extract(0)
-
-        let rb: [u32; 4] = transmute(_mm_cmpge_ss(a, b));
-        let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
-        assert_eq!(rb, eb);
-
-        let rc: [u32; 4] = transmute(_mm_cmpge_ss(a, c));
-        let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
-        assert_eq!(rc, ec);
-
-        let rd: [u32; 4] = transmute(_mm_cmpge_ss(a, d));
-        let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
-        assert_eq!(rd, ed);
-    }
-    test_mm_cmpge_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpneq_ss() {
-        let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
-        let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
-        let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
-        let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
-
-        let b1 = !0u32; // a.extract(0) != b.extract(0)
-        let c1 = 0u32; // a.extract(0) != c.extract(0)
-        let d1 = !0u32; // a.extract(0) != d.extract(0)
-
-        let rb: [u32; 4] = transmute(_mm_cmpneq_ss(a, b));
-        let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
-        assert_eq!(rb, eb);
-
-        let rc: [u32; 4] = transmute(_mm_cmpneq_ss(a, c));
-        let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
-        assert_eq!(rc, ec);
-
-        let rd: [u32; 4] = transmute(_mm_cmpneq_ss(a, d));
-        let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
-        assert_eq!(rd, ed);
-    }
-    test_mm_cmpneq_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpnlt_ss() {
-        // TODO: this test is exactly the same as for `_mm_cmpge_ss`, but there
-        // must be a difference. It may have to do with behavior in the
-        // presence of NaNs (signaling or quiet). If so, we should add tests
-        // for those.
-
-        let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
-        let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
-        let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
-        let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
-
-        let b1 = !0u32; // a.extract(0) >= b.extract(0)
-        let c1 = !0u32; // a.extract(0) >= c.extract(0)
-        let d1 = 0u32; // a.extract(0) >= d.extract(0)
-
-        let rb: [u32; 4] = transmute(_mm_cmpnlt_ss(a, b));
-        let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
-        assert_eq!(rb, eb);
-
-        let rc: [u32; 4] = transmute(_mm_cmpnlt_ss(a, c));
-        let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
-        assert_eq!(rc, ec);
-
-        let rd: [u32; 4] = transmute(_mm_cmpnlt_ss(a, d));
-        let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
-        assert_eq!(rd, ed);
-    }
-    test_mm_cmpnlt_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpnle_ss() {
-        // TODO: this test is exactly the same as for `_mm_cmpgt_ss`, but there
-        // must be a difference. It may have to do with behavior in the
-        // presence
-        // of NaNs (signaling or quiet). If so, we should add tests for those.
-
-        let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
-        let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
-        let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
-        let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
-
-        let b1 = !0u32; // a.extract(0) > b.extract(0)
-        let c1 = 0u32; // a.extract(0) > c.extract(0)
-        let d1 = 0u32; // a.extract(0) > d.extract(0)
-
-        let rb: [u32; 4] = transmute(_mm_cmpnle_ss(a, b));
-        let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
-        assert_eq!(rb, eb);
-
-        let rc: [u32; 4] = transmute(_mm_cmpnle_ss(a, c));
-        let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
-        assert_eq!(rc, ec);
-
-        let rd: [u32; 4] = transmute(_mm_cmpnle_ss(a, d));
-        let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
-        assert_eq!(rd, ed);
-    }
-    test_mm_cmpnle_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpngt_ss() {
-        // TODO: this test is exactly the same as for `_mm_cmple_ss`, but there
-        // must be a difference. It may have to do with behavior in the
-        // presence of NaNs (signaling or quiet). If so, we should add tests
-        // for those.
-
-        let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
-        let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
-        let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
-        let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
-
-        let b1 = 0u32; // a.extract(0) <= b.extract(0)
-        let c1 = !0u32; // a.extract(0) <= c.extract(0)
-        let d1 = !0u32; // a.extract(0) <= d.extract(0)
-
-        let rb: [u32; 4] = transmute(_mm_cmpngt_ss(a, b));
-        let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
-        assert_eq!(rb, eb);
-
-        let rc: [u32; 4] = transmute(_mm_cmpngt_ss(a, c));
-        let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
-        assert_eq!(rc, ec);
-
-        let rd: [u32; 4] = transmute(_mm_cmpngt_ss(a, d));
-        let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
-        assert_eq!(rd, ed);
-    }
-    test_mm_cmpngt_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpnge_ss() {
-        // TODO: this test is exactly the same as for `_mm_cmplt_ss`, but there
-        // must be a difference. It may have to do with behavior in the
-        // presence of NaNs (signaling or quiet). If so, we should add tests
-        // for those.
-
-        let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
-        let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
-        let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
-        let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
-
-        let b1 = 0u32; // a.extract(0) < b.extract(0)
-        let c1 = 0u32; // a.extract(0) < c.extract(0)
-        let d1 = !0u32; // a.extract(0) < d.extract(0)
-
-        let rb: [u32; 4] = transmute(_mm_cmpnge_ss(a, b));
-        let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
-        assert_eq!(rb, eb);
-
-        let rc: [u32; 4] = transmute(_mm_cmpnge_ss(a, c));
-        let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
-        assert_eq!(rc, ec);
-
-        let rd: [u32; 4] = transmute(_mm_cmpnge_ss(a, d));
-        let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
-        assert_eq!(rd, ed);
-    }
-    test_mm_cmpnge_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpord_ss() {
-        let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
-        let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
-        let c = _mm_setr_ps(NAN, 5.0, 6.0, 7.0);
-        let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
-
-        let b1 = !0u32; // a.extract(0) ord b.extract(0)
-        let c1 = 0u32; // a.extract(0) ord c.extract(0)
-        let d1 = !0u32; // a.extract(0) ord d.extract(0)
-
-        let rb: [u32; 4] = transmute(_mm_cmpord_ss(a, b));
-        let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
-        assert_eq!(rb, eb);
-
-        let rc: [u32; 4] = transmute(_mm_cmpord_ss(a, c));
-        let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
-        assert_eq!(rc, ec);
-
-        let rd: [u32; 4] = transmute(_mm_cmpord_ss(a, d));
-        let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
-        assert_eq!(rd, ed);
-    }
-    test_mm_cmpord_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpunord_ss() {
-        let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
-        let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
-        let c = _mm_setr_ps(NAN, 5.0, 6.0, 7.0);
-        let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
-
-        let b1 = 0u32; // a.extract(0) unord b.extract(0)
-        let c1 = !0u32; // a.extract(0) unord c.extract(0)
-        let d1 = 0u32; // a.extract(0) unord d.extract(0)
-
-        let rb: [u32; 4] = transmute(_mm_cmpunord_ss(a, b));
-        let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
-        assert_eq!(rb, eb);
-
-        let rc: [u32; 4] = transmute(_mm_cmpunord_ss(a, c));
-        let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
-        assert_eq!(rc, ec);
-
-        let rd: [u32; 4] = transmute(_mm_cmpunord_ss(a, d));
-        let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
-        assert_eq!(rd, ed);
-    }
-    test_mm_cmpunord_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpeq_ps() {
-        let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
-        let b = _mm_setr_ps(15.0, 20.0, 1.0, NAN);
-        let tru = !0u32;
-        let fls = 0u32;
-
-        let e = [fls, fls, tru, fls];
-        let r: [u32; 4] = transmute(_mm_cmpeq_ps(a, b));
-        assert_eq!(r, e);
-    }
-    test_mm_cmpeq_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmplt_ps() {
-        let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
-        let b = _mm_setr_ps(15.0, 20.0, 1.0, NAN);
-        let tru = !0u32;
-        let fls = 0u32;
-
-        let e = [tru, fls, fls, fls];
-        let r: [u32; 4] = transmute(_mm_cmplt_ps(a, b));
-        assert_eq!(r, e);
-    }
-    test_mm_cmplt_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmple_ps() {
-        let a = _mm_setr_ps(10.0, 50.0, 1.0, 4.0);
-        let b = _mm_setr_ps(15.0, 20.0, 1.0, NAN);
-        let tru = !0u32;
-        let fls = 0u32;
-
-        let e = [tru, fls, tru, fls];
-        let r: [u32; 4] = transmute(_mm_cmple_ps(a, b));
-        assert_eq!(r, e);
-    }
-    test_mm_cmple_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpgt_ps() {
-        let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
-        let b = _mm_setr_ps(15.0, 20.0, 1.0, 42.0);
-        let tru = !0u32;
-        let fls = 0u32;
-
-        let e = [fls, tru, fls, fls];
-        let r: [u32; 4] = transmute(_mm_cmpgt_ps(a, b));
-        assert_eq!(r, e);
-    }
-    test_mm_cmpgt_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpge_ps() {
-        let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
-        let b = _mm_setr_ps(15.0, 20.0, 1.0, 42.0);
-        let tru = !0u32;
-        let fls = 0u32;
-
-        let e = [fls, tru, tru, fls];
-        let r: [u32; 4] = transmute(_mm_cmpge_ps(a, b));
-        assert_eq!(r, e);
-    }
-    test_mm_cmpge_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpneq_ps() {
-        let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
-        let b = _mm_setr_ps(15.0, 20.0, 1.0, NAN);
-        let tru = !0u32;
-        let fls = 0u32;
-
-        let e = [tru, tru, fls, tru];
-        let r: [u32; 4] = transmute(_mm_cmpneq_ps(a, b));
-        assert_eq!(r, e);
-    }
-    test_mm_cmpneq_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpnlt_ps() {
-        let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
-        let b = _mm_setr_ps(15.0, 20.0, 1.0, 5.0);
-        let tru = !0u32;
-        let fls = 0u32;
-
-        let e = [fls, tru, tru, tru];
-        let r: [u32; 4] = transmute(_mm_cmpnlt_ps(a, b));
-        assert_eq!(r, e);
-    }
-    test_mm_cmpnlt_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpnle_ps() {
-        let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
-        let b = _mm_setr_ps(15.0, 20.0, 1.0, 5.0);
-        let tru = !0u32;
-        let fls = 0u32;
-
-        let e = [fls, tru, fls, tru];
-        let r: [u32; 4] = transmute(_mm_cmpnle_ps(a, b));
-        assert_eq!(r, e);
-    }
-    test_mm_cmpnle_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpngt_ps() {
-        let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
-        let b = _mm_setr_ps(15.0, 20.0, 1.0, 5.0);
-        let tru = !0u32;
-        let fls = 0u32;
-
-        let e = [tru, fls, tru, tru];
-        let r: [u32; 4] = transmute(_mm_cmpngt_ps(a, b));
-        assert_eq!(r, e);
-    }
-    test_mm_cmpngt_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpnge_ps() {
-        let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
-        let b = _mm_setr_ps(15.0, 20.0, 1.0, 5.0);
-        let tru = !0u32;
-        let fls = 0u32;
-
-        let e = [tru, fls, fls, tru];
-        let r: [u32; 4] = transmute(_mm_cmpnge_ps(a, b));
-        assert_eq!(r, e);
-    }
-    test_mm_cmpnge_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpord_ps() {
-        let a = _mm_setr_ps(10.0, 50.0, NAN, NAN);
-        let b = _mm_setr_ps(15.0, NAN, 1.0, NAN);
-        let tru = !0u32;
-        let fls = 0u32;
-
-        let e = [tru, fls, fls, fls];
-        let r: [u32; 4] = transmute(_mm_cmpord_ps(a, b));
-        assert_eq!(r, e);
-    }
-    test_mm_cmpord_ps();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cmpunord_ps() {
-        let a = _mm_setr_ps(10.0, 50.0, NAN, NAN);
-        let b = _mm_setr_ps(15.0, NAN, 1.0, NAN);
-        let tru = !0u32;
-        let fls = 0u32;
-
-        let e = [fls, tru, tru, tru];
-        let r: [u32; 4] = transmute(_mm_cmpunord_ps(a, b));
-        assert_eq!(r, e);
-    }
-    test_mm_cmpunord_ps();
+        test_mm_mul_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_div_ss() {
+            let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0);
+            let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0);
+            let r = _mm_div_ss(a, b);
+            assert_eq_m128(r, _mm_setr_ps(0.01, 5.0, 0.0, -10.0));
+        }
+        test_mm_div_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_sqrt_ss() {
+            let a = _mm_setr_ps(4.0, 13.0, 16.0, 100.0);
+            let r = _mm_sqrt_ss(a);
+            let e = _mm_setr_ps(2.0, 13.0, 16.0, 100.0);
+            assert_eq_m128(r, e);
+        }
+        test_mm_sqrt_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_sqrt_ps() {
+            let a = _mm_setr_ps(4.0, 13.0, 16.0, 100.0);
+            let r = _mm_sqrt_ps(a);
+            let e = _mm_setr_ps(2.0, 3.6055512, 4.0, 10.0);
+            assert_eq_m128(r, e);
+        }
+        test_mm_sqrt_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_rcp_ss() {
+            let a = _mm_setr_ps(4.0, 13.0, 16.0, 100.0);
+            let r = _mm_rcp_ss(a);
+            let e = _mm_setr_ps(0.24993896, 13.0, 16.0, 100.0);
+            let rel_err = 0.00048828125;
+
+            let r: [f32; 4] = transmute(r);
+            let e: [f32; 4] = transmute(e);
+            assert_approx_eq!(r[0], e[0], 2. * rel_err);
+            for i in 1..4 {
+                assert_eq!(r[i], e[i]);
+            }
+        }
+        test_mm_rcp_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_rcp_ps() {
+            let a = _mm_setr_ps(4.0, 13.0, 16.0, 100.0);
+            let r = _mm_rcp_ps(a);
+            let e = _mm_setr_ps(0.24993896, 0.0769043, 0.06248474, 0.0099983215);
+            let rel_err = 0.00048828125;
+
+            let r: [f32; 4] = transmute(r);
+            let e: [f32; 4] = transmute(e);
+            for i in 0..4 {
+                assert_approx_eq!(r[i], e[i], 2. * rel_err);
+            }
+        }
+        test_mm_rcp_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_rsqrt_ss() {
+            let a = _mm_setr_ps(4.0, 13.0, 16.0, 100.0);
+            let r = _mm_rsqrt_ss(a);
+            let e = _mm_setr_ps(0.49987793, 13.0, 16.0, 100.0);
+            let rel_err = 0.00048828125;
+
+            let r: [f32; 4] = transmute(r);
+            let e: [f32; 4] = transmute(e);
+            assert_approx_eq!(r[0], e[0], 2. * rel_err);
+            for i in 1..4 {
+                assert_eq!(r[i], e[i]);
+            }
+        }
+        test_mm_rsqrt_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_rsqrt_ps() {
+            let a = _mm_setr_ps(4.0, 13.0, 16.0, 100.0);
+            let r = _mm_rsqrt_ps(a);
+            let e = _mm_setr_ps(0.49987793, 0.2772827, 0.24993896, 0.099990845);
+            let rel_err = 0.00048828125;
+
+            let r: [f32; 4] = transmute(r);
+            let e: [f32; 4] = transmute(e);
+            for i in 0..4 {
+                assert_approx_eq!(r[i], e[i], 2. * rel_err);
+            }
+        }
+        test_mm_rsqrt_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_min_ss() {
+            let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0);
+            let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0);
+            let r = _mm_min_ss(a, b);
+            assert_eq_m128(r, _mm_setr_ps(-100.0, 5.0, 0.0, -10.0));
+        }
+        test_mm_min_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_min_ps() {
+            let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0);
+            let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0);
+            let r = _mm_min_ps(a, b);
+            assert_eq_m128(r, _mm_setr_ps(-100.0, 5.0, 0.0, -10.0));
+
+            // `_mm_min_ps` can **not** be implemented using the `simd_min` rust intrinsic because
+            // the semantics of `simd_min` are different to those of `_mm_min_ps` regarding handling
+            // of `-0.0`.
+            let a = _mm_setr_ps(-0.0, 0.0, 0.0, 0.0);
+            let b = _mm_setr_ps(0.0, 0.0, 0.0, 0.0);
+            let r1: [u8; 16] = transmute(_mm_min_ps(a, b));
+            let r2: [u8; 16] = transmute(_mm_min_ps(b, a));
+            let a: [u8; 16] = transmute(a);
+            let b: [u8; 16] = transmute(b);
+            assert_eq!(r1, b);
+            assert_eq!(r2, a);
+            assert_ne!(a, b); // sanity check that -0.0 is actually present
+        }
+        test_mm_min_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_max_ss() {
+            let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0);
+            let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0);
+            let r = _mm_max_ss(a, b);
+            assert_eq_m128(r, _mm_setr_ps(-1.0, 5.0, 0.0, -10.0));
+        }
+        test_mm_max_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_max_ps() {
+            let a = _mm_setr_ps(-1.0, 5.0, 0.0, -10.0);
+            let b = _mm_setr_ps(-100.0, 20.0, 0.0, -5.0);
+            let r = _mm_max_ps(a, b);
+            assert_eq_m128(r, _mm_setr_ps(-1.0, 20.0, 0.0, -5.0));
+
+            // `_mm_max_ps` can **not** be implemented using the `simd_max` rust intrinsic because
+            // the semantics of `simd_max` are different to those of `_mm_max_ps` regarding handling
+            // of `-0.0`.
+            let a = _mm_setr_ps(-0.0, 0.0, 0.0, 0.0);
+            let b = _mm_setr_ps(0.0, 0.0, 0.0, 0.0);
+            let r1: [u8; 16] = transmute(_mm_max_ps(a, b));
+            let r2: [u8; 16] = transmute(_mm_max_ps(b, a));
+            let a: [u8; 16] = transmute(a);
+            let b: [u8; 16] = transmute(b);
+            assert_eq!(r1, b);
+            assert_eq!(r2, a);
+            assert_ne!(a, b); // sanity check that -0.0 is actually present
+        }
+        test_mm_max_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpeq_ss() {
+            let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
+            let b = _mm_setr_ps(-1.0, 5.0, 6.0, 7.0);
+            let r: [u32; 4] = transmute(_mm_cmpeq_ss(a, b));
+            let e: [u32; 4] = transmute(_mm_setr_ps(transmute(0u32), 2.0, 3.0, 4.0));
+            assert_eq!(r, e);
+
+            let b2 = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
+            let r2: [u32; 4] = transmute(_mm_cmpeq_ss(a, b2));
+            let e2: [u32; 4] = transmute(_mm_setr_ps(transmute(0xffffffffu32), 2.0, 3.0, 4.0));
+            assert_eq!(r2, e2);
+        }
+        test_mm_cmpeq_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmplt_ss() {
+            let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
+            let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
+            let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
+            let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
+
+            let b1 = 0u32; // a.extract(0) < b.extract(0)
+            let c1 = 0u32; // a.extract(0) < c.extract(0)
+            let d1 = !0u32; // a.extract(0) < d.extract(0)
+
+            let rb: [u32; 4] = transmute(_mm_cmplt_ss(a, b));
+            let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
+            assert_eq!(rb, eb);
+
+            let rc: [u32; 4] = transmute(_mm_cmplt_ss(a, c));
+            let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
+            assert_eq!(rc, ec);
+
+            let rd: [u32; 4] = transmute(_mm_cmplt_ss(a, d));
+            let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
+            assert_eq!(rd, ed);
+        }
+        test_mm_cmplt_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmple_ss() {
+            let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
+            let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
+            let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
+            let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
+
+            let b1 = 0u32; // a.extract(0) <= b.extract(0)
+            let c1 = !0u32; // a.extract(0) <= c.extract(0)
+            let d1 = !0u32; // a.extract(0) <= d.extract(0)
+
+            let rb: [u32; 4] = transmute(_mm_cmple_ss(a, b));
+            let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
+            assert_eq!(rb, eb);
+
+            let rc: [u32; 4] = transmute(_mm_cmple_ss(a, c));
+            let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
+            assert_eq!(rc, ec);
+
+            let rd: [u32; 4] = transmute(_mm_cmple_ss(a, d));
+            let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
+            assert_eq!(rd, ed);
+        }
+        test_mm_cmple_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpgt_ss() {
+            let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
+            let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
+            let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
+            let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
+
+            let b1 = !0u32; // a.extract(0) > b.extract(0)
+            let c1 = 0u32; // a.extract(0) > c.extract(0)
+            let d1 = 0u32; // a.extract(0) > d.extract(0)
+
+            let rb: [u32; 4] = transmute(_mm_cmpgt_ss(a, b));
+            let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
+            assert_eq!(rb, eb);
+
+            let rc: [u32; 4] = transmute(_mm_cmpgt_ss(a, c));
+            let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
+            assert_eq!(rc, ec);
+
+            let rd: [u32; 4] = transmute(_mm_cmpgt_ss(a, d));
+            let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
+            assert_eq!(rd, ed);
+        }
+        test_mm_cmpgt_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpge_ss() {
+            let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
+            let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
+            let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
+            let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
+
+            let b1 = !0u32; // a.extract(0) >= b.extract(0)
+            let c1 = !0u32; // a.extract(0) >= c.extract(0)
+            let d1 = 0u32; // a.extract(0) >= d.extract(0)
+
+            let rb: [u32; 4] = transmute(_mm_cmpge_ss(a, b));
+            let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
+            assert_eq!(rb, eb);
+
+            let rc: [u32; 4] = transmute(_mm_cmpge_ss(a, c));
+            let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
+            assert_eq!(rc, ec);
+
+            let rd: [u32; 4] = transmute(_mm_cmpge_ss(a, d));
+            let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
+            assert_eq!(rd, ed);
+        }
+        test_mm_cmpge_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpneq_ss() {
+            let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
+            let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
+            let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
+            let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
+
+            let b1 = !0u32; // a.extract(0) != b.extract(0)
+            let c1 = 0u32; // a.extract(0) != c.extract(0)
+            let d1 = !0u32; // a.extract(0) != d.extract(0)
+
+            let rb: [u32; 4] = transmute(_mm_cmpneq_ss(a, b));
+            let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
+            assert_eq!(rb, eb);
+
+            let rc: [u32; 4] = transmute(_mm_cmpneq_ss(a, c));
+            let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
+            assert_eq!(rc, ec);
+
+            let rd: [u32; 4] = transmute(_mm_cmpneq_ss(a, d));
+            let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
+            assert_eq!(rd, ed);
+        }
+        test_mm_cmpneq_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpnlt_ss() {
+            // TODO: this test is exactly the same as for `_mm_cmpge_ss`, but there
+            // must be a difference. It may have to do with behavior in the
+            // presence of NaNs (signaling or quiet). If so, we should add tests
+            // for those.
+
+            let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
+            let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
+            let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
+            let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
+
+            let b1 = !0u32; // a.extract(0) >= b.extract(0)
+            let c1 = !0u32; // a.extract(0) >= c.extract(0)
+            let d1 = 0u32; // a.extract(0) >= d.extract(0)
+
+            let rb: [u32; 4] = transmute(_mm_cmpnlt_ss(a, b));
+            let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
+            assert_eq!(rb, eb);
+
+            let rc: [u32; 4] = transmute(_mm_cmpnlt_ss(a, c));
+            let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
+            assert_eq!(rc, ec);
+
+            let rd: [u32; 4] = transmute(_mm_cmpnlt_ss(a, d));
+            let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
+            assert_eq!(rd, ed);
+        }
+        test_mm_cmpnlt_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpnle_ss() {
+            // TODO: this test is exactly the same as for `_mm_cmpgt_ss`, but there
+            // must be a difference. It may have to do with behavior in the
+            // presence
+            // of NaNs (signaling or quiet). If so, we should add tests for those.
+
+            let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
+            let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
+            let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
+            let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
+
+            let b1 = !0u32; // a.extract(0) > b.extract(0)
+            let c1 = 0u32; // a.extract(0) > c.extract(0)
+            let d1 = 0u32; // a.extract(0) > d.extract(0)
+
+            let rb: [u32; 4] = transmute(_mm_cmpnle_ss(a, b));
+            let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
+            assert_eq!(rb, eb);
+
+            let rc: [u32; 4] = transmute(_mm_cmpnle_ss(a, c));
+            let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
+            assert_eq!(rc, ec);
+
+            let rd: [u32; 4] = transmute(_mm_cmpnle_ss(a, d));
+            let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
+            assert_eq!(rd, ed);
+        }
+        test_mm_cmpnle_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpngt_ss() {
+            // TODO: this test is exactly the same as for `_mm_cmple_ss`, but there
+            // must be a difference. It may have to do with behavior in the
+            // presence of NaNs (signaling or quiet). If so, we should add tests
+            // for those.
+
+            let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
+            let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
+            let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
+            let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
+
+            let b1 = 0u32; // a.extract(0) <= b.extract(0)
+            let c1 = !0u32; // a.extract(0) <= c.extract(0)
+            let d1 = !0u32; // a.extract(0) <= d.extract(0)
+
+            let rb: [u32; 4] = transmute(_mm_cmpngt_ss(a, b));
+            let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
+            assert_eq!(rb, eb);
+
+            let rc: [u32; 4] = transmute(_mm_cmpngt_ss(a, c));
+            let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
+            assert_eq!(rc, ec);
+
+            let rd: [u32; 4] = transmute(_mm_cmpngt_ss(a, d));
+            let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
+            assert_eq!(rd, ed);
+        }
+        test_mm_cmpngt_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpnge_ss() {
+            // TODO: this test is exactly the same as for `_mm_cmplt_ss`, but there
+            // must be a difference. It may have to do with behavior in the
+            // presence of NaNs (signaling or quiet). If so, we should add tests
+            // for those.
+
+            let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
+            let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
+            let c = _mm_setr_ps(1.0, 5.0, 6.0, 7.0);
+            let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
+
+            let b1 = 0u32; // a.extract(0) < b.extract(0)
+            let c1 = 0u32; // a.extract(0) < c.extract(0)
+            let d1 = !0u32; // a.extract(0) < d.extract(0)
+
+            let rb: [u32; 4] = transmute(_mm_cmpnge_ss(a, b));
+            let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
+            assert_eq!(rb, eb);
+
+            let rc: [u32; 4] = transmute(_mm_cmpnge_ss(a, c));
+            let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
+            assert_eq!(rc, ec);
+
+            let rd: [u32; 4] = transmute(_mm_cmpnge_ss(a, d));
+            let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
+            assert_eq!(rd, ed);
+        }
+        test_mm_cmpnge_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpord_ss() {
+            let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
+            let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
+            let c = _mm_setr_ps(NAN, 5.0, 6.0, 7.0);
+            let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
+
+            let b1 = !0u32; // a.extract(0) ord b.extract(0)
+            let c1 = 0u32; // a.extract(0) ord c.extract(0)
+            let d1 = !0u32; // a.extract(0) ord d.extract(0)
+
+            let rb: [u32; 4] = transmute(_mm_cmpord_ss(a, b));
+            let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
+            assert_eq!(rb, eb);
+
+            let rc: [u32; 4] = transmute(_mm_cmpord_ss(a, c));
+            let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
+            assert_eq!(rc, ec);
+
+            let rd: [u32; 4] = transmute(_mm_cmpord_ss(a, d));
+            let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
+            assert_eq!(rd, ed);
+        }
+        test_mm_cmpord_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpunord_ss() {
+            let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
+            let b = _mm_setr_ps(0.0, 5.0, 6.0, 7.0);
+            let c = _mm_setr_ps(NAN, 5.0, 6.0, 7.0);
+            let d = _mm_setr_ps(2.0, 5.0, 6.0, 7.0);
+
+            let b1 = 0u32; // a.extract(0) unord b.extract(0)
+            let c1 = !0u32; // a.extract(0) unord c.extract(0)
+            let d1 = 0u32; // a.extract(0) unord d.extract(0)
+
+            let rb: [u32; 4] = transmute(_mm_cmpunord_ss(a, b));
+            let eb: [u32; 4] = transmute(_mm_setr_ps(transmute(b1), 2.0, 3.0, 4.0));
+            assert_eq!(rb, eb);
+
+            let rc: [u32; 4] = transmute(_mm_cmpunord_ss(a, c));
+            let ec: [u32; 4] = transmute(_mm_setr_ps(transmute(c1), 2.0, 3.0, 4.0));
+            assert_eq!(rc, ec);
+
+            let rd: [u32; 4] = transmute(_mm_cmpunord_ss(a, d));
+            let ed: [u32; 4] = transmute(_mm_setr_ps(transmute(d1), 2.0, 3.0, 4.0));
+            assert_eq!(rd, ed);
+        }
+        test_mm_cmpunord_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpeq_ps() {
+            let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
+            let b = _mm_setr_ps(15.0, 20.0, 1.0, NAN);
+            let tru = !0u32;
+            let fls = 0u32;
+
+            let e = [fls, fls, tru, fls];
+            let r: [u32; 4] = transmute(_mm_cmpeq_ps(a, b));
+            assert_eq!(r, e);
+        }
+        test_mm_cmpeq_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmplt_ps() {
+            let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
+            let b = _mm_setr_ps(15.0, 20.0, 1.0, NAN);
+            let tru = !0u32;
+            let fls = 0u32;
+
+            let e = [tru, fls, fls, fls];
+            let r: [u32; 4] = transmute(_mm_cmplt_ps(a, b));
+            assert_eq!(r, e);
+        }
+        test_mm_cmplt_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmple_ps() {
+            let a = _mm_setr_ps(10.0, 50.0, 1.0, 4.0);
+            let b = _mm_setr_ps(15.0, 20.0, 1.0, NAN);
+            let tru = !0u32;
+            let fls = 0u32;
+
+            let e = [tru, fls, tru, fls];
+            let r: [u32; 4] = transmute(_mm_cmple_ps(a, b));
+            assert_eq!(r, e);
+        }
+        test_mm_cmple_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpgt_ps() {
+            let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
+            let b = _mm_setr_ps(15.0, 20.0, 1.0, 42.0);
+            let tru = !0u32;
+            let fls = 0u32;
+
+            let e = [fls, tru, fls, fls];
+            let r: [u32; 4] = transmute(_mm_cmpgt_ps(a, b));
+            assert_eq!(r, e);
+        }
+        test_mm_cmpgt_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpge_ps() {
+            let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
+            let b = _mm_setr_ps(15.0, 20.0, 1.0, 42.0);
+            let tru = !0u32;
+            let fls = 0u32;
+
+            let e = [fls, tru, tru, fls];
+            let r: [u32; 4] = transmute(_mm_cmpge_ps(a, b));
+            assert_eq!(r, e);
+        }
+        test_mm_cmpge_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpneq_ps() {
+            let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
+            let b = _mm_setr_ps(15.0, 20.0, 1.0, NAN);
+            let tru = !0u32;
+            let fls = 0u32;
+
+            let e = [tru, tru, fls, tru];
+            let r: [u32; 4] = transmute(_mm_cmpneq_ps(a, b));
+            assert_eq!(r, e);
+        }
+        test_mm_cmpneq_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpnlt_ps() {
+            let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
+            let b = _mm_setr_ps(15.0, 20.0, 1.0, 5.0);
+            let tru = !0u32;
+            let fls = 0u32;
+
+            let e = [fls, tru, tru, tru];
+            let r: [u32; 4] = transmute(_mm_cmpnlt_ps(a, b));
+            assert_eq!(r, e);
+        }
+        test_mm_cmpnlt_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpnle_ps() {
+            let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
+            let b = _mm_setr_ps(15.0, 20.0, 1.0, 5.0);
+            let tru = !0u32;
+            let fls = 0u32;
+
+            let e = [fls, tru, fls, tru];
+            let r: [u32; 4] = transmute(_mm_cmpnle_ps(a, b));
+            assert_eq!(r, e);
+        }
+        test_mm_cmpnle_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpngt_ps() {
+            let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
+            let b = _mm_setr_ps(15.0, 20.0, 1.0, 5.0);
+            let tru = !0u32;
+            let fls = 0u32;
+
+            let e = [tru, fls, tru, tru];
+            let r: [u32; 4] = transmute(_mm_cmpngt_ps(a, b));
+            assert_eq!(r, e);
+        }
+        test_mm_cmpngt_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpnge_ps() {
+            let a = _mm_setr_ps(10.0, 50.0, 1.0, NAN);
+            let b = _mm_setr_ps(15.0, 20.0, 1.0, 5.0);
+            let tru = !0u32;
+            let fls = 0u32;
+
+            let e = [tru, fls, fls, tru];
+            let r: [u32; 4] = transmute(_mm_cmpnge_ps(a, b));
+            assert_eq!(r, e);
+        }
+        test_mm_cmpnge_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpord_ps() {
+            let a = _mm_setr_ps(10.0, 50.0, NAN, NAN);
+            let b = _mm_setr_ps(15.0, NAN, 1.0, NAN);
+            let tru = !0u32;
+            let fls = 0u32;
+
+            let e = [tru, fls, fls, fls];
+            let r: [u32; 4] = transmute(_mm_cmpord_ps(a, b));
+            assert_eq!(r, e);
+        }
+        test_mm_cmpord_ps();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cmpunord_ps() {
+            let a = _mm_setr_ps(10.0, 50.0, NAN, NAN);
+            let b = _mm_setr_ps(15.0, NAN, 1.0, NAN);
+            let tru = !0u32;
+            let fls = 0u32;
+
+            let e = [fls, tru, tru, tru];
+            let r: [u32; 4] = transmute(_mm_cmpunord_ps(a, b));
+            assert_eq!(r, e);
+        }
+        test_mm_cmpunord_ps();
 
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_comieq_ss() {
-        let aa = &[3.0f32, 12.0, 23.0, NAN];
-        let bb = &[3.0f32, 47.5, 1.5, NAN];
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_comieq_ss() {
+            let aa = &[3.0f32, 12.0, 23.0, NAN];
+            let bb = &[3.0f32, 47.5, 1.5, NAN];
 
-        let ee = &[1i32, 0, 0, 0];
+            let ee = &[1i32, 0, 0, 0];
 
-        for i in 0..4 {
-            let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
-            let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
+            for i in 0..4 {
+                let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
+                let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
 
-            let r = _mm_comieq_ss(a, b);
+                let r = _mm_comieq_ss(a, b);
 
-            assert_eq!(
-                ee[i], r,
-                "_mm_comieq_ss({:?}, {:?}) = {}, expected: {} (i={})",
-                a, b, r, ee[i], i
-            );
+                assert_eq!(
+                    ee[i], r,
+                    "_mm_comieq_ss({:?}, {:?}) = {}, expected: {} (i={})",
+                    a, b, r, ee[i], i
+                );
+            }
         }
-    }
-    test_mm_comieq_ss();
+        test_mm_comieq_ss();
 
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_comilt_ss() {
-        let aa = &[3.0f32, 12.0, 23.0, NAN];
-        let bb = &[3.0f32, 47.5, 1.5, NAN];
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_comilt_ss() {
+            let aa = &[3.0f32, 12.0, 23.0, NAN];
+            let bb = &[3.0f32, 47.5, 1.5, NAN];
 
-        let ee = &[0i32, 1, 0, 0];
+            let ee = &[0i32, 1, 0, 0];
 
-        for i in 0..4 {
-            let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
-            let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
+            for i in 0..4 {
+                let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
+                let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
 
-            let r = _mm_comilt_ss(a, b);
+                let r = _mm_comilt_ss(a, b);
 
-            assert_eq!(
-                ee[i], r,
-                "_mm_comilt_ss({:?}, {:?}) = {}, expected: {} (i={})",
-                a, b, r, ee[i], i
-            );
+                assert_eq!(
+                    ee[i], r,
+                    "_mm_comilt_ss({:?}, {:?}) = {}, expected: {} (i={})",
+                    a, b, r, ee[i], i
+                );
+            }
         }
-    }
-    test_mm_comilt_ss();
+        test_mm_comilt_ss();
 
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_comile_ss() {
-        let aa = &[3.0f32, 12.0, 23.0, NAN];
-        let bb = &[3.0f32, 47.5, 1.5, NAN];
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_comile_ss() {
+            let aa = &[3.0f32, 12.0, 23.0, NAN];
+            let bb = &[3.0f32, 47.5, 1.5, NAN];
 
-        let ee = &[1i32, 1, 0, 0];
+            let ee = &[1i32, 1, 0, 0];
 
-        for i in 0..4 {
-            let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
-            let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
+            for i in 0..4 {
+                let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
+                let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
 
-            let r = _mm_comile_ss(a, b);
+                let r = _mm_comile_ss(a, b);
 
-            assert_eq!(
-                ee[i], r,
-                "_mm_comile_ss({:?}, {:?}) = {}, expected: {} (i={})",
-                a, b, r, ee[i], i
-            );
+                assert_eq!(
+                    ee[i], r,
+                    "_mm_comile_ss({:?}, {:?}) = {}, expected: {} (i={})",
+                    a, b, r, ee[i], i
+                );
+            }
         }
-    }
-    test_mm_comile_ss();
+        test_mm_comile_ss();
 
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_comigt_ss() {
-        let aa = &[3.0f32, 12.0, 23.0, NAN];
-        let bb = &[3.0f32, 47.5, 1.5, NAN];
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_comigt_ss() {
+            let aa = &[3.0f32, 12.0, 23.0, NAN];
+            let bb = &[3.0f32, 47.5, 1.5, NAN];
 
-        let ee = &[1i32, 0, 1, 0];
+            let ee = &[1i32, 0, 1, 0];
 
-        for i in 0..4 {
-            let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
-            let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
+            for i in 0..4 {
+                let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
+                let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
 
-            let r = _mm_comige_ss(a, b);
+                let r = _mm_comige_ss(a, b);
 
-            assert_eq!(
-                ee[i], r,
-                "_mm_comige_ss({:?}, {:?}) = {}, expected: {} (i={})",
-                a, b, r, ee[i], i
-            );
+                assert_eq!(
+                    ee[i], r,
+                    "_mm_comige_ss({:?}, {:?}) = {}, expected: {} (i={})",
+                    a, b, r, ee[i], i
+                );
+            }
         }
-    }
-    test_mm_comigt_ss();
+        test_mm_comigt_ss();
 
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_comineq_ss() {
-        let aa = &[3.0f32, 12.0, 23.0, NAN];
-        let bb = &[3.0f32, 47.5, 1.5, NAN];
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_comineq_ss() {
+            let aa = &[3.0f32, 12.0, 23.0, NAN];
+            let bb = &[3.0f32, 47.5, 1.5, NAN];
 
-        let ee = &[0i32, 1, 1, 1];
+            let ee = &[0i32, 1, 1, 1];
 
-        for i in 0..4 {
-            let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
-            let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
+            for i in 0..4 {
+                let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
+                let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
 
-            let r = _mm_comineq_ss(a, b);
+                let r = _mm_comineq_ss(a, b);
 
-            assert_eq!(
-                ee[i], r,
-                "_mm_comineq_ss({:?}, {:?}) = {}, expected: {} (i={})",
-                a, b, r, ee[i], i
-            );
+                assert_eq!(
+                    ee[i], r,
+                    "_mm_comineq_ss({:?}, {:?}) = {}, expected: {} (i={})",
+                    a, b, r, ee[i], i
+                );
+            }
         }
-    }
-    test_mm_comineq_ss();
+        test_mm_comineq_ss();
 
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_ucomieq_ss() {
-        let aa = &[3.0f32, 12.0, 23.0, NAN];
-        let bb = &[3.0f32, 47.5, 1.5, NAN];
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_ucomieq_ss() {
+            let aa = &[3.0f32, 12.0, 23.0, NAN];
+            let bb = &[3.0f32, 47.5, 1.5, NAN];
 
-        let ee = &[1i32, 0, 0, 0];
+            let ee = &[1i32, 0, 0, 0];
 
-        for i in 0..4 {
-            let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
-            let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
+            for i in 0..4 {
+                let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
+                let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
 
-            let r = _mm_ucomieq_ss(a, b);
+                let r = _mm_ucomieq_ss(a, b);
 
-            assert_eq!(
-                ee[i], r,
-                "_mm_ucomieq_ss({:?}, {:?}) = {}, expected: {} (i={})",
-                a, b, r, ee[i], i
-            );
+                assert_eq!(
+                    ee[i], r,
+                    "_mm_ucomieq_ss({:?}, {:?}) = {}, expected: {} (i={})",
+                    a, b, r, ee[i], i
+                );
+            }
         }
-    }
-    test_mm_ucomieq_ss();
+        test_mm_ucomieq_ss();
 
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_ucomilt_ss() {
-        let aa = &[3.0f32, 12.0, 23.0, NAN];
-        let bb = &[3.0f32, 47.5, 1.5, NAN];
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_ucomilt_ss() {
+            let aa = &[3.0f32, 12.0, 23.0, NAN];
+            let bb = &[3.0f32, 47.5, 1.5, NAN];
 
-        let ee = &[0i32, 1, 0, 0];
+            let ee = &[0i32, 1, 0, 0];
 
-        for i in 0..4 {
-            let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
-            let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
+            for i in 0..4 {
+                let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
+                let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
 
-            let r = _mm_ucomilt_ss(a, b);
+                let r = _mm_ucomilt_ss(a, b);
 
-            assert_eq!(
-                ee[i], r,
-                "_mm_ucomilt_ss({:?}, {:?}) = {}, expected: {} (i={})",
-                a, b, r, ee[i], i
-            );
+                assert_eq!(
+                    ee[i], r,
+                    "_mm_ucomilt_ss({:?}, {:?}) = {}, expected: {} (i={})",
+                    a, b, r, ee[i], i
+                );
+            }
         }
-    }
-    test_mm_ucomilt_ss();
+        test_mm_ucomilt_ss();
 
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_ucomile_ss() {
-        let aa = &[3.0f32, 12.0, 23.0, NAN];
-        let bb = &[3.0f32, 47.5, 1.5, NAN];
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_ucomile_ss() {
+            let aa = &[3.0f32, 12.0, 23.0, NAN];
+            let bb = &[3.0f32, 47.5, 1.5, NAN];
 
-        let ee = &[1i32, 1, 0, 0];
+            let ee = &[1i32, 1, 0, 0];
 
-        for i in 0..4 {
-            let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
-            let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
+            for i in 0..4 {
+                let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
+                let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
 
-            let r = _mm_ucomile_ss(a, b);
+                let r = _mm_ucomile_ss(a, b);
 
-            assert_eq!(
-                ee[i], r,
-                "_mm_ucomile_ss({:?}, {:?}) = {}, expected: {} (i={})",
-                a, b, r, ee[i], i
-            );
+                assert_eq!(
+                    ee[i], r,
+                    "_mm_ucomile_ss({:?}, {:?}) = {}, expected: {} (i={})",
+                    a, b, r, ee[i], i
+                );
+            }
         }
-    }
-    test_mm_ucomile_ss();
+        test_mm_ucomile_ss();
 
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_ucomigt_ss() {
-        let aa = &[3.0f32, 12.0, 23.0, NAN];
-        let bb = &[3.0f32, 47.5, 1.5, NAN];
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_ucomigt_ss() {
+            let aa = &[3.0f32, 12.0, 23.0, NAN];
+            let bb = &[3.0f32, 47.5, 1.5, NAN];
 
-        let ee = &[0i32, 0, 1, 0];
+            let ee = &[0i32, 0, 1, 0];
 
-        for i in 0..4 {
-            let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
-            let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
+            for i in 0..4 {
+                let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
+                let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
 
-            let r = _mm_ucomigt_ss(a, b);
+                let r = _mm_ucomigt_ss(a, b);
 
-            assert_eq!(
-                ee[i], r,
-                "_mm_ucomigt_ss({:?}, {:?}) = {}, expected: {} (i={})",
-                a, b, r, ee[i], i
-            );
+                assert_eq!(
+                    ee[i], r,
+                    "_mm_ucomigt_ss({:?}, {:?}) = {}, expected: {} (i={})",
+                    a, b, r, ee[i], i
+                );
+            }
         }
-    }
-    test_mm_ucomigt_ss();
+        test_mm_ucomigt_ss();
 
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_ucomige_ss() {
-        let aa = &[3.0f32, 12.0, 23.0, NAN];
-        let bb = &[3.0f32, 47.5, 1.5, NAN];
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_ucomige_ss() {
+            let aa = &[3.0f32, 12.0, 23.0, NAN];
+            let bb = &[3.0f32, 47.5, 1.5, NAN];
 
-        let ee = &[1i32, 0, 1, 0];
+            let ee = &[1i32, 0, 1, 0];
 
-        for i in 0..4 {
-            let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
-            let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
+            for i in 0..4 {
+                let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
+                let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
 
-            let r = _mm_ucomige_ss(a, b);
+                let r = _mm_ucomige_ss(a, b);
 
-            assert_eq!(
-                ee[i], r,
-                "_mm_ucomige_ss({:?}, {:?}) = {}, expected: {} (i={})",
-                a, b, r, ee[i], i
-            );
+                assert_eq!(
+                    ee[i], r,
+                    "_mm_ucomige_ss({:?}, {:?}) = {}, expected: {} (i={})",
+                    a, b, r, ee[i], i
+                );
+            }
         }
-    }
-    test_mm_ucomige_ss();
+        test_mm_ucomige_ss();
 
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_ucomineq_ss() {
-        let aa = &[3.0f32, 12.0, 23.0, NAN];
-        let bb = &[3.0f32, 47.5, 1.5, NAN];
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_ucomineq_ss() {
+            let aa = &[3.0f32, 12.0, 23.0, NAN];
+            let bb = &[3.0f32, 47.5, 1.5, NAN];
 
-        let ee = &[0i32, 1, 1, 1];
+            let ee = &[0i32, 1, 1, 1];
 
-        for i in 0..4 {
-            let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
-            let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
+            for i in 0..4 {
+                let a = _mm_setr_ps(aa[i], 1.0, 2.0, 3.0);
+                let b = _mm_setr_ps(bb[i], 0.0, 2.0, 4.0);
 
-            let r = _mm_ucomineq_ss(a, b);
+                let r = _mm_ucomineq_ss(a, b);
 
-            assert_eq!(
-                ee[i], r,
-                "_mm_ucomineq_ss({:?}, {:?}) = {}, expected: {} (i={})",
-                a, b, r, ee[i], i
-            );
+                assert_eq!(
+                    ee[i], r,
+                    "_mm_ucomineq_ss({:?}, {:?}) = {}, expected: {} (i={})",
+                    a, b, r, ee[i], i
+                );
+            }
         }
-    }
-    test_mm_ucomineq_ss();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cvtss_si32() {
-        let inputs = &[42.0f32, -3.1, 4.0e10, 4.0e-20, NAN, 2147483500.1];
-        let result = &[42i32, -3, i32::MIN, 0, i32::MIN, 2147483520];
-        for i in 0..inputs.len() {
-            let x = _mm_setr_ps(inputs[i], 1.0, 3.0, 4.0);
-            let e = result[i];
-            let r = _mm_cvtss_si32(x);
-            assert_eq!(e, r, "TestCase #{} _mm_cvtss_si32({:?}) = {}, expected: {}", i, x, r, e);
+        test_mm_ucomineq_ss();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cvtss_si32() {
+            let inputs = &[42.0f32, -3.1, 4.0e10, 4.0e-20, NAN, 2147483500.1];
+            let result = &[42i32, -3, i32::MIN, 0, i32::MIN, 2147483520];
+            for i in 0..inputs.len() {
+                let x = _mm_setr_ps(inputs[i], 1.0, 3.0, 4.0);
+                let e = result[i];
+                let r = _mm_cvtss_si32(x);
+                assert_eq!(
+                    e, r,
+                    "TestCase #{} _mm_cvtss_si32({:?}) = {}, expected: {}",
+                    i, x, r, e
+                );
+            }
         }
-    }
-    test_mm_cvtss_si32();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cvttss_si32() {
-        let inputs = &[
-            (42.0f32, 42i32),
-            (-31.4, -31),
-            (-33.5, -33),
-            (-34.5, -34),
-            (10.999, 10),
-            (-5.99, -5),
-            (4.0e10, i32::MIN),
-            (4.0e-10, 0),
-            (NAN, i32::MIN),
-            (2147483500.1, 2147483520),
-        ];
-        for i in 0..inputs.len() {
-            let (xi, e) = inputs[i];
-            let x = _mm_setr_ps(xi, 1.0, 3.0, 4.0);
-            let r = _mm_cvttss_si32(x);
-            assert_eq!(e, r, "TestCase #{} _mm_cvttss_si32({:?}) = {}, expected: {}", i, x, r, e);
+        test_mm_cvtss_si32();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cvttss_si32() {
+            let inputs = &[
+                (42.0f32, 42i32),
+                (-31.4, -31),
+                (-33.5, -33),
+                (-34.5, -34),
+                (10.999, 10),
+                (-5.99, -5),
+                (4.0e10, i32::MIN),
+                (4.0e-10, 0),
+                (NAN, i32::MIN),
+                (2147483500.1, 2147483520),
+            ];
+            for i in 0..inputs.len() {
+                let (xi, e) = inputs[i];
+                let x = _mm_setr_ps(xi, 1.0, 3.0, 4.0);
+                let r = _mm_cvttss_si32(x);
+                assert_eq!(
+                    e, r,
+                    "TestCase #{} _mm_cvttss_si32({:?}) = {}, expected: {}",
+                    i, x, r, e
+                );
+            }
         }
-    }
-    test_mm_cvttss_si32();
-
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cvtss_f32() {
-        let a = _mm_setr_ps(312.0134, 5.0, 6.0, 7.0);
-        assert_eq!(_mm_cvtss_f32(a), 312.0134);
-    }
-    test_mm_cvtss_f32();
+        test_mm_cvttss_si32();
 
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cvtsi32_ss() {
-        let inputs = &[
-            (4555i32, 4555.0f32),
-            (322223333, 322223330.0),
-            (-432, -432.0),
-            (-322223333, -322223330.0),
-        ];
-
-        for i in 0..inputs.len() {
-            let (x, f) = inputs[i];
-            let a = _mm_setr_ps(5.0, 6.0, 7.0, 8.0);
-            let r = _mm_cvtsi32_ss(a, x);
-            let e = _mm_setr_ps(f, 6.0, 7.0, 8.0);
-            assert_eq_m128(e, r);
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cvtss_f32() {
+            let a = _mm_setr_ps(312.0134, 5.0, 6.0, 7.0);
+            assert_eq!(_mm_cvtss_f32(a), 312.0134);
         }
-    }
-    test_mm_cvtsi32_ss();
-
-    // Intrinsic only available on x86_64
-    #[cfg(target_arch = "x86_64")]
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cvtss_si64() {
-        let inputs = &[
-            (42.0f32, 42i64),
-            (-31.4, -31),
-            (-33.5, -34),
-            (-34.5, -34),
-            (4.0e10, 40_000_000_000),
-            (4.0e-10, 0),
-            (f32::NAN, i64::MIN),
-            (2147483500.1, 2147483520),
-            (9.223371e18, 9223370937343148032),
-        ];
-        for i in 0..inputs.len() {
-            let (xi, e) = inputs[i];
-            let x = _mm_setr_ps(xi, 1.0, 3.0, 4.0);
-            let r = _mm_cvtss_si64(x);
-            assert_eq!(e, r, "TestCase #{} _mm_cvtss_si64({:?}) = {}, expected: {}", i, x, r, e);
+        test_mm_cvtss_f32();
+
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cvtsi32_ss() {
+            let inputs = &[
+                (4555i32, 4555.0f32),
+                (322223333, 322223330.0),
+                (-432, -432.0),
+                (-322223333, -322223330.0),
+            ];
+
+            for i in 0..inputs.len() {
+                let (x, f) = inputs[i];
+                let a = _mm_setr_ps(5.0, 6.0, 7.0, 8.0);
+                let r = _mm_cvtsi32_ss(a, x);
+                let e = _mm_setr_ps(f, 6.0, 7.0, 8.0);
+                assert_eq_m128(e, r);
+            }
         }
-    }
-    #[cfg(target_arch = "x86_64")]
-    test_mm_cvtss_si64();
-
-    // Intrinsic only available on x86_64
-    #[cfg(target_arch = "x86_64")]
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cvttss_si64() {
-        let inputs = &[
-            (42.0f32, 42i64),
-            (-31.4, -31),
-            (-33.5, -33),
-            (-34.5, -34),
-            (10.999, 10),
-            (-5.99, -5),
-            (4.0e10, 40_000_000_000),
-            (4.0e-10, 0),
-            (f32::NAN, i64::MIN),
-            (2147483500.1, 2147483520),
-            (9.223371e18, 9223370937343148032),
-            (9.223372e18, i64::MIN),
-        ];
-        for i in 0..inputs.len() {
-            let (xi, e) = inputs[i];
-            let x = _mm_setr_ps(xi, 1.0, 3.0, 4.0);
-            let r = _mm_cvttss_si64(x);
-            assert_eq!(e, r, "TestCase #{} _mm_cvttss_si64({:?}) = {}, expected: {}", i, x, r, e);
+        test_mm_cvtsi32_ss();
+
+        // Intrinsic only available on x86_64
+        #[cfg(target_arch = "x86_64")]
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cvtss_si64() {
+            let inputs = &[
+                (42.0f32, 42i64),
+                (-31.4, -31),
+                (-33.5, -34),
+                (-34.5, -34),
+                (4.0e10, 40_000_000_000),
+                (4.0e-10, 0),
+                (f32::NAN, i64::MIN),
+                (2147483500.1, 2147483520),
+                (9.223371e18, 9223370937343148032),
+            ];
+            for i in 0..inputs.len() {
+                let (xi, e) = inputs[i];
+                let x = _mm_setr_ps(xi, 1.0, 3.0, 4.0);
+                let r = _mm_cvtss_si64(x);
+                assert_eq!(
+                    e, r,
+                    "TestCase #{} _mm_cvtss_si64({:?}) = {}, expected: {}",
+                    i, x, r, e
+                );
+            }
         }
-    }
-    #[cfg(target_arch = "x86_64")]
-    test_mm_cvttss_si64();
-
-    // Intrinsic only available on x86_64
-    #[cfg(target_arch = "x86_64")]
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_cvtsi64_ss() {
-        let inputs = &[
-            (4555i64, 4555.0f32),
-            (322223333, 322223330.0),
-            (-432, -432.0),
-            (-322223333, -322223330.0),
-            (9223372036854775807, 9.223372e18),
-            (-9223372036854775808, -9.223372e18),
-        ];
-
-        for i in 0..inputs.len() {
-            let (x, f) = inputs[i];
-            let a = _mm_setr_ps(5.0, 6.0, 7.0, 8.0);
-            let r = _mm_cvtsi64_ss(a, x);
-            let e = _mm_setr_ps(f, 6.0, 7.0, 8.0);
-            assert_eq_m128(e, r);
+        #[cfg(target_arch = "x86_64")]
+        test_mm_cvtss_si64();
+
+        // Intrinsic only available on x86_64
+        #[cfg(target_arch = "x86_64")]
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cvttss_si64() {
+            let inputs = &[
+                (42.0f32, 42i64),
+                (-31.4, -31),
+                (-33.5, -33),
+                (-34.5, -34),
+                (10.999, 10),
+                (-5.99, -5),
+                (4.0e10, 40_000_000_000),
+                (4.0e-10, 0),
+                (f32::NAN, i64::MIN),
+                (2147483500.1, 2147483520),
+                (9.223371e18, 9223370937343148032),
+                (9.223372e18, i64::MIN),
+            ];
+            for i in 0..inputs.len() {
+                let (xi, e) = inputs[i];
+                let x = _mm_setr_ps(xi, 1.0, 3.0, 4.0);
+                let r = _mm_cvttss_si64(x);
+                assert_eq!(
+                    e, r,
+                    "TestCase #{} _mm_cvttss_si64({:?}) = {}, expected: {}",
+                    i, x, r, e
+                );
+            }
         }
-    }
-    #[cfg(target_arch = "x86_64")]
-    test_mm_cvtsi64_ss();
+        #[cfg(target_arch = "x86_64")]
+        test_mm_cvttss_si64();
+
+        // Intrinsic only available on x86_64
+        #[cfg(target_arch = "x86_64")]
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_cvtsi64_ss() {
+            let inputs = &[
+                (4555i64, 4555.0f32),
+                (322223333, 322223330.0),
+                (-432, -432.0),
+                (-322223333, -322223330.0),
+                (9223372036854775807, 9.223372e18),
+                (-9223372036854775808, -9.223372e18),
+            ];
+
+            for i in 0..inputs.len() {
+                let (x, f) = inputs[i];
+                let a = _mm_setr_ps(5.0, 6.0, 7.0, 8.0);
+                let r = _mm_cvtsi64_ss(a, x);
+                let e = _mm_setr_ps(f, 6.0, 7.0, 8.0);
+                assert_eq_m128(e, r);
+            }
+        }
+        #[cfg(target_arch = "x86_64")]
+        test_mm_cvtsi64_ss();
 
-    #[target_feature(enable = "sse")]
-    unsafe fn test_mm_movemask_ps() {
-        let r = _mm_movemask_ps(_mm_setr_ps(-1.0, 5.0, -5.0, 0.0));
-        assert_eq!(r, 0b0101);
+        #[target_feature(enable = "sse")]
+        unsafe fn test_mm_movemask_ps() {
+            let r = _mm_movemask_ps(_mm_setr_ps(-1.0, 5.0, -5.0, 0.0));
+            assert_eq!(r, 0b0101);
 
-        let r = _mm_movemask_ps(_mm_setr_ps(-1.0, -5.0, -5.0, 0.0));
-        assert_eq!(r, 0b0111);
+            let r = _mm_movemask_ps(_mm_setr_ps(-1.0, -5.0, -5.0, 0.0));
+            assert_eq!(r, 0b0111);
+        }
+        test_mm_movemask_ps();
+
+        let x = 0i8;
+        _mm_prefetch(&x, _MM_HINT_T0);
+        _mm_prefetch(&x, _MM_HINT_T1);
+        _mm_prefetch(&x, _MM_HINT_T2);
+        _mm_prefetch(&x, _MM_HINT_NTA);
+        _mm_prefetch(&x, _MM_HINT_ET0);
+        _mm_prefetch(&x, _MM_HINT_ET1);
     }
-    test_mm_movemask_ps();
-
-    let x = 0i8;
-    _mm_prefetch(&x, _MM_HINT_T0);
-    _mm_prefetch(&x, _MM_HINT_T1);
-    _mm_prefetch(&x, _MM_HINT_T2);
-    _mm_prefetch(&x, _MM_HINT_NTA);
-    _mm_prefetch(&x, _MM_HINT_ET0);
-    _mm_prefetch(&x, _MM_HINT_ET1);
 }
diff --git a/src/tools/miri/tests/pass/intrinsics-x86-sse2.rs b/src/tools/miri/tests/pass/intrinsics-x86-sse2.rs
index 1b55a94783a..fa9df04d368 100644
--- a/src/tools/miri/tests/pass/intrinsics-x86-sse2.rs
+++ b/src/tools/miri/tests/pass/intrinsics-x86-sse2.rs
@@ -1,828 +1,825 @@
-// Ignore everything except x86 and x86_64
-// Any additional target are added to CI should be ignored here
-//@ignore-target-aarch64
-//@ignore-target-arm
-//@ignore-target-avr
-//@ignore-target-s390x
-//@ignore-target-thumbv7em
-//@ignore-target-wasm32
-
-#[cfg(target_arch = "x86")]
-use std::arch::x86::*;
-#[cfg(target_arch = "x86_64")]
-use std::arch::x86_64::*;
-use std::f64::NAN;
-use std::mem::transmute;
-
 fn main() {
-    assert!(is_x86_feature_detected!("sse2"));
+    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+    {
+        assert!(is_x86_feature_detected!("sse2"));
 
-    unsafe {
-        test_sse2();
+        unsafe {
+            tests::test_sse2();
+        }
     }
 }
 
-#[target_feature(enable = "sse2")]
-unsafe fn _mm_setr_epi64x(a: i64, b: i64) -> __m128i {
-    _mm_set_epi64x(b, a)
-}
-
-#[target_feature(enable = "sse2")]
-unsafe fn test_sse2() {
-    // Mostly copied from library/stdarch/crates/core_arch/src/x86{,_64}/sse2.rs
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+mod tests {
+    #[cfg(target_arch = "x86")]
+    use std::arch::x86::*;
+    #[cfg(target_arch = "x86_64")]
+    use std::arch::x86_64::*;
+    use std::f64::NAN;
+    use std::mem::transmute;
 
+    #[target_feature(enable = "sse2")]
     unsafe fn _mm_setr_epi64x(a: i64, b: i64) -> __m128i {
         _mm_set_epi64x(b, a)
     }
 
-    #[track_caller]
-    #[target_feature(enable = "sse")]
-    unsafe fn assert_eq_m128(a: __m128, b: __m128) {
-        let r = _mm_cmpeq_ps(a, b);
-        if _mm_movemask_ps(r) != 0b1111 {
-            panic!("{:?} != {:?}", a, b);
+    #[target_feature(enable = "sse2")]
+    pub(super) unsafe fn test_sse2() {
+        // Mostly copied from library/stdarch/crates/core_arch/src/x86{,_64}/sse2.rs
+
+        unsafe fn _mm_setr_epi64x(a: i64, b: i64) -> __m128i {
+            _mm_set_epi64x(b, a)
         }
-    }
 
-    #[track_caller]
-    #[target_feature(enable = "sse2")]
-    unsafe fn assert_eq_m128i(a: __m128i, b: __m128i) {
-        assert_eq!(transmute::<_, [u64; 2]>(a), transmute::<_, [u64; 2]>(b))
-    }
+        #[track_caller]
+        #[target_feature(enable = "sse")]
+        unsafe fn assert_eq_m128(a: __m128, b: __m128) {
+            let r = _mm_cmpeq_ps(a, b);
+            if _mm_movemask_ps(r) != 0b1111 {
+                panic!("{:?} != {:?}", a, b);
+            }
+        }
 
-    #[track_caller]
-    #[target_feature(enable = "sse2")]
-    unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) {
-        if _mm_movemask_pd(_mm_cmpeq_pd(a, b)) != 0b11 {
-            panic!("{:?} != {:?}", a, b);
+        #[track_caller]
+        #[target_feature(enable = "sse2")]
+        unsafe fn assert_eq_m128i(a: __m128i, b: __m128i) {
+            assert_eq!(transmute::<_, [u64; 2]>(a), transmute::<_, [u64; 2]>(b))
         }
-    }
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_avg_epu8() {
-        let (a, b) = (_mm_set1_epi8(3), _mm_set1_epi8(9));
-        let r = _mm_avg_epu8(a, b);
-        assert_eq_m128i(r, _mm_set1_epi8(6));
-    }
-    test_mm_avg_epu8();
+        #[track_caller]
+        #[target_feature(enable = "sse2")]
+        unsafe fn assert_eq_m128d(a: __m128d, b: __m128d) {
+            if _mm_movemask_pd(_mm_cmpeq_pd(a, b)) != 0b11 {
+                panic!("{:?} != {:?}", a, b);
+            }
+        }
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_avg_epu16() {
-        let (a, b) = (_mm_set1_epi16(3), _mm_set1_epi16(9));
-        let r = _mm_avg_epu16(a, b);
-        assert_eq_m128i(r, _mm_set1_epi16(6));
-    }
-    test_mm_avg_epu16();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_avg_epu8() {
+            let (a, b) = (_mm_set1_epi8(3), _mm_set1_epi8(9));
+            let r = _mm_avg_epu8(a, b);
+            assert_eq_m128i(r, _mm_set1_epi8(6));
+        }
+        test_mm_avg_epu8();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_mulhi_epi16() {
-        let (a, b) = (_mm_set1_epi16(1000), _mm_set1_epi16(-1001));
-        let r = _mm_mulhi_epi16(a, b);
-        assert_eq_m128i(r, _mm_set1_epi16(-16));
-    }
-    test_mm_mulhi_epi16();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_avg_epu16() {
+            let (a, b) = (_mm_set1_epi16(3), _mm_set1_epi16(9));
+            let r = _mm_avg_epu16(a, b);
+            assert_eq_m128i(r, _mm_set1_epi16(6));
+        }
+        test_mm_avg_epu16();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_mulhi_epu16() {
-        let (a, b) = (_mm_set1_epi16(1000), _mm_set1_epi16(1001));
-        let r = _mm_mulhi_epu16(a, b);
-        assert_eq_m128i(r, _mm_set1_epi16(15));
-    }
-    test_mm_mulhi_epu16();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_mulhi_epi16() {
+            let (a, b) = (_mm_set1_epi16(1000), _mm_set1_epi16(-1001));
+            let r = _mm_mulhi_epi16(a, b);
+            assert_eq_m128i(r, _mm_set1_epi16(-16));
+        }
+        test_mm_mulhi_epi16();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_mul_epu32() {
-        let a = _mm_setr_epi64x(1_000_000_000, 1 << 34);
-        let b = _mm_setr_epi64x(1_000_000_000, 1 << 35);
-        let r = _mm_mul_epu32(a, b);
-        let e = _mm_setr_epi64x(1_000_000_000 * 1_000_000_000, 0);
-        assert_eq_m128i(r, e);
-    }
-    test_mm_mul_epu32();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_mulhi_epu16() {
+            let (a, b) = (_mm_set1_epi16(1000), _mm_set1_epi16(1001));
+            let r = _mm_mulhi_epu16(a, b);
+            assert_eq_m128i(r, _mm_set1_epi16(15));
+        }
+        test_mm_mulhi_epu16();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_mul_epu32() {
+            let a = _mm_setr_epi64x(1_000_000_000, 1 << 34);
+            let b = _mm_setr_epi64x(1_000_000_000, 1 << 35);
+            let r = _mm_mul_epu32(a, b);
+            let e = _mm_setr_epi64x(1_000_000_000 * 1_000_000_000, 0);
+            assert_eq_m128i(r, e);
+        }
+        test_mm_mul_epu32();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_sad_epu8() {
-        #[rustfmt::skip]
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_sad_epu8() {
+            #[rustfmt::skip]
         let a = _mm_setr_epi8(
             255u8 as i8, 254u8 as i8, 253u8 as i8, 252u8 as i8,
             1, 2, 3, 4,
             155u8 as i8, 154u8 as i8, 153u8 as i8, 152u8 as i8,
             1, 2, 3, 4,
         );
-        let b = _mm_setr_epi8(0, 0, 0, 0, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2);
-        let r = _mm_sad_epu8(a, b);
-        let e = _mm_setr_epi64x(1020, 614);
-        assert_eq_m128i(r, e);
-    }
-    test_mm_sad_epu8();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_sll_epi16() {
-        let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF);
-        let r = _mm_sll_epi16(a, _mm_set_epi64x(0, 4));
-        assert_eq_m128i(
-            r,
-            _mm_setr_epi16(0xCC0, -0xCC0, 0xDD0, -0xDD0, 0xEE0, -0xEE0, 0xFF0, -0xFF0),
-        );
-        let r = _mm_sll_epi16(a, _mm_set_epi64x(4, 0));
-        assert_eq_m128i(r, a);
-        let r = _mm_sll_epi16(a, _mm_set_epi64x(0, 16));
-        assert_eq_m128i(r, _mm_set1_epi16(0));
-        let r = _mm_sll_epi16(a, _mm_set_epi64x(0, i64::MAX));
-        assert_eq_m128i(r, _mm_set1_epi16(0));
-    }
-    test_mm_sll_epi16();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_srl_epi16() {
-        let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF);
-        let r = _mm_srl_epi16(a, _mm_set_epi64x(0, 4));
-        assert_eq_m128i(r, _mm_setr_epi16(0xC, 0xFF3, 0xD, 0xFF2, 0xE, 0xFF1, 0xF, 0xFF0));
-        let r = _mm_srl_epi16(a, _mm_set_epi64x(4, 0));
-        assert_eq_m128i(r, a);
-        let r = _mm_srl_epi16(a, _mm_set_epi64x(0, 16));
-        assert_eq_m128i(r, _mm_set1_epi16(0));
-        let r = _mm_srl_epi16(a, _mm_set_epi64x(0, i64::MAX));
-        assert_eq_m128i(r, _mm_set1_epi16(0));
-    }
-    test_mm_srl_epi16();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_sra_epi16() {
-        let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF);
-        let r = _mm_sra_epi16(a, _mm_set_epi64x(0, 4));
-        assert_eq_m128i(r, _mm_setr_epi16(0xC, -0xD, 0xD, -0xE, 0xE, -0xF, 0xF, -0x10));
-        let r = _mm_sra_epi16(a, _mm_set_epi64x(4, 0));
-        assert_eq_m128i(r, a);
-        let r = _mm_sra_epi16(a, _mm_set_epi64x(0, 16));
-        assert_eq_m128i(r, _mm_setr_epi16(0, -1, 0, -1, 0, -1, 0, -1));
-        let r = _mm_sra_epi16(a, _mm_set_epi64x(0, i64::MAX));
-        assert_eq_m128i(r, _mm_setr_epi16(0, -1, 0, -1, 0, -1, 0, -1));
-    }
-    test_mm_sra_epi16();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_sll_epi32() {
-        let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF);
-        let r = _mm_sll_epi32(a, _mm_set_epi64x(0, 4));
-        assert_eq_m128i(r, _mm_setr_epi32(0xEEEE0, -0xEEEE0, 0xFFFF0, -0xFFFF0));
-        let r = _mm_sll_epi32(a, _mm_set_epi64x(4, 0));
-        assert_eq_m128i(r, a);
-        let r = _mm_sll_epi32(a, _mm_set_epi64x(0, 32));
-        assert_eq_m128i(r, _mm_set1_epi32(0));
-        let r = _mm_sll_epi32(a, _mm_set_epi64x(0, i64::MAX));
-        assert_eq_m128i(r, _mm_set1_epi32(0));
-    }
-    test_mm_sll_epi32();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_srl_epi32() {
-        let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF);
-        let r = _mm_srl_epi32(a, _mm_set_epi64x(0, 4));
-        assert_eq_m128i(r, _mm_setr_epi32(0xEEE, 0xFFFF111, 0xFFF, 0xFFFF000));
-        let r = _mm_srl_epi32(a, _mm_set_epi64x(4, 0));
-        assert_eq_m128i(r, a);
-        let r = _mm_srl_epi32(a, _mm_set_epi64x(0, 32));
-        assert_eq_m128i(r, _mm_set1_epi32(0));
-        let r = _mm_srl_epi32(a, _mm_set_epi64x(0, i64::MAX));
-        assert_eq_m128i(r, _mm_set1_epi32(0));
-    }
-    test_mm_srl_epi32();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_sra_epi32() {
-        let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF);
-        let r = _mm_sra_epi32(a, _mm_set_epi64x(0, 4));
-        assert_eq_m128i(r, _mm_setr_epi32(0xEEE, -0xEEF, 0xFFF, -0x1000));
-        let r = _mm_sra_epi32(a, _mm_set_epi64x(4, 0));
-        assert_eq_m128i(r, a);
-        let r = _mm_sra_epi32(a, _mm_set_epi64x(0, 32));
-        assert_eq_m128i(r, _mm_setr_epi32(0, -1, 0, -1));
-        let r = _mm_sra_epi32(a, _mm_set_epi64x(0, i64::MAX));
-        assert_eq_m128i(r, _mm_setr_epi32(0, -1, 0, -1));
-    }
-    test_mm_sra_epi32();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_sll_epi64() {
-        let a = _mm_set_epi64x(0xFFFFFFFF, -0xFFFFFFFF);
-        let r = _mm_sll_epi64(a, _mm_set_epi64x(0, 4));
-        assert_eq_m128i(r, _mm_set_epi64x(0xFFFFFFFF0, -0xFFFFFFFF0));
-        let r = _mm_sll_epi64(a, _mm_set_epi64x(4, 0));
-        assert_eq_m128i(r, a);
-        let r = _mm_sll_epi64(a, _mm_set_epi64x(0, 64));
-        assert_eq_m128i(r, _mm_set1_epi64x(0));
-        let r = _mm_sll_epi64(a, _mm_set_epi64x(0, i64::MAX));
-        assert_eq_m128i(r, _mm_set1_epi64x(0));
-    }
-    test_mm_sll_epi64();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_srl_epi64() {
-        let a = _mm_set_epi64x(0xFFFFFFFF, -0xFFFFFFFF);
-        let r = _mm_srl_epi64(a, _mm_set_epi64x(0, 4));
-        assert_eq_m128i(r, _mm_set_epi64x(0xFFFFFFF, 0xFFFFFFFF0000000));
-        let r = _mm_srl_epi64(a, _mm_set_epi64x(4, 0));
-        assert_eq_m128i(r, a);
-        let r = _mm_srl_epi64(a, _mm_set_epi64x(0, 64));
-        assert_eq_m128i(r, _mm_set1_epi64x(0));
-        let r = _mm_srl_epi64(a, _mm_set_epi64x(0, i64::MAX));
-        assert_eq_m128i(r, _mm_set1_epi64x(0));
-    }
-    test_mm_srl_epi64();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cvtepi32_ps() {
-        let a = _mm_setr_epi32(1, 2, 3, 4);
-        let r = _mm_cvtepi32_ps(a);
-        assert_eq_m128(r, _mm_setr_ps(1.0, 2.0, 3.0, 4.0));
-    }
-    test_mm_cvtepi32_ps();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cvtps_epi32() {
-        let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
-        let r = _mm_cvtps_epi32(a);
-        assert_eq_m128i(r, _mm_setr_epi32(1, 2, 3, 4));
-    }
-    test_mm_cvtps_epi32();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cvttps_epi32() {
-        let a = _mm_setr_ps(-1.1, 2.2, -3.3, 6.6);
-        let r = _mm_cvttps_epi32(a);
-        assert_eq_m128i(r, _mm_setr_epi32(-1, 2, -3, 6));
-
-        let a = _mm_setr_ps(f32::NEG_INFINITY, f32::INFINITY, f32::MIN, f32::MAX);
-        let r = _mm_cvttps_epi32(a);
-        assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, i32::MIN, i32::MIN));
-    }
-    test_mm_cvttps_epi32();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_packs_epi16() {
-        let a = _mm_setr_epi16(0x80, -0x81, 0, 0, 0, 0, 0, 0);
-        let b = _mm_setr_epi16(0, 0, 0, 0, 0, 0, -0x81, 0x80);
-        let r = _mm_packs_epi16(a, b);
-        assert_eq_m128i(
-            r,
-            _mm_setr_epi8(0x7F, -0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0x80, 0x7F),
-        );
-    }
-    test_mm_packs_epi16();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_packus_epi16() {
-        let a = _mm_setr_epi16(0x100, -1, 0, 0, 0, 0, 0, 0);
-        let b = _mm_setr_epi16(0, 0, 0, 0, 0, 0, -1, 0x100);
-        let r = _mm_packus_epi16(a, b);
-        assert_eq_m128i(r, _mm_setr_epi8(!0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, !0));
-    }
-    test_mm_packus_epi16();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_packs_epi32() {
-        let a = _mm_setr_epi32(0x8000, -0x8001, 0, 0);
-        let b = _mm_setr_epi32(0, 0, -0x8001, 0x8000);
-        let r = _mm_packs_epi32(a, b);
-        assert_eq_m128i(r, _mm_setr_epi16(0x7FFF, -0x8000, 0, 0, 0, 0, -0x8000, 0x7FFF));
-    }
-    test_mm_packs_epi32();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_min_sd() {
-        let a = _mm_setr_pd(1.0, 2.0);
-        let b = _mm_setr_pd(5.0, 10.0);
-        let r = _mm_min_sd(a, b);
-        assert_eq_m128d(r, _mm_setr_pd(1.0, 2.0));
-    }
-    test_mm_min_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_min_pd() {
-        let a = _mm_setr_pd(-1.0, 5.0);
-        let b = _mm_setr_pd(-100.0, 20.0);
-        let r = _mm_min_pd(a, b);
-        assert_eq_m128d(r, _mm_setr_pd(-100.0, 5.0));
-
-        // `_mm_min_pd` can **not** be implemented using the `simd_min` rust intrinsic because
-        // the semantics of `simd_min` are different to those of `_mm_min_pd` regarding handling
-        // of `-0.0`.
-        let a = _mm_setr_pd(-0.0, 0.0);
-        let b = _mm_setr_pd(0.0, 0.0);
-        let r1: [u8; 16] = transmute(_mm_min_pd(a, b));
-        let r2: [u8; 16] = transmute(_mm_min_pd(b, a));
-        let a: [u8; 16] = transmute(a);
-        let b: [u8; 16] = transmute(b);
-        assert_eq!(r1, b);
-        assert_eq!(r2, a);
-        assert_ne!(a, b); // sanity check that -0.0 is actually present
-    }
-    test_mm_min_pd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_max_sd() {
-        let a = _mm_setr_pd(1.0, 2.0);
-        let b = _mm_setr_pd(5.0, 10.0);
-        let r = _mm_max_sd(a, b);
-        assert_eq_m128d(r, _mm_setr_pd(5.0, 2.0));
-    }
-    test_mm_max_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_max_pd() {
-        let a = _mm_setr_pd(-1.0, 5.0);
-        let b = _mm_setr_pd(-100.0, 20.0);
-        let r = _mm_max_pd(a, b);
-        assert_eq_m128d(r, _mm_setr_pd(-1.0, 20.0));
-
-        // `_mm_max_pd` can **not** be implemented using the `simd_max` rust intrinsic because
-        // the semantics of `simd_max` are different to those of `_mm_max_pd` regarding handling
-        // of `-0.0`.
-        let a = _mm_setr_pd(-0.0, 0.0);
-        let b = _mm_setr_pd(0.0, 0.0);
-        let r1: [u8; 16] = transmute(_mm_max_pd(a, b));
-        let r2: [u8; 16] = transmute(_mm_max_pd(b, a));
-        let a: [u8; 16] = transmute(a);
-        let b: [u8; 16] = transmute(b);
-        assert_eq!(r1, b);
-        assert_eq!(r2, a);
-        assert_ne!(a, b); // sanity check that -0.0 is actually present
-    }
-    test_mm_max_pd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_sqrt_sd() {
-        let a = _mm_setr_pd(1.0, 2.0);
-        let b = _mm_setr_pd(5.0, 10.0);
-        let r = _mm_sqrt_sd(a, b);
-        assert_eq_m128d(r, _mm_setr_pd(5.0f64.sqrt(), 2.0));
-    }
-    test_mm_sqrt_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_sqrt_pd() {
-        let r = _mm_sqrt_pd(_mm_setr_pd(1.0, 2.0));
-        assert_eq_m128d(r, _mm_setr_pd(1.0f64.sqrt(), 2.0f64.sqrt()));
-    }
-    test_mm_sqrt_pd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpeq_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(!0, transmute(2.0f64));
-        let r = transmute::<_, __m128i>(_mm_cmpeq_sd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpeq_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmplt_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
-        let e = _mm_setr_epi64x(!0, transmute(2.0f64));
-        let r = transmute::<_, __m128i>(_mm_cmplt_sd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmplt_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmple_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(!0, transmute(2.0f64));
-        let r = transmute::<_, __m128i>(_mm_cmple_sd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmple_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpgt_sd() {
-        let (a, b) = (_mm_setr_pd(5.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(!0, transmute(2.0f64));
-        let r = transmute::<_, __m128i>(_mm_cmpgt_sd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpgt_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpge_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(!0, transmute(2.0f64));
-        let r = transmute::<_, __m128i>(_mm_cmpge_sd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpge_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpord_sd() {
-        let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(5.0, 3.0));
-        let e = _mm_setr_epi64x(0, transmute(2.0f64));
-        let r = transmute::<_, __m128i>(_mm_cmpord_sd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpord_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpunord_sd() {
-        let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(5.0, 3.0));
-        let e = _mm_setr_epi64x(!0, transmute(2.0f64));
-        let r = transmute::<_, __m128i>(_mm_cmpunord_sd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpunord_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpneq_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
-        let e = _mm_setr_epi64x(!0, transmute(2.0f64));
-        let r = transmute::<_, __m128i>(_mm_cmpneq_sd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpneq_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpnlt_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
-        let e = _mm_setr_epi64x(0, transmute(2.0f64));
-        let r = transmute::<_, __m128i>(_mm_cmpnlt_sd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpnlt_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpnle_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(0, transmute(2.0f64));
-        let r = transmute::<_, __m128i>(_mm_cmpnle_sd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpnle_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpngt_sd() {
-        let (a, b) = (_mm_setr_pd(5.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(0, transmute(2.0f64));
-        let r = transmute::<_, __m128i>(_mm_cmpngt_sd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpngt_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpnge_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(0, transmute(2.0f64));
-        let r = transmute::<_, __m128i>(_mm_cmpnge_sd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpnge_sd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpeq_pd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(!0, 0);
-        let r = transmute::<_, __m128i>(_mm_cmpeq_pd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpeq_pd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmplt_pd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(0, !0);
-        let r = transmute::<_, __m128i>(_mm_cmplt_pd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmplt_pd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmple_pd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(!0, !0);
-        let r = transmute::<_, __m128i>(_mm_cmple_pd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmple_pd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpgt_pd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(0, 0);
-        let r = transmute::<_, __m128i>(_mm_cmpgt_pd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpgt_pd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpge_pd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(!0, 0);
-        let r = transmute::<_, __m128i>(_mm_cmpge_pd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpge_pd();
-
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpord_pd() {
-        let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(5.0, 3.0));
-        let e = _mm_setr_epi64x(0, !0);
-        let r = transmute::<_, __m128i>(_mm_cmpord_pd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpord_pd();
+            let b = _mm_setr_epi8(0, 0, 0, 0, 2, 1, 2, 1, 1, 1, 1, 1, 1, 2, 1, 2);
+            let r = _mm_sad_epu8(a, b);
+            let e = _mm_setr_epi64x(1020, 614);
+            assert_eq_m128i(r, e);
+        }
+        test_mm_sad_epu8();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_sll_epi16() {
+            let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF);
+            let r = _mm_sll_epi16(a, _mm_set_epi64x(0, 4));
+            assert_eq_m128i(
+                r,
+                _mm_setr_epi16(0xCC0, -0xCC0, 0xDD0, -0xDD0, 0xEE0, -0xEE0, 0xFF0, -0xFF0),
+            );
+            let r = _mm_sll_epi16(a, _mm_set_epi64x(4, 0));
+            assert_eq_m128i(r, a);
+            let r = _mm_sll_epi16(a, _mm_set_epi64x(0, 16));
+            assert_eq_m128i(r, _mm_set1_epi16(0));
+            let r = _mm_sll_epi16(a, _mm_set_epi64x(0, i64::MAX));
+            assert_eq_m128i(r, _mm_set1_epi16(0));
+        }
+        test_mm_sll_epi16();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_srl_epi16() {
+            let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF);
+            let r = _mm_srl_epi16(a, _mm_set_epi64x(0, 4));
+            assert_eq_m128i(r, _mm_setr_epi16(0xC, 0xFF3, 0xD, 0xFF2, 0xE, 0xFF1, 0xF, 0xFF0));
+            let r = _mm_srl_epi16(a, _mm_set_epi64x(4, 0));
+            assert_eq_m128i(r, a);
+            let r = _mm_srl_epi16(a, _mm_set_epi64x(0, 16));
+            assert_eq_m128i(r, _mm_set1_epi16(0));
+            let r = _mm_srl_epi16(a, _mm_set_epi64x(0, i64::MAX));
+            assert_eq_m128i(r, _mm_set1_epi16(0));
+        }
+        test_mm_srl_epi16();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_sra_epi16() {
+            let a = _mm_setr_epi16(0xCC, -0xCC, 0xDD, -0xDD, 0xEE, -0xEE, 0xFF, -0xFF);
+            let r = _mm_sra_epi16(a, _mm_set_epi64x(0, 4));
+            assert_eq_m128i(r, _mm_setr_epi16(0xC, -0xD, 0xD, -0xE, 0xE, -0xF, 0xF, -0x10));
+            let r = _mm_sra_epi16(a, _mm_set_epi64x(4, 0));
+            assert_eq_m128i(r, a);
+            let r = _mm_sra_epi16(a, _mm_set_epi64x(0, 16));
+            assert_eq_m128i(r, _mm_setr_epi16(0, -1, 0, -1, 0, -1, 0, -1));
+            let r = _mm_sra_epi16(a, _mm_set_epi64x(0, i64::MAX));
+            assert_eq_m128i(r, _mm_setr_epi16(0, -1, 0, -1, 0, -1, 0, -1));
+        }
+        test_mm_sra_epi16();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_sll_epi32() {
+            let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF);
+            let r = _mm_sll_epi32(a, _mm_set_epi64x(0, 4));
+            assert_eq_m128i(r, _mm_setr_epi32(0xEEEE0, -0xEEEE0, 0xFFFF0, -0xFFFF0));
+            let r = _mm_sll_epi32(a, _mm_set_epi64x(4, 0));
+            assert_eq_m128i(r, a);
+            let r = _mm_sll_epi32(a, _mm_set_epi64x(0, 32));
+            assert_eq_m128i(r, _mm_set1_epi32(0));
+            let r = _mm_sll_epi32(a, _mm_set_epi64x(0, i64::MAX));
+            assert_eq_m128i(r, _mm_set1_epi32(0));
+        }
+        test_mm_sll_epi32();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_srl_epi32() {
+            let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF);
+            let r = _mm_srl_epi32(a, _mm_set_epi64x(0, 4));
+            assert_eq_m128i(r, _mm_setr_epi32(0xEEE, 0xFFFF111, 0xFFF, 0xFFFF000));
+            let r = _mm_srl_epi32(a, _mm_set_epi64x(4, 0));
+            assert_eq_m128i(r, a);
+            let r = _mm_srl_epi32(a, _mm_set_epi64x(0, 32));
+            assert_eq_m128i(r, _mm_set1_epi32(0));
+            let r = _mm_srl_epi32(a, _mm_set_epi64x(0, i64::MAX));
+            assert_eq_m128i(r, _mm_set1_epi32(0));
+        }
+        test_mm_srl_epi32();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_sra_epi32() {
+            let a = _mm_setr_epi32(0xEEEE, -0xEEEE, 0xFFFF, -0xFFFF);
+            let r = _mm_sra_epi32(a, _mm_set_epi64x(0, 4));
+            assert_eq_m128i(r, _mm_setr_epi32(0xEEE, -0xEEF, 0xFFF, -0x1000));
+            let r = _mm_sra_epi32(a, _mm_set_epi64x(4, 0));
+            assert_eq_m128i(r, a);
+            let r = _mm_sra_epi32(a, _mm_set_epi64x(0, 32));
+            assert_eq_m128i(r, _mm_setr_epi32(0, -1, 0, -1));
+            let r = _mm_sra_epi32(a, _mm_set_epi64x(0, i64::MAX));
+            assert_eq_m128i(r, _mm_setr_epi32(0, -1, 0, -1));
+        }
+        test_mm_sra_epi32();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_sll_epi64() {
+            let a = _mm_set_epi64x(0xFFFFFFFF, -0xFFFFFFFF);
+            let r = _mm_sll_epi64(a, _mm_set_epi64x(0, 4));
+            assert_eq_m128i(r, _mm_set_epi64x(0xFFFFFFFF0, -0xFFFFFFFF0));
+            let r = _mm_sll_epi64(a, _mm_set_epi64x(4, 0));
+            assert_eq_m128i(r, a);
+            let r = _mm_sll_epi64(a, _mm_set_epi64x(0, 64));
+            assert_eq_m128i(r, _mm_set1_epi64x(0));
+            let r = _mm_sll_epi64(a, _mm_set_epi64x(0, i64::MAX));
+            assert_eq_m128i(r, _mm_set1_epi64x(0));
+        }
+        test_mm_sll_epi64();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_srl_epi64() {
+            let a = _mm_set_epi64x(0xFFFFFFFF, -0xFFFFFFFF);
+            let r = _mm_srl_epi64(a, _mm_set_epi64x(0, 4));
+            assert_eq_m128i(r, _mm_set_epi64x(0xFFFFFFF, 0xFFFFFFFF0000000));
+            let r = _mm_srl_epi64(a, _mm_set_epi64x(4, 0));
+            assert_eq_m128i(r, a);
+            let r = _mm_srl_epi64(a, _mm_set_epi64x(0, 64));
+            assert_eq_m128i(r, _mm_set1_epi64x(0));
+            let r = _mm_srl_epi64(a, _mm_set_epi64x(0, i64::MAX));
+            assert_eq_m128i(r, _mm_set1_epi64x(0));
+        }
+        test_mm_srl_epi64();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpunord_pd() {
-        let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(5.0, 3.0));
-        let e = _mm_setr_epi64x(!0, 0);
-        let r = transmute::<_, __m128i>(_mm_cmpunord_pd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpunord_pd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cvtepi32_ps() {
+            let a = _mm_setr_epi32(1, 2, 3, 4);
+            let r = _mm_cvtepi32_ps(a);
+            assert_eq_m128(r, _mm_setr_ps(1.0, 2.0, 3.0, 4.0));
+        }
+        test_mm_cvtepi32_ps();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpneq_pd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
-        let e = _mm_setr_epi64x(!0, !0);
-        let r = transmute::<_, __m128i>(_mm_cmpneq_pd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpneq_pd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cvtps_epi32() {
+            let a = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
+            let r = _mm_cvtps_epi32(a);
+            assert_eq_m128i(r, _mm_setr_epi32(1, 2, 3, 4));
+        }
+        test_mm_cvtps_epi32();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpnlt_pd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
-        let e = _mm_setr_epi64x(0, 0);
-        let r = transmute::<_, __m128i>(_mm_cmpnlt_pd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpnlt_pd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cvttps_epi32() {
+            let a = _mm_setr_ps(-1.1, 2.2, -3.3, 6.6);
+            let r = _mm_cvttps_epi32(a);
+            assert_eq_m128i(r, _mm_setr_epi32(-1, 2, -3, 6));
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpnle_pd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(0, 0);
-        let r = transmute::<_, __m128i>(_mm_cmpnle_pd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpnle_pd();
+            let a = _mm_setr_ps(f32::NEG_INFINITY, f32::INFINITY, f32::MIN, f32::MAX);
+            let r = _mm_cvttps_epi32(a);
+            assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, i32::MIN, i32::MIN));
+        }
+        test_mm_cvttps_epi32();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_packs_epi16() {
+            let a = _mm_setr_epi16(0x80, -0x81, 0, 0, 0, 0, 0, 0);
+            let b = _mm_setr_epi16(0, 0, 0, 0, 0, 0, -0x81, 0x80);
+            let r = _mm_packs_epi16(a, b);
+            assert_eq_m128i(
+                r,
+                _mm_setr_epi8(0x7F, -0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -0x80, 0x7F),
+            );
+        }
+        test_mm_packs_epi16();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_packus_epi16() {
+            let a = _mm_setr_epi16(0x100, -1, 0, 0, 0, 0, 0, 0);
+            let b = _mm_setr_epi16(0, 0, 0, 0, 0, 0, -1, 0x100);
+            let r = _mm_packus_epi16(a, b);
+            assert_eq_m128i(r, _mm_setr_epi8(!0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, !0));
+        }
+        test_mm_packus_epi16();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_packs_epi32() {
+            let a = _mm_setr_epi32(0x8000, -0x8001, 0, 0);
+            let b = _mm_setr_epi32(0, 0, -0x8001, 0x8000);
+            let r = _mm_packs_epi32(a, b);
+            assert_eq_m128i(r, _mm_setr_epi16(0x7FFF, -0x8000, 0, 0, 0, 0, -0x8000, 0x7FFF));
+        }
+        test_mm_packs_epi32();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_min_sd() {
+            let a = _mm_setr_pd(1.0, 2.0);
+            let b = _mm_setr_pd(5.0, 10.0);
+            let r = _mm_min_sd(a, b);
+            assert_eq_m128d(r, _mm_setr_pd(1.0, 2.0));
+        }
+        test_mm_min_sd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_min_pd() {
+            let a = _mm_setr_pd(-1.0, 5.0);
+            let b = _mm_setr_pd(-100.0, 20.0);
+            let r = _mm_min_pd(a, b);
+            assert_eq_m128d(r, _mm_setr_pd(-100.0, 5.0));
+
+            // `_mm_min_pd` can **not** be implemented using the `simd_min` rust intrinsic because
+            // the semantics of `simd_min` are different to those of `_mm_min_pd` regarding handling
+            // of `-0.0`.
+            let a = _mm_setr_pd(-0.0, 0.0);
+            let b = _mm_setr_pd(0.0, 0.0);
+            let r1: [u8; 16] = transmute(_mm_min_pd(a, b));
+            let r2: [u8; 16] = transmute(_mm_min_pd(b, a));
+            let a: [u8; 16] = transmute(a);
+            let b: [u8; 16] = transmute(b);
+            assert_eq!(r1, b);
+            assert_eq!(r2, a);
+            assert_ne!(a, b); // sanity check that -0.0 is actually present
+        }
+        test_mm_min_pd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_max_sd() {
+            let a = _mm_setr_pd(1.0, 2.0);
+            let b = _mm_setr_pd(5.0, 10.0);
+            let r = _mm_max_sd(a, b);
+            assert_eq_m128d(r, _mm_setr_pd(5.0, 2.0));
+        }
+        test_mm_max_sd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_max_pd() {
+            let a = _mm_setr_pd(-1.0, 5.0);
+            let b = _mm_setr_pd(-100.0, 20.0);
+            let r = _mm_max_pd(a, b);
+            assert_eq_m128d(r, _mm_setr_pd(-1.0, 20.0));
+
+            // `_mm_max_pd` can **not** be implemented using the `simd_max` rust intrinsic because
+            // the semantics of `simd_max` are different to those of `_mm_max_pd` regarding handling
+            // of `-0.0`.
+            let a = _mm_setr_pd(-0.0, 0.0);
+            let b = _mm_setr_pd(0.0, 0.0);
+            let r1: [u8; 16] = transmute(_mm_max_pd(a, b));
+            let r2: [u8; 16] = transmute(_mm_max_pd(b, a));
+            let a: [u8; 16] = transmute(a);
+            let b: [u8; 16] = transmute(b);
+            assert_eq!(r1, b);
+            assert_eq!(r2, a);
+            assert_ne!(a, b); // sanity check that -0.0 is actually present
+        }
+        test_mm_max_pd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_sqrt_sd() {
+            let a = _mm_setr_pd(1.0, 2.0);
+            let b = _mm_setr_pd(5.0, 10.0);
+            let r = _mm_sqrt_sd(a, b);
+            assert_eq_m128d(r, _mm_setr_pd(5.0f64.sqrt(), 2.0));
+        }
+        test_mm_sqrt_sd();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpngt_pd() {
-        let (a, b) = (_mm_setr_pd(5.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(0, !0);
-        let r = transmute::<_, __m128i>(_mm_cmpngt_pd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpngt_pd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_sqrt_pd() {
+            let r = _mm_sqrt_pd(_mm_setr_pd(1.0, 2.0));
+            assert_eq_m128d(r, _mm_setr_pd(1.0f64.sqrt(), 2.0f64.sqrt()));
+        }
+        test_mm_sqrt_pd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpeq_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(!0, transmute(2.0f64));
+            let r = transmute::<_, __m128i>(_mm_cmpeq_sd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpeq_sd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmplt_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
+            let e = _mm_setr_epi64x(!0, transmute(2.0f64));
+            let r = transmute::<_, __m128i>(_mm_cmplt_sd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmplt_sd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmple_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(!0, transmute(2.0f64));
+            let r = transmute::<_, __m128i>(_mm_cmple_sd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmple_sd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpgt_sd() {
+            let (a, b) = (_mm_setr_pd(5.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(!0, transmute(2.0f64));
+            let r = transmute::<_, __m128i>(_mm_cmpgt_sd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpgt_sd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpge_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(!0, transmute(2.0f64));
+            let r = transmute::<_, __m128i>(_mm_cmpge_sd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpge_sd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpord_sd() {
+            let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(5.0, 3.0));
+            let e = _mm_setr_epi64x(0, transmute(2.0f64));
+            let r = transmute::<_, __m128i>(_mm_cmpord_sd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpord_sd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpunord_sd() {
+            let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(5.0, 3.0));
+            let e = _mm_setr_epi64x(!0, transmute(2.0f64));
+            let r = transmute::<_, __m128i>(_mm_cmpunord_sd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpunord_sd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpneq_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
+            let e = _mm_setr_epi64x(!0, transmute(2.0f64));
+            let r = transmute::<_, __m128i>(_mm_cmpneq_sd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpneq_sd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpnlt_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
+            let e = _mm_setr_epi64x(0, transmute(2.0f64));
+            let r = transmute::<_, __m128i>(_mm_cmpnlt_sd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpnlt_sd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpnle_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(0, transmute(2.0f64));
+            let r = transmute::<_, __m128i>(_mm_cmpnle_sd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpnle_sd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpngt_sd() {
+            let (a, b) = (_mm_setr_pd(5.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(0, transmute(2.0f64));
+            let r = transmute::<_, __m128i>(_mm_cmpngt_sd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpngt_sd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpnge_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(0, transmute(2.0f64));
+            let r = transmute::<_, __m128i>(_mm_cmpnge_sd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpnge_sd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpeq_pd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(!0, 0);
+            let r = transmute::<_, __m128i>(_mm_cmpeq_pd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpeq_pd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmplt_pd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(0, !0);
+            let r = transmute::<_, __m128i>(_mm_cmplt_pd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmplt_pd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmple_pd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(!0, !0);
+            let r = transmute::<_, __m128i>(_mm_cmple_pd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmple_pd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpgt_pd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(0, 0);
+            let r = transmute::<_, __m128i>(_mm_cmpgt_pd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpgt_pd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpge_pd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(!0, 0);
+            let r = transmute::<_, __m128i>(_mm_cmpge_pd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpge_pd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpord_pd() {
+            let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(5.0, 3.0));
+            let e = _mm_setr_epi64x(0, !0);
+            let r = transmute::<_, __m128i>(_mm_cmpord_pd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpord_pd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpunord_pd() {
+            let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(5.0, 3.0));
+            let e = _mm_setr_epi64x(!0, 0);
+            let r = transmute::<_, __m128i>(_mm_cmpunord_pd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpunord_pd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpneq_pd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
+            let e = _mm_setr_epi64x(!0, !0);
+            let r = transmute::<_, __m128i>(_mm_cmpneq_pd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpneq_pd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpnlt_pd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(5.0, 3.0));
+            let e = _mm_setr_epi64x(0, 0);
+            let r = transmute::<_, __m128i>(_mm_cmpnlt_pd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpnlt_pd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpnle_pd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(0, 0);
+            let r = transmute::<_, __m128i>(_mm_cmpnle_pd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpnle_pd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpngt_pd() {
+            let (a, b) = (_mm_setr_pd(5.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(0, !0);
+            let r = transmute::<_, __m128i>(_mm_cmpngt_pd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpngt_pd();
+
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cmpnge_pd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            let e = _mm_setr_epi64x(0, !0);
+            let r = transmute::<_, __m128i>(_mm_cmpnge_pd(a, b));
+            assert_eq_m128i(r, e);
+        }
+        test_mm_cmpnge_pd();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cmpnge_pd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        let e = _mm_setr_epi64x(0, !0);
-        let r = transmute::<_, __m128i>(_mm_cmpnge_pd(a, b));
-        assert_eq_m128i(r, e);
-    }
-    test_mm_cmpnge_pd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_comieq_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            assert!(_mm_comieq_sd(a, b) != 0);
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_comieq_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        assert!(_mm_comieq_sd(a, b) != 0);
+            let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(1.0, 3.0));
+            assert!(_mm_comieq_sd(a, b) == 0);
+        }
+        test_mm_comieq_sd();
 
-        let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(1.0, 3.0));
-        assert!(_mm_comieq_sd(a, b) == 0);
-    }
-    test_mm_comieq_sd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_comilt_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            assert!(_mm_comilt_sd(a, b) == 0);
+        }
+        test_mm_comilt_sd();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_comilt_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        assert!(_mm_comilt_sd(a, b) == 0);
-    }
-    test_mm_comilt_sd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_comile_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            assert!(_mm_comile_sd(a, b) != 0);
+        }
+        test_mm_comile_sd();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_comile_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        assert!(_mm_comile_sd(a, b) != 0);
-    }
-    test_mm_comile_sd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_comigt_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            assert!(_mm_comigt_sd(a, b) == 0);
+        }
+        test_mm_comigt_sd();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_comigt_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        assert!(_mm_comigt_sd(a, b) == 0);
-    }
-    test_mm_comigt_sd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_comige_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            assert!(_mm_comige_sd(a, b) != 0);
+        }
+        test_mm_comige_sd();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_comige_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        assert!(_mm_comige_sd(a, b) != 0);
-    }
-    test_mm_comige_sd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_comineq_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            assert!(_mm_comineq_sd(a, b) == 0);
+        }
+        test_mm_comineq_sd();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_comineq_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        assert!(_mm_comineq_sd(a, b) == 0);
-    }
-    test_mm_comineq_sd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_ucomieq_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            assert!(_mm_ucomieq_sd(a, b) != 0);
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_ucomieq_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        assert!(_mm_ucomieq_sd(a, b) != 0);
+            let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(NAN, 3.0));
+            assert!(_mm_ucomieq_sd(a, b) == 0);
+        }
+        test_mm_ucomieq_sd();
 
-        let (a, b) = (_mm_setr_pd(NAN, 2.0), _mm_setr_pd(NAN, 3.0));
-        assert!(_mm_ucomieq_sd(a, b) == 0);
-    }
-    test_mm_ucomieq_sd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_ucomilt_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            assert!(_mm_ucomilt_sd(a, b) == 0);
+        }
+        test_mm_ucomilt_sd();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_ucomilt_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        assert!(_mm_ucomilt_sd(a, b) == 0);
-    }
-    test_mm_ucomilt_sd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_ucomile_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            assert!(_mm_ucomile_sd(a, b) != 0);
+        }
+        test_mm_ucomile_sd();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_ucomile_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        assert!(_mm_ucomile_sd(a, b) != 0);
-    }
-    test_mm_ucomile_sd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_ucomigt_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            assert!(_mm_ucomigt_sd(a, b) == 0);
+        }
+        test_mm_ucomigt_sd();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_ucomigt_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        assert!(_mm_ucomigt_sd(a, b) == 0);
-    }
-    test_mm_ucomigt_sd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_ucomige_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            assert!(_mm_ucomige_sd(a, b) != 0);
+        }
+        test_mm_ucomige_sd();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_ucomige_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        assert!(_mm_ucomige_sd(a, b) != 0);
-    }
-    test_mm_ucomige_sd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_ucomineq_sd() {
+            let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
+            assert!(_mm_ucomineq_sd(a, b) == 0);
+        }
+        test_mm_ucomineq_sd();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_ucomineq_sd() {
-        let (a, b) = (_mm_setr_pd(1.0, 2.0), _mm_setr_pd(1.0, 3.0));
-        assert!(_mm_ucomineq_sd(a, b) == 0);
-    }
-    test_mm_ucomineq_sd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cvtpd_ps() {
+            let r = _mm_cvtpd_ps(_mm_setr_pd(-1.0, 5.0));
+            assert_eq_m128(r, _mm_setr_ps(-1.0, 5.0, 0.0, 0.0));
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cvtpd_ps() {
-        let r = _mm_cvtpd_ps(_mm_setr_pd(-1.0, 5.0));
-        assert_eq_m128(r, _mm_setr_ps(-1.0, 5.0, 0.0, 0.0));
+            let r = _mm_cvtpd_ps(_mm_setr_pd(-1.0, -5.0));
+            assert_eq_m128(r, _mm_setr_ps(-1.0, -5.0, 0.0, 0.0));
 
-        let r = _mm_cvtpd_ps(_mm_setr_pd(-1.0, -5.0));
-        assert_eq_m128(r, _mm_setr_ps(-1.0, -5.0, 0.0, 0.0));
+            let r = _mm_cvtpd_ps(_mm_setr_pd(f64::MAX, f64::MIN));
+            assert_eq_m128(r, _mm_setr_ps(f32::INFINITY, f32::NEG_INFINITY, 0.0, 0.0));
 
-        let r = _mm_cvtpd_ps(_mm_setr_pd(f64::MAX, f64::MIN));
-        assert_eq_m128(r, _mm_setr_ps(f32::INFINITY, f32::NEG_INFINITY, 0.0, 0.0));
+            let r = _mm_cvtpd_ps(_mm_setr_pd(f32::MAX as f64, f32::MIN as f64));
+            assert_eq_m128(r, _mm_setr_ps(f32::MAX, f32::MIN, 0.0, 0.0));
+        }
+        test_mm_cvtpd_ps();
 
-        let r = _mm_cvtpd_ps(_mm_setr_pd(f32::MAX as f64, f32::MIN as f64));
-        assert_eq_m128(r, _mm_setr_ps(f32::MAX, f32::MIN, 0.0, 0.0));
-    }
-    test_mm_cvtpd_ps();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cvtps_pd() {
+            let r = _mm_cvtps_pd(_mm_setr_ps(-1.0, 2.0, -3.0, 5.0));
+            assert_eq_m128d(r, _mm_setr_pd(-1.0, 2.0));
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cvtps_pd() {
-        let r = _mm_cvtps_pd(_mm_setr_ps(-1.0, 2.0, -3.0, 5.0));
-        assert_eq_m128d(r, _mm_setr_pd(-1.0, 2.0));
+            let r = _mm_cvtps_pd(_mm_setr_ps(f32::MAX, f32::INFINITY, f32::NEG_INFINITY, f32::MIN));
+            assert_eq_m128d(r, _mm_setr_pd(f32::MAX as f64, f64::INFINITY));
+        }
+        test_mm_cvtps_pd();
 
-        let r = _mm_cvtps_pd(_mm_setr_ps(f32::MAX, f32::INFINITY, f32::NEG_INFINITY, f32::MIN));
-        assert_eq_m128d(r, _mm_setr_pd(f32::MAX as f64, f64::INFINITY));
-    }
-    test_mm_cvtps_pd();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cvtpd_epi32() {
+            let r = _mm_cvtpd_epi32(_mm_setr_pd(-1.0, 5.0));
+            assert_eq_m128i(r, _mm_setr_epi32(-1, 5, 0, 0));
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cvtpd_epi32() {
-        let r = _mm_cvtpd_epi32(_mm_setr_pd(-1.0, 5.0));
-        assert_eq_m128i(r, _mm_setr_epi32(-1, 5, 0, 0));
+            let r = _mm_cvtpd_epi32(_mm_setr_pd(-1.0, -5.0));
+            assert_eq_m128i(r, _mm_setr_epi32(-1, -5, 0, 0));
 
-        let r = _mm_cvtpd_epi32(_mm_setr_pd(-1.0, -5.0));
-        assert_eq_m128i(r, _mm_setr_epi32(-1, -5, 0, 0));
+            let r = _mm_cvtpd_epi32(_mm_setr_pd(f64::MAX, f64::MIN));
+            assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, 0, 0));
 
-        let r = _mm_cvtpd_epi32(_mm_setr_pd(f64::MAX, f64::MIN));
-        assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, 0, 0));
+            let r = _mm_cvtpd_epi32(_mm_setr_pd(f64::INFINITY, f64::NEG_INFINITY));
+            assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, 0, 0));
 
-        let r = _mm_cvtpd_epi32(_mm_setr_pd(f64::INFINITY, f64::NEG_INFINITY));
-        assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, 0, 0));
+            let r = _mm_cvtpd_epi32(_mm_setr_pd(f64::NAN, f64::NAN));
+            assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, 0, 0));
+        }
+        test_mm_cvtpd_epi32();
 
-        let r = _mm_cvtpd_epi32(_mm_setr_pd(f64::NAN, f64::NAN));
-        assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, 0, 0));
-    }
-    test_mm_cvtpd_epi32();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cvttpd_epi32() {
+            let a = _mm_setr_pd(-1.1, 2.2);
+            let r = _mm_cvttpd_epi32(a);
+            assert_eq_m128i(r, _mm_setr_epi32(-1, 2, 0, 0));
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cvttpd_epi32() {
-        let a = _mm_setr_pd(-1.1, 2.2);
-        let r = _mm_cvttpd_epi32(a);
-        assert_eq_m128i(r, _mm_setr_epi32(-1, 2, 0, 0));
-
-        let a = _mm_setr_pd(f64::NEG_INFINITY, f64::NAN);
-        let r = _mm_cvttpd_epi32(a);
-        assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, 0, 0));
-    }
-    test_mm_cvttpd_epi32();
+            let a = _mm_setr_pd(f64::NEG_INFINITY, f64::NAN);
+            let r = _mm_cvttpd_epi32(a);
+            assert_eq_m128i(r, _mm_setr_epi32(i32::MIN, i32::MIN, 0, 0));
+        }
+        test_mm_cvttpd_epi32();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cvtsd_si32() {
-        let r = _mm_cvtsd_si32(_mm_setr_pd(-2.0, 5.0));
-        assert_eq!(r, -2);
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cvtsd_si32() {
+            let r = _mm_cvtsd_si32(_mm_setr_pd(-2.0, 5.0));
+            assert_eq!(r, -2);
 
-        let r = _mm_cvtsd_si32(_mm_setr_pd(f64::MAX, f64::MIN));
-        assert_eq!(r, i32::MIN);
+            let r = _mm_cvtsd_si32(_mm_setr_pd(f64::MAX, f64::MIN));
+            assert_eq!(r, i32::MIN);
 
-        let r = _mm_cvtsd_si32(_mm_setr_pd(f64::NAN, f64::NAN));
-        assert_eq!(r, i32::MIN);
-    }
-    test_mm_cvtsd_si32();
+            let r = _mm_cvtsd_si32(_mm_setr_pd(f64::NAN, f64::NAN));
+            assert_eq!(r, i32::MIN);
+        }
+        test_mm_cvtsd_si32();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cvttsd_si32() {
-        let a = _mm_setr_pd(-1.1, 2.2);
-        let r = _mm_cvttsd_si32(a);
-        assert_eq!(r, -1);
-
-        let a = _mm_setr_pd(f64::NEG_INFINITY, f64::NAN);
-        let r = _mm_cvttsd_si32(a);
-        assert_eq!(r, i32::MIN);
-    }
-    test_mm_cvttsd_si32();
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cvttsd_si32() {
+            let a = _mm_setr_pd(-1.1, 2.2);
+            let r = _mm_cvttsd_si32(a);
+            assert_eq!(r, -1);
 
-    // Intrinsic only available on x86_64
-    #[cfg(target_arch = "x86_64")]
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cvtsd_si64() {
-        let r = _mm_cvtsd_si64(_mm_setr_pd(-2.0, 5.0));
-        assert_eq!(r, -2_i64);
+            let a = _mm_setr_pd(f64::NEG_INFINITY, f64::NAN);
+            let r = _mm_cvttsd_si32(a);
+            assert_eq!(r, i32::MIN);
+        }
+        test_mm_cvttsd_si32();
 
-        let r = _mm_cvtsd_si64(_mm_setr_pd(f64::MAX, f64::MIN));
-        assert_eq!(r, i64::MIN);
-    }
-    #[cfg(target_arch = "x86_64")]
-    test_mm_cvtsd_si64();
+        // Intrinsic only available on x86_64
+        #[cfg(target_arch = "x86_64")]
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cvtsd_si64() {
+            let r = _mm_cvtsd_si64(_mm_setr_pd(-2.0, 5.0));
+            assert_eq!(r, -2_i64);
 
-    // Intrinsic only available on x86_64
-    #[cfg(target_arch = "x86_64")]
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cvttsd_si64() {
-        let a = _mm_setr_pd(-1.1, 2.2);
-        let r = _mm_cvttsd_si64(a);
-        assert_eq!(r, -1_i64);
-    }
-    #[cfg(target_arch = "x86_64")]
-    test_mm_cvttsd_si64();
+            let r = _mm_cvtsd_si64(_mm_setr_pd(f64::MAX, f64::MIN));
+            assert_eq!(r, i64::MIN);
+        }
+        #[cfg(target_arch = "x86_64")]
+        test_mm_cvtsd_si64();
+
+        // Intrinsic only available on x86_64
+        #[cfg(target_arch = "x86_64")]
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cvttsd_si64() {
+            let a = _mm_setr_pd(-1.1, 2.2);
+            let r = _mm_cvttsd_si64(a);
+            assert_eq!(r, -1_i64);
+        }
+        #[cfg(target_arch = "x86_64")]
+        test_mm_cvttsd_si64();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cvtsd_ss() {
-        let a = _mm_setr_ps(-1.1, -2.2, 3.3, 4.4);
-        let b = _mm_setr_pd(2.0, -5.0);
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cvtsd_ss() {
+            let a = _mm_setr_ps(-1.1, -2.2, 3.3, 4.4);
+            let b = _mm_setr_pd(2.0, -5.0);
 
-        let r = _mm_cvtsd_ss(a, b);
+            let r = _mm_cvtsd_ss(a, b);
 
-        assert_eq_m128(r, _mm_setr_ps(2.0, -2.2, 3.3, 4.4));
+            assert_eq_m128(r, _mm_setr_ps(2.0, -2.2, 3.3, 4.4));
 
-        let a = _mm_setr_ps(-1.1, f32::NEG_INFINITY, f32::MAX, f32::NEG_INFINITY);
-        let b = _mm_setr_pd(f64::INFINITY, -5.0);
+            let a = _mm_setr_ps(-1.1, f32::NEG_INFINITY, f32::MAX, f32::NEG_INFINITY);
+            let b = _mm_setr_pd(f64::INFINITY, -5.0);
 
-        let r = _mm_cvtsd_ss(a, b);
+            let r = _mm_cvtsd_ss(a, b);
 
-        assert_eq_m128(
-            r,
-            _mm_setr_ps(f32::INFINITY, f32::NEG_INFINITY, f32::MAX, f32::NEG_INFINITY),
-        );
-    }
-    test_mm_cvtsd_ss();
+            assert_eq_m128(
+                r,
+                _mm_setr_ps(f32::INFINITY, f32::NEG_INFINITY, f32::MAX, f32::NEG_INFINITY),
+            );
+        }
+        test_mm_cvtsd_ss();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_cvtss_sd() {
-        let a = _mm_setr_pd(-1.1, 2.2);
-        let b = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_cvtss_sd() {
+            let a = _mm_setr_pd(-1.1, 2.2);
+            let b = _mm_setr_ps(1.0, 2.0, 3.0, 4.0);
 
-        let r = _mm_cvtss_sd(a, b);
-        assert_eq_m128d(r, _mm_setr_pd(1.0, 2.2));
+            let r = _mm_cvtss_sd(a, b);
+            assert_eq_m128d(r, _mm_setr_pd(1.0, 2.2));
 
-        let a = _mm_setr_pd(-1.1, f64::INFINITY);
-        let b = _mm_setr_ps(f32::NEG_INFINITY, 2.0, 3.0, 4.0);
+            let a = _mm_setr_pd(-1.1, f64::INFINITY);
+            let b = _mm_setr_ps(f32::NEG_INFINITY, 2.0, 3.0, 4.0);
 
-        let r = _mm_cvtss_sd(a, b);
-        assert_eq_m128d(r, _mm_setr_pd(f64::NEG_INFINITY, f64::INFINITY));
-    }
-    test_mm_cvtss_sd();
+            let r = _mm_cvtss_sd(a, b);
+            assert_eq_m128d(r, _mm_setr_pd(f64::NEG_INFINITY, f64::INFINITY));
+        }
+        test_mm_cvtss_sd();
 
-    #[target_feature(enable = "sse2")]
-    unsafe fn test_mm_movemask_pd() {
-        let r = _mm_movemask_pd(_mm_setr_pd(-1.0, 5.0));
-        assert_eq!(r, 0b01);
+        #[target_feature(enable = "sse2")]
+        unsafe fn test_mm_movemask_pd() {
+            let r = _mm_movemask_pd(_mm_setr_pd(-1.0, 5.0));
+            assert_eq!(r, 0b01);
 
-        let r = _mm_movemask_pd(_mm_setr_pd(-1.0, -5.0));
-        assert_eq!(r, 0b11);
+            let r = _mm_movemask_pd(_mm_setr_pd(-1.0, -5.0));
+            assert_eq!(r, 0b11);
+        }
+        test_mm_movemask_pd();
     }
-    test_mm_movemask_pd();
 }
diff --git a/src/tools/miri/tests/pass/intrinsics-x86.rs b/src/tools/miri/tests/pass/intrinsics-x86.rs
index 88cd782e70a..90bcdba4353 100644
--- a/src/tools/miri/tests/pass/intrinsics-x86.rs
+++ b/src/tools/miri/tests/pass/intrinsics-x86.rs
@@ -1,3 +1,51 @@
+#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+mod x86 {
+    #[cfg(target_arch = "x86")]
+    use core::arch::x86 as arch;
+    #[cfg(target_arch = "x86_64")]
+    use core::arch::x86_64 as arch;
+
+    fn adc(c_in: u8, a: u32, b: u32) -> (u8, u32) {
+        let mut sum = 0;
+        // SAFETY: There are no safety requirements for calling `_addcarry_u32`.
+        // It's just unsafe for API consistency with other intrinsics.
+        let c_out = unsafe { arch::_addcarry_u32(c_in, a, b, &mut sum) };
+        (c_out, sum)
+    }
+
+    fn sbb(b_in: u8, a: u32, b: u32) -> (u8, u32) {
+        let mut sum = 0;
+        // SAFETY: There are no safety requirements for calling `_subborrow_u32`.
+        // It's just unsafe for API consistency with other intrinsics.
+        let b_out = unsafe { arch::_subborrow_u32(b_in, a, b, &mut sum) };
+        (b_out, sum)
+    }
+
+    pub fn main() {
+        assert_eq!(adc(0, 1, 1), (0, 2));
+        assert_eq!(adc(1, 1, 1), (0, 3));
+        assert_eq!(adc(2, 1, 1), (0, 3)); // any non-zero carry acts as 1!
+        assert_eq!(adc(u8::MAX, 1, 1), (0, 3));
+        assert_eq!(adc(0, u32::MAX, u32::MAX), (1, u32::MAX - 1));
+        assert_eq!(adc(1, u32::MAX, u32::MAX), (1, u32::MAX));
+        assert_eq!(adc(2, u32::MAX, u32::MAX), (1, u32::MAX));
+        assert_eq!(adc(u8::MAX, u32::MAX, u32::MAX), (1, u32::MAX));
+
+        assert_eq!(sbb(0, 1, 1), (0, 0));
+        assert_eq!(sbb(1, 1, 1), (1, u32::MAX));
+        assert_eq!(sbb(2, 1, 1), (1, u32::MAX)); // any non-zero borrow acts as 1!
+        assert_eq!(sbb(u8::MAX, 1, 1), (1, u32::MAX));
+        assert_eq!(sbb(0, 2, 1), (0, 1));
+        assert_eq!(sbb(1, 2, 1), (0, 0));
+        assert_eq!(sbb(2, 2, 1), (0, 0));
+        assert_eq!(sbb(u8::MAX, 2, 1), (0, 0));
+        assert_eq!(sbb(0, 1, 2), (1, u32::MAX));
+        assert_eq!(sbb(1, 1, 2), (1, u32::MAX - 1));
+        assert_eq!(sbb(2, 1, 2), (1, u32::MAX - 1));
+        assert_eq!(sbb(u8::MAX, 1, 2), (1, u32::MAX - 1));
+    }
+}
+
 #[cfg(target_arch = "x86_64")]
 mod x86_64 {
     use core::arch::x86_64 as arch;
@@ -10,13 +58,42 @@ mod x86_64 {
         (c_out, sum)
     }
 
+    fn sbb(b_in: u8, a: u64, b: u64) -> (u8, u64) {
+        let mut sum = 0;
+        // SAFETY: There are no safety requirements for calling `_subborrow_u64`.
+        // It's just unsafe for API consistency with other intrinsics.
+        let b_out = unsafe { arch::_subborrow_u64(b_in, a, b, &mut sum) };
+        (b_out, sum)
+    }
+
     pub fn main() {
+        assert_eq!(adc(0, 1, 1), (0, 2));
         assert_eq!(adc(1, 1, 1), (0, 3));
-        assert_eq!(adc(3, u64::MAX, u64::MAX), (2, 1));
+        assert_eq!(adc(2, 1, 1), (0, 3)); // any non-zero carry acts as 1!
+        assert_eq!(adc(u8::MAX, 1, 1), (0, 3));
+        assert_eq!(adc(0, u64::MAX, u64::MAX), (1, u64::MAX - 1));
+        assert_eq!(adc(1, u64::MAX, u64::MAX), (1, u64::MAX));
+        assert_eq!(adc(2, u64::MAX, u64::MAX), (1, u64::MAX));
+        assert_eq!(adc(u8::MAX, u64::MAX, u64::MAX), (1, u64::MAX));
+
+        assert_eq!(sbb(0, 1, 1), (0, 0));
+        assert_eq!(sbb(1, 1, 1), (1, u64::MAX));
+        assert_eq!(sbb(2, 1, 1), (1, u64::MAX)); // any non-zero borrow acts as 1!
+        assert_eq!(sbb(u8::MAX, 1, 1), (1, u64::MAX));
+        assert_eq!(sbb(0, 2, 1), (0, 1));
+        assert_eq!(sbb(1, 2, 1), (0, 0));
+        assert_eq!(sbb(2, 2, 1), (0, 0));
+        assert_eq!(sbb(u8::MAX, 2, 1), (0, 0));
+        assert_eq!(sbb(0, 1, 2), (1, u64::MAX));
+        assert_eq!(sbb(1, 1, 2), (1, u64::MAX - 1));
+        assert_eq!(sbb(2, 1, 2), (1, u64::MAX - 1));
+        assert_eq!(sbb(u8::MAX, 1, 2), (1, u64::MAX - 1));
     }
 }
 
 fn main() {
+    #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
+    x86::main();
     #[cfg(target_arch = "x86_64")]
     x86_64::main();
 }
diff --git a/src/tools/miri/tests/pass/portable-simd.rs b/src/tools/miri/tests/pass/portable-simd.rs
index ee67a65a4f9..c1f5618c163 100644
--- a/src/tools/miri/tests/pass/portable-simd.rs
+++ b/src/tools/miri/tests/pass/portable-simd.rs
@@ -1,5 +1,6 @@
 //@compile-flags: -Zmiri-strict-provenance
-#![feature(portable_simd, platform_intrinsics)]
+#![feature(portable_simd, platform_intrinsics, adt_const_params, inline_const)]
+#![allow(incomplete_features)]
 use std::simd::*;
 
 extern "platform-intrinsic" {
@@ -390,6 +391,8 @@ fn simd_intrinsics() {
         fn simd_reduce_any<T>(x: T) -> bool;
         fn simd_reduce_all<T>(x: T) -> bool;
         fn simd_select<M, T>(m: M, yes: T, no: T) -> T;
+        fn simd_shuffle_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;
+        fn simd_shuffle<T, IDX, U>(x: T, y: T, idx: IDX) -> U;
     }
     unsafe {
         // Make sure simd_eq returns all-1 for `true`
@@ -413,6 +416,22 @@ fn simd_intrinsics() {
             simd_select(i8x4::from_array([0, -1, -1, 0]), b, a),
             i32x4::from_array([10, 2, 10, 10])
         );
+        assert_eq!(
+            simd_shuffle_generic::<_, i32x4, {&[3, 1, 0, 2]}>(a, b),
+            a,
+        );
+        assert_eq!(
+            simd_shuffle::<_, _, i32x4>(a, b, const {[3, 1, 0, 2]}),
+            a,
+        );
+        assert_eq!(
+            simd_shuffle_generic::<_, i32x4, {&[7, 5, 4, 6]}>(a, b),
+            i32x4::from_array([4, 2, 1, 10]),
+        );
+        assert_eq!(
+            simd_shuffle::<_, _, i32x4>(a, b, const {[7, 5, 4, 6]}),
+            i32x4::from_array([4, 2, 1, 10]),
+        );
     }
 }
 
diff --git a/src/tools/miri/triagebot.toml b/src/tools/miri/triagebot.toml
index 69f3cd2f810..1c520a9c779 100644
--- a/src/tools/miri/triagebot.toml
+++ b/src/tools/miri/triagebot.toml
@@ -10,5 +10,6 @@ allow-unauthenticated = [
 # Gives us the commands 'ready', 'author', 'blocked'
 [shortcut]
 
-[no-merges]
-exclude_labels = ["rollup", "subtree-sync"]
+# disabled until https://github.com/rust-lang/triagebot/pull/1720 lands
+#[no-merges]
+#exclude_titles = ["Rollup of", "sync from rustc"]
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 843ffe2c4c3..7d3ef4197a7 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -18,6 +18,7 @@ const LICENSES: &[&str] = &[
     "Apache-2.0/MIT",
     "ISC",
     "MIT / Apache-2.0",
+    "MIT OR Apache-2.0 OR LGPL-2.1-or-later",              // r-efi, r-efi-alloc
     "MIT OR Apache-2.0 OR Zlib",                           // tinyvec_macros
     "MIT OR Apache-2.0",
     "MIT OR Zlib OR Apache-2.0",                           // miniz_oxide
@@ -57,14 +58,14 @@ const EXCEPTIONS_CARGO: &[(&str, &str)] = &[
     // tidy-alphabetical-start
     ("bitmaps", "MPL-2.0+"),
     ("bytesize", "Apache-2.0"),
+    ("byteyarn", "Apache-2.0"),
     ("ciborium", "Apache-2.0"),
     ("ciborium-io", "Apache-2.0"),
     ("ciborium-ll", "Apache-2.0"),
     ("dunce", "CC0-1.0 OR MIT-0 OR Apache-2.0"),
+    ("encoding_rs", "(Apache-2.0 OR MIT) AND BSD-3-Clause"),
     ("fiat-crypto", "MIT OR Apache-2.0 OR BSD-1-Clause"),
     ("im-rc", "MPL-2.0+"),
-    ("imara-diff", "Apache-2.0"),
-    ("instant", "BSD-3-Clause"),
     ("normalize-line-endings", "Apache-2.0"),
     ("openssl", "Apache-2.0"),
     ("ryu", "Apache-2.0 OR BSL-1.0"),
@@ -179,7 +180,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "instant",
     "intl-memoizer",
     "intl_pluralrules",
-    "io-lifetimes",
     "is-terminal",
     "itertools",
     "itoa",
@@ -217,6 +217,8 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "pulldown-cmark",
     "punycode",
     "quote",
+    "r-efi",
+    "r-efi-alloc",
     "rand",
     "rand_chacha",
     "rand_core",
diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs
index 3a4d9c53d7b..5f6b63a67fd 100644
--- a/src/tools/tidy/src/pal.rs
+++ b/src/tools/tidy/src/pal.rs
@@ -56,6 +56,7 @@ const EXCEPTION_PATHS: &[&str] = &[
     "library/std/src/path.rs",
     "library/std/src/sys_common", // Should only contain abstractions over platforms
     "library/std/src/net/test.rs", // Utility helpers for tests
+    "library/std/src/io/error.rs", // Repr unpacked needed for UEFI
 ];
 
 pub fn check(path: &Path, bad: &mut bool) {
diff --git a/tests/assembly/closure-inherit-target-feature.rs b/tests/assembly/closure-inherit-target-feature.rs
new file mode 100644
index 00000000000..65728a15516
--- /dev/null
+++ b/tests/assembly/closure-inherit-target-feature.rs
@@ -0,0 +1,58 @@
+// only-x86_64
+// assembly-output: emit-asm
+// make sure the feature is not enabled at compile-time
+// compile-flags: -C opt-level=3 -C target-feature=-sse4.1 -C llvm-args=-x86-asm-syntax=intel
+
+#![feature(target_feature_11)]
+#![crate_type = "rlib"]
+
+use std::arch::x86_64::{__m128, _mm_blend_ps};
+
+#[no_mangle]
+pub unsafe fn sse41_blend_nofeature(x: __m128, y: __m128) -> __m128 {
+    let f = {
+        // check that _mm_blend_ps is not being inlined into the closure
+        // CHECK-LABEL: {{sse41_blend_nofeature.*closure.*:}}
+        // CHECK-NOT: blendps
+        // CHECK: {{call .*_mm_blend_ps.*}}
+        // CHECK-NOT: blendps
+        // CHECK: ret
+        #[inline(never)] |x, y| _mm_blend_ps(x, y, 0b0101)
+    };
+    f(x, y)
+}
+
+#[target_feature(enable = "sse4.1")]
+pub fn sse41_blend_noinline(x: __m128, y: __m128) -> __m128 {
+    let f = {
+        // check that _mm_blend_ps is being inlined into the closure
+        // CHECK-LABEL: {{sse41_blend_noinline.*closure.*:}}
+        // CHECK-NOT: _mm_blend_ps
+        // CHECK: blendps
+        // CHECK-NOT: _mm_blend_ps
+        // CHECK: ret
+        #[inline(never)] |x, y| unsafe {
+            _mm_blend_ps(x, y, 0b0101)
+        }
+    };
+    f(x, y)
+}
+
+#[no_mangle]
+#[target_feature(enable = "sse4.1")]
+pub fn sse41_blend_doinline(x: __m128, y: __m128) -> __m128 {
+    // check that the closure and _mm_blend_ps are being inlined into the function
+    // CHECK-LABEL: sse41_blend_doinline:
+    // CHECK-NOT: {{sse41_blend_doinline.*closure.*}}
+    // CHECK-NOT: _mm_blend_ps
+    // CHECK: blendps
+    // CHECK-NOT: {{sse41_blend_doinline.*closure.*}}
+    // CHECK-NOT: _mm_blend_ps
+    // CHECK: ret
+    let f = {
+        #[inline] |x, y| unsafe {
+            _mm_blend_ps(x, y, 0b0101)
+        }
+    };
+    f(x, y)
+}
diff --git a/tests/codegen/async-fn-debug-awaitee-field.rs b/tests/codegen/async-fn-debug-awaitee-field.rs
index bc268615814..690505fd72b 100644
--- a/tests/codegen/async-fn-debug-awaitee-field.rs
+++ b/tests/codegen/async-fn-debug-awaitee-field.rs
@@ -5,12 +5,14 @@
 // ignore-tidy-linelength
 // compile-flags: -C debuginfo=2 --edition=2018
 
-async fn foo() {}
+#![crate_type = "lib"]
 
-async fn async_fn_test() {
+pub async fn async_fn_test() {
     foo().await;
 }
 
+pub async fn foo() {}
+
 // NONMSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}", scope: [[GEN_SCOPE:![0-9]*]],
 // MSVC: [[GEN:!.*]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::async_fn_test::async_fn_env$0>",
 // NONMSVC: [[GEN_SCOPE:!.*]] = !DINamespace(name: "async_fn_test",
@@ -19,7 +21,3 @@ async fn async_fn_test() {
 // NONMSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_structure_type, name: "{async_fn_env#0}", scope: [[AWAITEE_SCOPE:![0-9]*]],
 // MSVC: [[AWAITEE_TYPE]] = !DICompositeType(tag: DW_TAG_union_type, name: "enum2$<async_fn_debug_awaitee_field::foo::async_fn_env$0>",
 // NONMSVC: [[AWAITEE_SCOPE]] = !DINamespace(name: "foo",
-
-fn main() {
-    let _fn = async_fn_test();
-}
diff --git a/tests/codegen/macos/i686-macosx-deployment-target.rs b/tests/codegen/macos/i686-macosx-deployment-target.rs
index 17258a264a5..ba49178dcb6 100644
--- a/tests/codegen/macos/i686-macosx-deployment-target.rs
+++ b/tests/codegen/macos/i686-macosx-deployment-target.rs
@@ -4,7 +4,7 @@
 
 // compile-flags: -O --target=i686-apple-darwin --crate-type=rlib
 // needs-llvm-components: x86
-// rustc-env:MACOSX_DEPLOYMENT_TARGET=10.9
+// rustc-env:MACOSX_DEPLOYMENT_TARGET=10.14
 #![feature(no_core, lang_items)]
 #![no_core]
 
@@ -20,7 +20,7 @@ pub struct Bool {
     b: bool,
 }
 
-// CHECK: target triple = "i686-apple-macosx10.9.0"
+// CHECK: target triple = "i686-apple-macosx10.14.0"
 #[no_mangle]
 pub extern "C" fn structbool() -> Bool {
     Bool { b: true }
diff --git a/tests/codegen/macos/i686-no-macosx-deployment-target.rs b/tests/codegen/macos/i686-no-macosx-deployment-target.rs
index 043040a95e3..479fe7968f7 100644
--- a/tests/codegen/macos/i686-no-macosx-deployment-target.rs
+++ b/tests/codegen/macos/i686-no-macosx-deployment-target.rs
@@ -20,7 +20,7 @@ pub struct Bool {
     b: bool,
 }
 
-// CHECK: target triple = "i686-apple-macosx10.7.0"
+// CHECK: target triple = "i686-apple-macosx10.12.0"
 #[no_mangle]
 pub extern "C" fn structbool() -> Bool {
     Bool { b: true }
diff --git a/tests/codegen/macos/x86_64-macosx-deployment-target.rs b/tests/codegen/macos/x86_64-macosx-deployment-target.rs
index 8e673d11d98..957c727bb93 100644
--- a/tests/codegen/macos/x86_64-macosx-deployment-target.rs
+++ b/tests/codegen/macos/x86_64-macosx-deployment-target.rs
@@ -4,7 +4,7 @@
 
 // compile-flags: -O --target=x86_64-apple-darwin --crate-type=rlib
 // needs-llvm-components: x86
-// rustc-env:MACOSX_DEPLOYMENT_TARGET=10.9
+// rustc-env:MACOSX_DEPLOYMENT_TARGET=10.14
 #![feature(no_core, lang_items)]
 #![no_core]
 
@@ -20,7 +20,7 @@ pub struct Bool {
     b: bool,
 }
 
-// CHECK: target triple = "x86_64-apple-macosx10.9.0"
+// CHECK: target triple = "x86_64-apple-macosx10.14.0"
 #[no_mangle]
 pub extern "C" fn structbool() -> Bool {
     Bool { b: true }
diff --git a/tests/codegen/macos/x86_64-no-macosx-deployment-target.rs b/tests/codegen/macos/x86_64-no-macosx-deployment-target.rs
index 25ae6924de0..edbc1b66c71 100644
--- a/tests/codegen/macos/x86_64-no-macosx-deployment-target.rs
+++ b/tests/codegen/macos/x86_64-no-macosx-deployment-target.rs
@@ -20,7 +20,7 @@ pub struct Bool {
     b: bool,
 }
 
-// CHECK: target triple = "x86_64-apple-macosx10.7.0"
+// CHECK: target triple = "x86_64-apple-macosx10.12.0"
 #[no_mangle]
 pub extern "C" fn structbool() -> Bool {
     Bool { b: true }
diff --git a/tests/codegen/vecdeque-nonempty-get-no-panic.rs b/tests/codegen/vecdeque-nonempty-get-no-panic.rs
new file mode 100644
index 00000000000..c2877d2d0ca
--- /dev/null
+++ b/tests/codegen/vecdeque-nonempty-get-no-panic.rs
@@ -0,0 +1,17 @@
+// Guards against regression for optimization discussed in issue #80836
+
+// compile-flags: -O
+// ignore-debug: the debug assertions get in the way
+
+#![crate_type = "lib"]
+
+use std::collections::VecDeque;
+
+// CHECK-LABEL: @front
+// CHECK: ret void
+#[no_mangle]
+pub fn front(v: VecDeque<usize>) {
+    if !v.is_empty() {
+        v.get(0).unwrap();
+    }
+}
diff --git a/tests/incremental/change_crate_dep_kind.rs b/tests/incremental/change_crate_dep_kind.rs
index f518266016e..b9f74340472 100644
--- a/tests/incremental/change_crate_dep_kind.rs
+++ b/tests/incremental/change_crate_dep_kind.rs
@@ -5,6 +5,7 @@
 // needs-unwind
 // revisions:cfail1 cfail2
 // compile-flags: -Z query-dep-graph -Cpanic=unwind
+// needs-unwind
 // build-pass (FIXME(62277): could be check-pass?)
 
 #![feature(panic_unwind)]
diff --git a/tests/incremental/hashes/function_interfaces.rs b/tests/incremental/hashes/function_interfaces.rs
index 182ca7d926c..23b81705f9a 100644
--- a/tests/incremental/hashes/function_interfaces.rs
+++ b/tests/incremental/hashes/function_interfaces.rs
@@ -302,7 +302,7 @@ pub fn return_impl_trait() -> i32        {
 }
 
 #[cfg(not(any(cfail1,cfail4)))]
-#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, typeck, fn_sig, optimized_mir")]
+#[rustc_clean(cfg = "cfail2", except = "hir_owner, hir_owner_nodes, typeck, fn_sig")]
 #[rustc_clean(cfg = "cfail3")]
 #[rustc_clean(cfg = "cfail5", except = "hir_owner, hir_owner_nodes, typeck, fn_sig, optimized_mir")]
 #[rustc_clean(cfg = "cfail6")]
diff --git a/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir
index 51e0faf1733..98b1befc3bf 100644
--- a/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir
+++ b/tests/mir-opt/building/async_await.a-{closure#0}.generator_resume.0.mir
@@ -18,22 +18,30 @@ fn a::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>
 
     bb0: {
         _5 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16})));
-        switchInt(move _5) -> [0: bb1, 1: bb2, otherwise: bb3];
+        switchInt(move _5) -> [0: bb1, 1: bb4, otherwise: bb5];
     }
 
     bb1: {
         _4 = move _2;
         _3 = const ();
+        goto -> bb3;
+    }
+
+    bb2: {
         _0 = Poll::<()>::Ready(move _3);
         discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16}))) = 1;
         return;
     }
 
-    bb2: {
-        assert(const false, "`async fn` resumed after completion") -> [success: bb2, unwind unreachable];
+    bb3: {
+        goto -> bb2;
     }
 
-    bb3: {
+    bb4: {
+        assert(const false, "`async fn` resumed after completion") -> [success: bb4, unwind unreachable];
+    }
+
+    bb5: {
         unreachable;
     }
 }
diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir
index 0c46c60a2da..15330b13cc2 100644
--- a/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir
+++ b/tests/mir-opt/building/async_await.b-{closure#0}.generator_resume.0.mir
@@ -2,13 +2,16 @@
 /* generator_layout = GeneratorLayout {
     field_tys: {
         _0: GeneratorSavedTy {
-            ty: Alias(
-                Opaque,
-                AliasTy {
-                    args: [
-                    ],
-                    def_id: DefId(0:7 ~ async_await[ccf8]::a::{opaque#0}),
-                },
+            ty: Generator(
+                DefId(0:4 ~ async_await[ccf8]::a::{closure#0}),
+                [
+                std::future::ResumeTy,
+                (),
+                (),
+                GeneratorWitness(DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), []),
+                (),
+                ],
+                Static,
             ),
             source_info: SourceInfo {
                 span: $DIR/async_await.rs:15:9: 15:14 (#8),
@@ -17,13 +20,16 @@
             ignore_for_traits: false,
         },
         _1: GeneratorSavedTy {
-            ty: Alias(
-                Opaque,
-                AliasTy {
-                    args: [
-                    ],
-                    def_id: DefId(0:7 ~ async_await[ccf8]::a::{opaque#0}),
-                },
+            ty: Generator(
+                DefId(0:4 ~ async_await[ccf8]::a::{closure#0}),
+                [
+                std::future::ResumeTy,
+                (),
+                (),
+                GeneratorWitness(DefId(0:4 ~ async_await[ccf8]::a::{closure#0}), []),
+                (),
+                ],
+                Static,
             ),
             source_info: SourceInfo {
                 span: $DIR/async_await.rs:16:9: 16:14 (#10),
@@ -49,15 +55,15 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
     debug _task_context => _38;
     let mut _0: std::task::Poll<()>;
     let _3: ();
-    let mut _4: impl std::future::Future<Output = ()>;
-    let mut _5: impl std::future::Future<Output = ()>;
-    let mut _6: impl std::future::Future<Output = ()>;
+    let mut _4: {async fn body@$DIR/async_await.rs:11:14: 11:16};
+    let mut _5: {async fn body@$DIR/async_await.rs:11:14: 11:16};
+    let mut _6: {async fn body@$DIR/async_await.rs:11:14: 11:16};
     let mut _7: ();
     let _8: ();
     let mut _9: std::task::Poll<()>;
-    let mut _10: std::pin::Pin<&mut impl std::future::Future<Output = ()>>;
-    let mut _11: &mut impl std::future::Future<Output = ()>;
-    let mut _12: &mut impl std::future::Future<Output = ()>;
+    let mut _10: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>;
+    let mut _11: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
+    let mut _12: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
     let mut _13: &mut std::task::Context<'_>;
     let mut _14: &mut std::task::Context<'_>;
     let mut _15: &mut std::task::Context<'_>;
@@ -65,14 +71,14 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
     let mut _18: !;
     let mut _19: &mut std::task::Context<'_>;
     let mut _20: ();
-    let mut _21: impl std::future::Future<Output = ()>;
-    let mut _22: impl std::future::Future<Output = ()>;
-    let mut _23: impl std::future::Future<Output = ()>;
+    let mut _21: {async fn body@$DIR/async_await.rs:11:14: 11:16};
+    let mut _22: {async fn body@$DIR/async_await.rs:11:14: 11:16};
+    let mut _23: {async fn body@$DIR/async_await.rs:11:14: 11:16};
     let _24: ();
     let mut _25: std::task::Poll<()>;
-    let mut _26: std::pin::Pin<&mut impl std::future::Future<Output = ()>>;
-    let mut _27: &mut impl std::future::Future<Output = ()>;
-    let mut _28: &mut impl std::future::Future<Output = ()>;
+    let mut _26: std::pin::Pin<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>;
+    let mut _27: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
+    let mut _28: &mut {async fn body@$DIR/async_await.rs:11:14: 11:16};
     let mut _29: &mut std::task::Context<'_>;
     let mut _30: &mut std::task::Context<'_>;
     let mut _31: &mut std::task::Context<'_>;
@@ -84,7 +90,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
     let mut _38: &mut std::task::Context<'_>;
     let mut _39: u32;
     scope 1 {
-        debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future<Output = ()>);
+        debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
         let _17: ();
         scope 2 {
         }
@@ -93,7 +99,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
         }
     }
     scope 4 {
-        debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future<Output = ()>);
+        debug __awaitee => (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
         let _33: ();
         scope 5 {
         }
@@ -104,7 +110,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
 
     bb0: {
         _39 = discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})));
-        switchInt(move _39) -> [0: bb1, 1: bb28, 3: bb26, 4: bb27, otherwise: bb29];
+        switchInt(move _39) -> [0: bb1, 1: bb29, 3: bb27, 4: bb28, otherwise: bb30];
     }
 
     bb1: {
@@ -116,13 +122,13 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
     }
 
     bb2: {
-        _4 = <impl Future<Output = ()> as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable];
+        _4 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as IntoFuture>::into_future(move _5) -> [return: bb3, unwind unreachable];
     }
 
     bb3: {
         StorageDead(_5);
         nop;
-        (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future<Output = ()>) = move _4;
+        (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}) = move _4;
         goto -> bb4;
     }
 
@@ -132,9 +138,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
         StorageLive(_10);
         StorageLive(_11);
         StorageLive(_12);
-        _12 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: impl std::future::Future<Output = ()>);
+        _12 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
         _11 = &mut (*_12);
-        _10 = Pin::<&mut impl Future<Output = ()>>::new_unchecked(move _11) -> [return: bb5, unwind unreachable];
+        _10 = Pin::<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>::new_unchecked(move _11) -> [return: bb5, unwind unreachable];
     }
 
     bb5: {
@@ -150,7 +156,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
     bb6: {
         _13 = &mut (*_14);
         StorageDead(_15);
-        _9 = <impl Future<Output = ()> as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable];
+        _9 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as Future>::poll(move _10, move _13) -> [return: bb7, unwind unreachable];
     }
 
     bb7: {
@@ -187,7 +193,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
         StorageDead(_12);
         StorageDead(_9);
         StorageDead(_8);
-        goto -> bb12;
+        drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:11:14: 11:16})) -> [return: bb12, unwind unreachable];
     }
 
     bb11: {
@@ -212,13 +218,13 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
     }
 
     bb14: {
-        _21 = <impl Future<Output = ()> as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable];
+        _21 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as IntoFuture>::into_future(move _22) -> [return: bb15, unwind unreachable];
     }
 
     bb15: {
         StorageDead(_22);
         nop;
-        (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future<Output = ()>) = move _21;
+        (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16}) = move _21;
         goto -> bb16;
     }
 
@@ -228,9 +234,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
         StorageLive(_26);
         StorageLive(_27);
         StorageLive(_28);
-        _28 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: impl std::future::Future<Output = ()>);
+        _28 = &mut (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16});
         _27 = &mut (*_28);
-        _26 = Pin::<&mut impl Future<Output = ()>>::new_unchecked(move _27) -> [return: bb17, unwind unreachable];
+        _26 = Pin::<&mut {async fn body@$DIR/async_await.rs:11:14: 11:16}>::new_unchecked(move _27) -> [return: bb17, unwind unreachable];
     }
 
     bb17: {
@@ -246,7 +252,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
     bb18: {
         _29 = &mut (*_30);
         StorageDead(_31);
-        _25 = <impl Future<Output = ()> as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable];
+        _25 = <{async fn body@$DIR/async_await.rs:11:14: 11:16} as Future>::poll(move _26, move _29) -> [return: bb19, unwind unreachable];
     }
 
     bb19: {
@@ -279,7 +285,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
         StorageDead(_28);
         StorageDead(_25);
         StorageDead(_24);
-        goto -> bb23;
+        drop((((*(_1.0: &mut {async fn body@$DIR/async_await.rs:14:18: 17:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:11:14: 11:16})) -> [return: bb23, unwind unreachable];
     }
 
     bb22: {
@@ -297,7 +303,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
 
     bb24: {
         StorageDead(_21);
-        goto -> bb25;
+        goto -> bb26;
     }
 
     bb25: {
@@ -307,6 +313,10 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
     }
 
     bb26: {
+        goto -> bb25;
+    }
+
+    bb27: {
         StorageLive(_3);
         StorageLive(_4);
         StorageLive(_19);
@@ -315,7 +325,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
         goto -> bb11;
     }
 
-    bb27: {
+    bb28: {
         StorageLive(_21);
         StorageLive(_35);
         StorageLive(_36);
@@ -323,11 +333,11 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:14:18: 17:2}>,
         goto -> bb22;
     }
 
-    bb28: {
-        assert(const false, "`async fn` resumed after completion") -> [success: bb28, unwind unreachable];
+    bb29: {
+        assert(const false, "`async fn` resumed after completion") -> [success: bb29, unwind unreachable];
     }
 
-    bb29: {
+    bb30: {
         unreachable;
     }
 }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-abort.diff
new file mode 100644
index 00000000000..b9b46f16a8b
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-abort.diff
@@ -0,0 +1,119 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+-         _7 = AlignOf([bool; 0]);
+-         _6 = _7 as *mut [bool; 0] (Transmute);
++         _7 = const 1_usize;
++         _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+-         _8 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+-         _5 = NonNull::<[bool; 0]> { pointer: _8 };
++         _8 = const {0x1 as *const [bool; 0]};
++         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+-         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
++         _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+-         _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
++         _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+-         _2 = Box::<[bool]>(_3, const std::alloc::Global);
++         _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+-         _1 = A { foo: move _2 };
++         _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
++ }
++ 
++ alloc11 (size: 8, align: 4) {
++     01 00 00 00 00 00 00 00                         │ ........
++ }
++ 
++ alloc10 (size: 8, align: 4) {
++     01 00 00 00 00 00 00 00                         │ ........
++ }
++ 
++ alloc7 (size: 8, align: 4) {
++     01 00 00 00 00 00 00 00                         │ ........
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-unwind.diff
new file mode 100644
index 00000000000..93b18f23e61
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.32bit.panic-unwind.diff
@@ -0,0 +1,123 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+-         _7 = AlignOf([bool; 0]);
+-         _6 = _7 as *mut [bool; 0] (Transmute);
++         _7 = const 1_usize;
++         _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+-         _8 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+-         _5 = NonNull::<[bool; 0]> { pointer: _8 };
++         _8 = const {0x1 as *const [bool; 0]};
++         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+-         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
++         _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+-         _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
++         _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+-         _2 = Box::<[bool]>(_3, const std::alloc::Global);
++         _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+-         _1 = A { foo: move _2 };
++         _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind: bb2];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
++ }
++ 
++ alloc11 (size: 8, align: 4) {
++     01 00 00 00 00 00 00 00                         │ ........
++ }
++ 
++ alloc10 (size: 8, align: 4) {
++     01 00 00 00 00 00 00 00                         │ ........
++ }
++ 
++ alloc7 (size: 8, align: 4) {
++     01 00 00 00 00 00 00 00                         │ ........
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-abort.diff
new file mode 100644
index 00000000000..3d3af62856b
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-abort.diff
@@ -0,0 +1,119 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+-         _7 = AlignOf([bool; 0]);
+-         _6 = _7 as *mut [bool; 0] (Transmute);
++         _7 = const 1_usize;
++         _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+-         _8 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+-         _5 = NonNull::<[bool; 0]> { pointer: _8 };
++         _8 = const {0x1 as *const [bool; 0]};
++         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+-         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
++         _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+-         _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
++         _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+-         _2 = Box::<[bool]>(_3, const std::alloc::Global);
++         _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+-         _1 = A { foo: move _2 };
++         _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
++ }
++ 
++ alloc11 (size: 16, align: 8) {
++     01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
++ }
++ 
++ alloc10 (size: 16, align: 8) {
++     01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
++ }
++ 
++ alloc7 (size: 16, align: 8) {
++     01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-unwind.diff
new file mode 100644
index 00000000000..1933f9bafb3
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.ConstProp.64bit.panic-unwind.diff
@@ -0,0 +1,123 @@
+- // MIR for `main` before ConstProp
++ // MIR for `main` after ConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+-         _7 = AlignOf([bool; 0]);
+-         _6 = _7 as *mut [bool; 0] (Transmute);
++         _7 = const 1_usize;
++         _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+-         _8 = _6 as *const [bool; 0] (PointerCoercion(MutToConstPointer));
+-         _5 = NonNull::<[bool; 0]> { pointer: _8 };
++         _8 = const {0x1 as *const [bool; 0]};
++         _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+-         _4 = Unique::<[bool; 0]> { pointer: move _5, _marker: const PhantomData::<[bool; 0]> };
++         _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+-         _3 = move _4 as std::ptr::Unique<[bool]> (PointerCoercion(Unsize));
++         _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+-         _2 = Box::<[bool]>(_3, const std::alloc::Global);
++         _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+-         _1 = A { foo: move _2 };
++         _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind: bb2];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
++ }
++ 
++ alloc11 (size: 16, align: 8) {
++     01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
++ }
++ 
++ alloc10 (size: 16, align: 8) {
++     01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
++ }
++ 
++ alloc7 (size: 16, align: 8) {
++     01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
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
new file mode 100644
index 00000000000..7862c23da80
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
@@ -0,0 +1,111 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 1_usize;
+          _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+          _8 = const {0x1 as *const [bool; 0]};
+          _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+          _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+          _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+          _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+          _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  }
+  
+  alloc11 (size: 8, align: 4) {
+      01 00 00 00 00 00 00 00                         │ ........
+  }
+  
+  alloc10 (size: 8, align: 4) {
+      01 00 00 00 00 00 00 00                         │ ........
+  }
+  
+  alloc7 (size: 8, align: 4) {
+      01 00 00 00 00 00 00 00                         │ ........
+  }
+  
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
new file mode 100644
index 00000000000..bd4150ebb45
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -0,0 +1,115 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 1_usize;
+          _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+          _8 = const {0x1 as *const [bool; 0]};
+          _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+          _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+          _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+          _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+          _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind: bb2];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
+  }
+  
+  alloc11 (size: 8, align: 4) {
+      01 00 00 00 00 00 00 00                         │ ........
+  }
+  
+  alloc10 (size: 8, align: 4) {
+      01 00 00 00 00 00 00 00                         │ ........
+  }
+  
+  alloc7 (size: 8, align: 4) {
+      01 00 00 00 00 00 00 00                         │ ........
+  }
+  
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
new file mode 100644
index 00000000000..312fc7b7a82
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
@@ -0,0 +1,111 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 1_usize;
+          _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+          _8 = const {0x1 as *const [bool; 0]};
+          _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+          _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+          _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+          _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+          _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  }
+  
+  alloc11 (size: 16, align: 8) {
+      01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
+  alloc10 (size: 16, align: 8) {
+      01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
+  alloc7 (size: 16, align: 8) {
+      01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
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
new file mode 100644
index 00000000000..3227d8b8435
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -0,0 +1,115 @@
+- // MIR for `main` before DataflowConstProp
++ // MIR for `main` after DataflowConstProp
+  
+  fn main() -> () {
+      let mut _0: ();
+      let _1: A;
+      let mut _2: std::boxed::Box<[bool]>;
+      scope 1 {
+          debug a => _1;
+      }
+      scope 2 (inlined <Box<[bool]> as Default>::default) {
+          let _3: std::ptr::Unique<[bool]>;
+          let mut _4: std::ptr::Unique<[bool; 0]>;
+          scope 3 {
+              debug ptr => _3;
+          }
+          scope 4 (inlined Unique::<[bool; 0]>::dangling) {
+              let mut _5: std::ptr::NonNull<[bool; 0]>;
+              scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let mut _7: usize;
+                  scope 6 {
+                      let _6: *mut [bool; 0];
+                      scope 7 {
+                          debug ptr => _6;
+                          scope 11 (inlined NonNull::<[bool; 0]>::new_unchecked) {
+                              debug ptr => _6;
+                              let mut _8: *const [bool; 0];
+                              scope 12 {
+                                  scope 13 (inlined NonNull::<T>::new_unchecked::runtime::<[bool; 0]>) {
+                                      debug ptr => _6;
+                                      scope 14 (inlined ptr::mut_ptr::<impl *mut [bool; 0]>::is_null) {
+                                          debug self => _6;
+                                          let mut _9: *mut u8;
+                                          scope 15 {
+                                              scope 16 (inlined ptr::mut_ptr::<impl *mut T>::is_null::runtime_impl) {
+                                                  debug ptr => _9;
+                                                  scope 17 (inlined ptr::mut_ptr::<impl *mut u8>::addr) {
+                                                      debug self => _9;
+                                                      scope 18 {
+                                                          scope 19 (inlined ptr::mut_ptr::<impl *mut u8>::cast::<()>) {
+                                                              debug self => _9;
+                                                          }
+                                                      }
+                                                  }
+                                              }
+                                          }
+                                      }
+                                  }
+                              }
+                          }
+                      }
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined invalid_mut::<[bool; 0]>) {
+                          debug addr => _7;
+                          scope 10 {
+                          }
+                      }
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_1);
+          StorageLive(_2);
+          StorageLive(_3);
+          StorageLive(_4);
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 1_usize;
+          _6 = const {0x1 as *mut [bool; 0]};
+          StorageDead(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+          _8 = const {0x1 as *const [bool; 0]};
+          _5 = const NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }};
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageDead(_6);
+          _4 = const Unique::<[bool; 0]> {{ pointer: NonNull::<[bool; 0]> {{ pointer: {0x1 as *const [bool; 0]} }}, _marker: PhantomData::<[bool; 0]> }};
+          StorageDead(_5);
+          _3 = const Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc7, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }};
+          StorageDead(_4);
+          _2 = const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc10, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global);
+          StorageDead(_3);
+          _1 = A { foo: const Box::<[bool]>(Unique::<[bool]> {{ pointer: NonNull::<[bool]> {{ pointer: Indirect { alloc_id: alloc11, offset: Size(0 bytes) }: *const [bool] }}, _marker: PhantomData::<[bool]> }}, std::alloc::Global) };
+          StorageDead(_2);
+          _0 = const ();
+          drop(_1) -> [return: bb1, unwind: bb2];
+      }
+  
+      bb1: {
+          StorageDead(_1);
+          return;
+      }
+  
+      bb2 (cleanup): {
+          resume;
+      }
+  }
+  
+  alloc11 (size: 16, align: 8) {
+      01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
+  alloc10 (size: 16, align: 8) {
+      01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
+  alloc7 (size: 16, align: 8) {
+      01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 │ ................
+  }
+  
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs
new file mode 100644
index 00000000000..dfeccd3eb94
--- /dev/null
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.rs
@@ -0,0 +1,17 @@
+// unit-test: DataflowConstProp
+// compile-flags: -Zmir-enable-passes=+ConstProp,+Inline
+// ignore-debug assertions change the output MIR
+// EMIT_MIR_FOR_EACH_BIT_WIDTH
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+
+struct A {
+    foo: Box<[bool]>,
+}
+
+// EMIT_MIR default_boxed_slice.main.ConstProp.diff
+// EMIT_MIR default_boxed_slice.main.DataflowConstProp.diff
+fn main() {
+    // ConstProp will create a constant of type `Box<[bool]>`.
+    // Verify that `DataflowConstProp` does not ICE trying to dereference it directly.
+    let a: A = A { foo: Box::default() };
+}
diff --git a/tests/mir-opt/gvn.arithmetic.GVN.panic-abort.diff b/tests/mir-opt/gvn.arithmetic.GVN.panic-abort.diff
new file mode 100644
index 00000000000..3f5173c189e
--- /dev/null
+++ b/tests/mir-opt/gvn.arithmetic.GVN.panic-abort.diff
@@ -0,0 +1,342 @@
+- // MIR for `arithmetic` before GVN
++ // MIR for `arithmetic` after GVN
+  
+  fn arithmetic(_1: u64) -> () {
+      debug x => _1;
+      let mut _0: ();
+      let _2: ();
+      let mut _3: u64;
+      let mut _4: u64;
+      let _5: ();
+      let mut _6: u64;
+      let mut _7: u64;
+      let _8: ();
+      let mut _9: u64;
+      let mut _10: u64;
+      let _11: ();
+      let mut _12: u64;
+      let mut _13: u64;
+      let _14: ();
+      let mut _15: u64;
+      let mut _16: u64;
+      let mut _17: bool;
+      let _18: ();
+      let mut _19: u64;
+      let mut _20: u64;
+      let mut _21: bool;
+      let _22: ();
+      let mut _23: u64;
+      let mut _24: u64;
+      let mut _25: bool;
+      let _26: ();
+      let mut _27: u64;
+      let mut _28: u64;
+      let mut _29: bool;
+      let _30: ();
+      let mut _31: u64;
+      let mut _32: u64;
+      let mut _33: bool;
+      let _34: ();
+      let mut _35: u64;
+      let mut _36: u64;
+      let mut _37: bool;
+      let _38: ();
+      let mut _39: u64;
+      let mut _40: u64;
+      let mut _41: bool;
+      let _42: ();
+      let mut _43: u64;
+      let mut _44: u64;
+      let mut _45: bool;
+      let _46: ();
+      let mut _47: u64;
+      let mut _48: u64;
+      let _49: ();
+      let mut _50: u64;
+      let mut _51: u64;
+      let _52: ();
+      let mut _53: u64;
+      let mut _54: u64;
+      let _55: ();
+      let mut _56: u64;
+      let mut _57: u64;
+      let _58: ();
+      let mut _59: u64;
+      let mut _60: u64;
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+-         StorageLive(_4);
+-         _4 = _1;
+-         _3 = Add(move _4, const 0_u64);
+-         StorageDead(_4);
++         _3 = Add(_1, const 0_u64);
+          _2 = opaque::<u64>(move _3) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_3);
+          StorageDead(_2);
+          StorageLive(_5);
+          StorageLive(_6);
+-         StorageLive(_7);
+-         _7 = _1;
+-         _6 = Sub(move _7, const 0_u64);
+-         StorageDead(_7);
++         _6 = Sub(_1, const 0_u64);
+          _5 = opaque::<u64>(move _6) -> [return: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+          StorageDead(_6);
+          StorageDead(_5);
+          StorageLive(_8);
+          StorageLive(_9);
+-         StorageLive(_10);
+-         _10 = _1;
+-         _9 = Mul(move _10, const 0_u64);
+-         StorageDead(_10);
++         _9 = Mul(_1, const 0_u64);
+          _8 = opaque::<u64>(move _9) -> [return: bb3, unwind unreachable];
+      }
+  
+      bb3: {
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageLive(_11);
+          StorageLive(_12);
+-         StorageLive(_13);
+-         _13 = _1;
+-         _12 = Mul(move _13, const 1_u64);
+-         StorageDead(_13);
++         _12 = Mul(_1, const 1_u64);
+          _11 = opaque::<u64>(move _12) -> [return: bb4, unwind unreachable];
+      }
+  
+      bb4: {
+          StorageDead(_12);
+          StorageDead(_11);
+          StorageLive(_14);
+          StorageLive(_15);
+-         StorageLive(_16);
+-         _16 = _1;
+          _17 = Eq(const 0_u64, const 0_u64);
+-         assert(!move _17, "attempt to divide `{}` by zero", _16) -> [success: bb5, unwind unreachable];
++         assert(!_17, "attempt to divide `{}` by zero", _1) -> [success: bb5, unwind unreachable];
+      }
+  
+      bb5: {
+-         _15 = Div(move _16, const 0_u64);
+-         StorageDead(_16);
++         _15 = Div(_1, const 0_u64);
+          _14 = opaque::<u64>(move _15) -> [return: bb6, unwind unreachable];
+      }
+  
+      bb6: {
+          StorageDead(_15);
+          StorageDead(_14);
+          StorageLive(_18);
+          StorageLive(_19);
+-         StorageLive(_20);
+-         _20 = _1;
+          _21 = Eq(const 1_u64, const 0_u64);
+-         assert(!move _21, "attempt to divide `{}` by zero", _20) -> [success: bb7, unwind unreachable];
++         assert(!_21, "attempt to divide `{}` by zero", _1) -> [success: bb7, unwind unreachable];
+      }
+  
+      bb7: {
+-         _19 = Div(move _20, const 1_u64);
+-         StorageDead(_20);
++         _19 = Div(_1, const 1_u64);
+          _18 = opaque::<u64>(move _19) -> [return: bb8, unwind unreachable];
+      }
+  
+      bb8: {
+          StorageDead(_19);
+          StorageDead(_18);
+          StorageLive(_22);
+          StorageLive(_23);
+-         StorageLive(_24);
+-         _24 = _1;
+-         _25 = Eq(_24, const 0_u64);
+-         assert(!move _25, "attempt to divide `{}` by zero", const 0_u64) -> [success: bb9, unwind unreachable];
++         _25 = Eq(_1, const 0_u64);
++         assert(!_25, "attempt to divide `{}` by zero", const 0_u64) -> [success: bb9, unwind unreachable];
+      }
+  
+      bb9: {
+-         _23 = Div(const 0_u64, move _24);
+-         StorageDead(_24);
++         _23 = Div(const 0_u64, _1);
+          _22 = opaque::<u64>(move _23) -> [return: bb10, unwind unreachable];
+      }
+  
+      bb10: {
+          StorageDead(_23);
+          StorageDead(_22);
+          StorageLive(_26);
+          StorageLive(_27);
+-         StorageLive(_28);
+-         _28 = _1;
+-         _29 = Eq(_28, const 0_u64);
+-         assert(!move _29, "attempt to divide `{}` by zero", const 1_u64) -> [success: bb11, unwind unreachable];
++         assert(!_25, "attempt to divide `{}` by zero", const 1_u64) -> [success: bb11, unwind unreachable];
+      }
+  
+      bb11: {
+-         _27 = Div(const 1_u64, move _28);
+-         StorageDead(_28);
++         _27 = Div(const 1_u64, _1);
+          _26 = opaque::<u64>(move _27) -> [return: bb12, unwind unreachable];
+      }
+  
+      bb12: {
+          StorageDead(_27);
+          StorageDead(_26);
+          StorageLive(_30);
+          StorageLive(_31);
+-         StorageLive(_32);
+-         _32 = _1;
+-         _33 = Eq(const 0_u64, const 0_u64);
+-         assert(!move _33, "attempt to calculate the remainder of `{}` with a divisor of zero", _32) -> [success: bb13, unwind unreachable];
++         assert(!_17, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb13, unwind unreachable];
+      }
+  
+      bb13: {
+-         _31 = Rem(move _32, const 0_u64);
+-         StorageDead(_32);
++         _31 = Rem(_1, const 0_u64);
+          _30 = opaque::<u64>(move _31) -> [return: bb14, unwind unreachable];
+      }
+  
+      bb14: {
+          StorageDead(_31);
+          StorageDead(_30);
+          StorageLive(_34);
+          StorageLive(_35);
+-         StorageLive(_36);
+-         _36 = _1;
+-         _37 = Eq(const 1_u64, const 0_u64);
+-         assert(!move _37, "attempt to calculate the remainder of `{}` with a divisor of zero", _36) -> [success: bb15, unwind unreachable];
++         assert(!_21, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb15, unwind unreachable];
+      }
+  
+      bb15: {
+-         _35 = Rem(move _36, const 1_u64);
+-         StorageDead(_36);
++         _35 = Rem(_1, const 1_u64);
+          _34 = opaque::<u64>(move _35) -> [return: bb16, unwind unreachable];
+      }
+  
+      bb16: {
+          StorageDead(_35);
+          StorageDead(_34);
+          StorageLive(_38);
+          StorageLive(_39);
+-         StorageLive(_40);
+-         _40 = _1;
+-         _41 = Eq(_40, const 0_u64);
+-         assert(!move _41, "attempt to calculate the remainder of `{}` with a divisor of zero", const 0_u64) -> [success: bb17, unwind unreachable];
++         assert(!_25, "attempt to calculate the remainder of `{}` with a divisor of zero", const 0_u64) -> [success: bb17, unwind unreachable];
+      }
+  
+      bb17: {
+-         _39 = Rem(const 0_u64, move _40);
+-         StorageDead(_40);
++         _39 = Rem(const 0_u64, _1);
+          _38 = opaque::<u64>(move _39) -> [return: bb18, unwind unreachable];
+      }
+  
+      bb18: {
+          StorageDead(_39);
+          StorageDead(_38);
+          StorageLive(_42);
+          StorageLive(_43);
+-         StorageLive(_44);
+-         _44 = _1;
+-         _45 = Eq(_44, const 0_u64);
+-         assert(!move _45, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_u64) -> [success: bb19, unwind unreachable];
++         assert(!_25, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_u64) -> [success: bb19, unwind unreachable];
+      }
+  
+      bb19: {
+-         _43 = Rem(const 1_u64, move _44);
+-         StorageDead(_44);
++         _43 = Rem(const 1_u64, _1);
+          _42 = opaque::<u64>(move _43) -> [return: bb20, unwind unreachable];
+      }
+  
+      bb20: {
+          StorageDead(_43);
+          StorageDead(_42);
+          StorageLive(_46);
+          StorageLive(_47);
+-         StorageLive(_48);
+-         _48 = _1;
+-         _47 = BitAnd(move _48, const 0_u64);
+-         StorageDead(_48);
++         _47 = BitAnd(_1, const 0_u64);
+          _46 = opaque::<u64>(move _47) -> [return: bb21, unwind unreachable];
+      }
+  
+      bb21: {
+          StorageDead(_47);
+          StorageDead(_46);
+          StorageLive(_49);
+          StorageLive(_50);
+-         StorageLive(_51);
+-         _51 = _1;
+-         _50 = BitOr(move _51, const 0_u64);
+-         StorageDead(_51);
++         _50 = BitOr(_1, const 0_u64);
+          _49 = opaque::<u64>(move _50) -> [return: bb22, unwind unreachable];
+      }
+  
+      bb22: {
+          StorageDead(_50);
+          StorageDead(_49);
+          StorageLive(_52);
+          StorageLive(_53);
+-         StorageLive(_54);
+-         _54 = _1;
+-         _53 = BitXor(move _54, const 0_u64);
+-         StorageDead(_54);
++         _53 = BitXor(_1, const 0_u64);
+          _52 = opaque::<u64>(move _53) -> [return: bb23, unwind unreachable];
+      }
+  
+      bb23: {
+          StorageDead(_53);
+          StorageDead(_52);
+          StorageLive(_55);
+          StorageLive(_56);
+-         StorageLive(_57);
+-         _57 = _1;
+-         _56 = Shr(move _57, const 0_i32);
+-         StorageDead(_57);
++         _56 = Shr(_1, const 0_i32);
+          _55 = opaque::<u64>(move _56) -> [return: bb24, unwind unreachable];
+      }
+  
+      bb24: {
+          StorageDead(_56);
+          StorageDead(_55);
+          StorageLive(_58);
+          StorageLive(_59);
+-         StorageLive(_60);
+-         _60 = _1;
+-         _59 = Shl(move _60, const 0_i32);
+-         StorageDead(_60);
++         _59 = Shl(_1, const 0_i32);
+          _58 = opaque::<u64>(move _59) -> [return: bb25, unwind unreachable];
+      }
+  
+      bb25: {
+          StorageDead(_59);
+          StorageDead(_58);
+          _0 = const ();
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.arithmetic.GVN.panic-unwind.diff b/tests/mir-opt/gvn.arithmetic.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..38da21d91d4
--- /dev/null
+++ b/tests/mir-opt/gvn.arithmetic.GVN.panic-unwind.diff
@@ -0,0 +1,342 @@
+- // MIR for `arithmetic` before GVN
++ // MIR for `arithmetic` after GVN
+  
+  fn arithmetic(_1: u64) -> () {
+      debug x => _1;
+      let mut _0: ();
+      let _2: ();
+      let mut _3: u64;
+      let mut _4: u64;
+      let _5: ();
+      let mut _6: u64;
+      let mut _7: u64;
+      let _8: ();
+      let mut _9: u64;
+      let mut _10: u64;
+      let _11: ();
+      let mut _12: u64;
+      let mut _13: u64;
+      let _14: ();
+      let mut _15: u64;
+      let mut _16: u64;
+      let mut _17: bool;
+      let _18: ();
+      let mut _19: u64;
+      let mut _20: u64;
+      let mut _21: bool;
+      let _22: ();
+      let mut _23: u64;
+      let mut _24: u64;
+      let mut _25: bool;
+      let _26: ();
+      let mut _27: u64;
+      let mut _28: u64;
+      let mut _29: bool;
+      let _30: ();
+      let mut _31: u64;
+      let mut _32: u64;
+      let mut _33: bool;
+      let _34: ();
+      let mut _35: u64;
+      let mut _36: u64;
+      let mut _37: bool;
+      let _38: ();
+      let mut _39: u64;
+      let mut _40: u64;
+      let mut _41: bool;
+      let _42: ();
+      let mut _43: u64;
+      let mut _44: u64;
+      let mut _45: bool;
+      let _46: ();
+      let mut _47: u64;
+      let mut _48: u64;
+      let _49: ();
+      let mut _50: u64;
+      let mut _51: u64;
+      let _52: ();
+      let mut _53: u64;
+      let mut _54: u64;
+      let _55: ();
+      let mut _56: u64;
+      let mut _57: u64;
+      let _58: ();
+      let mut _59: u64;
+      let mut _60: u64;
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+-         StorageLive(_4);
+-         _4 = _1;
+-         _3 = Add(move _4, const 0_u64);
+-         StorageDead(_4);
++         _3 = Add(_1, const 0_u64);
+          _2 = opaque::<u64>(move _3) -> [return: bb1, unwind continue];
+      }
+  
+      bb1: {
+          StorageDead(_3);
+          StorageDead(_2);
+          StorageLive(_5);
+          StorageLive(_6);
+-         StorageLive(_7);
+-         _7 = _1;
+-         _6 = Sub(move _7, const 0_u64);
+-         StorageDead(_7);
++         _6 = Sub(_1, const 0_u64);
+          _5 = opaque::<u64>(move _6) -> [return: bb2, unwind continue];
+      }
+  
+      bb2: {
+          StorageDead(_6);
+          StorageDead(_5);
+          StorageLive(_8);
+          StorageLive(_9);
+-         StorageLive(_10);
+-         _10 = _1;
+-         _9 = Mul(move _10, const 0_u64);
+-         StorageDead(_10);
++         _9 = Mul(_1, const 0_u64);
+          _8 = opaque::<u64>(move _9) -> [return: bb3, unwind continue];
+      }
+  
+      bb3: {
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageLive(_11);
+          StorageLive(_12);
+-         StorageLive(_13);
+-         _13 = _1;
+-         _12 = Mul(move _13, const 1_u64);
+-         StorageDead(_13);
++         _12 = Mul(_1, const 1_u64);
+          _11 = opaque::<u64>(move _12) -> [return: bb4, unwind continue];
+      }
+  
+      bb4: {
+          StorageDead(_12);
+          StorageDead(_11);
+          StorageLive(_14);
+          StorageLive(_15);
+-         StorageLive(_16);
+-         _16 = _1;
+          _17 = Eq(const 0_u64, const 0_u64);
+-         assert(!move _17, "attempt to divide `{}` by zero", _16) -> [success: bb5, unwind continue];
++         assert(!_17, "attempt to divide `{}` by zero", _1) -> [success: bb5, unwind continue];
+      }
+  
+      bb5: {
+-         _15 = Div(move _16, const 0_u64);
+-         StorageDead(_16);
++         _15 = Div(_1, const 0_u64);
+          _14 = opaque::<u64>(move _15) -> [return: bb6, unwind continue];
+      }
+  
+      bb6: {
+          StorageDead(_15);
+          StorageDead(_14);
+          StorageLive(_18);
+          StorageLive(_19);
+-         StorageLive(_20);
+-         _20 = _1;
+          _21 = Eq(const 1_u64, const 0_u64);
+-         assert(!move _21, "attempt to divide `{}` by zero", _20) -> [success: bb7, unwind continue];
++         assert(!_21, "attempt to divide `{}` by zero", _1) -> [success: bb7, unwind continue];
+      }
+  
+      bb7: {
+-         _19 = Div(move _20, const 1_u64);
+-         StorageDead(_20);
++         _19 = Div(_1, const 1_u64);
+          _18 = opaque::<u64>(move _19) -> [return: bb8, unwind continue];
+      }
+  
+      bb8: {
+          StorageDead(_19);
+          StorageDead(_18);
+          StorageLive(_22);
+          StorageLive(_23);
+-         StorageLive(_24);
+-         _24 = _1;
+-         _25 = Eq(_24, const 0_u64);
+-         assert(!move _25, "attempt to divide `{}` by zero", const 0_u64) -> [success: bb9, unwind continue];
++         _25 = Eq(_1, const 0_u64);
++         assert(!_25, "attempt to divide `{}` by zero", const 0_u64) -> [success: bb9, unwind continue];
+      }
+  
+      bb9: {
+-         _23 = Div(const 0_u64, move _24);
+-         StorageDead(_24);
++         _23 = Div(const 0_u64, _1);
+          _22 = opaque::<u64>(move _23) -> [return: bb10, unwind continue];
+      }
+  
+      bb10: {
+          StorageDead(_23);
+          StorageDead(_22);
+          StorageLive(_26);
+          StorageLive(_27);
+-         StorageLive(_28);
+-         _28 = _1;
+-         _29 = Eq(_28, const 0_u64);
+-         assert(!move _29, "attempt to divide `{}` by zero", const 1_u64) -> [success: bb11, unwind continue];
++         assert(!_25, "attempt to divide `{}` by zero", const 1_u64) -> [success: bb11, unwind continue];
+      }
+  
+      bb11: {
+-         _27 = Div(const 1_u64, move _28);
+-         StorageDead(_28);
++         _27 = Div(const 1_u64, _1);
+          _26 = opaque::<u64>(move _27) -> [return: bb12, unwind continue];
+      }
+  
+      bb12: {
+          StorageDead(_27);
+          StorageDead(_26);
+          StorageLive(_30);
+          StorageLive(_31);
+-         StorageLive(_32);
+-         _32 = _1;
+-         _33 = Eq(const 0_u64, const 0_u64);
+-         assert(!move _33, "attempt to calculate the remainder of `{}` with a divisor of zero", _32) -> [success: bb13, unwind continue];
++         assert(!_17, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb13, unwind continue];
+      }
+  
+      bb13: {
+-         _31 = Rem(move _32, const 0_u64);
+-         StorageDead(_32);
++         _31 = Rem(_1, const 0_u64);
+          _30 = opaque::<u64>(move _31) -> [return: bb14, unwind continue];
+      }
+  
+      bb14: {
+          StorageDead(_31);
+          StorageDead(_30);
+          StorageLive(_34);
+          StorageLive(_35);
+-         StorageLive(_36);
+-         _36 = _1;
+-         _37 = Eq(const 1_u64, const 0_u64);
+-         assert(!move _37, "attempt to calculate the remainder of `{}` with a divisor of zero", _36) -> [success: bb15, unwind continue];
++         assert(!_21, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb15, unwind continue];
+      }
+  
+      bb15: {
+-         _35 = Rem(move _36, const 1_u64);
+-         StorageDead(_36);
++         _35 = Rem(_1, const 1_u64);
+          _34 = opaque::<u64>(move _35) -> [return: bb16, unwind continue];
+      }
+  
+      bb16: {
+          StorageDead(_35);
+          StorageDead(_34);
+          StorageLive(_38);
+          StorageLive(_39);
+-         StorageLive(_40);
+-         _40 = _1;
+-         _41 = Eq(_40, const 0_u64);
+-         assert(!move _41, "attempt to calculate the remainder of `{}` with a divisor of zero", const 0_u64) -> [success: bb17, unwind continue];
++         assert(!_25, "attempt to calculate the remainder of `{}` with a divisor of zero", const 0_u64) -> [success: bb17, unwind continue];
+      }
+  
+      bb17: {
+-         _39 = Rem(const 0_u64, move _40);
+-         StorageDead(_40);
++         _39 = Rem(const 0_u64, _1);
+          _38 = opaque::<u64>(move _39) -> [return: bb18, unwind continue];
+      }
+  
+      bb18: {
+          StorageDead(_39);
+          StorageDead(_38);
+          StorageLive(_42);
+          StorageLive(_43);
+-         StorageLive(_44);
+-         _44 = _1;
+-         _45 = Eq(_44, const 0_u64);
+-         assert(!move _45, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_u64) -> [success: bb19, unwind continue];
++         assert(!_25, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_u64) -> [success: bb19, unwind continue];
+      }
+  
+      bb19: {
+-         _43 = Rem(const 1_u64, move _44);
+-         StorageDead(_44);
++         _43 = Rem(const 1_u64, _1);
+          _42 = opaque::<u64>(move _43) -> [return: bb20, unwind continue];
+      }
+  
+      bb20: {
+          StorageDead(_43);
+          StorageDead(_42);
+          StorageLive(_46);
+          StorageLive(_47);
+-         StorageLive(_48);
+-         _48 = _1;
+-         _47 = BitAnd(move _48, const 0_u64);
+-         StorageDead(_48);
++         _47 = BitAnd(_1, const 0_u64);
+          _46 = opaque::<u64>(move _47) -> [return: bb21, unwind continue];
+      }
+  
+      bb21: {
+          StorageDead(_47);
+          StorageDead(_46);
+          StorageLive(_49);
+          StorageLive(_50);
+-         StorageLive(_51);
+-         _51 = _1;
+-         _50 = BitOr(move _51, const 0_u64);
+-         StorageDead(_51);
++         _50 = BitOr(_1, const 0_u64);
+          _49 = opaque::<u64>(move _50) -> [return: bb22, unwind continue];
+      }
+  
+      bb22: {
+          StorageDead(_50);
+          StorageDead(_49);
+          StorageLive(_52);
+          StorageLive(_53);
+-         StorageLive(_54);
+-         _54 = _1;
+-         _53 = BitXor(move _54, const 0_u64);
+-         StorageDead(_54);
++         _53 = BitXor(_1, const 0_u64);
+          _52 = opaque::<u64>(move _53) -> [return: bb23, unwind continue];
+      }
+  
+      bb23: {
+          StorageDead(_53);
+          StorageDead(_52);
+          StorageLive(_55);
+          StorageLive(_56);
+-         StorageLive(_57);
+-         _57 = _1;
+-         _56 = Shr(move _57, const 0_i32);
+-         StorageDead(_57);
++         _56 = Shr(_1, const 0_i32);
+          _55 = opaque::<u64>(move _56) -> [return: bb24, unwind continue];
+      }
+  
+      bb24: {
+          StorageDead(_56);
+          StorageDead(_55);
+          StorageLive(_58);
+          StorageLive(_59);
+-         StorageLive(_60);
+-         _60 = _1;
+-         _59 = Shl(move _60, const 0_i32);
+-         StorageDead(_60);
++         _59 = Shl(_1, const 0_i32);
+          _58 = opaque::<u64>(move _59) -> [return: bb25, unwind continue];
+      }
+  
+      bb25: {
+          StorageDead(_59);
+          StorageDead(_58);
+          _0 = const ();
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.arithmetic_checked.GVN.panic-abort.diff b/tests/mir-opt/gvn.arithmetic_checked.GVN.panic-abort.diff
new file mode 100644
index 00000000000..0c342799e07
--- /dev/null
+++ b/tests/mir-opt/gvn.arithmetic_checked.GVN.panic-abort.diff
@@ -0,0 +1,389 @@
+- // MIR for `arithmetic_checked` before GVN
++ // MIR for `arithmetic_checked` after GVN
+  
+  fn arithmetic_checked(_1: u64) -> () {
+      debug x => _1;
+      let mut _0: ();
+      let _2: ();
+      let mut _3: u64;
+      let mut _4: u64;
+      let mut _5: (u64, bool);
+      let _6: ();
+      let mut _7: u64;
+      let mut _8: u64;
+      let mut _9: (u64, bool);
+      let _10: ();
+      let mut _11: u64;
+      let mut _12: u64;
+      let mut _13: (u64, bool);
+      let _14: ();
+      let mut _15: u64;
+      let mut _16: u64;
+      let mut _17: (u64, bool);
+      let _18: ();
+      let mut _19: u64;
+      let mut _20: u64;
+      let mut _21: bool;
+      let _22: ();
+      let mut _23: u64;
+      let mut _24: u64;
+      let mut _25: bool;
+      let _26: ();
+      let mut _27: u64;
+      let mut _28: u64;
+      let mut _29: bool;
+      let _30: ();
+      let mut _31: u64;
+      let mut _32: u64;
+      let mut _33: bool;
+      let _34: ();
+      let mut _35: u64;
+      let mut _36: u64;
+      let mut _37: bool;
+      let _38: ();
+      let mut _39: u64;
+      let mut _40: u64;
+      let mut _41: bool;
+      let _42: ();
+      let mut _43: u64;
+      let mut _44: u64;
+      let mut _45: bool;
+      let _46: ();
+      let mut _47: u64;
+      let mut _48: u64;
+      let mut _49: bool;
+      let _50: ();
+      let mut _51: u64;
+      let mut _52: u64;
+      let _53: ();
+      let mut _54: u64;
+      let mut _55: u64;
+      let _56: ();
+      let mut _57: u64;
+      let mut _58: u64;
+      let _59: ();
+      let mut _60: u64;
+      let mut _61: u64;
+      let mut _62: u32;
+      let mut _63: bool;
+      let _64: ();
+      let mut _65: u64;
+      let mut _66: u64;
+      let mut _67: u32;
+      let mut _68: bool;
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+-         StorageLive(_4);
+-         _4 = _1;
+-         _5 = CheckedAdd(_4, const 0_u64);
+-         assert(!move (_5.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, const 0_u64) -> [success: bb1, unwind unreachable];
++         _5 = CheckedAdd(_1, const 0_u64);
++         assert(!move (_5.1: bool), "attempt to compute `{} + {}`, which would overflow", _1, const 0_u64) -> [success: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          _3 = move (_5.0: u64);
+-         StorageDead(_4);
+          _2 = opaque::<u64>(move _3) -> [return: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+          StorageDead(_3);
+          StorageDead(_2);
+          StorageLive(_6);
+          StorageLive(_7);
+-         StorageLive(_8);
+-         _8 = _1;
+-         _9 = CheckedSub(_8, const 0_u64);
+-         assert(!move (_9.1: bool), "attempt to compute `{} - {}`, which would overflow", move _8, const 0_u64) -> [success: bb3, unwind unreachable];
++         _9 = CheckedSub(_1, const 0_u64);
++         assert(!move (_9.1: bool), "attempt to compute `{} - {}`, which would overflow", _1, const 0_u64) -> [success: bb3, unwind unreachable];
+      }
+  
+      bb3: {
+          _7 = move (_9.0: u64);
+-         StorageDead(_8);
+          _6 = opaque::<u64>(move _7) -> [return: bb4, unwind unreachable];
+      }
+  
+      bb4: {
+          StorageDead(_7);
+          StorageDead(_6);
+          StorageLive(_10);
+          StorageLive(_11);
+-         StorageLive(_12);
+-         _12 = _1;
+-         _13 = CheckedMul(_12, const 0_u64);
+-         assert(!move (_13.1: bool), "attempt to compute `{} * {}`, which would overflow", move _12, const 0_u64) -> [success: bb5, unwind unreachable];
++         _13 = CheckedMul(_1, const 0_u64);
++         assert(!move (_13.1: bool), "attempt to compute `{} * {}`, which would overflow", _1, const 0_u64) -> [success: bb5, unwind unreachable];
+      }
+  
+      bb5: {
+          _11 = move (_13.0: u64);
+-         StorageDead(_12);
+          _10 = opaque::<u64>(move _11) -> [return: bb6, unwind unreachable];
+      }
+  
+      bb6: {
+          StorageDead(_11);
+          StorageDead(_10);
+          StorageLive(_14);
+          StorageLive(_15);
+-         StorageLive(_16);
+-         _16 = _1;
+-         _17 = CheckedMul(_16, const 1_u64);
+-         assert(!move (_17.1: bool), "attempt to compute `{} * {}`, which would overflow", move _16, const 1_u64) -> [success: bb7, unwind unreachable];
++         _17 = CheckedMul(_1, const 1_u64);
++         assert(!move (_17.1: bool), "attempt to compute `{} * {}`, which would overflow", _1, const 1_u64) -> [success: bb7, unwind unreachable];
+      }
+  
+      bb7: {
+          _15 = move (_17.0: u64);
+-         StorageDead(_16);
+          _14 = opaque::<u64>(move _15) -> [return: bb8, unwind unreachable];
+      }
+  
+      bb8: {
+          StorageDead(_15);
+          StorageDead(_14);
+          StorageLive(_18);
+          StorageLive(_19);
+-         StorageLive(_20);
+-         _20 = _1;
+          _21 = Eq(const 0_u64, const 0_u64);
+-         assert(!move _21, "attempt to divide `{}` by zero", _20) -> [success: bb9, unwind unreachable];
++         assert(!_21, "attempt to divide `{}` by zero", _1) -> [success: bb9, unwind unreachable];
+      }
+  
+      bb9: {
+-         _19 = Div(move _20, const 0_u64);
+-         StorageDead(_20);
++         _19 = Div(_1, const 0_u64);
+          _18 = opaque::<u64>(move _19) -> [return: bb10, unwind unreachable];
+      }
+  
+      bb10: {
+          StorageDead(_19);
+          StorageDead(_18);
+          StorageLive(_22);
+          StorageLive(_23);
+-         StorageLive(_24);
+-         _24 = _1;
+          _25 = Eq(const 1_u64, const 0_u64);
+-         assert(!move _25, "attempt to divide `{}` by zero", _24) -> [success: bb11, unwind unreachable];
++         assert(!_25, "attempt to divide `{}` by zero", _1) -> [success: bb11, unwind unreachable];
+      }
+  
+      bb11: {
+-         _23 = Div(move _24, const 1_u64);
+-         StorageDead(_24);
++         _23 = Div(_1, const 1_u64);
+          _22 = opaque::<u64>(move _23) -> [return: bb12, unwind unreachable];
+      }
+  
+      bb12: {
+          StorageDead(_23);
+          StorageDead(_22);
+          StorageLive(_26);
+          StorageLive(_27);
+-         StorageLive(_28);
+-         _28 = _1;
+-         _29 = Eq(_28, const 0_u64);
+-         assert(!move _29, "attempt to divide `{}` by zero", const 0_u64) -> [success: bb13, unwind unreachable];
++         _29 = Eq(_1, const 0_u64);
++         assert(!_29, "attempt to divide `{}` by zero", const 0_u64) -> [success: bb13, unwind unreachable];
+      }
+  
+      bb13: {
+-         _27 = Div(const 0_u64, move _28);
+-         StorageDead(_28);
++         _27 = Div(const 0_u64, _1);
+          _26 = opaque::<u64>(move _27) -> [return: bb14, unwind unreachable];
+      }
+  
+      bb14: {
+          StorageDead(_27);
+          StorageDead(_26);
+          StorageLive(_30);
+          StorageLive(_31);
+-         StorageLive(_32);
+-         _32 = _1;
+-         _33 = Eq(_32, const 0_u64);
+-         assert(!move _33, "attempt to divide `{}` by zero", const 1_u64) -> [success: bb15, unwind unreachable];
++         assert(!_29, "attempt to divide `{}` by zero", const 1_u64) -> [success: bb15, unwind unreachable];
+      }
+  
+      bb15: {
+-         _31 = Div(const 1_u64, move _32);
+-         StorageDead(_32);
++         _31 = Div(const 1_u64, _1);
+          _30 = opaque::<u64>(move _31) -> [return: bb16, unwind unreachable];
+      }
+  
+      bb16: {
+          StorageDead(_31);
+          StorageDead(_30);
+          StorageLive(_34);
+          StorageLive(_35);
+-         StorageLive(_36);
+-         _36 = _1;
+-         _37 = Eq(const 0_u64, const 0_u64);
+-         assert(!move _37, "attempt to calculate the remainder of `{}` with a divisor of zero", _36) -> [success: bb17, unwind unreachable];
++         assert(!_21, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb17, unwind unreachable];
+      }
+  
+      bb17: {
+-         _35 = Rem(move _36, const 0_u64);
+-         StorageDead(_36);
++         _35 = Rem(_1, const 0_u64);
+          _34 = opaque::<u64>(move _35) -> [return: bb18, unwind unreachable];
+      }
+  
+      bb18: {
+          StorageDead(_35);
+          StorageDead(_34);
+          StorageLive(_38);
+          StorageLive(_39);
+-         StorageLive(_40);
+-         _40 = _1;
+-         _41 = Eq(const 1_u64, const 0_u64);
+-         assert(!move _41, "attempt to calculate the remainder of `{}` with a divisor of zero", _40) -> [success: bb19, unwind unreachable];
++         assert(!_25, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb19, unwind unreachable];
+      }
+  
+      bb19: {
+-         _39 = Rem(move _40, const 1_u64);
+-         StorageDead(_40);
++         _39 = Rem(_1, const 1_u64);
+          _38 = opaque::<u64>(move _39) -> [return: bb20, unwind unreachable];
+      }
+  
+      bb20: {
+          StorageDead(_39);
+          StorageDead(_38);
+          StorageLive(_42);
+          StorageLive(_43);
+-         StorageLive(_44);
+-         _44 = _1;
+-         _45 = Eq(_44, const 0_u64);
+-         assert(!move _45, "attempt to calculate the remainder of `{}` with a divisor of zero", const 0_u64) -> [success: bb21, unwind unreachable];
++         assert(!_29, "attempt to calculate the remainder of `{}` with a divisor of zero", const 0_u64) -> [success: bb21, unwind unreachable];
+      }
+  
+      bb21: {
+-         _43 = Rem(const 0_u64, move _44);
+-         StorageDead(_44);
++         _43 = Rem(const 0_u64, _1);
+          _42 = opaque::<u64>(move _43) -> [return: bb22, unwind unreachable];
+      }
+  
+      bb22: {
+          StorageDead(_43);
+          StorageDead(_42);
+          StorageLive(_46);
+          StorageLive(_47);
+-         StorageLive(_48);
+-         _48 = _1;
+-         _49 = Eq(_48, const 0_u64);
+-         assert(!move _49, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_u64) -> [success: bb23, unwind unreachable];
++         assert(!_29, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_u64) -> [success: bb23, unwind unreachable];
+      }
+  
+      bb23: {
+-         _47 = Rem(const 1_u64, move _48);
+-         StorageDead(_48);
++         _47 = Rem(const 1_u64, _1);
+          _46 = opaque::<u64>(move _47) -> [return: bb24, unwind unreachable];
+      }
+  
+      bb24: {
+          StorageDead(_47);
+          StorageDead(_46);
+          StorageLive(_50);
+          StorageLive(_51);
+-         StorageLive(_52);
+-         _52 = _1;
+-         _51 = BitAnd(move _52, const 0_u64);
+-         StorageDead(_52);
++         _51 = BitAnd(_1, const 0_u64);
+          _50 = opaque::<u64>(move _51) -> [return: bb25, unwind unreachable];
+      }
+  
+      bb25: {
+          StorageDead(_51);
+          StorageDead(_50);
+          StorageLive(_53);
+          StorageLive(_54);
+-         StorageLive(_55);
+-         _55 = _1;
+-         _54 = BitOr(move _55, const 0_u64);
+-         StorageDead(_55);
++         _54 = BitOr(_1, const 0_u64);
+          _53 = opaque::<u64>(move _54) -> [return: bb26, unwind unreachable];
+      }
+  
+      bb26: {
+          StorageDead(_54);
+          StorageDead(_53);
+          StorageLive(_56);
+          StorageLive(_57);
+-         StorageLive(_58);
+-         _58 = _1;
+-         _57 = BitXor(move _58, const 0_u64);
+-         StorageDead(_58);
++         _57 = BitXor(_1, const 0_u64);
+          _56 = opaque::<u64>(move _57) -> [return: bb27, unwind unreachable];
+      }
+  
+      bb27: {
+          StorageDead(_57);
+          StorageDead(_56);
+          StorageLive(_59);
+          StorageLive(_60);
+-         StorageLive(_61);
+-         _61 = _1;
+          _62 = const 0_i32 as u32 (IntToInt);
+-         _63 = Lt(move _62, const 64_u32);
+-         assert(move _63, "attempt to shift right by `{}`, which would overflow", const 0_i32) -> [success: bb28, unwind unreachable];
++         _63 = Lt(_62, const 64_u32);
++         assert(_63, "attempt to shift right by `{}`, which would overflow", const 0_i32) -> [success: bb28, unwind unreachable];
+      }
+  
+      bb28: {
+-         _60 = Shr(move _61, const 0_i32);
+-         StorageDead(_61);
++         _60 = Shr(_1, const 0_i32);
+          _59 = opaque::<u64>(move _60) -> [return: bb29, unwind unreachable];
+      }
+  
+      bb29: {
+          StorageDead(_60);
+          StorageDead(_59);
+          StorageLive(_64);
+          StorageLive(_65);
+-         StorageLive(_66);
+-         _66 = _1;
+-         _67 = const 0_i32 as u32 (IntToInt);
+-         _68 = Lt(move _67, const 64_u32);
+-         assert(move _68, "attempt to shift left by `{}`, which would overflow", const 0_i32) -> [success: bb30, unwind unreachable];
++         assert(_63, "attempt to shift left by `{}`, which would overflow", const 0_i32) -> [success: bb30, unwind unreachable];
+      }
+  
+      bb30: {
+-         _65 = Shl(move _66, const 0_i32);
+-         StorageDead(_66);
++         _65 = Shl(_1, const 0_i32);
+          _64 = opaque::<u64>(move _65) -> [return: bb31, unwind unreachable];
+      }
+  
+      bb31: {
+          StorageDead(_65);
+          StorageDead(_64);
+          _0 = const ();
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.arithmetic_checked.GVN.panic-unwind.diff b/tests/mir-opt/gvn.arithmetic_checked.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..7813c29b962
--- /dev/null
+++ b/tests/mir-opt/gvn.arithmetic_checked.GVN.panic-unwind.diff
@@ -0,0 +1,389 @@
+- // MIR for `arithmetic_checked` before GVN
++ // MIR for `arithmetic_checked` after GVN
+  
+  fn arithmetic_checked(_1: u64) -> () {
+      debug x => _1;
+      let mut _0: ();
+      let _2: ();
+      let mut _3: u64;
+      let mut _4: u64;
+      let mut _5: (u64, bool);
+      let _6: ();
+      let mut _7: u64;
+      let mut _8: u64;
+      let mut _9: (u64, bool);
+      let _10: ();
+      let mut _11: u64;
+      let mut _12: u64;
+      let mut _13: (u64, bool);
+      let _14: ();
+      let mut _15: u64;
+      let mut _16: u64;
+      let mut _17: (u64, bool);
+      let _18: ();
+      let mut _19: u64;
+      let mut _20: u64;
+      let mut _21: bool;
+      let _22: ();
+      let mut _23: u64;
+      let mut _24: u64;
+      let mut _25: bool;
+      let _26: ();
+      let mut _27: u64;
+      let mut _28: u64;
+      let mut _29: bool;
+      let _30: ();
+      let mut _31: u64;
+      let mut _32: u64;
+      let mut _33: bool;
+      let _34: ();
+      let mut _35: u64;
+      let mut _36: u64;
+      let mut _37: bool;
+      let _38: ();
+      let mut _39: u64;
+      let mut _40: u64;
+      let mut _41: bool;
+      let _42: ();
+      let mut _43: u64;
+      let mut _44: u64;
+      let mut _45: bool;
+      let _46: ();
+      let mut _47: u64;
+      let mut _48: u64;
+      let mut _49: bool;
+      let _50: ();
+      let mut _51: u64;
+      let mut _52: u64;
+      let _53: ();
+      let mut _54: u64;
+      let mut _55: u64;
+      let _56: ();
+      let mut _57: u64;
+      let mut _58: u64;
+      let _59: ();
+      let mut _60: u64;
+      let mut _61: u64;
+      let mut _62: u32;
+      let mut _63: bool;
+      let _64: ();
+      let mut _65: u64;
+      let mut _66: u64;
+      let mut _67: u32;
+      let mut _68: bool;
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+-         StorageLive(_4);
+-         _4 = _1;
+-         _5 = CheckedAdd(_4, const 0_u64);
+-         assert(!move (_5.1: bool), "attempt to compute `{} + {}`, which would overflow", move _4, const 0_u64) -> [success: bb1, unwind continue];
++         _5 = CheckedAdd(_1, const 0_u64);
++         assert(!move (_5.1: bool), "attempt to compute `{} + {}`, which would overflow", _1, const 0_u64) -> [success: bb1, unwind continue];
+      }
+  
+      bb1: {
+          _3 = move (_5.0: u64);
+-         StorageDead(_4);
+          _2 = opaque::<u64>(move _3) -> [return: bb2, unwind continue];
+      }
+  
+      bb2: {
+          StorageDead(_3);
+          StorageDead(_2);
+          StorageLive(_6);
+          StorageLive(_7);
+-         StorageLive(_8);
+-         _8 = _1;
+-         _9 = CheckedSub(_8, const 0_u64);
+-         assert(!move (_9.1: bool), "attempt to compute `{} - {}`, which would overflow", move _8, const 0_u64) -> [success: bb3, unwind continue];
++         _9 = CheckedSub(_1, const 0_u64);
++         assert(!move (_9.1: bool), "attempt to compute `{} - {}`, which would overflow", _1, const 0_u64) -> [success: bb3, unwind continue];
+      }
+  
+      bb3: {
+          _7 = move (_9.0: u64);
+-         StorageDead(_8);
+          _6 = opaque::<u64>(move _7) -> [return: bb4, unwind continue];
+      }
+  
+      bb4: {
+          StorageDead(_7);
+          StorageDead(_6);
+          StorageLive(_10);
+          StorageLive(_11);
+-         StorageLive(_12);
+-         _12 = _1;
+-         _13 = CheckedMul(_12, const 0_u64);
+-         assert(!move (_13.1: bool), "attempt to compute `{} * {}`, which would overflow", move _12, const 0_u64) -> [success: bb5, unwind continue];
++         _13 = CheckedMul(_1, const 0_u64);
++         assert(!move (_13.1: bool), "attempt to compute `{} * {}`, which would overflow", _1, const 0_u64) -> [success: bb5, unwind continue];
+      }
+  
+      bb5: {
+          _11 = move (_13.0: u64);
+-         StorageDead(_12);
+          _10 = opaque::<u64>(move _11) -> [return: bb6, unwind continue];
+      }
+  
+      bb6: {
+          StorageDead(_11);
+          StorageDead(_10);
+          StorageLive(_14);
+          StorageLive(_15);
+-         StorageLive(_16);
+-         _16 = _1;
+-         _17 = CheckedMul(_16, const 1_u64);
+-         assert(!move (_17.1: bool), "attempt to compute `{} * {}`, which would overflow", move _16, const 1_u64) -> [success: bb7, unwind continue];
++         _17 = CheckedMul(_1, const 1_u64);
++         assert(!move (_17.1: bool), "attempt to compute `{} * {}`, which would overflow", _1, const 1_u64) -> [success: bb7, unwind continue];
+      }
+  
+      bb7: {
+          _15 = move (_17.0: u64);
+-         StorageDead(_16);
+          _14 = opaque::<u64>(move _15) -> [return: bb8, unwind continue];
+      }
+  
+      bb8: {
+          StorageDead(_15);
+          StorageDead(_14);
+          StorageLive(_18);
+          StorageLive(_19);
+-         StorageLive(_20);
+-         _20 = _1;
+          _21 = Eq(const 0_u64, const 0_u64);
+-         assert(!move _21, "attempt to divide `{}` by zero", _20) -> [success: bb9, unwind continue];
++         assert(!_21, "attempt to divide `{}` by zero", _1) -> [success: bb9, unwind continue];
+      }
+  
+      bb9: {
+-         _19 = Div(move _20, const 0_u64);
+-         StorageDead(_20);
++         _19 = Div(_1, const 0_u64);
+          _18 = opaque::<u64>(move _19) -> [return: bb10, unwind continue];
+      }
+  
+      bb10: {
+          StorageDead(_19);
+          StorageDead(_18);
+          StorageLive(_22);
+          StorageLive(_23);
+-         StorageLive(_24);
+-         _24 = _1;
+          _25 = Eq(const 1_u64, const 0_u64);
+-         assert(!move _25, "attempt to divide `{}` by zero", _24) -> [success: bb11, unwind continue];
++         assert(!_25, "attempt to divide `{}` by zero", _1) -> [success: bb11, unwind continue];
+      }
+  
+      bb11: {
+-         _23 = Div(move _24, const 1_u64);
+-         StorageDead(_24);
++         _23 = Div(_1, const 1_u64);
+          _22 = opaque::<u64>(move _23) -> [return: bb12, unwind continue];
+      }
+  
+      bb12: {
+          StorageDead(_23);
+          StorageDead(_22);
+          StorageLive(_26);
+          StorageLive(_27);
+-         StorageLive(_28);
+-         _28 = _1;
+-         _29 = Eq(_28, const 0_u64);
+-         assert(!move _29, "attempt to divide `{}` by zero", const 0_u64) -> [success: bb13, unwind continue];
++         _29 = Eq(_1, const 0_u64);
++         assert(!_29, "attempt to divide `{}` by zero", const 0_u64) -> [success: bb13, unwind continue];
+      }
+  
+      bb13: {
+-         _27 = Div(const 0_u64, move _28);
+-         StorageDead(_28);
++         _27 = Div(const 0_u64, _1);
+          _26 = opaque::<u64>(move _27) -> [return: bb14, unwind continue];
+      }
+  
+      bb14: {
+          StorageDead(_27);
+          StorageDead(_26);
+          StorageLive(_30);
+          StorageLive(_31);
+-         StorageLive(_32);
+-         _32 = _1;
+-         _33 = Eq(_32, const 0_u64);
+-         assert(!move _33, "attempt to divide `{}` by zero", const 1_u64) -> [success: bb15, unwind continue];
++         assert(!_29, "attempt to divide `{}` by zero", const 1_u64) -> [success: bb15, unwind continue];
+      }
+  
+      bb15: {
+-         _31 = Div(const 1_u64, move _32);
+-         StorageDead(_32);
++         _31 = Div(const 1_u64, _1);
+          _30 = opaque::<u64>(move _31) -> [return: bb16, unwind continue];
+      }
+  
+      bb16: {
+          StorageDead(_31);
+          StorageDead(_30);
+          StorageLive(_34);
+          StorageLive(_35);
+-         StorageLive(_36);
+-         _36 = _1;
+-         _37 = Eq(const 0_u64, const 0_u64);
+-         assert(!move _37, "attempt to calculate the remainder of `{}` with a divisor of zero", _36) -> [success: bb17, unwind continue];
++         assert(!_21, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb17, unwind continue];
+      }
+  
+      bb17: {
+-         _35 = Rem(move _36, const 0_u64);
+-         StorageDead(_36);
++         _35 = Rem(_1, const 0_u64);
+          _34 = opaque::<u64>(move _35) -> [return: bb18, unwind continue];
+      }
+  
+      bb18: {
+          StorageDead(_35);
+          StorageDead(_34);
+          StorageLive(_38);
+          StorageLive(_39);
+-         StorageLive(_40);
+-         _40 = _1;
+-         _41 = Eq(const 1_u64, const 0_u64);
+-         assert(!move _41, "attempt to calculate the remainder of `{}` with a divisor of zero", _40) -> [success: bb19, unwind continue];
++         assert(!_25, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb19, unwind continue];
+      }
+  
+      bb19: {
+-         _39 = Rem(move _40, const 1_u64);
+-         StorageDead(_40);
++         _39 = Rem(_1, const 1_u64);
+          _38 = opaque::<u64>(move _39) -> [return: bb20, unwind continue];
+      }
+  
+      bb20: {
+          StorageDead(_39);
+          StorageDead(_38);
+          StorageLive(_42);
+          StorageLive(_43);
+-         StorageLive(_44);
+-         _44 = _1;
+-         _45 = Eq(_44, const 0_u64);
+-         assert(!move _45, "attempt to calculate the remainder of `{}` with a divisor of zero", const 0_u64) -> [success: bb21, unwind continue];
++         assert(!_29, "attempt to calculate the remainder of `{}` with a divisor of zero", const 0_u64) -> [success: bb21, unwind continue];
+      }
+  
+      bb21: {
+-         _43 = Rem(const 0_u64, move _44);
+-         StorageDead(_44);
++         _43 = Rem(const 0_u64, _1);
+          _42 = opaque::<u64>(move _43) -> [return: bb22, unwind continue];
+      }
+  
+      bb22: {
+          StorageDead(_43);
+          StorageDead(_42);
+          StorageLive(_46);
+          StorageLive(_47);
+-         StorageLive(_48);
+-         _48 = _1;
+-         _49 = Eq(_48, const 0_u64);
+-         assert(!move _49, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_u64) -> [success: bb23, unwind continue];
++         assert(!_29, "attempt to calculate the remainder of `{}` with a divisor of zero", const 1_u64) -> [success: bb23, unwind continue];
+      }
+  
+      bb23: {
+-         _47 = Rem(const 1_u64, move _48);
+-         StorageDead(_48);
++         _47 = Rem(const 1_u64, _1);
+          _46 = opaque::<u64>(move _47) -> [return: bb24, unwind continue];
+      }
+  
+      bb24: {
+          StorageDead(_47);
+          StorageDead(_46);
+          StorageLive(_50);
+          StorageLive(_51);
+-         StorageLive(_52);
+-         _52 = _1;
+-         _51 = BitAnd(move _52, const 0_u64);
+-         StorageDead(_52);
++         _51 = BitAnd(_1, const 0_u64);
+          _50 = opaque::<u64>(move _51) -> [return: bb25, unwind continue];
+      }
+  
+      bb25: {
+          StorageDead(_51);
+          StorageDead(_50);
+          StorageLive(_53);
+          StorageLive(_54);
+-         StorageLive(_55);
+-         _55 = _1;
+-         _54 = BitOr(move _55, const 0_u64);
+-         StorageDead(_55);
++         _54 = BitOr(_1, const 0_u64);
+          _53 = opaque::<u64>(move _54) -> [return: bb26, unwind continue];
+      }
+  
+      bb26: {
+          StorageDead(_54);
+          StorageDead(_53);
+          StorageLive(_56);
+          StorageLive(_57);
+-         StorageLive(_58);
+-         _58 = _1;
+-         _57 = BitXor(move _58, const 0_u64);
+-         StorageDead(_58);
++         _57 = BitXor(_1, const 0_u64);
+          _56 = opaque::<u64>(move _57) -> [return: bb27, unwind continue];
+      }
+  
+      bb27: {
+          StorageDead(_57);
+          StorageDead(_56);
+          StorageLive(_59);
+          StorageLive(_60);
+-         StorageLive(_61);
+-         _61 = _1;
+          _62 = const 0_i32 as u32 (IntToInt);
+-         _63 = Lt(move _62, const 64_u32);
+-         assert(move _63, "attempt to shift right by `{}`, which would overflow", const 0_i32) -> [success: bb28, unwind continue];
++         _63 = Lt(_62, const 64_u32);
++         assert(_63, "attempt to shift right by `{}`, which would overflow", const 0_i32) -> [success: bb28, unwind continue];
+      }
+  
+      bb28: {
+-         _60 = Shr(move _61, const 0_i32);
+-         StorageDead(_61);
++         _60 = Shr(_1, const 0_i32);
+          _59 = opaque::<u64>(move _60) -> [return: bb29, unwind continue];
+      }
+  
+      bb29: {
+          StorageDead(_60);
+          StorageDead(_59);
+          StorageLive(_64);
+          StorageLive(_65);
+-         StorageLive(_66);
+-         _66 = _1;
+-         _67 = const 0_i32 as u32 (IntToInt);
+-         _68 = Lt(move _67, const 64_u32);
+-         assert(move _68, "attempt to shift left by `{}`, which would overflow", const 0_i32) -> [success: bb30, unwind continue];
++         assert(_63, "attempt to shift left by `{}`, which would overflow", const 0_i32) -> [success: bb30, unwind continue];
+      }
+  
+      bb30: {
+-         _65 = Shl(move _66, const 0_i32);
+-         StorageDead(_66);
++         _65 = Shl(_1, const 0_i32);
+          _64 = opaque::<u64>(move _65) -> [return: bb31, unwind continue];
+      }
+  
+      bb31: {
+          StorageDead(_65);
+          StorageDead(_64);
+          _0 = const ();
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.arithmetic_float.GVN.panic-abort.diff b/tests/mir-opt/gvn.arithmetic_float.GVN.panic-abort.diff
new file mode 100644
index 00000000000..7d5ac8353fe
--- /dev/null
+++ b/tests/mir-opt/gvn.arithmetic_float.GVN.panic-abort.diff
@@ -0,0 +1,165 @@
+- // MIR for `arithmetic_float` before GVN
++ // MIR for `arithmetic_float` after GVN
+  
+  fn arithmetic_float(_1: f64) -> () {
+      debug x => _1;
+      let mut _0: ();
+      let _2: ();
+      let mut _3: f64;
+      let mut _4: f64;
+      let _5: ();
+      let mut _6: f64;
+      let mut _7: f64;
+      let _8: ();
+      let mut _9: f64;
+      let mut _10: f64;
+      let _11: ();
+      let mut _12: f64;
+      let mut _13: f64;
+      let _14: ();
+      let mut _15: f64;
+      let mut _16: f64;
+      let _17: ();
+      let mut _18: f64;
+      let mut _19: f64;
+      let _20: ();
+      let mut _21: f64;
+      let mut _22: f64;
+      let _23: ();
+      let mut _24: bool;
+      let mut _25: f64;
+      let mut _26: f64;
+      let _27: ();
+      let mut _28: bool;
+      let mut _29: f64;
+      let mut _30: f64;
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+-         StorageLive(_4);
+-         _4 = _1;
+-         _3 = Add(move _4, const 0f64);
+-         StorageDead(_4);
++         _3 = Add(_1, const 0f64);
+          _2 = opaque::<f64>(move _3) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_3);
+          StorageDead(_2);
+          StorageLive(_5);
+          StorageLive(_6);
+-         StorageLive(_7);
+-         _7 = _1;
+-         _6 = Sub(move _7, const 0f64);
+-         StorageDead(_7);
++         _6 = Sub(_1, const 0f64);
+          _5 = opaque::<f64>(move _6) -> [return: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+          StorageDead(_6);
+          StorageDead(_5);
+          StorageLive(_8);
+          StorageLive(_9);
+-         StorageLive(_10);
+-         _10 = _1;
+-         _9 = Mul(move _10, const 0f64);
+-         StorageDead(_10);
++         _9 = Mul(_1, const 0f64);
+          _8 = opaque::<f64>(move _9) -> [return: bb3, unwind unreachable];
+      }
+  
+      bb3: {
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageLive(_11);
+          StorageLive(_12);
+-         StorageLive(_13);
+-         _13 = _1;
+-         _12 = Div(move _13, const 0f64);
+-         StorageDead(_13);
++         _12 = Div(_1, const 0f64);
+          _11 = opaque::<f64>(move _12) -> [return: bb4, unwind unreachable];
+      }
+  
+      bb4: {
+          StorageDead(_12);
+          StorageDead(_11);
+          StorageLive(_14);
+          StorageLive(_15);
+-         StorageLive(_16);
+-         _16 = _1;
+-         _15 = Div(const 0f64, move _16);
+-         StorageDead(_16);
++         _15 = Div(const 0f64, _1);
+          _14 = opaque::<f64>(move _15) -> [return: bb5, unwind unreachable];
+      }
+  
+      bb5: {
+          StorageDead(_15);
+          StorageDead(_14);
+          StorageLive(_17);
+          StorageLive(_18);
+-         StorageLive(_19);
+-         _19 = _1;
+-         _18 = Rem(move _19, const 0f64);
+-         StorageDead(_19);
++         _18 = Rem(_1, const 0f64);
+          _17 = opaque::<f64>(move _18) -> [return: bb6, unwind unreachable];
+      }
+  
+      bb6: {
+          StorageDead(_18);
+          StorageDead(_17);
+          StorageLive(_20);
+          StorageLive(_21);
+-         StorageLive(_22);
+-         _22 = _1;
+-         _21 = Rem(const 0f64, move _22);
+-         StorageDead(_22);
++         _21 = Rem(const 0f64, _1);
+          _20 = opaque::<f64>(move _21) -> [return: bb7, unwind unreachable];
+      }
+  
+      bb7: {
+          StorageDead(_21);
+          StorageDead(_20);
+          StorageLive(_23);
+          StorageLive(_24);
+-         StorageLive(_25);
+-         _25 = _1;
+-         StorageLive(_26);
+-         _26 = _1;
+-         _24 = Eq(move _25, move _26);
+-         StorageDead(_26);
+-         StorageDead(_25);
++         _24 = Eq(_1, _1);
+          _23 = opaque::<bool>(move _24) -> [return: bb8, unwind unreachable];
+      }
+  
+      bb8: {
+          StorageDead(_24);
+          StorageDead(_23);
+          StorageLive(_27);
+          StorageLive(_28);
+-         StorageLive(_29);
+-         _29 = _1;
+-         StorageLive(_30);
+-         _30 = _1;
+-         _28 = Ne(move _29, move _30);
+-         StorageDead(_30);
+-         StorageDead(_29);
++         _28 = Ne(_1, _1);
+          _27 = opaque::<bool>(move _28) -> [return: bb9, unwind unreachable];
+      }
+  
+      bb9: {
+          StorageDead(_28);
+          StorageDead(_27);
+          _0 = const ();
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.arithmetic_float.GVN.panic-unwind.diff b/tests/mir-opt/gvn.arithmetic_float.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..36c26dc6605
--- /dev/null
+++ b/tests/mir-opt/gvn.arithmetic_float.GVN.panic-unwind.diff
@@ -0,0 +1,165 @@
+- // MIR for `arithmetic_float` before GVN
++ // MIR for `arithmetic_float` after GVN
+  
+  fn arithmetic_float(_1: f64) -> () {
+      debug x => _1;
+      let mut _0: ();
+      let _2: ();
+      let mut _3: f64;
+      let mut _4: f64;
+      let _5: ();
+      let mut _6: f64;
+      let mut _7: f64;
+      let _8: ();
+      let mut _9: f64;
+      let mut _10: f64;
+      let _11: ();
+      let mut _12: f64;
+      let mut _13: f64;
+      let _14: ();
+      let mut _15: f64;
+      let mut _16: f64;
+      let _17: ();
+      let mut _18: f64;
+      let mut _19: f64;
+      let _20: ();
+      let mut _21: f64;
+      let mut _22: f64;
+      let _23: ();
+      let mut _24: bool;
+      let mut _25: f64;
+      let mut _26: f64;
+      let _27: ();
+      let mut _28: bool;
+      let mut _29: f64;
+      let mut _30: f64;
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+-         StorageLive(_4);
+-         _4 = _1;
+-         _3 = Add(move _4, const 0f64);
+-         StorageDead(_4);
++         _3 = Add(_1, const 0f64);
+          _2 = opaque::<f64>(move _3) -> [return: bb1, unwind continue];
+      }
+  
+      bb1: {
+          StorageDead(_3);
+          StorageDead(_2);
+          StorageLive(_5);
+          StorageLive(_6);
+-         StorageLive(_7);
+-         _7 = _1;
+-         _6 = Sub(move _7, const 0f64);
+-         StorageDead(_7);
++         _6 = Sub(_1, const 0f64);
+          _5 = opaque::<f64>(move _6) -> [return: bb2, unwind continue];
+      }
+  
+      bb2: {
+          StorageDead(_6);
+          StorageDead(_5);
+          StorageLive(_8);
+          StorageLive(_9);
+-         StorageLive(_10);
+-         _10 = _1;
+-         _9 = Mul(move _10, const 0f64);
+-         StorageDead(_10);
++         _9 = Mul(_1, const 0f64);
+          _8 = opaque::<f64>(move _9) -> [return: bb3, unwind continue];
+      }
+  
+      bb3: {
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageLive(_11);
+          StorageLive(_12);
+-         StorageLive(_13);
+-         _13 = _1;
+-         _12 = Div(move _13, const 0f64);
+-         StorageDead(_13);
++         _12 = Div(_1, const 0f64);
+          _11 = opaque::<f64>(move _12) -> [return: bb4, unwind continue];
+      }
+  
+      bb4: {
+          StorageDead(_12);
+          StorageDead(_11);
+          StorageLive(_14);
+          StorageLive(_15);
+-         StorageLive(_16);
+-         _16 = _1;
+-         _15 = Div(const 0f64, move _16);
+-         StorageDead(_16);
++         _15 = Div(const 0f64, _1);
+          _14 = opaque::<f64>(move _15) -> [return: bb5, unwind continue];
+      }
+  
+      bb5: {
+          StorageDead(_15);
+          StorageDead(_14);
+          StorageLive(_17);
+          StorageLive(_18);
+-         StorageLive(_19);
+-         _19 = _1;
+-         _18 = Rem(move _19, const 0f64);
+-         StorageDead(_19);
++         _18 = Rem(_1, const 0f64);
+          _17 = opaque::<f64>(move _18) -> [return: bb6, unwind continue];
+      }
+  
+      bb6: {
+          StorageDead(_18);
+          StorageDead(_17);
+          StorageLive(_20);
+          StorageLive(_21);
+-         StorageLive(_22);
+-         _22 = _1;
+-         _21 = Rem(const 0f64, move _22);
+-         StorageDead(_22);
++         _21 = Rem(const 0f64, _1);
+          _20 = opaque::<f64>(move _21) -> [return: bb7, unwind continue];
+      }
+  
+      bb7: {
+          StorageDead(_21);
+          StorageDead(_20);
+          StorageLive(_23);
+          StorageLive(_24);
+-         StorageLive(_25);
+-         _25 = _1;
+-         StorageLive(_26);
+-         _26 = _1;
+-         _24 = Eq(move _25, move _26);
+-         StorageDead(_26);
+-         StorageDead(_25);
++         _24 = Eq(_1, _1);
+          _23 = opaque::<bool>(move _24) -> [return: bb8, unwind continue];
+      }
+  
+      bb8: {
+          StorageDead(_24);
+          StorageDead(_23);
+          StorageLive(_27);
+          StorageLive(_28);
+-         StorageLive(_29);
+-         _29 = _1;
+-         StorageLive(_30);
+-         _30 = _1;
+-         _28 = Ne(move _29, move _30);
+-         StorageDead(_30);
+-         StorageDead(_29);
++         _28 = Ne(_1, _1);
+          _27 = opaque::<bool>(move _28) -> [return: bb9, unwind continue];
+      }
+  
+      bb9: {
+          StorageDead(_28);
+          StorageDead(_27);
+          _0 = const ();
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.cast.GVN.panic-abort.diff b/tests/mir-opt/gvn.cast.GVN.panic-abort.diff
new file mode 100644
index 00000000000..513fe60b65d
--- /dev/null
+++ b/tests/mir-opt/gvn.cast.GVN.panic-abort.diff
@@ -0,0 +1,501 @@
+- // MIR for `cast` before GVN
++ // MIR for `cast` after GVN
+  
+  fn cast() -> () {
+      let mut _0: ();
+      let _1: i64;
+      let _4: ();
+      let mut _5: u8;
+      let mut _6: i64;
+      let _7: ();
+      let mut _8: u16;
+      let mut _9: i64;
+      let _10: ();
+      let mut _11: u32;
+      let mut _12: i64;
+      let _13: ();
+      let mut _14: u64;
+      let mut _15: i64;
+      let _16: ();
+      let mut _17: i8;
+      let mut _18: i64;
+      let _19: ();
+      let mut _20: i16;
+      let mut _21: i64;
+      let _22: ();
+      let mut _23: i32;
+      let mut _24: i64;
+      let _25: ();
+      let mut _26: i64;
+      let _27: ();
+      let mut _28: f32;
+      let mut _29: i64;
+      let _30: ();
+      let mut _31: f64;
+      let mut _32: i64;
+      let _33: ();
+      let mut _34: u8;
+      let mut _35: u64;
+      let _36: ();
+      let mut _37: u16;
+      let mut _38: u64;
+      let _39: ();
+      let mut _40: u32;
+      let mut _41: u64;
+      let _42: ();
+      let mut _43: u64;
+      let _44: ();
+      let mut _45: i8;
+      let mut _46: u64;
+      let _47: ();
+      let mut _48: i16;
+      let mut _49: u64;
+      let _50: ();
+      let mut _51: i32;
+      let mut _52: u64;
+      let _53: ();
+      let mut _54: i64;
+      let mut _55: u64;
+      let _56: ();
+      let mut _57: f32;
+      let mut _58: u64;
+      let _59: ();
+      let mut _60: f64;
+      let mut _61: u64;
+      let _62: ();
+      let mut _63: u8;
+      let mut _64: f64;
+      let _65: ();
+      let mut _66: u16;
+      let mut _67: f64;
+      let _68: ();
+      let mut _69: u32;
+      let mut _70: f64;
+      let _71: ();
+      let mut _72: u64;
+      let mut _73: f64;
+      let _74: ();
+      let mut _75: i8;
+      let mut _76: f64;
+      let _77: ();
+      let mut _78: i16;
+      let mut _79: f64;
+      let _80: ();
+      let mut _81: i32;
+      let mut _82: f64;
+      let _83: ();
+      let mut _84: i64;
+      let mut _85: f64;
+      let _86: ();
+      let mut _87: f32;
+      let mut _88: f64;
+      let _89: ();
+      let mut _90: f64;
+      scope 1 {
+          debug i => _1;
+          let _2: u64;
+          scope 2 {
+              debug u => _2;
+              let _3: f64;
+              scope 3 {
+                  debug f => _3;
+              }
+          }
+      }
+  
+      bb0: {
+-         StorageLive(_1);
+          _1 = const 1_i64;
+-         StorageLive(_2);
+          _2 = const 1_u64;
+-         StorageLive(_3);
+          _3 = const 1f64;
+          StorageLive(_4);
+          StorageLive(_5);
+-         StorageLive(_6);
+-         _6 = _1;
+-         _5 = move _6 as u8 (IntToInt);
+-         StorageDead(_6);
++         _5 = const 1_i64 as u8 (IntToInt);
+          _4 = opaque::<u8>(move _5) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_5);
+          StorageDead(_4);
+          StorageLive(_7);
+          StorageLive(_8);
+-         StorageLive(_9);
+-         _9 = _1;
+-         _8 = move _9 as u16 (IntToInt);
+-         StorageDead(_9);
++         _8 = const 1_i64 as u16 (IntToInt);
+          _7 = opaque::<u16>(move _8) -> [return: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+          StorageDead(_8);
+          StorageDead(_7);
+          StorageLive(_10);
+          StorageLive(_11);
+-         StorageLive(_12);
+-         _12 = _1;
+-         _11 = move _12 as u32 (IntToInt);
+-         StorageDead(_12);
++         _11 = const 1_i64 as u32 (IntToInt);
+          _10 = opaque::<u32>(move _11) -> [return: bb3, unwind unreachable];
+      }
+  
+      bb3: {
+          StorageDead(_11);
+          StorageDead(_10);
+          StorageLive(_13);
+          StorageLive(_14);
+-         StorageLive(_15);
+-         _15 = _1;
+-         _14 = move _15 as u64 (IntToInt);
+-         StorageDead(_15);
++         _14 = const 1_i64 as u64 (IntToInt);
+          _13 = opaque::<u64>(move _14) -> [return: bb4, unwind unreachable];
+      }
+  
+      bb4: {
+          StorageDead(_14);
+          StorageDead(_13);
+          StorageLive(_16);
+          StorageLive(_17);
+-         StorageLive(_18);
+-         _18 = _1;
+-         _17 = move _18 as i8 (IntToInt);
+-         StorageDead(_18);
++         _17 = const 1_i64 as i8 (IntToInt);
+          _16 = opaque::<i8>(move _17) -> [return: bb5, unwind unreachable];
+      }
+  
+      bb5: {
+          StorageDead(_17);
+          StorageDead(_16);
+          StorageLive(_19);
+          StorageLive(_20);
+-         StorageLive(_21);
+-         _21 = _1;
+-         _20 = move _21 as i16 (IntToInt);
+-         StorageDead(_21);
++         _20 = const 1_i64 as i16 (IntToInt);
+          _19 = opaque::<i16>(move _20) -> [return: bb6, unwind unreachable];
+      }
+  
+      bb6: {
+          StorageDead(_20);
+          StorageDead(_19);
+          StorageLive(_22);
+          StorageLive(_23);
+-         StorageLive(_24);
+-         _24 = _1;
+-         _23 = move _24 as i32 (IntToInt);
+-         StorageDead(_24);
++         _23 = const 1_i64 as i32 (IntToInt);
+          _22 = opaque::<i32>(move _23) -> [return: bb7, unwind unreachable];
+      }
+  
+      bb7: {
+          StorageDead(_23);
+          StorageDead(_22);
+          StorageLive(_25);
+-         StorageLive(_26);
+-         _26 = _1;
+-         _25 = opaque::<i64>(move _26) -> [return: bb8, unwind unreachable];
++         _25 = opaque::<i64>(const 1_i64) -> [return: bb8, unwind unreachable];
+      }
+  
+      bb8: {
+-         StorageDead(_26);
+          StorageDead(_25);
+          StorageLive(_27);
+          StorageLive(_28);
+-         StorageLive(_29);
+-         _29 = _1;
+-         _28 = move _29 as f32 (IntToFloat);
+-         StorageDead(_29);
++         _28 = const 1_i64 as f32 (IntToFloat);
+          _27 = opaque::<f32>(move _28) -> [return: bb9, unwind unreachable];
+      }
+  
+      bb9: {
+          StorageDead(_28);
+          StorageDead(_27);
+          StorageLive(_30);
+          StorageLive(_31);
+-         StorageLive(_32);
+-         _32 = _1;
+-         _31 = move _32 as f64 (IntToFloat);
+-         StorageDead(_32);
++         _31 = const 1_i64 as f64 (IntToFloat);
+          _30 = opaque::<f64>(move _31) -> [return: bb10, unwind unreachable];
+      }
+  
+      bb10: {
+          StorageDead(_31);
+          StorageDead(_30);
+          StorageLive(_33);
+          StorageLive(_34);
+-         StorageLive(_35);
+-         _35 = _2;
+-         _34 = move _35 as u8 (IntToInt);
+-         StorageDead(_35);
++         _34 = const 1_u64 as u8 (IntToInt);
+          _33 = opaque::<u8>(move _34) -> [return: bb11, unwind unreachable];
+      }
+  
+      bb11: {
+          StorageDead(_34);
+          StorageDead(_33);
+          StorageLive(_36);
+          StorageLive(_37);
+-         StorageLive(_38);
+-         _38 = _2;
+-         _37 = move _38 as u16 (IntToInt);
+-         StorageDead(_38);
++         _37 = const 1_u64 as u16 (IntToInt);
+          _36 = opaque::<u16>(move _37) -> [return: bb12, unwind unreachable];
+      }
+  
+      bb12: {
+          StorageDead(_37);
+          StorageDead(_36);
+          StorageLive(_39);
+          StorageLive(_40);
+-         StorageLive(_41);
+-         _41 = _2;
+-         _40 = move _41 as u32 (IntToInt);
+-         StorageDead(_41);
++         _40 = const 1_u64 as u32 (IntToInt);
+          _39 = opaque::<u32>(move _40) -> [return: bb13, unwind unreachable];
+      }
+  
+      bb13: {
+          StorageDead(_40);
+          StorageDead(_39);
+          StorageLive(_42);
+-         StorageLive(_43);
+-         _43 = _2;
+-         _42 = opaque::<u64>(move _43) -> [return: bb14, unwind unreachable];
++         _42 = opaque::<u64>(const 1_u64) -> [return: bb14, unwind unreachable];
+      }
+  
+      bb14: {
+-         StorageDead(_43);
+          StorageDead(_42);
+          StorageLive(_44);
+          StorageLive(_45);
+-         StorageLive(_46);
+-         _46 = _2;
+-         _45 = move _46 as i8 (IntToInt);
+-         StorageDead(_46);
++         _45 = const 1_u64 as i8 (IntToInt);
+          _44 = opaque::<i8>(move _45) -> [return: bb15, unwind unreachable];
+      }
+  
+      bb15: {
+          StorageDead(_45);
+          StorageDead(_44);
+          StorageLive(_47);
+          StorageLive(_48);
+-         StorageLive(_49);
+-         _49 = _2;
+-         _48 = move _49 as i16 (IntToInt);
+-         StorageDead(_49);
++         _48 = const 1_u64 as i16 (IntToInt);
+          _47 = opaque::<i16>(move _48) -> [return: bb16, unwind unreachable];
+      }
+  
+      bb16: {
+          StorageDead(_48);
+          StorageDead(_47);
+          StorageLive(_50);
+          StorageLive(_51);
+-         StorageLive(_52);
+-         _52 = _2;
+-         _51 = move _52 as i32 (IntToInt);
+-         StorageDead(_52);
++         _51 = const 1_u64 as i32 (IntToInt);
+          _50 = opaque::<i32>(move _51) -> [return: bb17, unwind unreachable];
+      }
+  
+      bb17: {
+          StorageDead(_51);
+          StorageDead(_50);
+          StorageLive(_53);
+          StorageLive(_54);
+-         StorageLive(_55);
+-         _55 = _2;
+-         _54 = move _55 as i64 (IntToInt);
+-         StorageDead(_55);
++         _54 = const 1_u64 as i64 (IntToInt);
+          _53 = opaque::<i64>(move _54) -> [return: bb18, unwind unreachable];
+      }
+  
+      bb18: {
+          StorageDead(_54);
+          StorageDead(_53);
+          StorageLive(_56);
+          StorageLive(_57);
+-         StorageLive(_58);
+-         _58 = _2;
+-         _57 = move _58 as f32 (IntToFloat);
+-         StorageDead(_58);
++         _57 = const 1_u64 as f32 (IntToFloat);
+          _56 = opaque::<f32>(move _57) -> [return: bb19, unwind unreachable];
+      }
+  
+      bb19: {
+          StorageDead(_57);
+          StorageDead(_56);
+          StorageLive(_59);
+          StorageLive(_60);
+-         StorageLive(_61);
+-         _61 = _2;
+-         _60 = move _61 as f64 (IntToFloat);
+-         StorageDead(_61);
++         _60 = const 1_u64 as f64 (IntToFloat);
+          _59 = opaque::<f64>(move _60) -> [return: bb20, unwind unreachable];
+      }
+  
+      bb20: {
+          StorageDead(_60);
+          StorageDead(_59);
+          StorageLive(_62);
+          StorageLive(_63);
+-         StorageLive(_64);
+-         _64 = _3;
+-         _63 = move _64 as u8 (FloatToInt);
+-         StorageDead(_64);
++         _63 = const 1f64 as u8 (FloatToInt);
+          _62 = opaque::<u8>(move _63) -> [return: bb21, unwind unreachable];
+      }
+  
+      bb21: {
+          StorageDead(_63);
+          StorageDead(_62);
+          StorageLive(_65);
+          StorageLive(_66);
+-         StorageLive(_67);
+-         _67 = _3;
+-         _66 = move _67 as u16 (FloatToInt);
+-         StorageDead(_67);
++         _66 = const 1f64 as u16 (FloatToInt);
+          _65 = opaque::<u16>(move _66) -> [return: bb22, unwind unreachable];
+      }
+  
+      bb22: {
+          StorageDead(_66);
+          StorageDead(_65);
+          StorageLive(_68);
+          StorageLive(_69);
+-         StorageLive(_70);
+-         _70 = _3;
+-         _69 = move _70 as u32 (FloatToInt);
+-         StorageDead(_70);
++         _69 = const 1f64 as u32 (FloatToInt);
+          _68 = opaque::<u32>(move _69) -> [return: bb23, unwind unreachable];
+      }
+  
+      bb23: {
+          StorageDead(_69);
+          StorageDead(_68);
+          StorageLive(_71);
+          StorageLive(_72);
+-         StorageLive(_73);
+-         _73 = _3;
+-         _72 = move _73 as u64 (FloatToInt);
+-         StorageDead(_73);
++         _72 = const 1f64 as u64 (FloatToInt);
+          _71 = opaque::<u64>(move _72) -> [return: bb24, unwind unreachable];
+      }
+  
+      bb24: {
+          StorageDead(_72);
+          StorageDead(_71);
+          StorageLive(_74);
+          StorageLive(_75);
+-         StorageLive(_76);
+-         _76 = _3;
+-         _75 = move _76 as i8 (FloatToInt);
+-         StorageDead(_76);
++         _75 = const 1f64 as i8 (FloatToInt);
+          _74 = opaque::<i8>(move _75) -> [return: bb25, unwind unreachable];
+      }
+  
+      bb25: {
+          StorageDead(_75);
+          StorageDead(_74);
+          StorageLive(_77);
+          StorageLive(_78);
+-         StorageLive(_79);
+-         _79 = _3;
+-         _78 = move _79 as i16 (FloatToInt);
+-         StorageDead(_79);
++         _78 = const 1f64 as i16 (FloatToInt);
+          _77 = opaque::<i16>(move _78) -> [return: bb26, unwind unreachable];
+      }
+  
+      bb26: {
+          StorageDead(_78);
+          StorageDead(_77);
+          StorageLive(_80);
+          StorageLive(_81);
+-         StorageLive(_82);
+-         _82 = _3;
+-         _81 = move _82 as i32 (FloatToInt);
+-         StorageDead(_82);
++         _81 = const 1f64 as i32 (FloatToInt);
+          _80 = opaque::<i32>(move _81) -> [return: bb27, unwind unreachable];
+      }
+  
+      bb27: {
+          StorageDead(_81);
+          StorageDead(_80);
+          StorageLive(_83);
+          StorageLive(_84);
+-         StorageLive(_85);
+-         _85 = _3;
+-         _84 = move _85 as i64 (FloatToInt);
+-         StorageDead(_85);
++         _84 = const 1f64 as i64 (FloatToInt);
+          _83 = opaque::<i64>(move _84) -> [return: bb28, unwind unreachable];
+      }
+  
+      bb28: {
+          StorageDead(_84);
+          StorageDead(_83);
+          StorageLive(_86);
+          StorageLive(_87);
+-         StorageLive(_88);
+-         _88 = _3;
+-         _87 = move _88 as f32 (FloatToFloat);
+-         StorageDead(_88);
++         _87 = const 1f64 as f32 (FloatToFloat);
+          _86 = opaque::<f32>(move _87) -> [return: bb29, unwind unreachable];
+      }
+  
+      bb29: {
+          StorageDead(_87);
+          StorageDead(_86);
+          StorageLive(_89);
+-         StorageLive(_90);
+-         _90 = _3;
+-         _89 = opaque::<f64>(move _90) -> [return: bb30, unwind unreachable];
++         _89 = opaque::<f64>(const 1f64) -> [return: bb30, unwind unreachable];
+      }
+  
+      bb30: {
+-         StorageDead(_90);
+          StorageDead(_89);
+          _0 = const ();
+-         StorageDead(_3);
+-         StorageDead(_2);
+-         StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.cast.GVN.panic-unwind.diff b/tests/mir-opt/gvn.cast.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..33192ed8de0
--- /dev/null
+++ b/tests/mir-opt/gvn.cast.GVN.panic-unwind.diff
@@ -0,0 +1,501 @@
+- // MIR for `cast` before GVN
++ // MIR for `cast` after GVN
+  
+  fn cast() -> () {
+      let mut _0: ();
+      let _1: i64;
+      let _4: ();
+      let mut _5: u8;
+      let mut _6: i64;
+      let _7: ();
+      let mut _8: u16;
+      let mut _9: i64;
+      let _10: ();
+      let mut _11: u32;
+      let mut _12: i64;
+      let _13: ();
+      let mut _14: u64;
+      let mut _15: i64;
+      let _16: ();
+      let mut _17: i8;
+      let mut _18: i64;
+      let _19: ();
+      let mut _20: i16;
+      let mut _21: i64;
+      let _22: ();
+      let mut _23: i32;
+      let mut _24: i64;
+      let _25: ();
+      let mut _26: i64;
+      let _27: ();
+      let mut _28: f32;
+      let mut _29: i64;
+      let _30: ();
+      let mut _31: f64;
+      let mut _32: i64;
+      let _33: ();
+      let mut _34: u8;
+      let mut _35: u64;
+      let _36: ();
+      let mut _37: u16;
+      let mut _38: u64;
+      let _39: ();
+      let mut _40: u32;
+      let mut _41: u64;
+      let _42: ();
+      let mut _43: u64;
+      let _44: ();
+      let mut _45: i8;
+      let mut _46: u64;
+      let _47: ();
+      let mut _48: i16;
+      let mut _49: u64;
+      let _50: ();
+      let mut _51: i32;
+      let mut _52: u64;
+      let _53: ();
+      let mut _54: i64;
+      let mut _55: u64;
+      let _56: ();
+      let mut _57: f32;
+      let mut _58: u64;
+      let _59: ();
+      let mut _60: f64;
+      let mut _61: u64;
+      let _62: ();
+      let mut _63: u8;
+      let mut _64: f64;
+      let _65: ();
+      let mut _66: u16;
+      let mut _67: f64;
+      let _68: ();
+      let mut _69: u32;
+      let mut _70: f64;
+      let _71: ();
+      let mut _72: u64;
+      let mut _73: f64;
+      let _74: ();
+      let mut _75: i8;
+      let mut _76: f64;
+      let _77: ();
+      let mut _78: i16;
+      let mut _79: f64;
+      let _80: ();
+      let mut _81: i32;
+      let mut _82: f64;
+      let _83: ();
+      let mut _84: i64;
+      let mut _85: f64;
+      let _86: ();
+      let mut _87: f32;
+      let mut _88: f64;
+      let _89: ();
+      let mut _90: f64;
+      scope 1 {
+          debug i => _1;
+          let _2: u64;
+          scope 2 {
+              debug u => _2;
+              let _3: f64;
+              scope 3 {
+                  debug f => _3;
+              }
+          }
+      }
+  
+      bb0: {
+-         StorageLive(_1);
+          _1 = const 1_i64;
+-         StorageLive(_2);
+          _2 = const 1_u64;
+-         StorageLive(_3);
+          _3 = const 1f64;
+          StorageLive(_4);
+          StorageLive(_5);
+-         StorageLive(_6);
+-         _6 = _1;
+-         _5 = move _6 as u8 (IntToInt);
+-         StorageDead(_6);
++         _5 = const 1_i64 as u8 (IntToInt);
+          _4 = opaque::<u8>(move _5) -> [return: bb1, unwind continue];
+      }
+  
+      bb1: {
+          StorageDead(_5);
+          StorageDead(_4);
+          StorageLive(_7);
+          StorageLive(_8);
+-         StorageLive(_9);
+-         _9 = _1;
+-         _8 = move _9 as u16 (IntToInt);
+-         StorageDead(_9);
++         _8 = const 1_i64 as u16 (IntToInt);
+          _7 = opaque::<u16>(move _8) -> [return: bb2, unwind continue];
+      }
+  
+      bb2: {
+          StorageDead(_8);
+          StorageDead(_7);
+          StorageLive(_10);
+          StorageLive(_11);
+-         StorageLive(_12);
+-         _12 = _1;
+-         _11 = move _12 as u32 (IntToInt);
+-         StorageDead(_12);
++         _11 = const 1_i64 as u32 (IntToInt);
+          _10 = opaque::<u32>(move _11) -> [return: bb3, unwind continue];
+      }
+  
+      bb3: {
+          StorageDead(_11);
+          StorageDead(_10);
+          StorageLive(_13);
+          StorageLive(_14);
+-         StorageLive(_15);
+-         _15 = _1;
+-         _14 = move _15 as u64 (IntToInt);
+-         StorageDead(_15);
++         _14 = const 1_i64 as u64 (IntToInt);
+          _13 = opaque::<u64>(move _14) -> [return: bb4, unwind continue];
+      }
+  
+      bb4: {
+          StorageDead(_14);
+          StorageDead(_13);
+          StorageLive(_16);
+          StorageLive(_17);
+-         StorageLive(_18);
+-         _18 = _1;
+-         _17 = move _18 as i8 (IntToInt);
+-         StorageDead(_18);
++         _17 = const 1_i64 as i8 (IntToInt);
+          _16 = opaque::<i8>(move _17) -> [return: bb5, unwind continue];
+      }
+  
+      bb5: {
+          StorageDead(_17);
+          StorageDead(_16);
+          StorageLive(_19);
+          StorageLive(_20);
+-         StorageLive(_21);
+-         _21 = _1;
+-         _20 = move _21 as i16 (IntToInt);
+-         StorageDead(_21);
++         _20 = const 1_i64 as i16 (IntToInt);
+          _19 = opaque::<i16>(move _20) -> [return: bb6, unwind continue];
+      }
+  
+      bb6: {
+          StorageDead(_20);
+          StorageDead(_19);
+          StorageLive(_22);
+          StorageLive(_23);
+-         StorageLive(_24);
+-         _24 = _1;
+-         _23 = move _24 as i32 (IntToInt);
+-         StorageDead(_24);
++         _23 = const 1_i64 as i32 (IntToInt);
+          _22 = opaque::<i32>(move _23) -> [return: bb7, unwind continue];
+      }
+  
+      bb7: {
+          StorageDead(_23);
+          StorageDead(_22);
+          StorageLive(_25);
+-         StorageLive(_26);
+-         _26 = _1;
+-         _25 = opaque::<i64>(move _26) -> [return: bb8, unwind continue];
++         _25 = opaque::<i64>(const 1_i64) -> [return: bb8, unwind continue];
+      }
+  
+      bb8: {
+-         StorageDead(_26);
+          StorageDead(_25);
+          StorageLive(_27);
+          StorageLive(_28);
+-         StorageLive(_29);
+-         _29 = _1;
+-         _28 = move _29 as f32 (IntToFloat);
+-         StorageDead(_29);
++         _28 = const 1_i64 as f32 (IntToFloat);
+          _27 = opaque::<f32>(move _28) -> [return: bb9, unwind continue];
+      }
+  
+      bb9: {
+          StorageDead(_28);
+          StorageDead(_27);
+          StorageLive(_30);
+          StorageLive(_31);
+-         StorageLive(_32);
+-         _32 = _1;
+-         _31 = move _32 as f64 (IntToFloat);
+-         StorageDead(_32);
++         _31 = const 1_i64 as f64 (IntToFloat);
+          _30 = opaque::<f64>(move _31) -> [return: bb10, unwind continue];
+      }
+  
+      bb10: {
+          StorageDead(_31);
+          StorageDead(_30);
+          StorageLive(_33);
+          StorageLive(_34);
+-         StorageLive(_35);
+-         _35 = _2;
+-         _34 = move _35 as u8 (IntToInt);
+-         StorageDead(_35);
++         _34 = const 1_u64 as u8 (IntToInt);
+          _33 = opaque::<u8>(move _34) -> [return: bb11, unwind continue];
+      }
+  
+      bb11: {
+          StorageDead(_34);
+          StorageDead(_33);
+          StorageLive(_36);
+          StorageLive(_37);
+-         StorageLive(_38);
+-         _38 = _2;
+-         _37 = move _38 as u16 (IntToInt);
+-         StorageDead(_38);
++         _37 = const 1_u64 as u16 (IntToInt);
+          _36 = opaque::<u16>(move _37) -> [return: bb12, unwind continue];
+      }
+  
+      bb12: {
+          StorageDead(_37);
+          StorageDead(_36);
+          StorageLive(_39);
+          StorageLive(_40);
+-         StorageLive(_41);
+-         _41 = _2;
+-         _40 = move _41 as u32 (IntToInt);
+-         StorageDead(_41);
++         _40 = const 1_u64 as u32 (IntToInt);
+          _39 = opaque::<u32>(move _40) -> [return: bb13, unwind continue];
+      }
+  
+      bb13: {
+          StorageDead(_40);
+          StorageDead(_39);
+          StorageLive(_42);
+-         StorageLive(_43);
+-         _43 = _2;
+-         _42 = opaque::<u64>(move _43) -> [return: bb14, unwind continue];
++         _42 = opaque::<u64>(const 1_u64) -> [return: bb14, unwind continue];
+      }
+  
+      bb14: {
+-         StorageDead(_43);
+          StorageDead(_42);
+          StorageLive(_44);
+          StorageLive(_45);
+-         StorageLive(_46);
+-         _46 = _2;
+-         _45 = move _46 as i8 (IntToInt);
+-         StorageDead(_46);
++         _45 = const 1_u64 as i8 (IntToInt);
+          _44 = opaque::<i8>(move _45) -> [return: bb15, unwind continue];
+      }
+  
+      bb15: {
+          StorageDead(_45);
+          StorageDead(_44);
+          StorageLive(_47);
+          StorageLive(_48);
+-         StorageLive(_49);
+-         _49 = _2;
+-         _48 = move _49 as i16 (IntToInt);
+-         StorageDead(_49);
++         _48 = const 1_u64 as i16 (IntToInt);
+          _47 = opaque::<i16>(move _48) -> [return: bb16, unwind continue];
+      }
+  
+      bb16: {
+          StorageDead(_48);
+          StorageDead(_47);
+          StorageLive(_50);
+          StorageLive(_51);
+-         StorageLive(_52);
+-         _52 = _2;
+-         _51 = move _52 as i32 (IntToInt);
+-         StorageDead(_52);
++         _51 = const 1_u64 as i32 (IntToInt);
+          _50 = opaque::<i32>(move _51) -> [return: bb17, unwind continue];
+      }
+  
+      bb17: {
+          StorageDead(_51);
+          StorageDead(_50);
+          StorageLive(_53);
+          StorageLive(_54);
+-         StorageLive(_55);
+-         _55 = _2;
+-         _54 = move _55 as i64 (IntToInt);
+-         StorageDead(_55);
++         _54 = const 1_u64 as i64 (IntToInt);
+          _53 = opaque::<i64>(move _54) -> [return: bb18, unwind continue];
+      }
+  
+      bb18: {
+          StorageDead(_54);
+          StorageDead(_53);
+          StorageLive(_56);
+          StorageLive(_57);
+-         StorageLive(_58);
+-         _58 = _2;
+-         _57 = move _58 as f32 (IntToFloat);
+-         StorageDead(_58);
++         _57 = const 1_u64 as f32 (IntToFloat);
+          _56 = opaque::<f32>(move _57) -> [return: bb19, unwind continue];
+      }
+  
+      bb19: {
+          StorageDead(_57);
+          StorageDead(_56);
+          StorageLive(_59);
+          StorageLive(_60);
+-         StorageLive(_61);
+-         _61 = _2;
+-         _60 = move _61 as f64 (IntToFloat);
+-         StorageDead(_61);
++         _60 = const 1_u64 as f64 (IntToFloat);
+          _59 = opaque::<f64>(move _60) -> [return: bb20, unwind continue];
+      }
+  
+      bb20: {
+          StorageDead(_60);
+          StorageDead(_59);
+          StorageLive(_62);
+          StorageLive(_63);
+-         StorageLive(_64);
+-         _64 = _3;
+-         _63 = move _64 as u8 (FloatToInt);
+-         StorageDead(_64);
++         _63 = const 1f64 as u8 (FloatToInt);
+          _62 = opaque::<u8>(move _63) -> [return: bb21, unwind continue];
+      }
+  
+      bb21: {
+          StorageDead(_63);
+          StorageDead(_62);
+          StorageLive(_65);
+          StorageLive(_66);
+-         StorageLive(_67);
+-         _67 = _3;
+-         _66 = move _67 as u16 (FloatToInt);
+-         StorageDead(_67);
++         _66 = const 1f64 as u16 (FloatToInt);
+          _65 = opaque::<u16>(move _66) -> [return: bb22, unwind continue];
+      }
+  
+      bb22: {
+          StorageDead(_66);
+          StorageDead(_65);
+          StorageLive(_68);
+          StorageLive(_69);
+-         StorageLive(_70);
+-         _70 = _3;
+-         _69 = move _70 as u32 (FloatToInt);
+-         StorageDead(_70);
++         _69 = const 1f64 as u32 (FloatToInt);
+          _68 = opaque::<u32>(move _69) -> [return: bb23, unwind continue];
+      }
+  
+      bb23: {
+          StorageDead(_69);
+          StorageDead(_68);
+          StorageLive(_71);
+          StorageLive(_72);
+-         StorageLive(_73);
+-         _73 = _3;
+-         _72 = move _73 as u64 (FloatToInt);
+-         StorageDead(_73);
++         _72 = const 1f64 as u64 (FloatToInt);
+          _71 = opaque::<u64>(move _72) -> [return: bb24, unwind continue];
+      }
+  
+      bb24: {
+          StorageDead(_72);
+          StorageDead(_71);
+          StorageLive(_74);
+          StorageLive(_75);
+-         StorageLive(_76);
+-         _76 = _3;
+-         _75 = move _76 as i8 (FloatToInt);
+-         StorageDead(_76);
++         _75 = const 1f64 as i8 (FloatToInt);
+          _74 = opaque::<i8>(move _75) -> [return: bb25, unwind continue];
+      }
+  
+      bb25: {
+          StorageDead(_75);
+          StorageDead(_74);
+          StorageLive(_77);
+          StorageLive(_78);
+-         StorageLive(_79);
+-         _79 = _3;
+-         _78 = move _79 as i16 (FloatToInt);
+-         StorageDead(_79);
++         _78 = const 1f64 as i16 (FloatToInt);
+          _77 = opaque::<i16>(move _78) -> [return: bb26, unwind continue];
+      }
+  
+      bb26: {
+          StorageDead(_78);
+          StorageDead(_77);
+          StorageLive(_80);
+          StorageLive(_81);
+-         StorageLive(_82);
+-         _82 = _3;
+-         _81 = move _82 as i32 (FloatToInt);
+-         StorageDead(_82);
++         _81 = const 1f64 as i32 (FloatToInt);
+          _80 = opaque::<i32>(move _81) -> [return: bb27, unwind continue];
+      }
+  
+      bb27: {
+          StorageDead(_81);
+          StorageDead(_80);
+          StorageLive(_83);
+          StorageLive(_84);
+-         StorageLive(_85);
+-         _85 = _3;
+-         _84 = move _85 as i64 (FloatToInt);
+-         StorageDead(_85);
++         _84 = const 1f64 as i64 (FloatToInt);
+          _83 = opaque::<i64>(move _84) -> [return: bb28, unwind continue];
+      }
+  
+      bb28: {
+          StorageDead(_84);
+          StorageDead(_83);
+          StorageLive(_86);
+          StorageLive(_87);
+-         StorageLive(_88);
+-         _88 = _3;
+-         _87 = move _88 as f32 (FloatToFloat);
+-         StorageDead(_88);
++         _87 = const 1f64 as f32 (FloatToFloat);
+          _86 = opaque::<f32>(move _87) -> [return: bb29, unwind continue];
+      }
+  
+      bb29: {
+          StorageDead(_87);
+          StorageDead(_86);
+          StorageLive(_89);
+-         StorageLive(_90);
+-         _90 = _3;
+-         _89 = opaque::<f64>(move _90) -> [return: bb30, unwind continue];
++         _89 = opaque::<f64>(const 1f64) -> [return: bb30, unwind continue];
+      }
+  
+      bb30: {
+-         StorageDead(_90);
+          StorageDead(_89);
+          _0 = const ();
+-         StorageDead(_3);
+-         StorageDead(_2);
+-         StorageDead(_1);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff b/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff
new file mode 100644
index 00000000000..ee320cf6787
--- /dev/null
+++ b/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff
@@ -0,0 +1,191 @@
+- // MIR for `dereferences` before GVN
++ // MIR for `dereferences` after GVN
+  
+  fn dereferences(_1: &mut u32, _2: &impl Copy, _3: &S<u32>) -> () {
+      debug t => _1;
+      debug u => _2;
+      debug s => _3;
+      let mut _0: ();
+      let _4: ();
+      let mut _5: u32;
+      let _6: ();
+      let mut _7: u32;
+      let _8: *const u32;
+      let _9: ();
+      let mut _10: u32;
+      let _11: ();
+      let mut _12: u32;
+      let _14: ();
+      let mut _15: u32;
+      let _16: ();
+      let mut _17: u32;
+      let _19: ();
+      let mut _20: u32;
+      let _21: ();
+      let mut _22: u32;
+      let _23: ();
+      let mut _24: &u32;
+      let _25: ();
+      let mut _26: impl Copy;
+      let _27: ();
+      let mut _28: impl Copy;
+      let _29: ();
+      let mut _30: u32;
+      let _31: ();
+      let mut _32: u32;
+      scope 1 {
+          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 {
+                  debug z => _18;
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_4);
+          StorageLive(_5);
+          _5 = (*_1);
+          _4 = opaque::<u32>(move _5) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_5);
+          StorageDead(_4);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = (*_1);
+          _6 = opaque::<u32>(move _7) -> [return: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+          StorageDead(_7);
+          StorageDead(_6);
+          StorageLive(_8);
+          _8 = &raw const (*_1);
+          StorageLive(_9);
+          StorageLive(_10);
+          _10 = (*_8);
+          _9 = opaque::<u32>(move _10) -> [return: bb3, unwind unreachable];
+      }
+  
+      bb3: {
+          StorageDead(_10);
+          StorageDead(_9);
+          StorageLive(_11);
+          StorageLive(_12);
+          _12 = (*_8);
+          _11 = opaque::<u32>(move _12) -> [return: bb4, unwind unreachable];
+      }
+  
+      bb4: {
+          StorageDead(_12);
+          StorageDead(_11);
+          StorageLive(_13);
+          _13 = &raw mut (*_1);
+          StorageLive(_14);
+          StorageLive(_15);
+          _15 = (*_13);
+          _14 = opaque::<u32>(move _15) -> [return: bb5, unwind unreachable];
+      }
+  
+      bb5: {
+          StorageDead(_15);
+          StorageDead(_14);
+          StorageLive(_16);
+          StorageLive(_17);
+          _17 = (*_13);
+          _16 = opaque::<u32>(move _17) -> [return: bb6, unwind unreachable];
+      }
+  
+      bb6: {
+          StorageDead(_17);
+          StorageDead(_16);
+          StorageLive(_18);
+          _18 = &(*_1);
+          StorageLive(_19);
+-         StorageLive(_20);
+          _20 = (*_18);
+-         _19 = opaque::<u32>(move _20) -> [return: bb7, unwind unreachable];
++         _19 = opaque::<u32>(_20) -> [return: bb7, unwind unreachable];
+      }
+  
+      bb7: {
+-         StorageDead(_20);
+          StorageDead(_19);
+          StorageLive(_21);
+-         StorageLive(_22);
+-         _22 = (*_18);
+-         _21 = opaque::<u32>(move _22) -> [return: bb8, unwind unreachable];
++         _21 = opaque::<u32>(_20) -> [return: bb8, unwind unreachable];
+      }
+  
+      bb8: {
+-         StorageDead(_22);
+          StorageDead(_21);
+          StorageLive(_23);
+          StorageLive(_24);
+          _24 = &(*_18);
+          _23 = opaque::<&u32>(move _24) -> [return: bb9, unwind unreachable];
+      }
+  
+      bb9: {
+          StorageDead(_24);
+          StorageDead(_23);
+          StorageLive(_25);
+          StorageLive(_26);
+          _26 = (*_2);
+          _25 = opaque::<impl Copy>(move _26) -> [return: bb10, unwind unreachable];
+      }
+  
+      bb10: {
+          StorageDead(_26);
+          StorageDead(_25);
+          StorageLive(_27);
+          StorageLive(_28);
+          _28 = (*_2);
+          _27 = opaque::<impl Copy>(move _28) -> [return: bb11, unwind unreachable];
+      }
+  
+      bb11: {
+          StorageDead(_28);
+          StorageDead(_27);
+          StorageLive(_29);
+-         StorageLive(_30);
+          _30 = ((*_3).0: u32);
+-         _29 = opaque::<u32>(move _30) -> [return: bb12, unwind unreachable];
++         _29 = opaque::<u32>(_30) -> [return: bb12, unwind unreachable];
+      }
+  
+      bb12: {
+-         StorageDead(_30);
+          StorageDead(_29);
+          StorageLive(_31);
+-         StorageLive(_32);
+-         _32 = ((*_3).0: u32);
+-         _31 = opaque::<u32>(move _32) -> [return: bb13, unwind unreachable];
++         _31 = opaque::<u32>(_30) -> [return: bb13, unwind unreachable];
+      }
+  
+      bb13: {
+-         StorageDead(_32);
+          StorageDead(_31);
+          _0 = const ();
+          StorageDead(_18);
+          StorageDead(_13);
+          StorageDead(_8);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff b/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..f627b4d5988
--- /dev/null
+++ b/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff
@@ -0,0 +1,191 @@
+- // MIR for `dereferences` before GVN
++ // MIR for `dereferences` after GVN
+  
+  fn dereferences(_1: &mut u32, _2: &impl Copy, _3: &S<u32>) -> () {
+      debug t => _1;
+      debug u => _2;
+      debug s => _3;
+      let mut _0: ();
+      let _4: ();
+      let mut _5: u32;
+      let _6: ();
+      let mut _7: u32;
+      let _8: *const u32;
+      let _9: ();
+      let mut _10: u32;
+      let _11: ();
+      let mut _12: u32;
+      let _14: ();
+      let mut _15: u32;
+      let _16: ();
+      let mut _17: u32;
+      let _19: ();
+      let mut _20: u32;
+      let _21: ();
+      let mut _22: u32;
+      let _23: ();
+      let mut _24: &u32;
+      let _25: ();
+      let mut _26: impl Copy;
+      let _27: ();
+      let mut _28: impl Copy;
+      let _29: ();
+      let mut _30: u32;
+      let _31: ();
+      let mut _32: u32;
+      scope 1 {
+          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 {
+                  debug z => _18;
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_4);
+          StorageLive(_5);
+          _5 = (*_1);
+          _4 = opaque::<u32>(move _5) -> [return: bb1, unwind continue];
+      }
+  
+      bb1: {
+          StorageDead(_5);
+          StorageDead(_4);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = (*_1);
+          _6 = opaque::<u32>(move _7) -> [return: bb2, unwind continue];
+      }
+  
+      bb2: {
+          StorageDead(_7);
+          StorageDead(_6);
+          StorageLive(_8);
+          _8 = &raw const (*_1);
+          StorageLive(_9);
+          StorageLive(_10);
+          _10 = (*_8);
+          _9 = opaque::<u32>(move _10) -> [return: bb3, unwind continue];
+      }
+  
+      bb3: {
+          StorageDead(_10);
+          StorageDead(_9);
+          StorageLive(_11);
+          StorageLive(_12);
+          _12 = (*_8);
+          _11 = opaque::<u32>(move _12) -> [return: bb4, unwind continue];
+      }
+  
+      bb4: {
+          StorageDead(_12);
+          StorageDead(_11);
+          StorageLive(_13);
+          _13 = &raw mut (*_1);
+          StorageLive(_14);
+          StorageLive(_15);
+          _15 = (*_13);
+          _14 = opaque::<u32>(move _15) -> [return: bb5, unwind continue];
+      }
+  
+      bb5: {
+          StorageDead(_15);
+          StorageDead(_14);
+          StorageLive(_16);
+          StorageLive(_17);
+          _17 = (*_13);
+          _16 = opaque::<u32>(move _17) -> [return: bb6, unwind continue];
+      }
+  
+      bb6: {
+          StorageDead(_17);
+          StorageDead(_16);
+          StorageLive(_18);
+          _18 = &(*_1);
+          StorageLive(_19);
+-         StorageLive(_20);
+          _20 = (*_18);
+-         _19 = opaque::<u32>(move _20) -> [return: bb7, unwind continue];
++         _19 = opaque::<u32>(_20) -> [return: bb7, unwind continue];
+      }
+  
+      bb7: {
+-         StorageDead(_20);
+          StorageDead(_19);
+          StorageLive(_21);
+-         StorageLive(_22);
+-         _22 = (*_18);
+-         _21 = opaque::<u32>(move _22) -> [return: bb8, unwind continue];
++         _21 = opaque::<u32>(_20) -> [return: bb8, unwind continue];
+      }
+  
+      bb8: {
+-         StorageDead(_22);
+          StorageDead(_21);
+          StorageLive(_23);
+          StorageLive(_24);
+          _24 = &(*_18);
+          _23 = opaque::<&u32>(move _24) -> [return: bb9, unwind continue];
+      }
+  
+      bb9: {
+          StorageDead(_24);
+          StorageDead(_23);
+          StorageLive(_25);
+          StorageLive(_26);
+          _26 = (*_2);
+          _25 = opaque::<impl Copy>(move _26) -> [return: bb10, unwind continue];
+      }
+  
+      bb10: {
+          StorageDead(_26);
+          StorageDead(_25);
+          StorageLive(_27);
+          StorageLive(_28);
+          _28 = (*_2);
+          _27 = opaque::<impl Copy>(move _28) -> [return: bb11, unwind continue];
+      }
+  
+      bb11: {
+          StorageDead(_28);
+          StorageDead(_27);
+          StorageLive(_29);
+-         StorageLive(_30);
+          _30 = ((*_3).0: u32);
+-         _29 = opaque::<u32>(move _30) -> [return: bb12, unwind continue];
++         _29 = opaque::<u32>(_30) -> [return: bb12, unwind continue];
+      }
+  
+      bb12: {
+-         StorageDead(_30);
+          StorageDead(_29);
+          StorageLive(_31);
+-         StorageLive(_32);
+-         _32 = ((*_3).0: u32);
+-         _31 = opaque::<u32>(move _32) -> [return: bb13, unwind continue];
++         _31 = opaque::<u32>(_30) -> [return: bb13, unwind continue];
+      }
+  
+      bb13: {
+-         StorageDead(_32);
+          StorageDead(_31);
+          _0 = const ();
+          StorageDead(_18);
+          StorageDead(_13);
+          StorageDead(_8);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.multiple_branches.GVN.panic-abort.diff b/tests/mir-opt/gvn.multiple_branches.GVN.panic-abort.diff
new file mode 100644
index 00000000000..0a66900283b
--- /dev/null
+++ b/tests/mir-opt/gvn.multiple_branches.GVN.panic-abort.diff
@@ -0,0 +1,198 @@
+- // MIR for `multiple_branches` before GVN
++ // MIR for `multiple_branches` after GVN
+  
+  fn multiple_branches(_1: bool, _2: u8, _3: u8) -> () {
+      debug t => _1;
+      debug x => _2;
+      debug y => _3;
+      let mut _0: ();
+      let _4: ();
+      let mut _5: bool;
+      let _6: ();
+      let mut _7: u8;
+      let mut _8: u8;
+      let mut _9: u8;
+      let _10: ();
+      let mut _11: u8;
+      let mut _12: u8;
+      let mut _13: u8;
+      let _14: ();
+      let mut _15: u8;
+      let mut _16: u8;
+      let mut _17: u8;
+      let _18: ();
+      let mut _19: u8;
+      let mut _20: u8;
+      let mut _21: u8;
+      let _22: ();
+      let mut _23: u8;
+      let mut _24: u8;
+      let mut _25: u8;
+      let mut _26: bool;
+      let _27: ();
+      let mut _28: u8;
+      let mut _29: u8;
+      let mut _30: u8;
+      let _31: ();
+      let mut _32: u8;
+      let mut _33: u8;
+      let mut _34: u8;
+  
+      bb0: {
+-         StorageLive(_4);
+-         StorageLive(_5);
+-         _5 = _1;
+-         switchInt(move _5) -> [0: bb4, otherwise: bb1];
++         switchInt(_1) -> [0: bb4, otherwise: bb1];
+      }
+  
+      bb1: {
+          StorageLive(_6);
+-         StorageLive(_7);
+-         StorageLive(_8);
+-         _8 = _2;
+-         StorageLive(_9);
+-         _9 = _3;
+-         _7 = Add(move _8, move _9);
+-         StorageDead(_9);
+-         StorageDead(_8);
+-         _6 = opaque::<u8>(move _7) -> [return: bb2, unwind unreachable];
++         _7 = Add(_2, _3);
++         _6 = opaque::<u8>(_7) -> [return: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+-         StorageDead(_7);
+          StorageDead(_6);
+          StorageLive(_10);
+-         StorageLive(_11);
+-         StorageLive(_12);
+-         _12 = _2;
+-         StorageLive(_13);
+-         _13 = _3;
+-         _11 = Add(move _12, move _13);
+-         StorageDead(_13);
+-         StorageDead(_12);
+-         _10 = opaque::<u8>(move _11) -> [return: bb3, unwind unreachable];
++         _10 = opaque::<u8>(_7) -> [return: bb3, unwind unreachable];
+      }
+  
+      bb3: {
+-         StorageDead(_11);
+          StorageDead(_10);
+-         _4 = const ();
+          goto -> bb7;
+      }
+  
+      bb4: {
+          StorageLive(_14);
+-         StorageLive(_15);
+-         StorageLive(_16);
+-         _16 = _2;
+-         StorageLive(_17);
+-         _17 = _3;
+-         _15 = Add(move _16, move _17);
+-         StorageDead(_17);
+-         StorageDead(_16);
+-         _14 = opaque::<u8>(move _15) -> [return: bb5, unwind unreachable];
++         _15 = Add(_2, _3);
++         _14 = opaque::<u8>(_15) -> [return: bb5, unwind unreachable];
+      }
+  
+      bb5: {
+-         StorageDead(_15);
+          StorageDead(_14);
+          StorageLive(_18);
+-         StorageLive(_19);
+-         StorageLive(_20);
+-         _20 = _2;
+-         StorageLive(_21);
+-         _21 = _3;
+-         _19 = Add(move _20, move _21);
+-         StorageDead(_21);
+-         StorageDead(_20);
+-         _18 = opaque::<u8>(move _19) -> [return: bb6, unwind unreachable];
++         _18 = opaque::<u8>(_15) -> [return: bb6, unwind unreachable];
+      }
+  
+      bb6: {
+-         StorageDead(_19);
+          StorageDead(_18);
+-         _4 = const ();
+          goto -> bb7;
+      }
+  
+      bb7: {
+-         StorageDead(_5);
+-         StorageDead(_4);
+          StorageLive(_22);
+-         StorageLive(_23);
+-         StorageLive(_24);
+-         _24 = _2;
+-         StorageLive(_25);
+-         _25 = _3;
+-         _23 = Add(move _24, move _25);
+-         StorageDead(_25);
+-         StorageDead(_24);
+-         _22 = opaque::<u8>(move _23) -> [return: bb8, unwind unreachable];
++         _23 = Add(_2, _3);
++         _22 = opaque::<u8>(_23) -> [return: bb8, unwind unreachable];
+      }
+  
+      bb8: {
+-         StorageDead(_23);
+          StorageDead(_22);
+-         StorageLive(_26);
+-         _26 = _1;
+-         switchInt(move _26) -> [0: bb11, otherwise: bb9];
++         switchInt(_1) -> [0: bb11, otherwise: bb9];
+      }
+  
+      bb9: {
+          StorageLive(_27);
+-         StorageLive(_28);
+-         StorageLive(_29);
+-         _29 = _2;
+-         StorageLive(_30);
+-         _30 = _3;
+-         _28 = Add(move _29, move _30);
+-         StorageDead(_30);
+-         StorageDead(_29);
+-         _27 = opaque::<u8>(move _28) -> [return: bb10, unwind unreachable];
++         _27 = opaque::<u8>(_23) -> [return: bb10, unwind unreachable];
+      }
+  
+      bb10: {
+-         StorageDead(_28);
+          StorageDead(_27);
+          _0 = const ();
+          goto -> bb13;
+      }
+  
+      bb11: {
+          StorageLive(_31);
+-         StorageLive(_32);
+-         StorageLive(_33);
+-         _33 = _2;
+-         StorageLive(_34);
+-         _34 = _3;
+-         _32 = Add(move _33, move _34);
+-         StorageDead(_34);
+-         StorageDead(_33);
+-         _31 = opaque::<u8>(move _32) -> [return: bb12, unwind unreachable];
++         _31 = opaque::<u8>(_23) -> [return: bb12, unwind unreachable];
+      }
+  
+      bb12: {
+-         StorageDead(_32);
+          StorageDead(_31);
+          _0 = const ();
+          goto -> bb13;
+      }
+  
+      bb13: {
+-         StorageDead(_26);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.multiple_branches.GVN.panic-unwind.diff b/tests/mir-opt/gvn.multiple_branches.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..0199f2720a9
--- /dev/null
+++ b/tests/mir-opt/gvn.multiple_branches.GVN.panic-unwind.diff
@@ -0,0 +1,198 @@
+- // MIR for `multiple_branches` before GVN
++ // MIR for `multiple_branches` after GVN
+  
+  fn multiple_branches(_1: bool, _2: u8, _3: u8) -> () {
+      debug t => _1;
+      debug x => _2;
+      debug y => _3;
+      let mut _0: ();
+      let _4: ();
+      let mut _5: bool;
+      let _6: ();
+      let mut _7: u8;
+      let mut _8: u8;
+      let mut _9: u8;
+      let _10: ();
+      let mut _11: u8;
+      let mut _12: u8;
+      let mut _13: u8;
+      let _14: ();
+      let mut _15: u8;
+      let mut _16: u8;
+      let mut _17: u8;
+      let _18: ();
+      let mut _19: u8;
+      let mut _20: u8;
+      let mut _21: u8;
+      let _22: ();
+      let mut _23: u8;
+      let mut _24: u8;
+      let mut _25: u8;
+      let mut _26: bool;
+      let _27: ();
+      let mut _28: u8;
+      let mut _29: u8;
+      let mut _30: u8;
+      let _31: ();
+      let mut _32: u8;
+      let mut _33: u8;
+      let mut _34: u8;
+  
+      bb0: {
+-         StorageLive(_4);
+-         StorageLive(_5);
+-         _5 = _1;
+-         switchInt(move _5) -> [0: bb4, otherwise: bb1];
++         switchInt(_1) -> [0: bb4, otherwise: bb1];
+      }
+  
+      bb1: {
+          StorageLive(_6);
+-         StorageLive(_7);
+-         StorageLive(_8);
+-         _8 = _2;
+-         StorageLive(_9);
+-         _9 = _3;
+-         _7 = Add(move _8, move _9);
+-         StorageDead(_9);
+-         StorageDead(_8);
+-         _6 = opaque::<u8>(move _7) -> [return: bb2, unwind continue];
++         _7 = Add(_2, _3);
++         _6 = opaque::<u8>(_7) -> [return: bb2, unwind continue];
+      }
+  
+      bb2: {
+-         StorageDead(_7);
+          StorageDead(_6);
+          StorageLive(_10);
+-         StorageLive(_11);
+-         StorageLive(_12);
+-         _12 = _2;
+-         StorageLive(_13);
+-         _13 = _3;
+-         _11 = Add(move _12, move _13);
+-         StorageDead(_13);
+-         StorageDead(_12);
+-         _10 = opaque::<u8>(move _11) -> [return: bb3, unwind continue];
++         _10 = opaque::<u8>(_7) -> [return: bb3, unwind continue];
+      }
+  
+      bb3: {
+-         StorageDead(_11);
+          StorageDead(_10);
+-         _4 = const ();
+          goto -> bb7;
+      }
+  
+      bb4: {
+          StorageLive(_14);
+-         StorageLive(_15);
+-         StorageLive(_16);
+-         _16 = _2;
+-         StorageLive(_17);
+-         _17 = _3;
+-         _15 = Add(move _16, move _17);
+-         StorageDead(_17);
+-         StorageDead(_16);
+-         _14 = opaque::<u8>(move _15) -> [return: bb5, unwind continue];
++         _15 = Add(_2, _3);
++         _14 = opaque::<u8>(_15) -> [return: bb5, unwind continue];
+      }
+  
+      bb5: {
+-         StorageDead(_15);
+          StorageDead(_14);
+          StorageLive(_18);
+-         StorageLive(_19);
+-         StorageLive(_20);
+-         _20 = _2;
+-         StorageLive(_21);
+-         _21 = _3;
+-         _19 = Add(move _20, move _21);
+-         StorageDead(_21);
+-         StorageDead(_20);
+-         _18 = opaque::<u8>(move _19) -> [return: bb6, unwind continue];
++         _18 = opaque::<u8>(_15) -> [return: bb6, unwind continue];
+      }
+  
+      bb6: {
+-         StorageDead(_19);
+          StorageDead(_18);
+-         _4 = const ();
+          goto -> bb7;
+      }
+  
+      bb7: {
+-         StorageDead(_5);
+-         StorageDead(_4);
+          StorageLive(_22);
+-         StorageLive(_23);
+-         StorageLive(_24);
+-         _24 = _2;
+-         StorageLive(_25);
+-         _25 = _3;
+-         _23 = Add(move _24, move _25);
+-         StorageDead(_25);
+-         StorageDead(_24);
+-         _22 = opaque::<u8>(move _23) -> [return: bb8, unwind continue];
++         _23 = Add(_2, _3);
++         _22 = opaque::<u8>(_23) -> [return: bb8, unwind continue];
+      }
+  
+      bb8: {
+-         StorageDead(_23);
+          StorageDead(_22);
+-         StorageLive(_26);
+-         _26 = _1;
+-         switchInt(move _26) -> [0: bb11, otherwise: bb9];
++         switchInt(_1) -> [0: bb11, otherwise: bb9];
+      }
+  
+      bb9: {
+          StorageLive(_27);
+-         StorageLive(_28);
+-         StorageLive(_29);
+-         _29 = _2;
+-         StorageLive(_30);
+-         _30 = _3;
+-         _28 = Add(move _29, move _30);
+-         StorageDead(_30);
+-         StorageDead(_29);
+-         _27 = opaque::<u8>(move _28) -> [return: bb10, unwind continue];
++         _27 = opaque::<u8>(_23) -> [return: bb10, unwind continue];
+      }
+  
+      bb10: {
+-         StorageDead(_28);
+          StorageDead(_27);
+          _0 = const ();
+          goto -> bb13;
+      }
+  
+      bb11: {
+          StorageLive(_31);
+-         StorageLive(_32);
+-         StorageLive(_33);
+-         _33 = _2;
+-         StorageLive(_34);
+-         _34 = _3;
+-         _32 = Add(move _33, move _34);
+-         StorageDead(_34);
+-         StorageDead(_33);
+-         _31 = opaque::<u8>(move _32) -> [return: bb12, unwind continue];
++         _31 = opaque::<u8>(_23) -> [return: bb12, unwind continue];
+      }
+  
+      bb12: {
+-         StorageDead(_32);
+          StorageDead(_31);
+          _0 = const ();
+          goto -> bb13;
+      }
+  
+      bb13: {
+-         StorageDead(_26);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.references.GVN.panic-abort.diff b/tests/mir-opt/gvn.references.GVN.panic-abort.diff
new file mode 100644
index 00000000000..b7ad4ab1fd3
--- /dev/null
+++ b/tests/mir-opt/gvn.references.GVN.panic-abort.diff
@@ -0,0 +1,105 @@
+- // MIR for `references` before GVN
++ // MIR for `references` after GVN
+  
+  fn references(_1: impl Sized) -> () {
+      debug x => _1;
+      let mut _0: ();
+      let _2: ();
+      let mut _3: &impl Sized;
+      let _4: ();
+      let mut _5: &impl Sized;
+      let _6: ();
+      let mut _7: &mut impl Sized;
+      let _8: ();
+      let mut _9: &mut impl Sized;
+      let _10: ();
+      let mut _11: *const impl Sized;
+      let _12: ();
+      let mut _13: *const impl Sized;
+      let _14: ();
+      let mut _15: *mut impl Sized;
+      let _16: ();
+      let mut _17: *mut impl Sized;
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = &_1;
+          _2 = opaque::<&impl Sized>(move _3) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_3);
+          StorageDead(_2);
+          StorageLive(_4);
+          StorageLive(_5);
+          _5 = &_1;
+          _4 = opaque::<&impl Sized>(move _5) -> [return: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+          StorageDead(_5);
+          StorageDead(_4);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = &mut _1;
+          _6 = opaque::<&mut impl Sized>(move _7) -> [return: bb3, unwind unreachable];
+      }
+  
+      bb3: {
+          StorageDead(_7);
+          StorageDead(_6);
+          StorageLive(_8);
+          StorageLive(_9);
+          _9 = &mut _1;
+          _8 = opaque::<&mut impl Sized>(move _9) -> [return: bb4, unwind unreachable];
+      }
+  
+      bb4: {
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageLive(_10);
+          StorageLive(_11);
+          _11 = &raw const _1;
+          _10 = opaque::<*const impl Sized>(move _11) -> [return: bb5, unwind unreachable];
+      }
+  
+      bb5: {
+          StorageDead(_11);
+          StorageDead(_10);
+          StorageLive(_12);
+          StorageLive(_13);
+          _13 = &raw const _1;
+          _12 = opaque::<*const impl Sized>(move _13) -> [return: bb6, unwind unreachable];
+      }
+  
+      bb6: {
+          StorageDead(_13);
+          StorageDead(_12);
+          StorageLive(_14);
+          StorageLive(_15);
+          _15 = &raw mut _1;
+          _14 = opaque::<*mut impl Sized>(move _15) -> [return: bb7, unwind unreachable];
+      }
+  
+      bb7: {
+          StorageDead(_15);
+          StorageDead(_14);
+          StorageLive(_16);
+          StorageLive(_17);
+          _17 = &raw mut _1;
+          _16 = opaque::<*mut impl Sized>(move _17) -> [return: bb8, unwind unreachable];
+      }
+  
+      bb8: {
+          StorageDead(_17);
+          StorageDead(_16);
+          _0 = const ();
+          drop(_1) -> [return: bb9, unwind unreachable];
+      }
+  
+      bb9: {
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.references.GVN.panic-unwind.diff b/tests/mir-opt/gvn.references.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..08ed4c629a6
--- /dev/null
+++ b/tests/mir-opt/gvn.references.GVN.panic-unwind.diff
@@ -0,0 +1,113 @@
+- // MIR for `references` before GVN
++ // MIR for `references` after GVN
+  
+  fn references(_1: impl Sized) -> () {
+      debug x => _1;
+      let mut _0: ();
+      let _2: ();
+      let mut _3: &impl Sized;
+      let _4: ();
+      let mut _5: &impl Sized;
+      let _6: ();
+      let mut _7: &mut impl Sized;
+      let _8: ();
+      let mut _9: &mut impl Sized;
+      let _10: ();
+      let mut _11: *const impl Sized;
+      let _12: ();
+      let mut _13: *const impl Sized;
+      let _14: ();
+      let mut _15: *mut impl Sized;
+      let _16: ();
+      let mut _17: *mut impl Sized;
+  
+      bb0: {
+          StorageLive(_2);
+          StorageLive(_3);
+          _3 = &_1;
+          _2 = opaque::<&impl Sized>(move _3) -> [return: bb1, unwind: bb10];
+      }
+  
+      bb1: {
+          StorageDead(_3);
+          StorageDead(_2);
+          StorageLive(_4);
+          StorageLive(_5);
+          _5 = &_1;
+          _4 = opaque::<&impl Sized>(move _5) -> [return: bb2, unwind: bb10];
+      }
+  
+      bb2: {
+          StorageDead(_5);
+          StorageDead(_4);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = &mut _1;
+          _6 = opaque::<&mut impl Sized>(move _7) -> [return: bb3, unwind: bb10];
+      }
+  
+      bb3: {
+          StorageDead(_7);
+          StorageDead(_6);
+          StorageLive(_8);
+          StorageLive(_9);
+          _9 = &mut _1;
+          _8 = opaque::<&mut impl Sized>(move _9) -> [return: bb4, unwind: bb10];
+      }
+  
+      bb4: {
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageLive(_10);
+          StorageLive(_11);
+          _11 = &raw const _1;
+          _10 = opaque::<*const impl Sized>(move _11) -> [return: bb5, unwind: bb10];
+      }
+  
+      bb5: {
+          StorageDead(_11);
+          StorageDead(_10);
+          StorageLive(_12);
+          StorageLive(_13);
+          _13 = &raw const _1;
+          _12 = opaque::<*const impl Sized>(move _13) -> [return: bb6, unwind: bb10];
+      }
+  
+      bb6: {
+          StorageDead(_13);
+          StorageDead(_12);
+          StorageLive(_14);
+          StorageLive(_15);
+          _15 = &raw mut _1;
+          _14 = opaque::<*mut impl Sized>(move _15) -> [return: bb7, unwind: bb10];
+      }
+  
+      bb7: {
+          StorageDead(_15);
+          StorageDead(_14);
+          StorageLive(_16);
+          StorageLive(_17);
+          _17 = &raw mut _1;
+          _16 = opaque::<*mut impl Sized>(move _17) -> [return: bb8, unwind: bb10];
+      }
+  
+      bb8: {
+          StorageDead(_17);
+          StorageDead(_16);
+          _0 = const ();
+          drop(_1) -> [return: bb9, unwind: bb11];
+      }
+  
+      bb9: {
+          return;
+      }
+  
+      bb10 (cleanup): {
+          drop(_1) -> [return: bb11, unwind terminate(cleanup)];
+      }
+  
+      bb11 (cleanup): {
+          resume;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff b/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
new file mode 100644
index 00000000000..4c29523d6b2
--- /dev/null
+++ b/tests/mir-opt/gvn.repeated_index.GVN.panic-abort.diff
@@ -0,0 +1,76 @@
+- // MIR for `repeated_index` before GVN
++ // MIR for `repeated_index` after GVN
+  
+  fn repeated_index(_1: T, _2: usize) -> () {
+      debug x => _1;
+      debug idx => _2;
+      let mut _0: ();
+      let _3: [T; N];
+      let mut _4: T;
+      let _5: ();
+      let mut _6: T;
+      let _7: usize;
+      let mut _8: usize;
+      let mut _9: bool;
+      let _10: ();
+      let mut _11: T;
+      let _12: usize;
+      let mut _13: usize;
+      let mut _14: bool;
+      scope 1 {
+          debug a => _3;
+      }
+  
+      bb0: {
+          StorageLive(_3);
+-         StorageLive(_4);
+-         _4 = _1;
+-         _3 = [move _4; N];
+-         StorageDead(_4);
++         _3 = [_1; N];
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 0_usize;
+          _8 = Len(_3);
+-         _9 = Lt(_7, _8);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> [success: bb1, unwind unreachable];
++         _9 = Lt(const 0_usize, _8);
++         assert(move _9, "index out of bounds: the length is {} but the index is {}", _8, const 0_usize) -> [success: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          _6 = _3[_7];
+          _5 = opaque::<T>(move _6) -> [return: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+          StorageDead(_6);
+          StorageDead(_7);
+          StorageDead(_5);
+          StorageLive(_10);
+          StorageLive(_11);
+          StorageLive(_12);
+          _12 = _2;
+-         _13 = Len(_3);
+-         _14 = Lt(_12, _13);
+-         assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, _12) -> [success: bb3, unwind unreachable];
++         _14 = Lt(_2, _8);
++         assert(move _14, "index out of bounds: the length is {} but the index is {}", _8, _2) -> [success: bb3, unwind unreachable];
+      }
+  
+      bb3: {
+          _11 = _3[_12];
+          _10 = opaque::<T>(move _11) -> [return: bb4, unwind unreachable];
+      }
+  
+      bb4: {
+          StorageDead(_11);
+          StorageDead(_12);
+          StorageDead(_10);
+          _0 = const ();
+          StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff b/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..e44f54cf3cf
--- /dev/null
+++ b/tests/mir-opt/gvn.repeated_index.GVN.panic-unwind.diff
@@ -0,0 +1,76 @@
+- // MIR for `repeated_index` before GVN
++ // MIR for `repeated_index` after GVN
+  
+  fn repeated_index(_1: T, _2: usize) -> () {
+      debug x => _1;
+      debug idx => _2;
+      let mut _0: ();
+      let _3: [T; N];
+      let mut _4: T;
+      let _5: ();
+      let mut _6: T;
+      let _7: usize;
+      let mut _8: usize;
+      let mut _9: bool;
+      let _10: ();
+      let mut _11: T;
+      let _12: usize;
+      let mut _13: usize;
+      let mut _14: bool;
+      scope 1 {
+          debug a => _3;
+      }
+  
+      bb0: {
+          StorageLive(_3);
+-         StorageLive(_4);
+-         _4 = _1;
+-         _3 = [move _4; N];
+-         StorageDead(_4);
++         _3 = [_1; N];
+          StorageLive(_5);
+          StorageLive(_6);
+          StorageLive(_7);
+          _7 = const 0_usize;
+          _8 = Len(_3);
+-         _9 = Lt(_7, _8);
+-         assert(move _9, "index out of bounds: the length is {} but the index is {}", move _8, _7) -> [success: bb1, unwind continue];
++         _9 = Lt(const 0_usize, _8);
++         assert(move _9, "index out of bounds: the length is {} but the index is {}", _8, const 0_usize) -> [success: bb1, unwind continue];
+      }
+  
+      bb1: {
+          _6 = _3[_7];
+          _5 = opaque::<T>(move _6) -> [return: bb2, unwind continue];
+      }
+  
+      bb2: {
+          StorageDead(_6);
+          StorageDead(_7);
+          StorageDead(_5);
+          StorageLive(_10);
+          StorageLive(_11);
+          StorageLive(_12);
+          _12 = _2;
+-         _13 = Len(_3);
+-         _14 = Lt(_12, _13);
+-         assert(move _14, "index out of bounds: the length is {} but the index is {}", move _13, _12) -> [success: bb3, unwind continue];
++         _14 = Lt(_2, _8);
++         assert(move _14, "index out of bounds: the length is {} but the index is {}", _8, _2) -> [success: bb3, unwind continue];
+      }
+  
+      bb3: {
+          _11 = _3[_12];
+          _10 = opaque::<T>(move _11) -> [return: bb4, unwind continue];
+      }
+  
+      bb4: {
+          StorageDead(_11);
+          StorageDead(_12);
+          StorageDead(_10);
+          _0 = const ();
+          StorageDead(_3);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.rs b/tests/mir-opt/gvn.rs
new file mode 100644
index 00000000000..a85e2ae368b
--- /dev/null
+++ b/tests/mir-opt/gvn.rs
@@ -0,0 +1,253 @@
+// unit-test: GVN
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+
+#![feature(raw_ref_op)]
+#![feature(rustc_attrs)]
+#![allow(unconditional_panic)]
+
+struct S<T>(T);
+
+fn subexpression_elimination(x: u64, y: u64, mut z: u64) {
+    opaque(x + y);
+    opaque(x * y);
+    opaque(x - y);
+    opaque(x / y);
+    opaque(x % y);
+    opaque(x & y);
+    opaque(x | y);
+    opaque(x ^ y);
+    opaque(x << y);
+    opaque(x >> y);
+    opaque(x as u32);
+    opaque(x as f32);
+    opaque(S(x));
+    opaque(S(x).0);
+
+    // Those are duplicates to substitute somehow.
+    opaque((x + y) + z);
+    opaque((x * y) + z);
+    opaque((x - y) + z);
+    opaque((x / y) + z);
+    opaque((x % y) + z);
+    opaque((x & y) + z);
+    opaque((x | y) + z);
+    opaque((x ^ y) + z);
+    opaque((x << y) + z);
+    opaque((x >> y) + z);
+    opaque(S(x));
+    opaque(S(x).0);
+
+    // We can substitute through an immutable reference too.
+    let a = &z;
+    opaque(*a + x);
+    opaque(*a + x);
+
+    // But not through a mutable reference or a pointer.
+    let b = &mut z;
+    opaque(*b + x);
+    opaque(*b + x);
+    unsafe {
+        let c = &raw const z;
+        opaque(*c + x);
+        opaque(*c + x);
+        let d = &raw mut z;
+        opaque(*d + x);
+        opaque(*d + x);
+    }
+
+    // We can substitute again, but not with the earlier computations.
+    // Important: `e` is not `a`!
+    let e = &z;
+    opaque(*e + x);
+    opaque(*e + x);
+
+}
+
+fn wrap_unwrap<T: Copy>(x: T) -> T {
+    match Some(x) {
+        Some(y) => y,
+        None => panic!(),
+    }
+}
+
+fn repeated_index<T: Copy, const N: usize>(x: T, idx: usize) {
+    let a = [x; N];
+    opaque(a[0]);
+    opaque(a[idx]);
+}
+
+fn arithmetic(x: u64) {
+    opaque(x + 0);
+    opaque(x - 0);
+    opaque(x * 0);
+    opaque(x * 1);
+    opaque(x / 0);
+    opaque(x / 1);
+    opaque(0 / x);
+    opaque(1 / x);
+    opaque(x % 0);
+    opaque(x % 1);
+    opaque(0 % x);
+    opaque(1 % x);
+    opaque(x & 0);
+    opaque(x | 0);
+    opaque(x ^ 0);
+    opaque(x >> 0);
+    opaque(x << 0);
+}
+
+#[rustc_inherit_overflow_checks]
+fn arithmetic_checked(x: u64) {
+    opaque(x + 0);
+    opaque(x - 0);
+    opaque(x * 0);
+    opaque(x * 1);
+    opaque(x / 0);
+    opaque(x / 1);
+    opaque(0 / x);
+    opaque(1 / x);
+    opaque(x % 0);
+    opaque(x % 1);
+    opaque(0 % x);
+    opaque(1 % x);
+    opaque(x & 0);
+    opaque(x | 0);
+    opaque(x ^ 0);
+    opaque(x >> 0);
+    opaque(x << 0);
+}
+
+fn arithmetic_float(x: f64) {
+    opaque(x + 0.);
+    opaque(x - 0.);
+    opaque(x * 0.);
+    opaque(x / 0.);
+    opaque(0. / x);
+    opaque(x % 0.);
+    opaque(0. % x);
+    // Those are not simplifiable to `true`/`false`, thanks to NaNs.
+    opaque(x == x);
+    opaque(x != x);
+}
+
+fn cast() {
+    let i = 1_i64;
+    let u = 1_u64;
+    let f = 1_f64;
+    opaque(i as u8);
+    opaque(i as u16);
+    opaque(i as u32);
+    opaque(i as u64);
+    opaque(i as i8);
+    opaque(i as i16);
+    opaque(i as i32);
+    opaque(i as i64);
+    opaque(i as f32);
+    opaque(i as f64);
+    opaque(u as u8);
+    opaque(u as u16);
+    opaque(u as u32);
+    opaque(u as u64);
+    opaque(u as i8);
+    opaque(u as i16);
+    opaque(u as i32);
+    opaque(u as i64);
+    opaque(u as f32);
+    opaque(u as f64);
+    opaque(f as u8);
+    opaque(f as u16);
+    opaque(f as u32);
+    opaque(f as u64);
+    opaque(f as i8);
+    opaque(f as i16);
+    opaque(f as i32);
+    opaque(f as i64);
+    opaque(f as f32);
+    opaque(f as f64);
+}
+
+fn multiple_branches(t: bool, x: u8, y: u8) {
+    if t {
+        opaque(x + y); // a
+        opaque(x + y); // should reuse a
+    } else {
+        opaque(x + y); // b
+        opaque(x + y); // shoud reuse b
+    }
+    opaque(x + y); // c
+    if t {
+        opaque(x + y); // should reuse c
+    } else {
+        opaque(x + y); // should reuse c
+    }
+}
+
+fn references(mut x: impl Sized) {
+    opaque(&x);
+    opaque(&x); // should not reuse a
+    opaque(&mut x);
+    opaque(&mut x); // should not reuse a
+    opaque(&raw const x);
+    opaque(&raw const x); // should not reuse a
+    opaque(&raw mut x);
+    opaque(&raw mut x); // should not reuse a
+}
+
+fn dereferences(t: &mut u32, u: &impl Copy, s: &S<u32>) {
+    opaque(*t);
+    opaque(*t); // this cannot reuse a, as x is &mut.
+    let z = &raw const *t;
+    unsafe { opaque(*z) };
+    unsafe { opaque(*z) }; // this cannot reuse a, as x is *const.
+    let z = &raw mut *t;
+    unsafe { opaque(*z) };
+    unsafe { opaque(*z) }; // this cannot reuse a, as x is *mut.
+    let z = &*t;
+    opaque(*z);
+    opaque(*z); // this can reuse, as `z` is immutable ref, Freeze and Copy.
+    opaque(&*z); // but not for a reborrow.
+    opaque(*u);
+    opaque(*u); // this cannot reuse, as `z` is not Freeze.
+    opaque(s.0);
+    opaque(s.0); // *s is not Copy, by (*s).0 is, so we can reuse.
+}
+
+fn slices() {
+    let s = "my favourite slice"; // This is a `Const::Slice` in MIR.
+    opaque(s);
+    let t = s; // This should be the same pointer, so cannot be a `Const::Slice`.
+    opaque(t);
+    assert_eq!(s.as_ptr(), t.as_ptr());
+    let u = unsafe { std::mem::transmute::<&str, &[u8]>(s) };
+    opaque(u);
+    assert_eq!(s.as_ptr(), u.as_ptr());
+}
+
+fn main() {
+    subexpression_elimination(2, 4, 5);
+    wrap_unwrap(5);
+    repeated_index::<u32, 7>(5, 3);
+    arithmetic(5);
+    arithmetic_checked(5);
+    arithmetic_float(5.);
+    cast();
+    multiple_branches(true, 5, 9);
+    references(5);
+    dereferences(&mut 5, &6, &S(7));
+    slices();
+}
+
+#[inline(never)]
+fn opaque(_: impl Sized) {}
+
+// EMIT_MIR gvn.subexpression_elimination.GVN.diff
+// EMIT_MIR gvn.wrap_unwrap.GVN.diff
+// EMIT_MIR gvn.repeated_index.GVN.diff
+// EMIT_MIR gvn.arithmetic.GVN.diff
+// EMIT_MIR gvn.arithmetic_checked.GVN.diff
+// EMIT_MIR gvn.arithmetic_float.GVN.diff
+// EMIT_MIR gvn.cast.GVN.diff
+// EMIT_MIR gvn.multiple_branches.GVN.diff
+// EMIT_MIR gvn.references.GVN.diff
+// EMIT_MIR gvn.dereferences.GVN.diff
+// EMIT_MIR gvn.slices.GVN.diff
diff --git a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
new file mode 100644
index 00000000000..de3d28d0575
--- /dev/null
+++ b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
@@ -0,0 +1,275 @@
+- // MIR for `slices` before GVN
++ // MIR for `slices` after GVN
+  
+  fn slices() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let _2: ();
+      let mut _3: &str;
+      let _5: ();
+      let mut _6: &str;
+      let _7: ();
+      let mut _8: (&*const u8, &*const u8);
+      let mut _9: &*const u8;
+      let _10: *const u8;
+      let mut _11: &str;
+      let mut _12: &*const u8;
+      let _13: *const u8;
+      let mut _14: &str;
+      let mut _17: bool;
+      let mut _18: *const u8;
+      let mut _19: *const u8;
+      let mut _20: !;
+      let _22: !;
+      let mut _23: core::panicking::AssertKind;
+      let mut _24: &*const u8;
+      let _25: &*const u8;
+      let mut _26: &*const u8;
+      let _27: &*const u8;
+      let mut _28: std::option::Option<std::fmt::Arguments<'_>>;
+      let mut _30: &str;
+      let _31: ();
+      let mut _32: &[u8];
+      let _33: ();
+      let mut _34: (&*const u8, &*const u8);
+      let mut _35: &*const u8;
+      let _36: *const u8;
+      let mut _37: &str;
+      let mut _38: &*const u8;
+      let _39: *const u8;
+      let mut _40: &[u8];
+      let mut _43: bool;
+      let mut _44: *const u8;
+      let mut _45: *const u8;
+      let mut _46: !;
+      let _48: !;
+      let mut _49: core::panicking::AssertKind;
+      let mut _50: &*const u8;
+      let _51: &*const u8;
+      let mut _52: &*const u8;
+      let _53: &*const u8;
+      let mut _54: std::option::Option<std::fmt::Arguments<'_>>;
+      scope 1 {
+          debug s => _1;
+          let _4: &str;
+          scope 2 {
+              debug t => _4;
+              let _15: &*const u8;
+              let _16: &*const u8;
+              let _29: &[u8];
+              scope 3 {
+                  debug left_val => _15;
+                  debug right_val => _16;
+                  let _21: core::panicking::AssertKind;
+                  scope 4 {
+                      debug kind => _21;
+                  }
+              }
+              scope 5 {
+                  debug u => _29;
+                  let _41: &*const u8;
+                  let _42: &*const u8;
+                  scope 7 {
+                      debug left_val => _41;
+                      debug right_val => _42;
+                      let _47: core::panicking::AssertKind;
+                      scope 8 {
+                          debug kind => _47;
+                      }
+                  }
+              }
+              scope 6 {
+              }
+          }
+      }
+  
+      bb0: {
+-         StorageLive(_1);
+          _1 = const "my favourite slice";
+          StorageLive(_2);
+-         StorageLive(_3);
+-         _3 = _1;
+-         _2 = opaque::<&str>(move _3) -> [return: bb1, unwind unreachable];
++         _2 = opaque::<&str>(_1) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+-         StorageDead(_3);
+          StorageDead(_2);
+          StorageLive(_4);
+          _4 = _1;
+          StorageLive(_5);
+-         StorageLive(_6);
+-         _6 = _4;
+-         _5 = opaque::<&str>(move _6) -> [return: bb2, unwind unreachable];
++         _5 = opaque::<&str>(_1) -> [return: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+-         StorageDead(_6);
+          StorageDead(_5);
+-         StorageLive(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+          StorageLive(_10);
+          StorageLive(_11);
+          _11 = &(*_1);
+          _10 = core::str::<impl str>::as_ptr(move _11) -> [return: bb3, unwind unreachable];
+      }
+  
+      bb3: {
+          StorageDead(_11);
+          _9 = &_10;
+          StorageLive(_12);
+          StorageLive(_13);
+          StorageLive(_14);
+          _14 = &(*_4);
+          _13 = core::str::<impl str>::as_ptr(move _14) -> [return: bb4, unwind unreachable];
+      }
+  
+      bb4: {
+          StorageDead(_14);
+          _12 = &_13;
+          _8 = (move _9, move _12);
+          StorageDead(_12);
+          StorageDead(_9);
+          StorageLive(_15);
+          _15 = (_8.0: &*const u8);
+          StorageLive(_16);
+          _16 = (_8.1: &*const u8);
+          StorageLive(_17);
+          StorageLive(_18);
+          _18 = (*_15);
+          StorageLive(_19);
+          _19 = (*_16);
+          _17 = Eq(move _18, move _19);
+          switchInt(move _17) -> [0: bb6, otherwise: bb5];
+      }
+  
+      bb5: {
+          StorageDead(_19);
+          StorageDead(_18);
+-         _7 = const ();
+          StorageDead(_17);
+          StorageDead(_16);
+          StorageDead(_15);
+          StorageDead(_13);
+          StorageDead(_10);
+          StorageDead(_8);
+-         StorageDead(_7);
+-         StorageLive(_29);
+          StorageLive(_30);
+          _30 = &(*_1);
+          _29 = move _30 as &[u8] (Transmute);
+          StorageDead(_30);
+          StorageLive(_31);
+-         StorageLive(_32);
+-         _32 = _29;
+-         _31 = opaque::<&[u8]>(move _32) -> [return: bb7, unwind unreachable];
++         _31 = opaque::<&[u8]>(_29) -> [return: bb7, unwind unreachable];
+      }
+  
+      bb6: {
+          StorageDead(_19);
+          StorageDead(_18);
+-         StorageLive(_21);
+          _21 = core::panicking::AssertKind::Eq;
+          StorageLive(_22);
+-         StorageLive(_23);
+-         _23 = move _21;
+          StorageLive(_24);
+          StorageLive(_25);
+          _25 = &(*_15);
+          _24 = &(*_25);
+          StorageLive(_26);
+          StorageLive(_27);
+          _27 = &(*_16);
+          _26 = &(*_27);
+          StorageLive(_28);
+          _28 = Option::<Arguments<'_>>::None;
+-         _22 = core::panicking::assert_failed::<*const u8, *const u8>(move _23, move _24, move _26, move _28) -> unwind unreachable;
++         _22 = core::panicking::assert_failed::<*const u8, *const u8>(_21, move _24, move _26, move _28) -> unwind unreachable;
+      }
+  
+      bb7: {
+-         StorageDead(_32);
+          StorageDead(_31);
+-         StorageLive(_33);
+          StorageLive(_34);
+          StorageLive(_35);
+          StorageLive(_36);
+          StorageLive(_37);
+          _37 = &(*_1);
+          _36 = core::str::<impl str>::as_ptr(move _37) -> [return: bb8, unwind unreachable];
+      }
+  
+      bb8: {
+          StorageDead(_37);
+          _35 = &_36;
+          StorageLive(_38);
+          StorageLive(_39);
+          StorageLive(_40);
+          _40 = &(*_29);
+          _39 = core::slice::<impl [u8]>::as_ptr(move _40) -> [return: bb9, unwind unreachable];
+      }
+  
+      bb9: {
+          StorageDead(_40);
+          _38 = &_39;
+          _34 = (move _35, move _38);
+          StorageDead(_38);
+          StorageDead(_35);
+          StorageLive(_41);
+          _41 = (_34.0: &*const u8);
+          StorageLive(_42);
+          _42 = (_34.1: &*const u8);
+          StorageLive(_43);
+          StorageLive(_44);
+          _44 = (*_41);
+          StorageLive(_45);
+          _45 = (*_42);
+          _43 = Eq(move _44, move _45);
+          switchInt(move _43) -> [0: bb11, otherwise: bb10];
+      }
+  
+      bb10: {
+          StorageDead(_45);
+          StorageDead(_44);
+-         _33 = const ();
+          StorageDead(_43);
+          StorageDead(_42);
+          StorageDead(_41);
+          StorageDead(_39);
+          StorageDead(_36);
+          StorageDead(_34);
+-         StorageDead(_33);
+          _0 = const ();
+-         StorageDead(_29);
+          StorageDead(_4);
+-         StorageDead(_1);
+          return;
+      }
+  
+      bb11: {
+          StorageDead(_45);
+          StorageDead(_44);
+-         StorageLive(_47);
+          _47 = core::panicking::AssertKind::Eq;
+          StorageLive(_48);
+-         StorageLive(_49);
+-         _49 = move _47;
+          StorageLive(_50);
+          StorageLive(_51);
+          _51 = &(*_41);
+          _50 = &(*_51);
+          StorageLive(_52);
+          StorageLive(_53);
+          _53 = &(*_42);
+          _52 = &(*_53);
+          StorageLive(_54);
+          _54 = Option::<Arguments<'_>>::None;
+-         _48 = core::panicking::assert_failed::<*const u8, *const u8>(move _49, move _50, move _52, move _54) -> unwind unreachable;
++         _48 = core::panicking::assert_failed::<*const u8, *const u8>(_47, move _50, move _52, move _54) -> unwind unreachable;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..f22bb25436f
--- /dev/null
+++ b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
@@ -0,0 +1,275 @@
+- // MIR for `slices` before GVN
++ // MIR for `slices` after GVN
+  
+  fn slices() -> () {
+      let mut _0: ();
+      let _1: &str;
+      let _2: ();
+      let mut _3: &str;
+      let _5: ();
+      let mut _6: &str;
+      let _7: ();
+      let mut _8: (&*const u8, &*const u8);
+      let mut _9: &*const u8;
+      let _10: *const u8;
+      let mut _11: &str;
+      let mut _12: &*const u8;
+      let _13: *const u8;
+      let mut _14: &str;
+      let mut _17: bool;
+      let mut _18: *const u8;
+      let mut _19: *const u8;
+      let mut _20: !;
+      let _22: !;
+      let mut _23: core::panicking::AssertKind;
+      let mut _24: &*const u8;
+      let _25: &*const u8;
+      let mut _26: &*const u8;
+      let _27: &*const u8;
+      let mut _28: std::option::Option<std::fmt::Arguments<'_>>;
+      let mut _30: &str;
+      let _31: ();
+      let mut _32: &[u8];
+      let _33: ();
+      let mut _34: (&*const u8, &*const u8);
+      let mut _35: &*const u8;
+      let _36: *const u8;
+      let mut _37: &str;
+      let mut _38: &*const u8;
+      let _39: *const u8;
+      let mut _40: &[u8];
+      let mut _43: bool;
+      let mut _44: *const u8;
+      let mut _45: *const u8;
+      let mut _46: !;
+      let _48: !;
+      let mut _49: core::panicking::AssertKind;
+      let mut _50: &*const u8;
+      let _51: &*const u8;
+      let mut _52: &*const u8;
+      let _53: &*const u8;
+      let mut _54: std::option::Option<std::fmt::Arguments<'_>>;
+      scope 1 {
+          debug s => _1;
+          let _4: &str;
+          scope 2 {
+              debug t => _4;
+              let _15: &*const u8;
+              let _16: &*const u8;
+              let _29: &[u8];
+              scope 3 {
+                  debug left_val => _15;
+                  debug right_val => _16;
+                  let _21: core::panicking::AssertKind;
+                  scope 4 {
+                      debug kind => _21;
+                  }
+              }
+              scope 5 {
+                  debug u => _29;
+                  let _41: &*const u8;
+                  let _42: &*const u8;
+                  scope 7 {
+                      debug left_val => _41;
+                      debug right_val => _42;
+                      let _47: core::panicking::AssertKind;
+                      scope 8 {
+                          debug kind => _47;
+                      }
+                  }
+              }
+              scope 6 {
+              }
+          }
+      }
+  
+      bb0: {
+-         StorageLive(_1);
+          _1 = const "my favourite slice";
+          StorageLive(_2);
+-         StorageLive(_3);
+-         _3 = _1;
+-         _2 = opaque::<&str>(move _3) -> [return: bb1, unwind continue];
++         _2 = opaque::<&str>(_1) -> [return: bb1, unwind continue];
+      }
+  
+      bb1: {
+-         StorageDead(_3);
+          StorageDead(_2);
+          StorageLive(_4);
+          _4 = _1;
+          StorageLive(_5);
+-         StorageLive(_6);
+-         _6 = _4;
+-         _5 = opaque::<&str>(move _6) -> [return: bb2, unwind continue];
++         _5 = opaque::<&str>(_1) -> [return: bb2, unwind continue];
+      }
+  
+      bb2: {
+-         StorageDead(_6);
+          StorageDead(_5);
+-         StorageLive(_7);
+          StorageLive(_8);
+          StorageLive(_9);
+          StorageLive(_10);
+          StorageLive(_11);
+          _11 = &(*_1);
+          _10 = core::str::<impl str>::as_ptr(move _11) -> [return: bb3, unwind continue];
+      }
+  
+      bb3: {
+          StorageDead(_11);
+          _9 = &_10;
+          StorageLive(_12);
+          StorageLive(_13);
+          StorageLive(_14);
+          _14 = &(*_4);
+          _13 = core::str::<impl str>::as_ptr(move _14) -> [return: bb4, unwind continue];
+      }
+  
+      bb4: {
+          StorageDead(_14);
+          _12 = &_13;
+          _8 = (move _9, move _12);
+          StorageDead(_12);
+          StorageDead(_9);
+          StorageLive(_15);
+          _15 = (_8.0: &*const u8);
+          StorageLive(_16);
+          _16 = (_8.1: &*const u8);
+          StorageLive(_17);
+          StorageLive(_18);
+          _18 = (*_15);
+          StorageLive(_19);
+          _19 = (*_16);
+          _17 = Eq(move _18, move _19);
+          switchInt(move _17) -> [0: bb6, otherwise: bb5];
+      }
+  
+      bb5: {
+          StorageDead(_19);
+          StorageDead(_18);
+-         _7 = const ();
+          StorageDead(_17);
+          StorageDead(_16);
+          StorageDead(_15);
+          StorageDead(_13);
+          StorageDead(_10);
+          StorageDead(_8);
+-         StorageDead(_7);
+-         StorageLive(_29);
+          StorageLive(_30);
+          _30 = &(*_1);
+          _29 = move _30 as &[u8] (Transmute);
+          StorageDead(_30);
+          StorageLive(_31);
+-         StorageLive(_32);
+-         _32 = _29;
+-         _31 = opaque::<&[u8]>(move _32) -> [return: bb7, unwind continue];
++         _31 = opaque::<&[u8]>(_29) -> [return: bb7, unwind continue];
+      }
+  
+      bb6: {
+          StorageDead(_19);
+          StorageDead(_18);
+-         StorageLive(_21);
+          _21 = core::panicking::AssertKind::Eq;
+          StorageLive(_22);
+-         StorageLive(_23);
+-         _23 = move _21;
+          StorageLive(_24);
+          StorageLive(_25);
+          _25 = &(*_15);
+          _24 = &(*_25);
+          StorageLive(_26);
+          StorageLive(_27);
+          _27 = &(*_16);
+          _26 = &(*_27);
+          StorageLive(_28);
+          _28 = Option::<Arguments<'_>>::None;
+-         _22 = core::panicking::assert_failed::<*const u8, *const u8>(move _23, move _24, move _26, move _28) -> unwind continue;
++         _22 = core::panicking::assert_failed::<*const u8, *const u8>(_21, move _24, move _26, move _28) -> unwind continue;
+      }
+  
+      bb7: {
+-         StorageDead(_32);
+          StorageDead(_31);
+-         StorageLive(_33);
+          StorageLive(_34);
+          StorageLive(_35);
+          StorageLive(_36);
+          StorageLive(_37);
+          _37 = &(*_1);
+          _36 = core::str::<impl str>::as_ptr(move _37) -> [return: bb8, unwind continue];
+      }
+  
+      bb8: {
+          StorageDead(_37);
+          _35 = &_36;
+          StorageLive(_38);
+          StorageLive(_39);
+          StorageLive(_40);
+          _40 = &(*_29);
+          _39 = core::slice::<impl [u8]>::as_ptr(move _40) -> [return: bb9, unwind continue];
+      }
+  
+      bb9: {
+          StorageDead(_40);
+          _38 = &_39;
+          _34 = (move _35, move _38);
+          StorageDead(_38);
+          StorageDead(_35);
+          StorageLive(_41);
+          _41 = (_34.0: &*const u8);
+          StorageLive(_42);
+          _42 = (_34.1: &*const u8);
+          StorageLive(_43);
+          StorageLive(_44);
+          _44 = (*_41);
+          StorageLive(_45);
+          _45 = (*_42);
+          _43 = Eq(move _44, move _45);
+          switchInt(move _43) -> [0: bb11, otherwise: bb10];
+      }
+  
+      bb10: {
+          StorageDead(_45);
+          StorageDead(_44);
+-         _33 = const ();
+          StorageDead(_43);
+          StorageDead(_42);
+          StorageDead(_41);
+          StorageDead(_39);
+          StorageDead(_36);
+          StorageDead(_34);
+-         StorageDead(_33);
+          _0 = const ();
+-         StorageDead(_29);
+          StorageDead(_4);
+-         StorageDead(_1);
+          return;
+      }
+  
+      bb11: {
+          StorageDead(_45);
+          StorageDead(_44);
+-         StorageLive(_47);
+          _47 = core::panicking::AssertKind::Eq;
+          StorageLive(_48);
+-         StorageLive(_49);
+-         _49 = move _47;
+          StorageLive(_50);
+          StorageLive(_51);
+          _51 = &(*_41);
+          _50 = &(*_51);
+          StorageLive(_52);
+          StorageLive(_53);
+          _53 = &(*_42);
+          _52 = &(*_53);
+          StorageLive(_54);
+          _54 = Option::<Arguments<'_>>::None;
+-         _48 = core::panicking::assert_failed::<*const u8, *const u8>(move _49, move _50, move _52, move _54) -> unwind continue;
++         _48 = core::panicking::assert_failed::<*const u8, *const u8>(_47, move _50, move _52, move _54) -> unwind continue;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff
new file mode 100644
index 00000000000..bf866e2f4d2
--- /dev/null
+++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff
@@ -0,0 +1,883 @@
+- // MIR for `subexpression_elimination` before GVN
++ // MIR for `subexpression_elimination` after GVN
+  
+  fn subexpression_elimination(_1: u64, _2: u64, _3: u64) -> () {
+      debug x => _1;
+      debug y => _2;
+      debug z => _3;
+      let mut _0: ();
+      let _4: ();
+      let mut _5: u64;
+      let mut _6: u64;
+      let mut _7: u64;
+      let _8: ();
+      let mut _9: u64;
+      let mut _10: u64;
+      let mut _11: u64;
+      let _12: ();
+      let mut _13: u64;
+      let mut _14: u64;
+      let mut _15: u64;
+      let _16: ();
+      let mut _17: u64;
+      let mut _18: u64;
+      let mut _19: u64;
+      let mut _20: bool;
+      let _21: ();
+      let mut _22: u64;
+      let mut _23: u64;
+      let mut _24: u64;
+      let mut _25: bool;
+      let _26: ();
+      let mut _27: u64;
+      let mut _28: u64;
+      let mut _29: u64;
+      let _30: ();
+      let mut _31: u64;
+      let mut _32: u64;
+      let mut _33: u64;
+      let _34: ();
+      let mut _35: u64;
+      let mut _36: u64;
+      let mut _37: u64;
+      let _38: ();
+      let mut _39: u64;
+      let mut _40: u64;
+      let mut _41: u64;
+      let _42: ();
+      let mut _43: u64;
+      let mut _44: u64;
+      let mut _45: u64;
+      let _46: ();
+      let mut _47: u32;
+      let mut _48: u64;
+      let _49: ();
+      let mut _50: f32;
+      let mut _51: u64;
+      let _52: ();
+      let mut _53: S<u64>;
+      let mut _54: u64;
+      let _55: ();
+      let mut _56: u64;
+      let mut _57: S<u64>;
+      let mut _58: u64;
+      let _59: ();
+      let mut _60: u64;
+      let mut _61: u64;
+      let mut _62: u64;
+      let mut _63: u64;
+      let mut _64: u64;
+      let _65: ();
+      let mut _66: u64;
+      let mut _67: u64;
+      let mut _68: u64;
+      let mut _69: u64;
+      let mut _70: u64;
+      let _71: ();
+      let mut _72: u64;
+      let mut _73: u64;
+      let mut _74: u64;
+      let mut _75: u64;
+      let mut _76: u64;
+      let _77: ();
+      let mut _78: u64;
+      let mut _79: u64;
+      let mut _80: u64;
+      let mut _81: u64;
+      let mut _82: bool;
+      let mut _83: u64;
+      let _84: ();
+      let mut _85: u64;
+      let mut _86: u64;
+      let mut _87: u64;
+      let mut _88: u64;
+      let mut _89: bool;
+      let mut _90: u64;
+      let _91: ();
+      let mut _92: u64;
+      let mut _93: u64;
+      let mut _94: u64;
+      let mut _95: u64;
+      let mut _96: u64;
+      let _97: ();
+      let mut _98: u64;
+      let mut _99: u64;
+      let mut _100: u64;
+      let mut _101: u64;
+      let mut _102: u64;
+      let _103: ();
+      let mut _104: u64;
+      let mut _105: u64;
+      let mut _106: u64;
+      let mut _107: u64;
+      let mut _108: u64;
+      let _109: ();
+      let mut _110: u64;
+      let mut _111: u64;
+      let mut _112: u64;
+      let mut _113: u64;
+      let mut _114: u64;
+      let _115: ();
+      let mut _116: u64;
+      let mut _117: u64;
+      let mut _118: u64;
+      let mut _119: u64;
+      let mut _120: u64;
+      let _121: ();
+      let mut _122: S<u64>;
+      let mut _123: u64;
+      let _124: ();
+      let mut _125: u64;
+      let mut _126: S<u64>;
+      let mut _127: u64;
+      let _128: &u64;
+      let _129: ();
+      let mut _130: u64;
+      let mut _131: u64;
+      let mut _132: u64;
+      let _133: ();
+      let mut _134: u64;
+      let mut _135: u64;
+      let mut _136: u64;
+      let _138: ();
+      let mut _139: u64;
+      let mut _140: u64;
+      let mut _141: u64;
+      let _142: ();
+      let mut _143: u64;
+      let mut _144: u64;
+      let mut _145: u64;
+      let _146: ();
+      let _148: ();
+      let mut _149: u64;
+      let mut _150: u64;
+      let mut _151: u64;
+      let _152: ();
+      let mut _153: u64;
+      let mut _154: u64;
+      let mut _155: u64;
+      let _157: ();
+      let mut _158: u64;
+      let mut _159: u64;
+      let mut _160: u64;
+      let _161: ();
+      let mut _162: u64;
+      let mut _163: u64;
+      let mut _164: u64;
+      let _166: ();
+      let mut _167: u64;
+      let mut _168: u64;
+      let mut _169: u64;
+      let _170: ();
+      let mut _171: u64;
+      let mut _172: u64;
+      let mut _173: u64;
+      scope 1 {
+          debug a => _128;
+          let _137: &mut u64;
+          scope 2 {
+              debug b => _137;
+              let _165: &u64;
+              scope 3 {
+                  let _147: *const u64;
+                  scope 4 {
+                      debug c => _147;
+                      let _156: *mut u64;
+                      scope 5 {
+                          debug d => _156;
+                      }
+                  }
+              }
+              scope 6 {
+                  debug e => _165;
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_4);
+-         StorageLive(_5);
+-         StorageLive(_6);
+-         _6 = _1;
+-         StorageLive(_7);
+-         _7 = _2;
+-         _5 = Add(move _6, move _7);
+-         StorageDead(_7);
+-         StorageDead(_6);
+-         _4 = opaque::<u64>(move _5) -> [return: bb1, unwind unreachable];
++         _5 = Add(_1, _2);
++         _4 = opaque::<u64>(_5) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+-         StorageDead(_5);
+          StorageDead(_4);
+          StorageLive(_8);
+-         StorageLive(_9);
+-         StorageLive(_10);
+-         _10 = _1;
+-         StorageLive(_11);
+-         _11 = _2;
+-         _9 = Mul(move _10, move _11);
+-         StorageDead(_11);
+-         StorageDead(_10);
+-         _8 = opaque::<u64>(move _9) -> [return: bb2, unwind unreachable];
++         _9 = Mul(_1, _2);
++         _8 = opaque::<u64>(_9) -> [return: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+-         StorageDead(_9);
+          StorageDead(_8);
+          StorageLive(_12);
+-         StorageLive(_13);
+-         StorageLive(_14);
+-         _14 = _1;
+-         StorageLive(_15);
+-         _15 = _2;
+-         _13 = Sub(move _14, move _15);
+-         StorageDead(_15);
+-         StorageDead(_14);
+-         _12 = opaque::<u64>(move _13) -> [return: bb3, unwind unreachable];
++         _13 = Sub(_1, _2);
++         _12 = opaque::<u64>(_13) -> [return: bb3, unwind unreachable];
+      }
+  
+      bb3: {
+-         StorageDead(_13);
+          StorageDead(_12);
+          StorageLive(_16);
+-         StorageLive(_17);
+-         StorageLive(_18);
+-         _18 = _1;
+-         StorageLive(_19);
+-         _19 = _2;
+-         _20 = Eq(_19, const 0_u64);
+-         assert(!move _20, "attempt to divide `{}` by zero", _18) -> [success: bb4, unwind unreachable];
++         _20 = Eq(_2, const 0_u64);
++         assert(!_20, "attempt to divide `{}` by zero", _1) -> [success: bb4, unwind unreachable];
+      }
+  
+      bb4: {
+-         _17 = Div(move _18, move _19);
+-         StorageDead(_19);
+-         StorageDead(_18);
+-         _16 = opaque::<u64>(move _17) -> [return: bb5, unwind unreachable];
++         _17 = Div(_1, _2);
++         _16 = opaque::<u64>(_17) -> [return: bb5, unwind unreachable];
+      }
+  
+      bb5: {
+-         StorageDead(_17);
+          StorageDead(_16);
+          StorageLive(_21);
+-         StorageLive(_22);
+-         StorageLive(_23);
+-         _23 = _1;
+-         StorageLive(_24);
+-         _24 = _2;
+-         _25 = Eq(_24, const 0_u64);
+-         assert(!move _25, "attempt to calculate the remainder of `{}` with a divisor of zero", _23) -> [success: bb6, unwind unreachable];
++         assert(!_20, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb6, unwind unreachable];
+      }
+  
+      bb6: {
+-         _22 = Rem(move _23, move _24);
+-         StorageDead(_24);
+-         StorageDead(_23);
+-         _21 = opaque::<u64>(move _22) -> [return: bb7, unwind unreachable];
++         _22 = Rem(_1, _2);
++         _21 = opaque::<u64>(_22) -> [return: bb7, unwind unreachable];
+      }
+  
+      bb7: {
+-         StorageDead(_22);
+          StorageDead(_21);
+          StorageLive(_26);
+-         StorageLive(_27);
+-         StorageLive(_28);
+-         _28 = _1;
+-         StorageLive(_29);
+-         _29 = _2;
+-         _27 = BitAnd(move _28, move _29);
+-         StorageDead(_29);
+-         StorageDead(_28);
+-         _26 = opaque::<u64>(move _27) -> [return: bb8, unwind unreachable];
++         _27 = BitAnd(_1, _2);
++         _26 = opaque::<u64>(_27) -> [return: bb8, unwind unreachable];
+      }
+  
+      bb8: {
+-         StorageDead(_27);
+          StorageDead(_26);
+          StorageLive(_30);
+-         StorageLive(_31);
+-         StorageLive(_32);
+-         _32 = _1;
+-         StorageLive(_33);
+-         _33 = _2;
+-         _31 = BitOr(move _32, move _33);
+-         StorageDead(_33);
+-         StorageDead(_32);
+-         _30 = opaque::<u64>(move _31) -> [return: bb9, unwind unreachable];
++         _31 = BitOr(_1, _2);
++         _30 = opaque::<u64>(_31) -> [return: bb9, unwind unreachable];
+      }
+  
+      bb9: {
+-         StorageDead(_31);
+          StorageDead(_30);
+          StorageLive(_34);
+-         StorageLive(_35);
+-         StorageLive(_36);
+-         _36 = _1;
+-         StorageLive(_37);
+-         _37 = _2;
+-         _35 = BitXor(move _36, move _37);
+-         StorageDead(_37);
+-         StorageDead(_36);
+-         _34 = opaque::<u64>(move _35) -> [return: bb10, unwind unreachable];
++         _35 = BitXor(_1, _2);
++         _34 = opaque::<u64>(_35) -> [return: bb10, unwind unreachable];
+      }
+  
+      bb10: {
+-         StorageDead(_35);
+          StorageDead(_34);
+          StorageLive(_38);
+-         StorageLive(_39);
+-         StorageLive(_40);
+-         _40 = _1;
+-         StorageLive(_41);
+-         _41 = _2;
+-         _39 = Shl(move _40, move _41);
+-         StorageDead(_41);
+-         StorageDead(_40);
+-         _38 = opaque::<u64>(move _39) -> [return: bb11, unwind unreachable];
++         _39 = Shl(_1, _2);
++         _38 = opaque::<u64>(_39) -> [return: bb11, unwind unreachable];
+      }
+  
+      bb11: {
+-         StorageDead(_39);
+          StorageDead(_38);
+          StorageLive(_42);
+-         StorageLive(_43);
+-         StorageLive(_44);
+-         _44 = _1;
+-         StorageLive(_45);
+-         _45 = _2;
+-         _43 = Shr(move _44, move _45);
+-         StorageDead(_45);
+-         StorageDead(_44);
+-         _42 = opaque::<u64>(move _43) -> [return: bb12, unwind unreachable];
++         _43 = Shr(_1, _2);
++         _42 = opaque::<u64>(_43) -> [return: bb12, unwind unreachable];
+      }
+  
+      bb12: {
+-         StorageDead(_43);
+          StorageDead(_42);
+          StorageLive(_46);
+          StorageLive(_47);
+-         StorageLive(_48);
+-         _48 = _1;
+-         _47 = move _48 as u32 (IntToInt);
+-         StorageDead(_48);
++         _47 = _1 as u32 (IntToInt);
+          _46 = opaque::<u32>(move _47) -> [return: bb13, unwind unreachable];
+      }
+  
+      bb13: {
+          StorageDead(_47);
+          StorageDead(_46);
+          StorageLive(_49);
+          StorageLive(_50);
+-         StorageLive(_51);
+-         _51 = _1;
+-         _50 = move _51 as f32 (IntToFloat);
+-         StorageDead(_51);
++         _50 = _1 as f32 (IntToFloat);
+          _49 = opaque::<f32>(move _50) -> [return: bb14, unwind unreachable];
+      }
+  
+      bb14: {
+          StorageDead(_50);
+          StorageDead(_49);
+          StorageLive(_52);
+-         StorageLive(_53);
+-         StorageLive(_54);
+-         _54 = _1;
+-         _53 = S::<u64>(move _54);
+-         StorageDead(_54);
+-         _52 = opaque::<S<u64>>(move _53) -> [return: bb15, unwind unreachable];
++         _53 = S::<u64>(_1);
++         _52 = opaque::<S<u64>>(_53) -> [return: bb15, unwind unreachable];
+      }
+  
+      bb15: {
+-         StorageDead(_53);
+          StorageDead(_52);
+          StorageLive(_55);
+-         StorageLive(_56);
+-         StorageLive(_57);
+-         StorageLive(_58);
+-         _58 = _1;
+-         _57 = S::<u64>(move _58);
+-         StorageDead(_58);
+-         _56 = (_57.0: u64);
+-         _55 = opaque::<u64>(move _56) -> [return: bb16, unwind unreachable];
++         _56 = (_53.0: u64);
++         _55 = opaque::<u64>(_56) -> [return: bb16, unwind unreachable];
+      }
+  
+      bb16: {
+-         StorageDead(_56);
+-         StorageDead(_57);
+          StorageDead(_55);
+          StorageLive(_59);
+          StorageLive(_60);
+-         StorageLive(_61);
+-         StorageLive(_62);
+-         _62 = _1;
+-         StorageLive(_63);
+-         _63 = _2;
+-         _61 = Add(move _62, move _63);
+-         StorageDead(_63);
+-         StorageDead(_62);
+          StorageLive(_64);
+          _64 = _3;
+-         _60 = Add(move _61, move _64);
++         _60 = Add(_5, move _64);
+          StorageDead(_64);
+-         StorageDead(_61);
+          _59 = opaque::<u64>(move _60) -> [return: bb17, unwind unreachable];
+      }
+  
+      bb17: {
+          StorageDead(_60);
+          StorageDead(_59);
+          StorageLive(_65);
+          StorageLive(_66);
+-         StorageLive(_67);
+-         StorageLive(_68);
+-         _68 = _1;
+-         StorageLive(_69);
+-         _69 = _2;
+-         _67 = Mul(move _68, move _69);
+-         StorageDead(_69);
+-         StorageDead(_68);
+          StorageLive(_70);
+          _70 = _3;
+-         _66 = Add(move _67, move _70);
++         _66 = Add(_9, move _70);
+          StorageDead(_70);
+-         StorageDead(_67);
+          _65 = opaque::<u64>(move _66) -> [return: bb18, unwind unreachable];
+      }
+  
+      bb18: {
+          StorageDead(_66);
+          StorageDead(_65);
+          StorageLive(_71);
+          StorageLive(_72);
+-         StorageLive(_73);
+-         StorageLive(_74);
+-         _74 = _1;
+-         StorageLive(_75);
+-         _75 = _2;
+-         _73 = Sub(move _74, move _75);
+-         StorageDead(_75);
+-         StorageDead(_74);
+          StorageLive(_76);
+          _76 = _3;
+-         _72 = Add(move _73, move _76);
++         _72 = Add(_13, move _76);
+          StorageDead(_76);
+-         StorageDead(_73);
+          _71 = opaque::<u64>(move _72) -> [return: bb19, unwind unreachable];
+      }
+  
+      bb19: {
+          StorageDead(_72);
+          StorageDead(_71);
+          StorageLive(_77);
+          StorageLive(_78);
+-         StorageLive(_79);
+-         StorageLive(_80);
+-         _80 = _1;
+-         StorageLive(_81);
+-         _81 = _2;
+-         _82 = Eq(_81, const 0_u64);
+-         assert(!move _82, "attempt to divide `{}` by zero", _80) -> [success: bb20, unwind unreachable];
++         assert(!_20, "attempt to divide `{}` by zero", _1) -> [success: bb20, unwind unreachable];
+      }
+  
+      bb20: {
+-         _79 = Div(move _80, move _81);
+-         StorageDead(_81);
+-         StorageDead(_80);
+          StorageLive(_83);
+          _83 = _3;
+-         _78 = Add(move _79, move _83);
++         _78 = Add(_17, move _83);
+          StorageDead(_83);
+-         StorageDead(_79);
+          _77 = opaque::<u64>(move _78) -> [return: bb21, unwind unreachable];
+      }
+  
+      bb21: {
+          StorageDead(_78);
+          StorageDead(_77);
+          StorageLive(_84);
+          StorageLive(_85);
+-         StorageLive(_86);
+-         StorageLive(_87);
+-         _87 = _1;
+-         StorageLive(_88);
+-         _88 = _2;
+-         _89 = Eq(_88, const 0_u64);
+-         assert(!move _89, "attempt to calculate the remainder of `{}` with a divisor of zero", _87) -> [success: bb22, unwind unreachable];
++         assert(!_20, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb22, unwind unreachable];
+      }
+  
+      bb22: {
+-         _86 = Rem(move _87, move _88);
+-         StorageDead(_88);
+-         StorageDead(_87);
+          StorageLive(_90);
+          _90 = _3;
+-         _85 = Add(move _86, move _90);
++         _85 = Add(_22, move _90);
+          StorageDead(_90);
+-         StorageDead(_86);
+          _84 = opaque::<u64>(move _85) -> [return: bb23, unwind unreachable];
+      }
+  
+      bb23: {
+          StorageDead(_85);
+          StorageDead(_84);
+          StorageLive(_91);
+          StorageLive(_92);
+-         StorageLive(_93);
+-         StorageLive(_94);
+-         _94 = _1;
+-         StorageLive(_95);
+-         _95 = _2;
+-         _93 = BitAnd(move _94, move _95);
+-         StorageDead(_95);
+-         StorageDead(_94);
+          StorageLive(_96);
+          _96 = _3;
+-         _92 = Add(move _93, move _96);
++         _92 = Add(_27, move _96);
+          StorageDead(_96);
+-         StorageDead(_93);
+          _91 = opaque::<u64>(move _92) -> [return: bb24, unwind unreachable];
+      }
+  
+      bb24: {
+          StorageDead(_92);
+          StorageDead(_91);
+          StorageLive(_97);
+          StorageLive(_98);
+-         StorageLive(_99);
+-         StorageLive(_100);
+-         _100 = _1;
+-         StorageLive(_101);
+-         _101 = _2;
+-         _99 = BitOr(move _100, move _101);
+-         StorageDead(_101);
+-         StorageDead(_100);
+          StorageLive(_102);
+          _102 = _3;
+-         _98 = Add(move _99, move _102);
++         _98 = Add(_31, move _102);
+          StorageDead(_102);
+-         StorageDead(_99);
+          _97 = opaque::<u64>(move _98) -> [return: bb25, unwind unreachable];
+      }
+  
+      bb25: {
+          StorageDead(_98);
+          StorageDead(_97);
+          StorageLive(_103);
+          StorageLive(_104);
+-         StorageLive(_105);
+-         StorageLive(_106);
+-         _106 = _1;
+-         StorageLive(_107);
+-         _107 = _2;
+-         _105 = BitXor(move _106, move _107);
+-         StorageDead(_107);
+-         StorageDead(_106);
+          StorageLive(_108);
+          _108 = _3;
+-         _104 = Add(move _105, move _108);
++         _104 = Add(_35, move _108);
+          StorageDead(_108);
+-         StorageDead(_105);
+          _103 = opaque::<u64>(move _104) -> [return: bb26, unwind unreachable];
+      }
+  
+      bb26: {
+          StorageDead(_104);
+          StorageDead(_103);
+          StorageLive(_109);
+          StorageLive(_110);
+-         StorageLive(_111);
+-         StorageLive(_112);
+-         _112 = _1;
+-         StorageLive(_113);
+-         _113 = _2;
+-         _111 = Shl(move _112, move _113);
+-         StorageDead(_113);
+-         StorageDead(_112);
+          StorageLive(_114);
+          _114 = _3;
+-         _110 = Add(move _111, move _114);
++         _110 = Add(_39, move _114);
+          StorageDead(_114);
+-         StorageDead(_111);
+          _109 = opaque::<u64>(move _110) -> [return: bb27, unwind unreachable];
+      }
+  
+      bb27: {
+          StorageDead(_110);
+          StorageDead(_109);
+          StorageLive(_115);
+          StorageLive(_116);
+-         StorageLive(_117);
+-         StorageLive(_118);
+-         _118 = _1;
+-         StorageLive(_119);
+-         _119 = _2;
+-         _117 = Shr(move _118, move _119);
+-         StorageDead(_119);
+-         StorageDead(_118);
+          StorageLive(_120);
+          _120 = _3;
+-         _116 = Add(move _117, move _120);
++         _116 = Add(_43, move _120);
+          StorageDead(_120);
+-         StorageDead(_117);
+          _115 = opaque::<u64>(move _116) -> [return: bb28, unwind unreachable];
+      }
+  
+      bb28: {
+          StorageDead(_116);
+          StorageDead(_115);
+          StorageLive(_121);
+-         StorageLive(_122);
+-         StorageLive(_123);
+-         _123 = _1;
+-         _122 = S::<u64>(move _123);
+-         StorageDead(_123);
+-         _121 = opaque::<S<u64>>(move _122) -> [return: bb29, unwind unreachable];
++         _121 = opaque::<S<u64>>(_53) -> [return: bb29, unwind unreachable];
+      }
+  
+      bb29: {
+-         StorageDead(_122);
+          StorageDead(_121);
+          StorageLive(_124);
+-         StorageLive(_125);
+-         StorageLive(_126);
+-         StorageLive(_127);
+-         _127 = _1;
+-         _126 = S::<u64>(move _127);
+-         StorageDead(_127);
+-         _125 = (_126.0: u64);
+-         _124 = opaque::<u64>(move _125) -> [return: bb30, unwind unreachable];
++         _124 = opaque::<u64>(_56) -> [return: bb30, unwind unreachable];
+      }
+  
+      bb30: {
+-         StorageDead(_125);
+-         StorageDead(_126);
+          StorageDead(_124);
+          StorageLive(_128);
+          _128 = &_3;
+          StorageLive(_129);
+-         StorageLive(_130);
+-         StorageLive(_131);
+          _131 = (*_128);
+-         StorageLive(_132);
+-         _132 = _1;
+-         _130 = Add(move _131, move _132);
+-         StorageDead(_132);
+-         StorageDead(_131);
+-         _129 = opaque::<u64>(move _130) -> [return: bb31, unwind unreachable];
++         _130 = Add(_131, _1);
++         _129 = opaque::<u64>(_130) -> [return: bb31, unwind unreachable];
+      }
+  
+      bb31: {
+-         StorageDead(_130);
+          StorageDead(_129);
+          StorageLive(_133);
+-         StorageLive(_134);
+-         StorageLive(_135);
+-         _135 = (*_128);
+-         StorageLive(_136);
+-         _136 = _1;
+-         _134 = Add(move _135, move _136);
+-         StorageDead(_136);
+-         StorageDead(_135);
+-         _133 = opaque::<u64>(move _134) -> [return: bb32, unwind unreachable];
++         _133 = opaque::<u64>(_130) -> [return: bb32, unwind unreachable];
+      }
+  
+      bb32: {
+-         StorageDead(_134);
+          StorageDead(_133);
+          StorageLive(_137);
+          _137 = &mut _3;
+          StorageLive(_138);
+          StorageLive(_139);
+          StorageLive(_140);
+          _140 = (*_137);
+-         StorageLive(_141);
+-         _141 = _1;
+-         _139 = Add(move _140, move _141);
+-         StorageDead(_141);
++         _139 = Add(move _140, _1);
+          StorageDead(_140);
+          _138 = opaque::<u64>(move _139) -> [return: bb33, unwind unreachable];
+      }
+  
+      bb33: {
+          StorageDead(_139);
+          StorageDead(_138);
+          StorageLive(_142);
+          StorageLive(_143);
+          StorageLive(_144);
+          _144 = (*_137);
+-         StorageLive(_145);
+-         _145 = _1;
+-         _143 = Add(move _144, move _145);
+-         StorageDead(_145);
++         _143 = Add(move _144, _1);
+          StorageDead(_144);
+          _142 = opaque::<u64>(move _143) -> [return: bb34, unwind unreachable];
+      }
+  
+      bb34: {
+          StorageDead(_143);
+          StorageDead(_142);
+-         StorageLive(_146);
+          StorageLive(_147);
+          _147 = &raw const _3;
+          StorageLive(_148);
+          StorageLive(_149);
+          StorageLive(_150);
+          _150 = (*_147);
+-         StorageLive(_151);
+-         _151 = _1;
+-         _149 = Add(move _150, move _151);
+-         StorageDead(_151);
++         _149 = Add(move _150, _1);
+          StorageDead(_150);
+          _148 = opaque::<u64>(move _149) -> [return: bb35, unwind unreachable];
+      }
+  
+      bb35: {
+          StorageDead(_149);
+          StorageDead(_148);
+          StorageLive(_152);
+          StorageLive(_153);
+          StorageLive(_154);
+          _154 = (*_147);
+-         StorageLive(_155);
+-         _155 = _1;
+-         _153 = Add(move _154, move _155);
+-         StorageDead(_155);
++         _153 = Add(move _154, _1);
+          StorageDead(_154);
+          _152 = opaque::<u64>(move _153) -> [return: bb36, unwind unreachable];
+      }
+  
+      bb36: {
+          StorageDead(_153);
+          StorageDead(_152);
+          StorageLive(_156);
+          _156 = &raw mut _3;
+          StorageLive(_157);
+          StorageLive(_158);
+          StorageLive(_159);
+          _159 = (*_156);
+-         StorageLive(_160);
+-         _160 = _1;
+-         _158 = Add(move _159, move _160);
+-         StorageDead(_160);
++         _158 = Add(move _159, _1);
+          StorageDead(_159);
+          _157 = opaque::<u64>(move _158) -> [return: bb37, unwind unreachable];
+      }
+  
+      bb37: {
+          StorageDead(_158);
+          StorageDead(_157);
+          StorageLive(_161);
+          StorageLive(_162);
+          StorageLive(_163);
+          _163 = (*_156);
+-         StorageLive(_164);
+-         _164 = _1;
+-         _162 = Add(move _163, move _164);
+-         StorageDead(_164);
++         _162 = Add(move _163, _1);
+          StorageDead(_163);
+          _161 = opaque::<u64>(move _162) -> [return: bb38, unwind unreachable];
+      }
+  
+      bb38: {
+          StorageDead(_162);
+          StorageDead(_161);
+-         _146 = const ();
+          StorageDead(_156);
+          StorageDead(_147);
+-         StorageDead(_146);
+          StorageLive(_165);
+          _165 = &_3;
+          StorageLive(_166);
+-         StorageLive(_167);
+-         StorageLive(_168);
+          _168 = (*_165);
+-         StorageLive(_169);
+-         _169 = _1;
+-         _167 = Add(move _168, move _169);
+-         StorageDead(_169);
+-         StorageDead(_168);
+-         _166 = opaque::<u64>(move _167) -> [return: bb39, unwind unreachable];
++         _167 = Add(_168, _1);
++         _166 = opaque::<u64>(_167) -> [return: bb39, unwind unreachable];
+      }
+  
+      bb39: {
+-         StorageDead(_167);
+          StorageDead(_166);
+          StorageLive(_170);
+-         StorageLive(_171);
+-         StorageLive(_172);
+-         _172 = (*_165);
+-         StorageLive(_173);
+-         _173 = _1;
+-         _171 = Add(move _172, move _173);
+-         StorageDead(_173);
+-         StorageDead(_172);
+-         _170 = opaque::<u64>(move _171) -> [return: bb40, unwind unreachable];
++         _170 = opaque::<u64>(_167) -> [return: bb40, unwind unreachable];
+      }
+  
+      bb40: {
+-         StorageDead(_171);
+          StorageDead(_170);
+          _0 = const ();
+          StorageDead(_165);
+          StorageDead(_137);
+          StorageDead(_128);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..68b05290719
--- /dev/null
+++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff
@@ -0,0 +1,883 @@
+- // MIR for `subexpression_elimination` before GVN
++ // MIR for `subexpression_elimination` after GVN
+  
+  fn subexpression_elimination(_1: u64, _2: u64, _3: u64) -> () {
+      debug x => _1;
+      debug y => _2;
+      debug z => _3;
+      let mut _0: ();
+      let _4: ();
+      let mut _5: u64;
+      let mut _6: u64;
+      let mut _7: u64;
+      let _8: ();
+      let mut _9: u64;
+      let mut _10: u64;
+      let mut _11: u64;
+      let _12: ();
+      let mut _13: u64;
+      let mut _14: u64;
+      let mut _15: u64;
+      let _16: ();
+      let mut _17: u64;
+      let mut _18: u64;
+      let mut _19: u64;
+      let mut _20: bool;
+      let _21: ();
+      let mut _22: u64;
+      let mut _23: u64;
+      let mut _24: u64;
+      let mut _25: bool;
+      let _26: ();
+      let mut _27: u64;
+      let mut _28: u64;
+      let mut _29: u64;
+      let _30: ();
+      let mut _31: u64;
+      let mut _32: u64;
+      let mut _33: u64;
+      let _34: ();
+      let mut _35: u64;
+      let mut _36: u64;
+      let mut _37: u64;
+      let _38: ();
+      let mut _39: u64;
+      let mut _40: u64;
+      let mut _41: u64;
+      let _42: ();
+      let mut _43: u64;
+      let mut _44: u64;
+      let mut _45: u64;
+      let _46: ();
+      let mut _47: u32;
+      let mut _48: u64;
+      let _49: ();
+      let mut _50: f32;
+      let mut _51: u64;
+      let _52: ();
+      let mut _53: S<u64>;
+      let mut _54: u64;
+      let _55: ();
+      let mut _56: u64;
+      let mut _57: S<u64>;
+      let mut _58: u64;
+      let _59: ();
+      let mut _60: u64;
+      let mut _61: u64;
+      let mut _62: u64;
+      let mut _63: u64;
+      let mut _64: u64;
+      let _65: ();
+      let mut _66: u64;
+      let mut _67: u64;
+      let mut _68: u64;
+      let mut _69: u64;
+      let mut _70: u64;
+      let _71: ();
+      let mut _72: u64;
+      let mut _73: u64;
+      let mut _74: u64;
+      let mut _75: u64;
+      let mut _76: u64;
+      let _77: ();
+      let mut _78: u64;
+      let mut _79: u64;
+      let mut _80: u64;
+      let mut _81: u64;
+      let mut _82: bool;
+      let mut _83: u64;
+      let _84: ();
+      let mut _85: u64;
+      let mut _86: u64;
+      let mut _87: u64;
+      let mut _88: u64;
+      let mut _89: bool;
+      let mut _90: u64;
+      let _91: ();
+      let mut _92: u64;
+      let mut _93: u64;
+      let mut _94: u64;
+      let mut _95: u64;
+      let mut _96: u64;
+      let _97: ();
+      let mut _98: u64;
+      let mut _99: u64;
+      let mut _100: u64;
+      let mut _101: u64;
+      let mut _102: u64;
+      let _103: ();
+      let mut _104: u64;
+      let mut _105: u64;
+      let mut _106: u64;
+      let mut _107: u64;
+      let mut _108: u64;
+      let _109: ();
+      let mut _110: u64;
+      let mut _111: u64;
+      let mut _112: u64;
+      let mut _113: u64;
+      let mut _114: u64;
+      let _115: ();
+      let mut _116: u64;
+      let mut _117: u64;
+      let mut _118: u64;
+      let mut _119: u64;
+      let mut _120: u64;
+      let _121: ();
+      let mut _122: S<u64>;
+      let mut _123: u64;
+      let _124: ();
+      let mut _125: u64;
+      let mut _126: S<u64>;
+      let mut _127: u64;
+      let _128: &u64;
+      let _129: ();
+      let mut _130: u64;
+      let mut _131: u64;
+      let mut _132: u64;
+      let _133: ();
+      let mut _134: u64;
+      let mut _135: u64;
+      let mut _136: u64;
+      let _138: ();
+      let mut _139: u64;
+      let mut _140: u64;
+      let mut _141: u64;
+      let _142: ();
+      let mut _143: u64;
+      let mut _144: u64;
+      let mut _145: u64;
+      let _146: ();
+      let _148: ();
+      let mut _149: u64;
+      let mut _150: u64;
+      let mut _151: u64;
+      let _152: ();
+      let mut _153: u64;
+      let mut _154: u64;
+      let mut _155: u64;
+      let _157: ();
+      let mut _158: u64;
+      let mut _159: u64;
+      let mut _160: u64;
+      let _161: ();
+      let mut _162: u64;
+      let mut _163: u64;
+      let mut _164: u64;
+      let _166: ();
+      let mut _167: u64;
+      let mut _168: u64;
+      let mut _169: u64;
+      let _170: ();
+      let mut _171: u64;
+      let mut _172: u64;
+      let mut _173: u64;
+      scope 1 {
+          debug a => _128;
+          let _137: &mut u64;
+          scope 2 {
+              debug b => _137;
+              let _165: &u64;
+              scope 3 {
+                  let _147: *const u64;
+                  scope 4 {
+                      debug c => _147;
+                      let _156: *mut u64;
+                      scope 5 {
+                          debug d => _156;
+                      }
+                  }
+              }
+              scope 6 {
+                  debug e => _165;
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_4);
+-         StorageLive(_5);
+-         StorageLive(_6);
+-         _6 = _1;
+-         StorageLive(_7);
+-         _7 = _2;
+-         _5 = Add(move _6, move _7);
+-         StorageDead(_7);
+-         StorageDead(_6);
+-         _4 = opaque::<u64>(move _5) -> [return: bb1, unwind continue];
++         _5 = Add(_1, _2);
++         _4 = opaque::<u64>(_5) -> [return: bb1, unwind continue];
+      }
+  
+      bb1: {
+-         StorageDead(_5);
+          StorageDead(_4);
+          StorageLive(_8);
+-         StorageLive(_9);
+-         StorageLive(_10);
+-         _10 = _1;
+-         StorageLive(_11);
+-         _11 = _2;
+-         _9 = Mul(move _10, move _11);
+-         StorageDead(_11);
+-         StorageDead(_10);
+-         _8 = opaque::<u64>(move _9) -> [return: bb2, unwind continue];
++         _9 = Mul(_1, _2);
++         _8 = opaque::<u64>(_9) -> [return: bb2, unwind continue];
+      }
+  
+      bb2: {
+-         StorageDead(_9);
+          StorageDead(_8);
+          StorageLive(_12);
+-         StorageLive(_13);
+-         StorageLive(_14);
+-         _14 = _1;
+-         StorageLive(_15);
+-         _15 = _2;
+-         _13 = Sub(move _14, move _15);
+-         StorageDead(_15);
+-         StorageDead(_14);
+-         _12 = opaque::<u64>(move _13) -> [return: bb3, unwind continue];
++         _13 = Sub(_1, _2);
++         _12 = opaque::<u64>(_13) -> [return: bb3, unwind continue];
+      }
+  
+      bb3: {
+-         StorageDead(_13);
+          StorageDead(_12);
+          StorageLive(_16);
+-         StorageLive(_17);
+-         StorageLive(_18);
+-         _18 = _1;
+-         StorageLive(_19);
+-         _19 = _2;
+-         _20 = Eq(_19, const 0_u64);
+-         assert(!move _20, "attempt to divide `{}` by zero", _18) -> [success: bb4, unwind continue];
++         _20 = Eq(_2, const 0_u64);
++         assert(!_20, "attempt to divide `{}` by zero", _1) -> [success: bb4, unwind continue];
+      }
+  
+      bb4: {
+-         _17 = Div(move _18, move _19);
+-         StorageDead(_19);
+-         StorageDead(_18);
+-         _16 = opaque::<u64>(move _17) -> [return: bb5, unwind continue];
++         _17 = Div(_1, _2);
++         _16 = opaque::<u64>(_17) -> [return: bb5, unwind continue];
+      }
+  
+      bb5: {
+-         StorageDead(_17);
+          StorageDead(_16);
+          StorageLive(_21);
+-         StorageLive(_22);
+-         StorageLive(_23);
+-         _23 = _1;
+-         StorageLive(_24);
+-         _24 = _2;
+-         _25 = Eq(_24, const 0_u64);
+-         assert(!move _25, "attempt to calculate the remainder of `{}` with a divisor of zero", _23) -> [success: bb6, unwind continue];
++         assert(!_20, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb6, unwind continue];
+      }
+  
+      bb6: {
+-         _22 = Rem(move _23, move _24);
+-         StorageDead(_24);
+-         StorageDead(_23);
+-         _21 = opaque::<u64>(move _22) -> [return: bb7, unwind continue];
++         _22 = Rem(_1, _2);
++         _21 = opaque::<u64>(_22) -> [return: bb7, unwind continue];
+      }
+  
+      bb7: {
+-         StorageDead(_22);
+          StorageDead(_21);
+          StorageLive(_26);
+-         StorageLive(_27);
+-         StorageLive(_28);
+-         _28 = _1;
+-         StorageLive(_29);
+-         _29 = _2;
+-         _27 = BitAnd(move _28, move _29);
+-         StorageDead(_29);
+-         StorageDead(_28);
+-         _26 = opaque::<u64>(move _27) -> [return: bb8, unwind continue];
++         _27 = BitAnd(_1, _2);
++         _26 = opaque::<u64>(_27) -> [return: bb8, unwind continue];
+      }
+  
+      bb8: {
+-         StorageDead(_27);
+          StorageDead(_26);
+          StorageLive(_30);
+-         StorageLive(_31);
+-         StorageLive(_32);
+-         _32 = _1;
+-         StorageLive(_33);
+-         _33 = _2;
+-         _31 = BitOr(move _32, move _33);
+-         StorageDead(_33);
+-         StorageDead(_32);
+-         _30 = opaque::<u64>(move _31) -> [return: bb9, unwind continue];
++         _31 = BitOr(_1, _2);
++         _30 = opaque::<u64>(_31) -> [return: bb9, unwind continue];
+      }
+  
+      bb9: {
+-         StorageDead(_31);
+          StorageDead(_30);
+          StorageLive(_34);
+-         StorageLive(_35);
+-         StorageLive(_36);
+-         _36 = _1;
+-         StorageLive(_37);
+-         _37 = _2;
+-         _35 = BitXor(move _36, move _37);
+-         StorageDead(_37);
+-         StorageDead(_36);
+-         _34 = opaque::<u64>(move _35) -> [return: bb10, unwind continue];
++         _35 = BitXor(_1, _2);
++         _34 = opaque::<u64>(_35) -> [return: bb10, unwind continue];
+      }
+  
+      bb10: {
+-         StorageDead(_35);
+          StorageDead(_34);
+          StorageLive(_38);
+-         StorageLive(_39);
+-         StorageLive(_40);
+-         _40 = _1;
+-         StorageLive(_41);
+-         _41 = _2;
+-         _39 = Shl(move _40, move _41);
+-         StorageDead(_41);
+-         StorageDead(_40);
+-         _38 = opaque::<u64>(move _39) -> [return: bb11, unwind continue];
++         _39 = Shl(_1, _2);
++         _38 = opaque::<u64>(_39) -> [return: bb11, unwind continue];
+      }
+  
+      bb11: {
+-         StorageDead(_39);
+          StorageDead(_38);
+          StorageLive(_42);
+-         StorageLive(_43);
+-         StorageLive(_44);
+-         _44 = _1;
+-         StorageLive(_45);
+-         _45 = _2;
+-         _43 = Shr(move _44, move _45);
+-         StorageDead(_45);
+-         StorageDead(_44);
+-         _42 = opaque::<u64>(move _43) -> [return: bb12, unwind continue];
++         _43 = Shr(_1, _2);
++         _42 = opaque::<u64>(_43) -> [return: bb12, unwind continue];
+      }
+  
+      bb12: {
+-         StorageDead(_43);
+          StorageDead(_42);
+          StorageLive(_46);
+          StorageLive(_47);
+-         StorageLive(_48);
+-         _48 = _1;
+-         _47 = move _48 as u32 (IntToInt);
+-         StorageDead(_48);
++         _47 = _1 as u32 (IntToInt);
+          _46 = opaque::<u32>(move _47) -> [return: bb13, unwind continue];
+      }
+  
+      bb13: {
+          StorageDead(_47);
+          StorageDead(_46);
+          StorageLive(_49);
+          StorageLive(_50);
+-         StorageLive(_51);
+-         _51 = _1;
+-         _50 = move _51 as f32 (IntToFloat);
+-         StorageDead(_51);
++         _50 = _1 as f32 (IntToFloat);
+          _49 = opaque::<f32>(move _50) -> [return: bb14, unwind continue];
+      }
+  
+      bb14: {
+          StorageDead(_50);
+          StorageDead(_49);
+          StorageLive(_52);
+-         StorageLive(_53);
+-         StorageLive(_54);
+-         _54 = _1;
+-         _53 = S::<u64>(move _54);
+-         StorageDead(_54);
+-         _52 = opaque::<S<u64>>(move _53) -> [return: bb15, unwind continue];
++         _53 = S::<u64>(_1);
++         _52 = opaque::<S<u64>>(_53) -> [return: bb15, unwind continue];
+      }
+  
+      bb15: {
+-         StorageDead(_53);
+          StorageDead(_52);
+          StorageLive(_55);
+-         StorageLive(_56);
+-         StorageLive(_57);
+-         StorageLive(_58);
+-         _58 = _1;
+-         _57 = S::<u64>(move _58);
+-         StorageDead(_58);
+-         _56 = (_57.0: u64);
+-         _55 = opaque::<u64>(move _56) -> [return: bb16, unwind continue];
++         _56 = (_53.0: u64);
++         _55 = opaque::<u64>(_56) -> [return: bb16, unwind continue];
+      }
+  
+      bb16: {
+-         StorageDead(_56);
+-         StorageDead(_57);
+          StorageDead(_55);
+          StorageLive(_59);
+          StorageLive(_60);
+-         StorageLive(_61);
+-         StorageLive(_62);
+-         _62 = _1;
+-         StorageLive(_63);
+-         _63 = _2;
+-         _61 = Add(move _62, move _63);
+-         StorageDead(_63);
+-         StorageDead(_62);
+          StorageLive(_64);
+          _64 = _3;
+-         _60 = Add(move _61, move _64);
++         _60 = Add(_5, move _64);
+          StorageDead(_64);
+-         StorageDead(_61);
+          _59 = opaque::<u64>(move _60) -> [return: bb17, unwind continue];
+      }
+  
+      bb17: {
+          StorageDead(_60);
+          StorageDead(_59);
+          StorageLive(_65);
+          StorageLive(_66);
+-         StorageLive(_67);
+-         StorageLive(_68);
+-         _68 = _1;
+-         StorageLive(_69);
+-         _69 = _2;
+-         _67 = Mul(move _68, move _69);
+-         StorageDead(_69);
+-         StorageDead(_68);
+          StorageLive(_70);
+          _70 = _3;
+-         _66 = Add(move _67, move _70);
++         _66 = Add(_9, move _70);
+          StorageDead(_70);
+-         StorageDead(_67);
+          _65 = opaque::<u64>(move _66) -> [return: bb18, unwind continue];
+      }
+  
+      bb18: {
+          StorageDead(_66);
+          StorageDead(_65);
+          StorageLive(_71);
+          StorageLive(_72);
+-         StorageLive(_73);
+-         StorageLive(_74);
+-         _74 = _1;
+-         StorageLive(_75);
+-         _75 = _2;
+-         _73 = Sub(move _74, move _75);
+-         StorageDead(_75);
+-         StorageDead(_74);
+          StorageLive(_76);
+          _76 = _3;
+-         _72 = Add(move _73, move _76);
++         _72 = Add(_13, move _76);
+          StorageDead(_76);
+-         StorageDead(_73);
+          _71 = opaque::<u64>(move _72) -> [return: bb19, unwind continue];
+      }
+  
+      bb19: {
+          StorageDead(_72);
+          StorageDead(_71);
+          StorageLive(_77);
+          StorageLive(_78);
+-         StorageLive(_79);
+-         StorageLive(_80);
+-         _80 = _1;
+-         StorageLive(_81);
+-         _81 = _2;
+-         _82 = Eq(_81, const 0_u64);
+-         assert(!move _82, "attempt to divide `{}` by zero", _80) -> [success: bb20, unwind continue];
++         assert(!_20, "attempt to divide `{}` by zero", _1) -> [success: bb20, unwind continue];
+      }
+  
+      bb20: {
+-         _79 = Div(move _80, move _81);
+-         StorageDead(_81);
+-         StorageDead(_80);
+          StorageLive(_83);
+          _83 = _3;
+-         _78 = Add(move _79, move _83);
++         _78 = Add(_17, move _83);
+          StorageDead(_83);
+-         StorageDead(_79);
+          _77 = opaque::<u64>(move _78) -> [return: bb21, unwind continue];
+      }
+  
+      bb21: {
+          StorageDead(_78);
+          StorageDead(_77);
+          StorageLive(_84);
+          StorageLive(_85);
+-         StorageLive(_86);
+-         StorageLive(_87);
+-         _87 = _1;
+-         StorageLive(_88);
+-         _88 = _2;
+-         _89 = Eq(_88, const 0_u64);
+-         assert(!move _89, "attempt to calculate the remainder of `{}` with a divisor of zero", _87) -> [success: bb22, unwind continue];
++         assert(!_20, "attempt to calculate the remainder of `{}` with a divisor of zero", _1) -> [success: bb22, unwind continue];
+      }
+  
+      bb22: {
+-         _86 = Rem(move _87, move _88);
+-         StorageDead(_88);
+-         StorageDead(_87);
+          StorageLive(_90);
+          _90 = _3;
+-         _85 = Add(move _86, move _90);
++         _85 = Add(_22, move _90);
+          StorageDead(_90);
+-         StorageDead(_86);
+          _84 = opaque::<u64>(move _85) -> [return: bb23, unwind continue];
+      }
+  
+      bb23: {
+          StorageDead(_85);
+          StorageDead(_84);
+          StorageLive(_91);
+          StorageLive(_92);
+-         StorageLive(_93);
+-         StorageLive(_94);
+-         _94 = _1;
+-         StorageLive(_95);
+-         _95 = _2;
+-         _93 = BitAnd(move _94, move _95);
+-         StorageDead(_95);
+-         StorageDead(_94);
+          StorageLive(_96);
+          _96 = _3;
+-         _92 = Add(move _93, move _96);
++         _92 = Add(_27, move _96);
+          StorageDead(_96);
+-         StorageDead(_93);
+          _91 = opaque::<u64>(move _92) -> [return: bb24, unwind continue];
+      }
+  
+      bb24: {
+          StorageDead(_92);
+          StorageDead(_91);
+          StorageLive(_97);
+          StorageLive(_98);
+-         StorageLive(_99);
+-         StorageLive(_100);
+-         _100 = _1;
+-         StorageLive(_101);
+-         _101 = _2;
+-         _99 = BitOr(move _100, move _101);
+-         StorageDead(_101);
+-         StorageDead(_100);
+          StorageLive(_102);
+          _102 = _3;
+-         _98 = Add(move _99, move _102);
++         _98 = Add(_31, move _102);
+          StorageDead(_102);
+-         StorageDead(_99);
+          _97 = opaque::<u64>(move _98) -> [return: bb25, unwind continue];
+      }
+  
+      bb25: {
+          StorageDead(_98);
+          StorageDead(_97);
+          StorageLive(_103);
+          StorageLive(_104);
+-         StorageLive(_105);
+-         StorageLive(_106);
+-         _106 = _1;
+-         StorageLive(_107);
+-         _107 = _2;
+-         _105 = BitXor(move _106, move _107);
+-         StorageDead(_107);
+-         StorageDead(_106);
+          StorageLive(_108);
+          _108 = _3;
+-         _104 = Add(move _105, move _108);
++         _104 = Add(_35, move _108);
+          StorageDead(_108);
+-         StorageDead(_105);
+          _103 = opaque::<u64>(move _104) -> [return: bb26, unwind continue];
+      }
+  
+      bb26: {
+          StorageDead(_104);
+          StorageDead(_103);
+          StorageLive(_109);
+          StorageLive(_110);
+-         StorageLive(_111);
+-         StorageLive(_112);
+-         _112 = _1;
+-         StorageLive(_113);
+-         _113 = _2;
+-         _111 = Shl(move _112, move _113);
+-         StorageDead(_113);
+-         StorageDead(_112);
+          StorageLive(_114);
+          _114 = _3;
+-         _110 = Add(move _111, move _114);
++         _110 = Add(_39, move _114);
+          StorageDead(_114);
+-         StorageDead(_111);
+          _109 = opaque::<u64>(move _110) -> [return: bb27, unwind continue];
+      }
+  
+      bb27: {
+          StorageDead(_110);
+          StorageDead(_109);
+          StorageLive(_115);
+          StorageLive(_116);
+-         StorageLive(_117);
+-         StorageLive(_118);
+-         _118 = _1;
+-         StorageLive(_119);
+-         _119 = _2;
+-         _117 = Shr(move _118, move _119);
+-         StorageDead(_119);
+-         StorageDead(_118);
+          StorageLive(_120);
+          _120 = _3;
+-         _116 = Add(move _117, move _120);
++         _116 = Add(_43, move _120);
+          StorageDead(_120);
+-         StorageDead(_117);
+          _115 = opaque::<u64>(move _116) -> [return: bb28, unwind continue];
+      }
+  
+      bb28: {
+          StorageDead(_116);
+          StorageDead(_115);
+          StorageLive(_121);
+-         StorageLive(_122);
+-         StorageLive(_123);
+-         _123 = _1;
+-         _122 = S::<u64>(move _123);
+-         StorageDead(_123);
+-         _121 = opaque::<S<u64>>(move _122) -> [return: bb29, unwind continue];
++         _121 = opaque::<S<u64>>(_53) -> [return: bb29, unwind continue];
+      }
+  
+      bb29: {
+-         StorageDead(_122);
+          StorageDead(_121);
+          StorageLive(_124);
+-         StorageLive(_125);
+-         StorageLive(_126);
+-         StorageLive(_127);
+-         _127 = _1;
+-         _126 = S::<u64>(move _127);
+-         StorageDead(_127);
+-         _125 = (_126.0: u64);
+-         _124 = opaque::<u64>(move _125) -> [return: bb30, unwind continue];
++         _124 = opaque::<u64>(_56) -> [return: bb30, unwind continue];
+      }
+  
+      bb30: {
+-         StorageDead(_125);
+-         StorageDead(_126);
+          StorageDead(_124);
+          StorageLive(_128);
+          _128 = &_3;
+          StorageLive(_129);
+-         StorageLive(_130);
+-         StorageLive(_131);
+          _131 = (*_128);
+-         StorageLive(_132);
+-         _132 = _1;
+-         _130 = Add(move _131, move _132);
+-         StorageDead(_132);
+-         StorageDead(_131);
+-         _129 = opaque::<u64>(move _130) -> [return: bb31, unwind continue];
++         _130 = Add(_131, _1);
++         _129 = opaque::<u64>(_130) -> [return: bb31, unwind continue];
+      }
+  
+      bb31: {
+-         StorageDead(_130);
+          StorageDead(_129);
+          StorageLive(_133);
+-         StorageLive(_134);
+-         StorageLive(_135);
+-         _135 = (*_128);
+-         StorageLive(_136);
+-         _136 = _1;
+-         _134 = Add(move _135, move _136);
+-         StorageDead(_136);
+-         StorageDead(_135);
+-         _133 = opaque::<u64>(move _134) -> [return: bb32, unwind continue];
++         _133 = opaque::<u64>(_130) -> [return: bb32, unwind continue];
+      }
+  
+      bb32: {
+-         StorageDead(_134);
+          StorageDead(_133);
+          StorageLive(_137);
+          _137 = &mut _3;
+          StorageLive(_138);
+          StorageLive(_139);
+          StorageLive(_140);
+          _140 = (*_137);
+-         StorageLive(_141);
+-         _141 = _1;
+-         _139 = Add(move _140, move _141);
+-         StorageDead(_141);
++         _139 = Add(move _140, _1);
+          StorageDead(_140);
+          _138 = opaque::<u64>(move _139) -> [return: bb33, unwind continue];
+      }
+  
+      bb33: {
+          StorageDead(_139);
+          StorageDead(_138);
+          StorageLive(_142);
+          StorageLive(_143);
+          StorageLive(_144);
+          _144 = (*_137);
+-         StorageLive(_145);
+-         _145 = _1;
+-         _143 = Add(move _144, move _145);
+-         StorageDead(_145);
++         _143 = Add(move _144, _1);
+          StorageDead(_144);
+          _142 = opaque::<u64>(move _143) -> [return: bb34, unwind continue];
+      }
+  
+      bb34: {
+          StorageDead(_143);
+          StorageDead(_142);
+-         StorageLive(_146);
+          StorageLive(_147);
+          _147 = &raw const _3;
+          StorageLive(_148);
+          StorageLive(_149);
+          StorageLive(_150);
+          _150 = (*_147);
+-         StorageLive(_151);
+-         _151 = _1;
+-         _149 = Add(move _150, move _151);
+-         StorageDead(_151);
++         _149 = Add(move _150, _1);
+          StorageDead(_150);
+          _148 = opaque::<u64>(move _149) -> [return: bb35, unwind continue];
+      }
+  
+      bb35: {
+          StorageDead(_149);
+          StorageDead(_148);
+          StorageLive(_152);
+          StorageLive(_153);
+          StorageLive(_154);
+          _154 = (*_147);
+-         StorageLive(_155);
+-         _155 = _1;
+-         _153 = Add(move _154, move _155);
+-         StorageDead(_155);
++         _153 = Add(move _154, _1);
+          StorageDead(_154);
+          _152 = opaque::<u64>(move _153) -> [return: bb36, unwind continue];
+      }
+  
+      bb36: {
+          StorageDead(_153);
+          StorageDead(_152);
+          StorageLive(_156);
+          _156 = &raw mut _3;
+          StorageLive(_157);
+          StorageLive(_158);
+          StorageLive(_159);
+          _159 = (*_156);
+-         StorageLive(_160);
+-         _160 = _1;
+-         _158 = Add(move _159, move _160);
+-         StorageDead(_160);
++         _158 = Add(move _159, _1);
+          StorageDead(_159);
+          _157 = opaque::<u64>(move _158) -> [return: bb37, unwind continue];
+      }
+  
+      bb37: {
+          StorageDead(_158);
+          StorageDead(_157);
+          StorageLive(_161);
+          StorageLive(_162);
+          StorageLive(_163);
+          _163 = (*_156);
+-         StorageLive(_164);
+-         _164 = _1;
+-         _162 = Add(move _163, move _164);
+-         StorageDead(_164);
++         _162 = Add(move _163, _1);
+          StorageDead(_163);
+          _161 = opaque::<u64>(move _162) -> [return: bb38, unwind continue];
+      }
+  
+      bb38: {
+          StorageDead(_162);
+          StorageDead(_161);
+-         _146 = const ();
+          StorageDead(_156);
+          StorageDead(_147);
+-         StorageDead(_146);
+          StorageLive(_165);
+          _165 = &_3;
+          StorageLive(_166);
+-         StorageLive(_167);
+-         StorageLive(_168);
+          _168 = (*_165);
+-         StorageLive(_169);
+-         _169 = _1;
+-         _167 = Add(move _168, move _169);
+-         StorageDead(_169);
+-         StorageDead(_168);
+-         _166 = opaque::<u64>(move _167) -> [return: bb39, unwind continue];
++         _167 = Add(_168, _1);
++         _166 = opaque::<u64>(_167) -> [return: bb39, unwind continue];
+      }
+  
+      bb39: {
+-         StorageDead(_167);
+          StorageDead(_166);
+          StorageLive(_170);
+-         StorageLive(_171);
+-         StorageLive(_172);
+-         _172 = (*_165);
+-         StorageLive(_173);
+-         _173 = _1;
+-         _171 = Add(move _172, move _173);
+-         StorageDead(_173);
+-         StorageDead(_172);
+-         _170 = opaque::<u64>(move _171) -> [return: bb40, unwind continue];
++         _170 = opaque::<u64>(_167) -> [return: bb40, unwind continue];
+      }
+  
+      bb40: {
+-         StorageDead(_171);
+          StorageDead(_170);
+          _0 = const ();
+          StorageDead(_165);
+          StorageDead(_137);
+          StorageDead(_128);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-abort.diff b/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-abort.diff
new file mode 100644
index 00000000000..f33845502ad
--- /dev/null
+++ b/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-abort.diff
@@ -0,0 +1,45 @@
+- // MIR for `wrap_unwrap` before GVN
++ // MIR for `wrap_unwrap` after GVN
+  
+  fn wrap_unwrap(_1: T) -> T {
+      debug x => _1;
+      let mut _0: T;
+      let mut _2: std::option::Option<T>;
+      let mut _3: T;
+      let mut _4: isize;
+      let _5: T;
+      let mut _6: !;
+      scope 1 {
+          debug y => _5;
+      }
+  
+      bb0: {
+          StorageLive(_2);
+-         StorageLive(_3);
+-         _3 = _1;
+-         _2 = Option::<T>::Some(move _3);
+-         StorageDead(_3);
++         _2 = Option::<T>::Some(_1);
+          _4 = discriminant(_2);
+          switchInt(move _4) -> [0: bb1, 1: bb3, otherwise: bb2];
+      }
+  
+      bb1: {
+          StorageLive(_6);
+          _6 = begin_panic::<&str>(const "explicit panic") -> unwind unreachable;
+      }
+  
+      bb2: {
+          unreachable;
+      }
+  
+      bb3: {
+-         StorageLive(_5);
+          _5 = ((_2 as Some).0: T);
+          _0 = _5;
+-         StorageDead(_5);
+          StorageDead(_2);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-unwind.diff b/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-unwind.diff
new file mode 100644
index 00000000000..edc05f99fe2
--- /dev/null
+++ b/tests/mir-opt/gvn.wrap_unwrap.GVN.panic-unwind.diff
@@ -0,0 +1,45 @@
+- // MIR for `wrap_unwrap` before GVN
++ // MIR for `wrap_unwrap` after GVN
+  
+  fn wrap_unwrap(_1: T) -> T {
+      debug x => _1;
+      let mut _0: T;
+      let mut _2: std::option::Option<T>;
+      let mut _3: T;
+      let mut _4: isize;
+      let _5: T;
+      let mut _6: !;
+      scope 1 {
+          debug y => _5;
+      }
+  
+      bb0: {
+          StorageLive(_2);
+-         StorageLive(_3);
+-         _3 = _1;
+-         _2 = Option::<T>::Some(move _3);
+-         StorageDead(_3);
++         _2 = Option::<T>::Some(_1);
+          _4 = discriminant(_2);
+          switchInt(move _4) -> [0: bb1, 1: bb3, otherwise: bb2];
+      }
+  
+      bb1: {
+          StorageLive(_6);
+          _6 = begin_panic::<&str>(const "explicit panic") -> unwind continue;
+      }
+  
+      bb2: {
+          unreachable;
+      }
+  
+      bb3: {
+-         StorageLive(_5);
+          _5 = ((_2 as Some).0: T);
+          _0 = _5;
+-         StorageDead(_5);
+          StorageDead(_2);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir b/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
index 549306071ad..721fac27d88 100644
--- a/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
+++ b/tests/mir-opt/inline/inline_closure_captures.foo.Inline.after.mir
@@ -42,10 +42,10 @@ fn foo(_1: T, _2: i32) -> (i32, T) {
         StorageLive(_9);
         _9 = move (_7.0: i32);
         StorageLive(_11);
-        _10 = deref_copy ((*_6).0: &i32);
+        _10 = ((*_6).0: &i32);
         _11 = (*_10);
         StorageLive(_13);
-        _12 = deref_copy ((*_6).1: &T);
+        _12 = ((*_6).1: &T);
         _13 = (*_12);
         _0 = (move _11, move _13);
         StorageDead(_13);
diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
index d2c0591cc0a..6779003b693 100644
--- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-abort.diff
@@ -26,8 +26,6 @@
 +         let mut _6: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
 +         let mut _7: u32;
 +         let mut _8: i32;
-+         let mut _9: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
-+         let mut _10: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
 +     }
   
       bb0: {
@@ -36,71 +34,74 @@
           StorageLive(_3);
           StorageLive(_4);
 -         _4 = g() -> [return: bb1, unwind unreachable];
--     }
-- 
--     bb1: {
 +         _4 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
-          _3 = &mut _4;
--         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new(move _3) -> [return: bb2, unwind unreachable];
--     }
-- 
--     bb2: {
++         _3 = &mut _4;
 +         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}> { pointer: move _3 };
-          StorageDead(_3);
--         _1 = <{generator@$DIR/inline_generator.rs:16:5: 16:8} as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind unreachable];
++         StorageDead(_3);
 +         StorageLive(_5);
 +         _5 = const false;
-+         _6 = deref_copy (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
++         _6 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
 +         _7 = discriminant((*_6));
-+         switchInt(move _7) -> [0: bb2, 1: bb6, 3: bb7, otherwise: bb8];
++         switchInt(move _7) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9];
       }
   
--     bb3: {
-+     bb1: {
+      bb1: {
+-         _3 = &mut _4;
+-         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new(move _3) -> [return: bb2, unwind unreachable];
 +         StorageDead(_5);
-          StorageDead(_2);
-          StorageDead(_4);
-          _0 = const ();
-          StorageDead(_1);
-          return;
-+     }
-+ 
-+     bb2: {
++         StorageDead(_2);
++         drop(_4) -> [return: bb2, unwind unreachable];
+      }
+  
+      bb2: {
+-         StorageDead(_3);
+-         _1 = <{generator@$DIR/inline_generator.rs:16:5: 16:8} as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind unreachable];
++         StorageDead(_4);
++         _0 = const ();
++         StorageDead(_1);
++         return;
+      }
+  
+      bb3: {
+-         StorageDead(_2);
+-         drop(_4) -> [return: bb4, unwind unreachable];
 +         StorageLive(_8);
-+         switchInt(_5) -> [0: bb3, otherwise: bb4];
-+     }
-+ 
-+     bb3: {
++         switchInt(_5) -> [0: bb4, otherwise: bb5];
+      }
+  
+      bb4: {
+-         StorageDead(_4);
+-         _0 = const ();
+-         StorageDead(_1);
+-         return;
 +         _8 = const 13_i32;
-+         goto -> bb5;
++         goto -> bb6;
 +     }
 + 
-+     bb4: {
++     bb5: {
 +         _8 = const 7_i32;
-+         goto -> bb5;
++         goto -> bb6;
 +     }
 + 
-+     bb5: {
++     bb6: {
 +         _1 = GeneratorState::<i32, bool>::Yielded(move _8);
-+         _9 = deref_copy (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
-+         discriminant((*_9)) = 3;
++         discriminant((*_6)) = 3;
 +         goto -> bb1;
 +     }
 + 
-+     bb6: {
-+         assert(const false, "generator resumed after completion") -> [success: bb6, unwind unreachable];
++     bb7: {
++         assert(const false, "generator resumed after completion") -> [success: bb7, unwind unreachable];
 +     }
 + 
-+     bb7: {
++     bb8: {
 +         StorageLive(_8);
 +         StorageDead(_8);
 +         _1 = GeneratorState::<i32, bool>::Complete(_5);
-+         _10 = deref_copy (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
-+         discriminant((*_10)) = 1;
++         discriminant((*_6)) = 1;
 +         goto -> bb1;
 +     }
 + 
-+     bb8: {
++     bb9: {
 +         unreachable;
       }
   }
diff --git a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
index c024e3d7f77..31744be99ec 100644
--- a/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_generator.main.Inline.panic-unwind.diff
@@ -26,8 +26,6 @@
 +         let mut _6: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
 +         let mut _7: u32;
 +         let mut _8: i32;
-+         let mut _9: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
-+         let mut _10: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8};
 +     }
   
       bb0: {
@@ -41,71 +39,81 @@
 -     bb1: {
 +         _4 = {generator@$DIR/inline_generator.rs:16:5: 16:8 (#0)};
           _3 = &mut _4;
--         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new(move _3) -> [return: bb2, unwind: bb4];
+-         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}>::new(move _3) -> [return: bb2, unwind: bb5];
 -     }
 - 
 -     bb2: {
 +         _2 = Pin::<&mut {generator@$DIR/inline_generator.rs:16:5: 16:8}> { pointer: move _3 };
           StorageDead(_3);
--         _1 = <{generator@$DIR/inline_generator.rs:16:5: 16:8} as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb4];
+-         _1 = <{generator@$DIR/inline_generator.rs:16:5: 16:8} as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb5];
 +         StorageLive(_5);
 +         _5 = const false;
-+         _6 = deref_copy (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
++         _6 = (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
 +         _7 = discriminant((*_6));
-+         switchInt(move _7) -> [0: bb3, 1: bb7, 3: bb8, otherwise: bb9];
++         switchInt(move _7) -> [0: bb5, 1: bb9, 3: bb10, otherwise: bb11];
       }
   
 -     bb3: {
 +     bb1: {
 +         StorageDead(_5);
           StorageDead(_2);
+-         drop(_4) -> [return: bb4, unwind: bb6];
++         drop(_4) -> [return: bb2, unwind: bb4];
+      }
+  
+-     bb4: {
++     bb2: {
           StorageDead(_4);
           _0 = const ();
           StorageDead(_1);
           return;
       }
   
--     bb4 (cleanup): {
-+     bb2 (cleanup): {
+-     bb5 (cleanup): {
+-         drop(_4) -> [return: bb6, unwind terminate(cleanup)];
++     bb3 (cleanup): {
++         drop(_4) -> [return: bb4, unwind terminate(cleanup)];
+      }
+  
+-     bb6 (cleanup): {
++     bb4 (cleanup): {
           resume;
 +     }
 + 
-+     bb3: {
++     bb5: {
 +         StorageLive(_8);
-+         switchInt(_5) -> [0: bb4, otherwise: bb5];
++         switchInt(_5) -> [0: bb6, otherwise: bb7];
 +     }
 + 
-+     bb4: {
++     bb6: {
 +         _8 = const 13_i32;
-+         goto -> bb6;
++         goto -> bb8;
 +     }
 + 
-+     bb5: {
++     bb7: {
 +         _8 = const 7_i32;
-+         goto -> bb6;
++         goto -> bb8;
 +     }
 + 
-+     bb6: {
++     bb8: {
 +         _1 = GeneratorState::<i32, bool>::Yielded(move _8);
-+         _9 = deref_copy (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
-+         discriminant((*_9)) = 3;
++         discriminant((*_6)) = 3;
 +         goto -> bb1;
 +     }
 + 
-+     bb7: {
-+         assert(const false, "generator resumed after completion") -> [success: bb7, unwind: bb2];
++     bb9: {
++         assert(const false, "generator resumed after completion") -> [success: bb9, unwind: bb3];
 +     }
 + 
-+     bb8: {
++     bb10: {
 +         StorageLive(_8);
 +         StorageDead(_8);
 +         _1 = GeneratorState::<i32, bool>::Complete(_5);
-+         _10 = deref_copy (_2.0: &mut {generator@$DIR/inline_generator.rs:16:5: 16:8});
-+         discriminant((*_10)) = 1;
++         discriminant((*_6)) = 1;
 +         goto -> bb1;
 +     }
 + 
-+     bb9: {
++     bb11: {
 +         unreachable;
       }
   }
diff --git a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff
index c94dd255695..b532b133a83 100644
--- a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff
+++ b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-abort.diff
@@ -15,28 +15,44 @@
           StorageLive(_2);
           StorageLive(_3);
           StorageLive(_4);
-          _4 = hide_foo() -> [return: bb1, unwind unreachable];
+          _4 = hide_foo() -> [return: bb1, unwind: bb6];
       }
   
       bb1: {
           _3 = &_4;
           StorageLive(_5);
           _5 = ();
--         _2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind unreachable];
-+         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind unreachable];
+-         _2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb5];
++         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb5];
       }
   
       bb2: {
           StorageDead(_5);
           StorageDead(_3);
+          drop(_4) -> [return: bb3, unwind: bb6];
+      }
+  
+      bb3: {
           StorageDead(_4);
           StorageDead(_2);
           _0 = const ();
-          drop(_1) -> [return: bb3, unwind unreachable];
+          drop(_1) -> [return: bb4, unwind: bb7];
       }
   
-      bb3: {
+      bb4: {
           return;
       }
+  
+      bb5 (cleanup): {
+          drop(_4) -> [return: bb6, unwind terminate(cleanup)];
+      }
+  
+      bb6 (cleanup): {
+          drop(_1) -> [return: bb7, unwind terminate(cleanup)];
+      }
+  
+      bb7 (cleanup): {
+          resume;
+      }
   }
   
diff --git a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff
index cbfb39115b3..bcebcf297c2 100644
--- a/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff
+++ b/tests/mir-opt/inline/issue_78442.bar.RevealAll.panic-unwind.diff
@@ -15,35 +15,43 @@
           StorageLive(_2);
           StorageLive(_3);
           StorageLive(_4);
-          _4 = hide_foo() -> [return: bb1, unwind: bb4];
+          _4 = hide_foo() -> [return: bb1, unwind: bb6];
       }
   
       bb1: {
           _3 = &_4;
           StorageLive(_5);
           _5 = ();
--         _2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4];
-+         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb4];
+-         _2 = <impl Fn() as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb5];
++         _2 = <fn() {foo} as Fn<()>>::call(move _3, move _5) -> [return: bb2, unwind: bb5];
       }
   
       bb2: {
           StorageDead(_5);
           StorageDead(_3);
+          drop(_4) -> [return: bb3, unwind: bb6];
+      }
+  
+      bb3: {
           StorageDead(_4);
           StorageDead(_2);
           _0 = const ();
-          drop(_1) -> [return: bb3, unwind: bb5];
+          drop(_1) -> [return: bb4, unwind continue];
       }
   
-      bb3: {
+      bb4: {
           return;
       }
   
-      bb4 (cleanup): {
-          drop(_1) -> [return: bb5, unwind terminate(cleanup)];
+      bb5 (cleanup): {
+          drop(_4) -> [return: bb6, unwind terminate(cleanup)];
       }
   
-      bb5 (cleanup): {
+      bb6 (cleanup): {
+          drop(_1) -> [return: bb7, unwind terminate(cleanup)];
+      }
+  
+      bb7 (cleanup): {
           resume;
       }
   }
diff --git a/tests/mir-opt/ssa_unreachable_116212.rs b/tests/mir-opt/ssa_unreachable_116212.rs
new file mode 100644
index 00000000000..f588665876c
--- /dev/null
+++ b/tests/mir-opt/ssa_unreachable_116212.rs
@@ -0,0 +1,14 @@
+// Regression test for issue #116212.
+
+#![feature(never_type)]
+
+use std::mem::MaybeUninit;
+
+struct Foo {
+    x: u8,
+    y: !,
+}
+
+fn main() {
+    let foo = unsafe { MaybeUninit::<Foo>::uninit().assume_init() };
+}
diff --git a/tests/run-make/macos-deployment-target/Makefile b/tests/run-make/macos-deployment-target/Makefile
index d0cf836bcdf..757ca699535 100644
--- a/tests/run-make/macos-deployment-target/Makefile
+++ b/tests/run-make/macos-deployment-target/Makefile
@@ -9,12 +9,12 @@ include ../tools.mk
 ifeq ($(strip $(shell uname -m)),arm64)
 	GREP_PATTERN = "minos 11.0"
 else
- 	GREP_PATTERN = "version 10.9"
+ 	GREP_PATTERN = "version 10.13"
 endif
 
 OUT_FILE=$(TMPDIR)/with_deployment_target.dylib
 all:
-	env MACOSX_DEPLOYMENT_TARGET=10.9 $(RUSTC) with_deployment_target.rs -o $(OUT_FILE)
+	env MACOSX_DEPLOYMENT_TARGET=10.13 $(RUSTC) with_deployment_target.rs -o $(OUT_FILE)
 # XXX: The check is for either the x86_64 minimum OR the aarch64 minimum (M1 starts at macOS 11).
 # They also use different load commands, so we let that change with each too. The aarch64 check
 # isn't as robust as the x86 one, but testing both seems unneeded.
diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile
index 1f2812cb087..9ba077b1854 100644
--- a/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile
+++ b/tests/run-make/rlib-format-packed-bundled-libs-3/Makefile
@@ -3,7 +3,7 @@ include ../tools.mk
 # ignore-cross-compile
 # only-linux
 
-# Make sure -Zpacked_bundled_libs-like behavior activates with whole-archive.
+# Make sure -Zpacked_bundled_libs-like behavior activates with +bundle,+whole-archive.
 
 # We're using the llvm-nm instead of the system nm to ensure it is compatible
 # with the LLVM bitcode generated by rustc.
@@ -11,7 +11,7 @@ NM = "$(LLVM_BIN_DIR)"/llvm-nm
 
 all: $(call NATIVE_STATICLIB,native_dep_1) $(call NATIVE_STATICLIB,native_dep_2) $(call NATIVE_STATICLIB,native_dep_3) $(call NATIVE_STATICLIB,native_dep_4)
 	# test cfg with packed bundle
-	$(RUSTC) rust_dep_cfg.rs --crate-type=rlib -Zpacked_bundled_libs
+	$(RUSTC) rust_dep_cfg.rs --crate-type=rlib
 	$(RUSTC) main.rs --extern rust_dep=$(TMPDIR)/librust_dep_cfg.rlib --crate-type=staticlib --cfg should_add
 	$(AR) t $(TMPDIR)/librust_dep_cfg.rlib | $(CGREP) -e "libnative_dep_1.a"
 	$(AR) t $(TMPDIR)/librust_dep_cfg.rlib | $(CGREP) -e "libnative_dep_2.a"
diff --git a/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs
index abd846b6862..bde9b739de6 100644
--- a/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs
+++ b/tests/run-make/rlib-format-packed-bundled-libs-3/rust_dep.rs
@@ -1,5 +1,3 @@
-#![feature(packed_bundled_libs)]
-
 #[link(name = "native_dep_1", kind = "static", modifiers = "+whole-archive,+bundle")]
 extern "C" {}
 
diff --git a/tests/rustdoc-gui/default-settings.goml b/tests/rustdoc-gui/default-settings.goml
index 3466f3693f9..ff4abb65c02 100644
--- a/tests/rustdoc-gui/default-settings.goml
+++ b/tests/rustdoc-gui/default-settings.goml
@@ -5,4 +5,4 @@
 go-to: "file://" + |DOC_PATH| + "/settings/index.html"
 // Wait a bit to be sure the default theme is applied.
 // If the theme isn't applied, the command will time out.
-wait-for-css: ("body", {"background-color": "rgb(15, 20, 25)"})
+wait-for-css: ("body", {"background-color": "#0f1419"})
diff --git a/tests/rustdoc-ui/issue-102467.rs b/tests/rustdoc-ui/issue-102467.rs
new file mode 100644
index 00000000000..bff876e41d6
--- /dev/null
+++ b/tests/rustdoc-ui/issue-102467.rs
@@ -0,0 +1,15 @@
+// Regression test for <https://github.com/rust-lang/rust/issues/102467>.
+// It ensures that the expected error is displayed.
+
+#![feature(associated_const_equality)]
+
+trait T {
+    type A: S<C<X = 0i32> = 34>;
+    //~^ ERROR associated type bindings are not allowed here
+}
+
+trait S {
+    const C: i32;
+}
+
+fn main() {}
diff --git a/tests/rustdoc-ui/issue-102467.stderr b/tests/rustdoc-ui/issue-102467.stderr
new file mode 100644
index 00000000000..a337293f7a0
--- /dev/null
+++ b/tests/rustdoc-ui/issue-102467.stderr
@@ -0,0 +1,9 @@
+error[E0229]: associated type bindings are not allowed here
+  --> $DIR/issue-102467.rs:7:17
+   |
+LL |     type A: S<C<X = 0i32> = 34>;
+   |                 ^^^^^^^^ associated type not allowed here
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0229`.
diff --git a/tests/rustdoc/issue-15169.rs b/tests/rustdoc/anchor-id-trait-method-15169.rs
index e525d85e21e..26bb59c1875 100644
--- a/tests/rustdoc/issue-15169.rs
+++ b/tests/rustdoc/anchor-id-trait-method-15169.rs
@@ -1,3 +1,7 @@
 // @has issue_15169/struct.Foo.html '//*[@id="method.eq"]' 'fn eq'
+
+// https://github.com/rust-lang/rust/issues/15169
+#![crate_name="issue_15169"]
+
 #[derive(PartialEq)]
 pub struct Foo;
diff --git a/tests/rustdoc/issue-20646.rs b/tests/rustdoc/assoc-type-bindings-20646.rs
index b2ee9c26014..375b5b5b23e 100644
--- a/tests/rustdoc/issue-20646.rs
+++ b/tests/rustdoc/assoc-type-bindings-20646.rs
@@ -1,6 +1,8 @@
 // aux-build:issue-20646.rs
 // ignore-cross-compile
 
+// https://github.com/rust-lang/rust/issues/20646
+#![crate_name="issue_20646"]
 #![feature(associated_types)]
 
 extern crate issue_20646;
diff --git a/tests/rustdoc/issue-19190-2.rs b/tests/rustdoc/deref-methods-19190-foreign-type.rs
index b6416e2e5b9..c8326992115 100644
--- a/tests/rustdoc/issue-19190-2.rs
+++ b/tests/rustdoc/deref-methods-19190-foreign-type.rs
@@ -1,3 +1,7 @@
+// https://github.com/rust-lang/rust/issues/19190
+
+#![crate_name="issue_19190_2"]
+
 use std::ops::Deref;
 
 pub struct Bar;
diff --git a/tests/rustdoc/issue-19190-3.rs b/tests/rustdoc/deref-methods-19190-inline.rs
index 4d34ce6509f..619b268d68b 100644
--- a/tests/rustdoc/issue-19190-3.rs
+++ b/tests/rustdoc/deref-methods-19190-inline.rs
@@ -1,6 +1,9 @@
 // aux-build:issue-19190-3.rs
 // ignore-cross-compile
 
+// https://github.com/rust-lang/rust/issues/19190
+#![crate_name="issue_19190_3"]
+
 extern crate issue_19190_3;
 
 use std::ops::Deref;
diff --git a/tests/rustdoc/issue-19190.rs b/tests/rustdoc/deref-methods-19190.rs
index 2046273e2c1..4c274d82ff7 100644
--- a/tests/rustdoc/issue-19190.rs
+++ b/tests/rustdoc/deref-methods-19190.rs
@@ -1,3 +1,6 @@
+// https://github.com/rust-lang/rust/issues/19190
+#![crate_name="issue_19190"]
+
 use std::ops::Deref;
 
 pub struct Foo;
diff --git a/tests/rustdoc/issue-13698.rs b/tests/rustdoc/doc-hidden-method-13698.rs
index 3046a8a2862..f1bd6e73bab 100644
--- a/tests/rustdoc/issue-13698.rs
+++ b/tests/rustdoc/doc-hidden-method-13698.rs
@@ -1,6 +1,9 @@
 // aux-build:issue-13698.rs
 // ignore-cross-compile
 
+// https://github.com/rust-lang/rust/issues/13698
+#![crate_name="issue_13698"]
+
 extern crate issue_13698;
 
 pub struct Foo;
diff --git a/tests/rustdoc/issue-18199.rs b/tests/rustdoc/doc-test-attr-18199.rs
index 9cc58b162f3..c9d2235321c 100644
--- a/tests/rustdoc/issue-18199.rs
+++ b/tests/rustdoc/doc-test-attr-18199.rs
@@ -1,4 +1,5 @@
 // compile-flags:--test
+// https://github.com/rust-lang/rust/issues/18199
 
 #![doc(test(attr(feature(staged_api))))]
 
diff --git a/tests/rustdoc/issue-15347.rs b/tests/rustdoc/document-hidden-items-15347.rs
index e93d7401168..d8a760e5666 100644
--- a/tests/rustdoc/issue-15347.rs
+++ b/tests/rustdoc/document-hidden-items-15347.rs
@@ -1,4 +1,7 @@
 // compile-flags: -Z unstable-options --document-hidden-items
+// https://github.com/rust-lang/rust/issues/15347
+
+#![crate_name="issue_15347"]
 
 // @has issue_15347/fn.foo.html
 #[doc(hidden)]
diff --git a/tests/rustdoc/issue-12834.rs b/tests/rustdoc/highlight-invalid-rust-12834.rs
index 9605a1e78c1..f8acc500264 100644
--- a/tests/rustdoc/issue-12834.rs
+++ b/tests/rustdoc/highlight-invalid-rust-12834.rs
@@ -1,6 +1,8 @@
 // Tests that failing to syntax highlight a rust code-block doesn't cause
 // rustdoc to fail, while still rendering the code-block (without highlighting).
+// https://github.com/rust-lang/rust/issues/12834
 
+#![crate_name="issue_12834"]
 #![allow(rustdoc::invalid_rust_codeblocks)]
 
 // @has issue_12834/fn.foo.html
diff --git a/tests/rustdoc/issue-19181.rs b/tests/rustdoc/ice-type-error-19181.rs
index 3dea152fc6e..3ced6136664 100644
--- a/tests/rustdoc/issue-19181.rs
+++ b/tests/rustdoc/ice-type-error-19181.rs
@@ -1,4 +1,5 @@
 // compile-flags:--test
+// https://github.com/rust-lang/rust/issues/19181
 
 // rustdoc should not panic when target crate has compilation errors
 
diff --git a/tests/rustdoc/issue-20175.rs b/tests/rustdoc/impl-ref-20175.rs
index 6a42e2afbf4..a92db2d0a66 100644
--- a/tests/rustdoc/issue-20175.rs
+++ b/tests/rustdoc/impl-ref-20175.rs
@@ -1,3 +1,7 @@
+// https://github.com/rust-lang/rust/issues/20175
+
+#![crate_name="issue_20175"]
+
 pub trait Foo {
     fn foo(&self) {}
 }
diff --git a/tests/rustdoc/issue-16265-1.rs b/tests/rustdoc/infinite-redirection-16265-1.rs
index 2fda637a641..7d72469bd72 100644
--- a/tests/rustdoc/issue-16265-1.rs
+++ b/tests/rustdoc/infinite-redirection-16265-1.rs
@@ -1,3 +1,6 @@
+// https://github.com/rust-lang/rust/issues/16265
+#![crate_name="issue_16265_1"]
+
 pub struct Foo;
 
 // @hasraw issue_16265_1/traits/index.html 'source'
diff --git a/tests/rustdoc/issue-16265-2.rs b/tests/rustdoc/infinite-redirection-16265-2.rs
index c3eb356171e..7a4791c5fd4 100644
--- a/tests/rustdoc/issue-16265-2.rs
+++ b/tests/rustdoc/infinite-redirection-16265-2.rs
@@ -1,3 +1,6 @@
+// https://github.com/rust-lang/rust/issues/16265
+#![crate_name="issue_16265_2"]
+
 // @hasraw issue_16265_2/index.html 'source'
 
 trait Y {}
diff --git a/tests/rustdoc/issue-20727-2.rs b/tests/rustdoc/inline-assoc-type-20727-bindings.rs
index c1aa9617b2e..e59dec29d03 100644
--- a/tests/rustdoc/issue-20727-2.rs
+++ b/tests/rustdoc/inline-assoc-type-20727-bindings.rs
@@ -1,6 +1,9 @@
 // aux-build:issue-20727.rs
 // ignore-cross-compile
 
+// https://github.com/rust-lang/rust/issues/20727
+#![crate_name="issue_20727_2"]
+
 extern crate issue_20727;
 
 // @has issue_20727_2/trait.Add.html
diff --git a/tests/rustdoc/issue-20727-3.rs b/tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs
index 2f9d91fc5f7..005ee3e3294 100644
--- a/tests/rustdoc/issue-20727-3.rs
+++ b/tests/rustdoc/inline-assoc-type-20727-bounds-deref.rs
@@ -1,6 +1,9 @@
 // aux-build:issue-20727.rs
 // ignore-cross-compile
 
+// https://github.com/rust-lang/rust/issues/20727
+#![crate_name="issue_20727_3"]
+
 extern crate issue_20727;
 
 pub trait Bar {}
diff --git a/tests/rustdoc/issue-20727-4.rs b/tests/rustdoc/inline-assoc-type-20727-bounds-index.rs
index ec9f18fc3fe..1a3f4cd20c1 100644
--- a/tests/rustdoc/issue-20727-4.rs
+++ b/tests/rustdoc/inline-assoc-type-20727-bounds-index.rs
@@ -1,6 +1,9 @@
 // aux-build:issue-20727.rs
 // ignore-cross-compile
 
+// https://github.com/rust-lang/rust/issues/20727
+#![crate_name="issue_20727_4"]
+
 extern crate issue_20727;
 
 // @has issue_20727_4/trait.Index.html
diff --git a/tests/rustdoc/issue-20727.rs b/tests/rustdoc/inline-assoc-type-20727-bounds.rs
index 266848beef9..7cbc8d38107 100644
--- a/tests/rustdoc/issue-20727.rs
+++ b/tests/rustdoc/inline-assoc-type-20727-bounds.rs
@@ -1,6 +1,9 @@
 // aux-build:issue-20727.rs
 // ignore-cross-compile
 
+// https://github.com/rust-lang/rust/issues/20727
+#![crate_name="issue_20727"]
+
 extern crate issue_20727;
 
 // @has issue_20727/trait.Deref.html
diff --git a/tests/rustdoc/inline_cross/async-fn.rs b/tests/rustdoc/inline_cross/async-fn.rs
new file mode 100644
index 00000000000..95e175aabd0
--- /dev/null
+++ b/tests/rustdoc/inline_cross/async-fn.rs
@@ -0,0 +1,19 @@
+// Regression test for issue #115760.
+// Check that we render the correct return type of free and
+// associated async functions reexported from external crates.
+
+// aux-crate:async_fn=async-fn.rs
+// edition: 2021
+#![crate_name = "user"]
+
+// @has user/fn.load.html
+// @has - '//pre[@class="rust item-decl"]' "pub async fn load() -> i32"
+pub use async_fn::load;
+
+// @has user/trait.Load.html
+// @has - '//*[@id="tymethod.run"]' 'async fn run(&self) -> i32'
+pub use async_fn::Load;
+
+// @has user/struct.Loader.html
+// @has - '//*[@id="method.run"]' 'async fn run(&self) -> i32'
+pub use async_fn::Loader;
diff --git a/tests/rustdoc/inline_cross/auxiliary/async-fn.rs b/tests/rustdoc/inline_cross/auxiliary/async-fn.rs
new file mode 100644
index 00000000000..767564ed145
--- /dev/null
+++ b/tests/rustdoc/inline_cross/auxiliary/async-fn.rs
@@ -0,0 +1,18 @@
+#![feature(async_fn_in_trait)]
+// edition: 2021
+
+pub async fn load() -> i32 {
+    0
+}
+
+pub trait Load {
+    async fn run(&self) -> i32;
+}
+
+pub struct Loader;
+
+impl Load for Loader {
+    async fn run(&self) -> i32 {
+        1
+    }
+}
diff --git a/tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs b/tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
index 19433c9682b..42cfc3dc319 100644
--- a/tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
+++ b/tests/rustdoc/inline_cross/auxiliary/impl_trait_aux.rs
@@ -33,9 +33,3 @@ pub struct Foo;
 impl Foo {
     pub fn method<'a>(_x: impl Clone + Into<Vec<u8>> + 'a) {}
 }
-
-pub struct Bar;
-
-impl Bar {
-    pub async fn async_foo(&self) {}
-}
diff --git a/tests/rustdoc/inline_cross/impl_trait.rs b/tests/rustdoc/inline_cross/impl_trait.rs
index b6a1552bc00..5c802c51486 100644
--- a/tests/rustdoc/inline_cross/impl_trait.rs
+++ b/tests/rustdoc/inline_cross/impl_trait.rs
@@ -33,15 +33,7 @@ pub use impl_trait_aux::func4;
 // @!has - '//pre[@class="rust item-decl"]' 'where'
 pub use impl_trait_aux::func5;
 
-// @has impl_trait/fn.async_fn.html
-// @has - '//pre[@class="rust item-decl"]' "pub async fn async_fn()"
-pub use impl_trait_aux::async_fn;
-
 // @has impl_trait/struct.Foo.html
 // @has - '//*[@id="method.method"]//h4[@class="code-header"]' "pub fn method<'a>(_x: impl Clone + Into<Vec<u8, Global>> + 'a)"
 // @!has - '//*[@id="method.method"]//h4[@class="code-header"]' 'where'
 pub use impl_trait_aux::Foo;
-
-// @has impl_trait/struct.Bar.html
-// @has - '//*[@id="method.async_foo"]' "pub async fn async_foo("
-pub use impl_trait_aux::Bar;
diff --git a/tests/rustdoc/issue-16019.rs b/tests/rustdoc/macro-ice-16019.rs
index 239d92378d9..d0f82e0a314 100644
--- a/tests/rustdoc/issue-16019.rs
+++ b/tests/rustdoc/macro-ice-16019.rs
@@ -1,3 +1,5 @@
+// https://github.com/rust-lang/rust/issues/16019
+
 macro_rules! define_struct {
     ($rounds:expr) => (
         struct Struct {
diff --git a/tests/rustdoc/issue-17476.rs b/tests/rustdoc/method-link-foreign-trait-impl-17476.rs
index a5b484c985f..e52ab6f38c2 100644
--- a/tests/rustdoc/issue-17476.rs
+++ b/tests/rustdoc/method-link-foreign-trait-impl-17476.rs
@@ -1,5 +1,8 @@
 // aux-build:issue-17476.rs
 // ignore-cross-compile
+// https://github.com/rust-lang/rust/issues/17476
+
+#![crate_name="issue_17476"]
 
 extern crate issue_17476;
 
diff --git a/tests/rustdoc/issue-15318-3.rs b/tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs
index 2dab8f94883..80c55975687 100644
--- a/tests/rustdoc/issue-15318-3.rs
+++ b/tests/rustdoc/primitive-raw-pointer-dox-15318-3.rs
@@ -1,3 +1,5 @@
+// https://github.com/rust-lang/rust/issues/15318
+#![crate_name="issue_15318_3"]
 #![feature(rustc_attrs)]
 
 // @has issue_15318_3/primitive.pointer.html
diff --git a/tests/rustdoc/issue-15318.rs b/tests/rustdoc/primitive-raw-pointer-link-15318.rs
index 0349fe2854c..77f25ff4cff 100644
--- a/tests/rustdoc/issue-15318.rs
+++ b/tests/rustdoc/primitive-raw-pointer-link-15318.rs
@@ -1,6 +1,8 @@
 // aux-build:issue-15318.rs
 // ignore-cross-compile
+// https://github.com/rust-lang/rust/issues/15318
 
+#![crate_name="issue_15318"]
 #![no_std]
 
 extern crate issue_15318;
diff --git a/tests/rustdoc/issue-15318-2.rs b/tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs
index 614f2c1c08e..1b35bb185ed 100644
--- a/tests/rustdoc/issue-15318-2.rs
+++ b/tests/rustdoc/primitive-raw-pointer-link-no-inlined-15318-2.rs
@@ -1,5 +1,8 @@
 // aux-build:issue-15318.rs
 // ignore-cross-compile
+// https://github.com/rust-lang/rust/issues/15318
+
+#![crate_name="issue_15318_2"]
 #![no_std]
 
 extern crate issue_15318;
diff --git a/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs b/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs
index f6f0c038536..fa6734b6c6c 100644
--- a/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs
+++ b/tests/ui-fulldeps/internal-lints/lint_pass_impl_without_macro.rs
@@ -6,7 +6,7 @@
 extern crate rustc_middle;
 extern crate rustc_session;
 
-use rustc_session::lint::{LintArray, LintPass};
+use rustc_session::lint::{LintPass, LintVec};
 use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
 
 declare_lint! {
diff --git a/tests/ui-fulldeps/internal-lints/ty_tykind_usage.rs b/tests/ui-fulldeps/internal-lints/ty_tykind_usage.rs
index bf655510a5a..3f7429a5fcc 100644
--- a/tests/ui-fulldeps/internal-lints/ty_tykind_usage.rs
+++ b/tests/ui-fulldeps/internal-lints/ty_tykind_usage.rs
@@ -31,7 +31,6 @@ fn main() {
         TyKind::Closure(..) => (),          //~ ERROR usage of `ty::TyKind::<kind>`
         TyKind::Generator(..) => (),        //~ ERROR usage of `ty::TyKind::<kind>`
         TyKind::GeneratorWitness(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
-        TyKind::GeneratorWitnessMIR(..) => (), //~ ERROR usage of `ty::TyKind::<kind>`
         TyKind::Never => (),                //~ ERROR usage of `ty::TyKind::<kind>`
         TyKind::Tuple(..) => (),            //~ ERROR usage of `ty::TyKind::<kind>`
         TyKind::Alias(..) => (),            //~ ERROR usage of `ty::TyKind::<kind>`
diff --git a/tests/ui-fulldeps/internal-lints/ty_tykind_usage.stderr b/tests/ui-fulldeps/internal-lints/ty_tykind_usage.stderr
index 9f8c0bea0ee..1f49d6b6464 100644
--- a/tests/ui-fulldeps/internal-lints/ty_tykind_usage.stderr
+++ b/tests/ui-fulldeps/internal-lints/ty_tykind_usage.stderr
@@ -121,65 +121,59 @@ LL |         TyKind::GeneratorWitness(..) => (),
 error: usage of `ty::TyKind::<kind>`
   --> $DIR/ty_tykind_usage.rs:34:9
    |
-LL |         TyKind::GeneratorWitnessMIR(..) => (),
-   |         ^^^^^^ help: try using `ty::<kind>` directly: `ty`
-
-error: usage of `ty::TyKind::<kind>`
-  --> $DIR/ty_tykind_usage.rs:35:9
-   |
 LL |         TyKind::Never => (),
    |         ^^^^^^ help: try using `ty::<kind>` directly: `ty`
 
 error: usage of `ty::TyKind::<kind>`
-  --> $DIR/ty_tykind_usage.rs:36:9
+  --> $DIR/ty_tykind_usage.rs:35:9
    |
 LL |         TyKind::Tuple(..) => (),
    |         ^^^^^^ help: try using `ty::<kind>` directly: `ty`
 
 error: usage of `ty::TyKind::<kind>`
-  --> $DIR/ty_tykind_usage.rs:37:9
+  --> $DIR/ty_tykind_usage.rs:36:9
    |
 LL |         TyKind::Alias(..) => (),
    |         ^^^^^^ help: try using `ty::<kind>` directly: `ty`
 
 error: usage of `ty::TyKind::<kind>`
-  --> $DIR/ty_tykind_usage.rs:38:9
+  --> $DIR/ty_tykind_usage.rs:37:9
    |
 LL |         TyKind::Param(..) => (),
    |         ^^^^^^ help: try using `ty::<kind>` directly: `ty`
 
 error: usage of `ty::TyKind::<kind>`
-  --> $DIR/ty_tykind_usage.rs:39:9
+  --> $DIR/ty_tykind_usage.rs:38:9
    |
 LL |         TyKind::Bound(..) => (),
    |         ^^^^^^ help: try using `ty::<kind>` directly: `ty`
 
 error: usage of `ty::TyKind::<kind>`
-  --> $DIR/ty_tykind_usage.rs:40:9
+  --> $DIR/ty_tykind_usage.rs:39:9
    |
 LL |         TyKind::Placeholder(..) => (),
    |         ^^^^^^ help: try using `ty::<kind>` directly: `ty`
 
 error: usage of `ty::TyKind::<kind>`
-  --> $DIR/ty_tykind_usage.rs:41:9
+  --> $DIR/ty_tykind_usage.rs:40:9
    |
 LL |         TyKind::Infer(..) => (),
    |         ^^^^^^ help: try using `ty::<kind>` directly: `ty`
 
 error: usage of `ty::TyKind::<kind>`
-  --> $DIR/ty_tykind_usage.rs:42:9
+  --> $DIR/ty_tykind_usage.rs:41:9
    |
 LL |         TyKind::Error(_) => (),
    |         ^^^^^^ help: try using `ty::<kind>` directly: `ty`
 
 error: usage of `ty::TyKind::<kind>`
-  --> $DIR/ty_tykind_usage.rs:47:12
+  --> $DIR/ty_tykind_usage.rs:46:12
    |
 LL |     if let TyKind::Int(int_ty) = kind {}
    |            ^^^^^^ help: try using `ty::<kind>` directly: `ty`
 
 error: usage of `ty::TyKind`
-  --> $DIR/ty_tykind_usage.rs:49:24
+  --> $DIR/ty_tykind_usage.rs:48:24
    |
 LL |     fn ty_kind(ty_bad: TyKind<'_>, ty_good: Ty<'_>) {}
    |                        ^^^^^^^^^^
@@ -187,7 +181,7 @@ LL |     fn ty_kind(ty_bad: TyKind<'_>, ty_good: Ty<'_>) {}
    = help: try using `Ty` instead
 
 error: usage of `ty::TyKind`
-  --> $DIR/ty_tykind_usage.rs:51:37
+  --> $DIR/ty_tykind_usage.rs:50:37
    |
 LL |     fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
    |                                     ^^^^^^^^^^^
@@ -195,7 +189,7 @@ LL |     fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
    = help: try using `Ty` instead
 
 error: usage of `ty::TyKind`
-  --> $DIR/ty_tykind_usage.rs:51:53
+  --> $DIR/ty_tykind_usage.rs:50:53
    |
 LL |     fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
    |                                                     ^^^^^^^^^^^
@@ -203,12 +197,12 @@ LL |     fn ir_ty_kind<I: Interner>(bad: IrTyKind<I>) -> IrTyKind<I> {
    = help: try using `Ty` instead
 
 error: usage of `ty::TyKind::<kind>`
-  --> $DIR/ty_tykind_usage.rs:54:9
+  --> $DIR/ty_tykind_usage.rs:53:9
    |
 LL |         IrTyKind::Bool
    |         --------^^^^^^
    |         |
    |         help: try using `ty::<kind>` directly: `ty`
 
-error: aborting due to 33 previous errors
+error: aborting due to 32 previous errors
 
diff --git a/tests/ui-fulldeps/lint-pass-macros.rs b/tests/ui-fulldeps/lint-pass-macros.rs
index b3c2a542792..4c61783418f 100644
--- a/tests/ui-fulldeps/lint-pass-macros.rs
+++ b/tests/ui-fulldeps/lint-pass-macros.rs
@@ -5,7 +5,7 @@
 
 extern crate rustc_session;
 
-use rustc_session::lint::{LintArray, LintPass};
+use rustc_session::lint::{LintPass, LintVec};
 use rustc_session::{declare_lint, declare_lint_pass, impl_lint_pass};
 
 declare_lint! {
diff --git a/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs
index 4a41e7fbb72..150f0c6b9a2 100644
--- a/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs
+++ b/tests/ui-fulldeps/plugin/auxiliary/lint-group-plugin-test.rs
@@ -5,13 +5,12 @@
 // Load rustc as a plugin to get macros.
 extern crate rustc_driver;
 extern crate rustc_hir;
-#[macro_use]
 extern crate rustc_lint;
 #[macro_use]
 extern crate rustc_session;
 
 use rustc_driver::plugin::Registry;
-use rustc_lint::{LateContext, LateLintPass, LintArray, LintContext, LintId, LintPass};
+use rustc_lint::{LateContext, LateLintPass, LintContext, LintId};
 
 declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
 
diff --git a/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs
index 30956deb799..acc5fe76051 100644
--- a/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs
+++ b/tests/ui-fulldeps/plugin/auxiliary/lint-plugin-test.rs
@@ -6,14 +6,14 @@ extern crate rustc_ast;
 
 // Load rustc as a plugin to get macros
 extern crate rustc_driver;
-#[macro_use]
 extern crate rustc_lint;
 #[macro_use]
 extern crate rustc_session;
 
+use rustc_ast::ast;
 use rustc_driver::plugin::Registry;
-use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintPass};
-use rustc_ast as ast;
+use rustc_lint::{EarlyContext, EarlyLintPass, LintContext};
+
 declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'");
 
 declare_lint_pass!(Pass => [TEST_LINT]);
diff --git a/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs b/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs
index c2c024865e8..21de4aa7008 100644
--- a/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs
+++ b/tests/ui-fulldeps/plugin/auxiliary/lint-tool-test.rs
@@ -4,14 +4,14 @@ extern crate rustc_ast;
 
 // Load rustc as a plugin to get macros
 extern crate rustc_driver;
-#[macro_use]
 extern crate rustc_lint;
 #[macro_use]
 extern crate rustc_session;
 
-use rustc_driver::plugin::Registry;
-use rustc_lint::{EarlyContext, EarlyLintPass, LintArray, LintContext, LintId, LintPass};
 use rustc_ast as ast;
+use rustc_driver::plugin::Registry;
+use rustc_lint::{EarlyContext, EarlyLintPass, LintContext, LintId};
+
 declare_tool_lint!(pub clippy::TEST_LINT, Warn, "Warn about stuff");
 declare_tool_lint!(
     /// Some docs
diff --git a/tests/ui-fulldeps/stable-mir/compilation-result.rs b/tests/ui-fulldeps/stable-mir/compilation-result.rs
index 23a9e2a064c..3ec1519fb13 100644
--- a/tests/ui-fulldeps/stable-mir/compilation-result.rs
+++ b/tests/ui-fulldeps/stable-mir/compilation-result.rs
@@ -11,9 +11,10 @@
 
 extern crate rustc_middle;
 extern crate rustc_smir;
+extern crate stable_mir;
 
 use rustc_middle::ty::TyCtxt;
-use rustc_smir::{rustc_internal, stable_mir};
+use rustc_smir::rustc_internal;
 use std::io::Write;
 use std::ops::ControlFlow;
 
diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs
index a11720c4b55..ce4ee3c2463 100644
--- a/tests/ui-fulldeps/stable-mir/crate-info.rs
+++ b/tests/ui-fulldeps/stable-mir/crate-info.rs
@@ -13,13 +13,13 @@
 extern crate rustc_hir;
 extern crate rustc_middle;
 extern crate rustc_smir;
+extern crate stable_mir;
 
 use rustc_hir::def::DefKind;
 use rustc_middle::ty::TyCtxt;
-use rustc_smir::{
-    rustc_internal,
-    stable_mir::{self, fold::Foldable},
-};
+use rustc_smir::rustc_internal;
+
+use stable_mir::fold::Foldable;
 use std::assert_matches::assert_matches;
 use std::io::Write;
 use std::ops::ControlFlow;
@@ -27,7 +27,7 @@ use std::ops::ControlFlow;
 const CRATE_NAME: &str = "input";
 
 /// This function uses the Stable MIR APIs to get information about the test crate.
-fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
+fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
     // Get the local crate using stable_mir API.
     let local = stable_mir::local_crate();
     assert_eq!(&local.name, CRATE_NAME);
@@ -36,12 +36,12 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
 
     // Find items in the local crate.
     let items = stable_mir::all_local_items();
-    assert!(get_item(tcx, &items, (DefKind::Fn, "foo::bar")).is_some());
+    assert!(get_item(&items, (DefKind::Fn, "foo::bar")).is_some());
 
     // Find the `std` crate.
     assert!(stable_mir::find_crate("std").is_some());
 
-    let bar = get_item(tcx, &items, (DefKind::Fn, "bar")).unwrap();
+    let bar = get_item(&items, (DefKind::Fn, "bar")).unwrap();
     let body = bar.body();
     assert_eq!(body.locals.len(), 2);
     assert_eq!(body.blocks.len(), 1);
@@ -56,7 +56,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
         other => panic!("{other:?}"),
     }
 
-    let foo_bar = get_item(tcx, &items, (DefKind::Fn, "foo_bar")).unwrap();
+    let foo_bar = get_item(&items, (DefKind::Fn, "foo_bar")).unwrap();
     let body = foo_bar.body();
     assert_eq!(body.locals.len(), 7);
     assert_eq!(body.blocks.len(), 4);
@@ -66,7 +66,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
         other => panic!("{other:?}"),
     }
 
-    let types = get_item(tcx, &items, (DefKind::Fn, "types")).unwrap();
+    let types = get_item(&items, (DefKind::Fn, "types")).unwrap();
     let body = types.body();
     assert_eq!(body.locals.len(), 6);
     assert_matches!(
@@ -96,7 +96,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
         ))
     );
 
-    let drop = get_item(tcx, &items, (DefKind::Fn, "drop")).unwrap();
+    let drop = get_item(&items, (DefKind::Fn, "drop")).unwrap();
     let body = drop.body();
     assert_eq!(body.blocks.len(), 2);
     let block = &body.blocks[0];
@@ -105,7 +105,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
         other => panic!("{other:?}"),
     }
 
-    let assert = get_item(tcx, &items, (DefKind::Fn, "assert")).unwrap();
+    let assert = get_item(&items, (DefKind::Fn, "assert")).unwrap();
     let body = assert.body();
     assert_eq!(body.blocks.len(), 2);
     let block = &body.blocks[0];
@@ -114,7 +114,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
         other => panic!("{other:?}"),
     }
 
-    let monomorphic = get_item(tcx, &items, (DefKind::Fn, "monomorphic")).unwrap();
+    let monomorphic = get_item(&items, (DefKind::Fn, "monomorphic")).unwrap();
     for block in monomorphic.body().blocks {
         match &block.terminator {
             stable_mir::mir::Terminator::Call { func, .. } => match func {
@@ -154,7 +154,7 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
         }
     }
 
-    let foo_const = get_item(tcx, &items, (DefKind::Const, "FOO")).unwrap();
+    let foo_const = get_item(&items, (DefKind::Const, "FOO")).unwrap();
     // Ensure we don't panic trying to get the body of a constant.
     foo_const.body();
 
@@ -163,13 +163,11 @@ fn test_stable_mir(tcx: TyCtxt<'_>) -> ControlFlow<()> {
 
 // Use internal API to find a function in a crate.
 fn get_item<'a>(
-    tcx: TyCtxt,
     items: &'a stable_mir::CrateItems,
     item: (DefKind, &str),
 ) -> Option<&'a stable_mir::CrateItem> {
     items.iter().find(|crate_item| {
-        let def_id = rustc_internal::item_def_id(crate_item);
-        tcx.def_kind(def_id) == item.0 && tcx.def_path_str(def_id) == item.1
+        crate_item.kind().to_string() == format!("{:?}", item.0) && crate_item.name() == item.1
     })
 }
 
diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs
index 249e8176283..1f049b1785a 100644
--- a/tests/ui/abi/compatibility.rs
+++ b/tests/ui/abi/compatibility.rs
@@ -1,16 +1,174 @@
 // check-pass
+// revisions: host
+// revisions: arm
+//[arm] compile-flags: --target arm-unknown-linux-gnueabi
+//[arm] needs-llvm-components: arm
+// revisions: aarch64
+//[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
+//[aarch64] needs-llvm-components: aarch64
+// revisions: s390x
+//[s390x] compile-flags: --target s390x-unknown-linux-gnu
+//[s390x] needs-llvm-components: systemz
+// revisions: mips
+//[mips] compile-flags: --target mips-unknown-linux-gnu
+//[mips] needs-llvm-components: mips
+// revisions: mips64
+//[mips64] compile-flags: --target mips64-unknown-linux-gnuabi64
+//[mips64] needs-llvm-components: mips
+// revisions: sparc
+//[sparc] compile-flags: --target sparc-unknown-linux-gnu
+//[sparc] needs-llvm-components: sparc
+// revisions: sparc64
+//[sparc64] compile-flags: --target sparc64-unknown-linux-gnu
+//[sparc64] needs-llvm-components: sparc
+// revisions: powerpc64
+//[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
+//[powerpc64] needs-llvm-components: powerpc
+// revisions: riscv
+//[riscv] compile-flags: --target riscv64gc-unknown-linux-gnu
+//[riscv] needs-llvm-components: riscv
+// revisions: loongarch64
+//[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
+//[loongarch64] needs-llvm-components: loongarch
+// revisions: wasm
+//[wasm] compile-flags: --target wasm32-unknown-unknown
+//[wasm] needs-llvm-components: webassembly
+// revisions: wasi
+//[wasi] compile-flags: --target wasm32-wasi
+//[wasi] needs-llvm-components: webassembly
+// revisions: nvptx64
+//[nvptx64] compile-flags: --target nvptx64-nvidia-cuda
+//[nvptx64] needs-llvm-components: nvptx
 #![feature(rustc_attrs, unsized_fn_params, transparent_unions)]
+#![cfg_attr(not(host), feature(no_core, lang_items), no_std, no_core)]
 #![allow(unused, improper_ctypes_definitions, internal_features)]
-use std::marker::PhantomData;
-use std::mem::ManuallyDrop;
-use std::num::NonZeroI32;
-use std::ptr::NonNull;
 
-// FIXME: a bunch of targets are broken in various ways.
+// FIXME: some targets are broken in various ways.
 // Hence there are `cfg` throughout this test to disable parts of it on those targets.
 // sparc64: https://github.com/rust-lang/rust/issues/115336
 // mips64: https://github.com/rust-lang/rust/issues/115404
 
+#[cfg(host)]
+use std::{
+    any::Any, marker::PhantomData, mem::ManuallyDrop, num::NonZeroI32, ptr::NonNull, rc::Rc,
+    sync::Arc,
+};
+
+/// To work cross-target this test must be no_core.
+/// This little prelude supplies what we need.
+#[cfg(not(host))]
+mod prelude {
+    #[lang = "sized"]
+    pub trait Sized {}
+
+    #[lang = "receiver"]
+    pub trait Receiver {}
+    impl<T: ?Sized> Receiver for &T {}
+    impl<T: ?Sized> Receiver for &mut T {}
+
+    #[lang = "copy"]
+    pub trait Copy: Sized {}
+    impl Copy for i32 {}
+    impl Copy for f32 {}
+    impl<T: ?Sized> Copy for &T {}
+    impl<T: ?Sized> Copy for *const T {}
+    impl<T: ?Sized> Copy for *mut T {}
+
+    #[lang = "clone"]
+    pub trait Clone: Sized {
+        fn clone(&self) -> Self;
+    }
+
+    #[lang = "phantom_data"]
+    pub struct PhantomData<T: ?Sized>;
+    impl<T: ?Sized> Copy for PhantomData<T> {}
+
+    #[lang = "unsafe_cell"]
+    #[repr(transparent)]
+    pub struct UnsafeCell<T: ?Sized> {
+        value: T,
+    }
+
+    pub trait Any: 'static {}
+
+    pub enum Option<T> {
+        None,
+        Some(T),
+    }
+    impl<T: Copy> Copy for Option<T> {}
+
+    pub enum Result<T, E> {
+        Ok(T),
+        Err(E),
+    }
+    impl<T: Copy, E: Copy> Copy for Result<T, E> {}
+
+    #[lang = "manually_drop"]
+    #[repr(transparent)]
+    pub struct ManuallyDrop<T: ?Sized> {
+        value: T,
+    }
+    impl<T: Copy + ?Sized> Copy for ManuallyDrop<T> {}
+
+    #[repr(transparent)]
+    #[rustc_layout_scalar_valid_range_start(1)]
+    #[rustc_nonnull_optimization_guaranteed]
+    pub struct NonNull<T: ?Sized> {
+        pointer: *const T,
+    }
+    impl<T: ?Sized> Copy for NonNull<T> {}
+
+    #[repr(transparent)]
+    #[rustc_layout_scalar_valid_range_start(1)]
+    #[rustc_nonnull_optimization_guaranteed]
+    pub struct NonZeroI32(i32);
+
+    // This just stands in for a non-trivial type.
+    pub struct Vec<T> {
+        ptr: NonNull<T>,
+        cap: usize,
+        len: usize,
+    }
+
+    pub struct Unique<T: ?Sized> {
+        pub pointer: NonNull<T>,
+        pub _marker: PhantomData<T>,
+    }
+
+    pub struct Global;
+
+    #[lang = "owned_box"]
+    pub struct Box<T: ?Sized, A = Global>(Unique<T>, A);
+
+    #[repr(C)]
+    struct RcBox<T: ?Sized> {
+        strong: UnsafeCell<usize>,
+        weak: UnsafeCell<usize>,
+        value: T,
+    }
+    pub struct Rc<T: ?Sized, A = Global> {
+        ptr: NonNull<RcBox<T>>,
+        phantom: PhantomData<RcBox<T>>,
+        alloc: A,
+    }
+
+    #[repr(C, align(8))]
+    struct AtomicUsize(usize);
+    #[repr(C)]
+    struct ArcInner<T: ?Sized> {
+        strong: AtomicUsize,
+        weak: AtomicUsize,
+        data: T,
+    }
+    pub struct Arc<T: ?Sized, A = Global> {
+        ptr: NonNull<ArcInner<T>>,
+        phantom: PhantomData<ArcInner<T>>,
+        alloc: A,
+    }
+}
+#[cfg(not(host))]
+use prelude::*;
+
 macro_rules! assert_abi_compatible {
     ($name:ident, $t1:ty, $t2:ty) => {
         mod $name {
@@ -26,8 +184,13 @@ macro_rules! assert_abi_compatible {
     };
 }
 
-#[derive(Copy, Clone)]
 struct Zst;
+impl Copy for Zst {}
+impl Clone for Zst {
+    fn clone(&self) -> Self {
+        Zst
+    }
+}
 
 #[repr(C)]
 struct ReprC1<T: ?Sized>(T);
@@ -85,8 +248,8 @@ test_abi_compatible!(nonzero_int, NonZeroI32, i32);
 
 // `DispatchFromDyn` relies on ABI compatibility.
 // This is interesting since these types are not `repr(transparent)`.
-test_abi_compatible!(rc, std::rc::Rc<i32>, *mut i32);
-test_abi_compatible!(arc, std::sync::Arc<i32>, *mut i32);
+test_abi_compatible!(rc, Rc<i32>, *mut i32);
+test_abi_compatible!(arc, Arc<i32>, *mut i32);
 
 // `repr(transparent)` compatibility.
 #[repr(transparent)]
@@ -160,7 +323,7 @@ mod unsized_ {
     use super::*;
     test_transparent_unsized!(str_, str);
     test_transparent_unsized!(slice, [u8]);
-    test_transparent_unsized!(dyn_trait, dyn std::any::Any);
+    test_transparent_unsized!(dyn_trait, dyn Any);
 }
 
 // RFC 3391 <https://rust-lang.github.io/rfcs/3391-result_ffi_guarantees.html>.
@@ -185,7 +348,7 @@ test_nonnull!(ref_unsized, &[i32]);
 test_nonnull!(mut_unsized, &mut [i32]);
 test_nonnull!(fn_, fn());
 test_nonnull!(nonnull, NonNull<i32>);
-test_nonnull!(nonnull_unsized, NonNull<dyn std::fmt::Debug>);
+test_nonnull!(nonnull_unsized, NonNull<dyn Any>);
 test_nonnull!(non_zero, NonZeroI32);
 
 fn main() {}
diff --git a/tests/ui/abi/relocation_model_pic.rs b/tests/ui/abi/relocation_model_pic.rs
index 0cfc44cd09d..cca2e8db74d 100644
--- a/tests/ui/abi/relocation_model_pic.rs
+++ b/tests/ui/abi/relocation_model_pic.rs
@@ -1,7 +1,6 @@
 // run-pass
 // compile-flags: -C relocation-model=pic
-// ignore-emscripten no pic
-// ignore-wasm
+// needs-relocation-model-pic
 
 #![feature(cfg_relocation_model)]
 
diff --git a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs
index 5c59f217be6..99769692342 100644
--- a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs
+++ b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.rs
@@ -1,6 +1,5 @@
-// FIXME(inherent_associated_types): This should be `check-pass`
-// known-bug: #108491
 // compile-flags: --crate-type=lib
+// check-pass
 
 #![feature(inherent_associated_types)]
 #![allow(incomplete_features)]
@@ -8,11 +7,6 @@
 // Bounds on the self type play a major role in the resolution of inherent associated types (*).
 // As a result of that, if a type alias contains any then its bounds have to be respected and the
 // lint `type_alias_bounds` should not fire.
-//
-// FIXME(inherent_associated_types): In the current implementation that is. We might move the
-// selection phase of IATs from hir_typeck to trait_selection resulting in us not requiring the
-// ParamEnv that early allowing us to ignore bounds on type aliases again.
-// Triage this before stabilization.
 
 #![deny(type_alias_bounds)]
 
diff --git a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.stderr b/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.stderr
deleted file mode 100644
index 5e18543fc90..00000000000
--- a/tests/ui/associated-inherent-types/type-alias-bounds-are-enforced.stderr
+++ /dev/null
@@ -1,55 +0,0 @@
-error[E0391]: cycle detected when expanding type alias `Alias`
-  --> $DIR/type-alias-bounds-are-enforced.rs:19:1
-   |
-LL | pub type Alias<T: Bound> = (Source<T>::Assoc,);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...which requires computing the variances of `Source`...
-  --> $DIR/type-alias-bounds-are-enforced.rs:21:1
-   |
-LL | pub struct Source<T>(T);
-   | ^^^^^^^^^^^^^^^^^^^^
-   = note: ...which requires computing the variances for items in this crate...
-   = note: ...which again requires expanding type alias `Alias`, completing the cycle
-note: cycle used when collecting item types in top-level module
-  --> $DIR/type-alias-bounds-are-enforced.rs:5:1
-   |
-LL | / #![feature(inherent_associated_types)]
-LL | | #![allow(incomplete_features)]
-LL | |
-LL | | // Bounds on the self type play a major role in the resolution of inherent associated types (*).
-...  |
-LL | |     pub type Assoc = ();
-LL | | }
-   | |_^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
-error[E0391]: cycle detected when expanding type alias `Alias`
-  --> $DIR/type-alias-bounds-are-enforced.rs:19:1
-   |
-LL | pub type Alias<T: Bound> = (Source<T>::Assoc,);
-   | ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-note: ...which requires computing the variances of `Source`...
-  --> $DIR/type-alias-bounds-are-enforced.rs:21:1
-   |
-LL | pub struct Source<T>(T);
-   | ^^^^^^^^^^^^^^^^^^^^
-   = note: ...which requires computing the variances for items in this crate...
-   = note: ...which again requires expanding type alias `Alias`, completing the cycle
-note: cycle used when collecting item types in top-level module
-  --> $DIR/type-alias-bounds-are-enforced.rs:5:1
-   |
-LL | / #![feature(inherent_associated_types)]
-LL | | #![allow(incomplete_features)]
-LL | |
-LL | | // Bounds on the self type play a major role in the resolution of inherent associated types (*).
-...  |
-LL | |     pub type Assoc = ();
-LL | | }
-   | |_^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/associated-types/defaults-specialization.stderr b/tests/ui/associated-types/defaults-specialization.stderr
index 7e21f7fc306..7ef433d859f 100644
--- a/tests/ui/associated-types/defaults-specialization.stderr
+++ b/tests/ui/associated-types/defaults-specialization.stderr
@@ -29,7 +29,7 @@ error[E0053]: method `make` has an incompatible type for trait
   --> $DIR/defaults-specialization.rs:35:18
    |
 LL |     default type Ty = bool;
-   |     ----------------------- expected this associated type
+   |     ----------------------- associated type is `default` and may be overridden
 LL |
 LL |     fn make() -> bool { true }
    |                  ^^^^
@@ -76,7 +76,7 @@ error[E0308]: mismatched types
   --> $DIR/defaults-specialization.rs:44:29
    |
 LL |     default type Ty = bool;
-   |     ----------------------- expected this associated type
+   |     ----------------------- associated type is `default` and may be overridden
 LL |
 LL |     fn make() -> Self::Ty { true }
    |                  --------   ^^^^ expected associated type, found `bool`
diff --git a/tests/ui/async-await/async-await-let-else.drop-tracking.stderr b/tests/ui/async-await/async-await-let-else.drop-tracking.stderr
deleted file mode 100644
index fb83ca90a37..00000000000
--- a/tests/ui/async-await/async-await-let-else.drop-tracking.stderr
+++ /dev/null
@@ -1,106 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:48:13
-   |
-LL |     is_send(foo(Some(true)));
-   |             ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:11:14
-   |
-LL |         let r = Rc::new(());
-   |             - has type `Rc<()>` which is not `Send`
-LL |         bar().await
-   |              ^^^^^^ await occurs here, with `r` maybe used later
-LL |     };
-   |     - `r` is later dropped here
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error[E0277]: `Rc<()>` cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:50:13
-   |
-LL | async fn foo2(x: Option<bool>) {
-   |                                - within this `impl Future<Output = ()>`
-...
-LL |     is_send(foo2(Some(true)));
-   |     ------- ^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: required because it's used within this `async fn` body
-  --> $DIR/async-await-let-else.rs:27:29
-   |
-LL |   async fn bar2<T>(_: T) -> ! {
-   |  _____________________________^
-LL | |     panic!()
-LL | | }
-   | |_^
-   = note: required because it captures the following types: `ResumeTy`, `Option<bool>`, `impl Future<Output = !>`, `()`
-note: required because it's used within this `async fn` body
-  --> $DIR/async-await-let-else.rs:21:32
-   |
-LL |   async fn foo2(x: Option<bool>) {
-   |  ________________________________^
-LL | |     let Some(_) = x else {
-LL | |         bar2(Rc::new(())).await
-LL | |     };
-LL | | }
-   | |_^
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:52:13
-   |
-LL |     is_send(foo3(Some(true)));
-   |             ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:33:28
-   |
-LL |         (Rc::new(()), bar().await);
-   |          -----------       ^^^^^^ - `Rc::new(())` is later dropped here
-   |          |                 |
-   |          |                 await occurs here, with `Rc::new(())` maybe used later
-   |          has type `Rc<()>` which is not `Send`
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:54:13
-   |
-LL |     is_send(foo4(Some(true)));
-   |             ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:41:14
-   |
-LL |         let r = Rc::new(());
-   |             - has type `Rc<()>` which is not `Send`
-LL |         bar().await;
-   |              ^^^^^^ await occurs here, with `r` maybe used later
-...
-LL |     };
-   |     - `r` is later dropped here
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/async-await-let-else.drop_tracking.stderr b/tests/ui/async-await/async-await-let-else.drop_tracking.stderr
deleted file mode 100644
index dee90262fd4..00000000000
--- a/tests/ui/async-await/async-await-let-else.drop_tracking.stderr
+++ /dev/null
@@ -1,106 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:48:13
-   |
-LL |     is_send(foo(Some(true)));
-   |             ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:11:15
-   |
-LL |         let r = Rc::new(());
-   |             - has type `Rc<()>` which is not `Send`
-LL |         bar().await
-   |               ^^^^^ await occurs here, with `r` maybe used later
-LL |     };
-   |     - `r` is later dropped here
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error[E0277]: `Rc<()>` cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:50:13
-   |
-LL | async fn foo2(x: Option<bool>) {
-   |                                - within this `impl Future<Output = ()>`
-...
-LL |     is_send(foo2(Some(true)));
-   |     ------- ^^^^^^^^^^^^^^^^ `Rc<()>` cannot be sent between threads safely
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: required because it's used within this `async fn` body
-  --> $DIR/async-await-let-else.rs:27:29
-   |
-LL |   async fn bar2<T>(_: T) -> ! {
-   |  _____________________________^
-LL | |     panic!()
-LL | | }
-   | |_^
-   = note: required because it captures the following types: `ResumeTy`, `Option<bool>`, `impl Future<Output = !>`, `()`
-note: required because it's used within this `async fn` body
-  --> $DIR/async-await-let-else.rs:21:32
-   |
-LL |   async fn foo2(x: Option<bool>) {
-   |  ________________________________^
-LL | |     let Some(_) = x else {
-LL | |         bar2(Rc::new(())).await
-LL | |     };
-LL | | }
-   | |_^
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:52:13
-   |
-LL |     is_send(foo3(Some(true)));
-   |             ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:33:29
-   |
-LL |         (Rc::new(()), bar().await);
-   |          -----------        ^^^^^ - `Rc::new(())` is later dropped here
-   |          |                  |
-   |          |                  await occurs here, with `Rc::new(())` maybe used later
-   |          has type `Rc<()>` which is not `Send`
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:54:13
-   |
-LL |     is_send(foo4(Some(true)));
-   |             ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:41:15
-   |
-LL |         let r = Rc::new(());
-   |             - has type `Rc<()>` which is not `Send`
-LL |         bar().await;
-   |               ^^^^^ await occurs here, with `r` maybe used later
-...
-LL |     };
-   |     - `r` is later dropped here
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/async-await-let-else.no-drop-tracking.stderr b/tests/ui/async-await/async-await-let-else.no-drop-tracking.stderr
deleted file mode 100644
index d3c5e80a30d..00000000000
--- a/tests/ui/async-await/async-await-let-else.no-drop-tracking.stderr
+++ /dev/null
@@ -1,90 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:48:13
-   |
-LL |     is_send(foo(Some(true)));
-   |             ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:11:14
-   |
-LL |         let r = Rc::new(());
-   |             - has type `Rc<()>` which is not `Send`
-LL |         bar().await
-   |              ^^^^^^ await occurs here, with `r` maybe used later
-LL |     };
-   |     - `r` is later dropped here
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:50:13
-   |
-LL |     is_send(foo2(Some(true)));
-   |             ^^^^^^^^^^^^^^^^ future returned by `foo2` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:23:26
-   |
-LL |         bar2(Rc::new(())).await
-   |              ----------- ^^^^^^ await occurs here, with `Rc::new(())` maybe used later
-   |              |
-   |              has type `Rc<()>` which is not `Send`
-LL |     };
-   |     - `Rc::new(())` is later dropped here
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:52:13
-   |
-LL |     is_send(foo3(Some(true)));
-   |             ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:33:28
-   |
-LL |         (Rc::new(()), bar().await);
-   |          -----------       ^^^^^^ - `Rc::new(())` is later dropped here
-   |          |                 |
-   |          |                 await occurs here, with `Rc::new(())` maybe used later
-   |          has type `Rc<()>` which is not `Send`
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:54:13
-   |
-LL |     is_send(foo4(Some(true)));
-   |             ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:41:14
-   |
-LL |         let r = Rc::new(());
-   |             - has type `Rc<()>` which is not `Send`
-LL |         bar().await;
-   |              ^^^^^^ await occurs here, with `r` maybe used later
-...
-LL |     };
-   |     - `r` is later dropped here
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error: aborting due to 4 previous errors
-
diff --git a/tests/ui/async-await/async-await-let-else.no_drop_tracking.stderr b/tests/ui/async-await/async-await-let-else.no_drop_tracking.stderr
deleted file mode 100644
index ece4e51ecff..00000000000
--- a/tests/ui/async-await/async-await-let-else.no_drop_tracking.stderr
+++ /dev/null
@@ -1,90 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:48:13
-   |
-LL |     is_send(foo(Some(true)));
-   |             ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:11:15
-   |
-LL |         let r = Rc::new(());
-   |             - has type `Rc<()>` which is not `Send`
-LL |         bar().await
-   |               ^^^^^ await occurs here, with `r` maybe used later
-LL |     };
-   |     - `r` is later dropped here
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:50:13
-   |
-LL |     is_send(foo2(Some(true)));
-   |             ^^^^^^^^^^^^^^^^ future returned by `foo2` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:23:27
-   |
-LL |         bar2(Rc::new(())).await
-   |              -----------  ^^^^^ await occurs here, with `Rc::new(())` maybe used later
-   |              |
-   |              has type `Rc<()>` which is not `Send`
-LL |     };
-   |     - `Rc::new(())` is later dropped here
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:52:13
-   |
-LL |     is_send(foo3(Some(true)));
-   |             ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:33:29
-   |
-LL |         (Rc::new(()), bar().await);
-   |          -----------        ^^^^^ - `Rc::new(())` is later dropped here
-   |          |                  |
-   |          |                  await occurs here, with `Rc::new(())` maybe used later
-   |          has type `Rc<()>` which is not `Send`
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:54:13
-   |
-LL |     is_send(foo4(Some(true)));
-   |             ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:41:15
-   |
-LL |         let r = Rc::new(());
-   |             - has type `Rc<()>` which is not `Send`
-LL |         bar().await;
-   |               ^^^^^ await occurs here, with `r` maybe used later
-...
-LL |     };
-   |     - `r` is later dropped here
-note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
-   |
-LL | fn is_send<T: Send>(_: T) {}
-   |               ^^^^ required by this bound in `is_send`
-
-error: aborting due to 4 previous errors
-
diff --git a/tests/ui/async-await/async-await-let-else.rs b/tests/ui/async-await/async-await-let-else.rs
index 113d576b5e7..a3c7226056b 100644
--- a/tests/ui/async-await/async-await-let-else.rs
+++ b/tests/ui/async-await/async-await-let-else.rs
@@ -1,7 +1,4 @@
 // edition:2021
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 
 use std::rc::Rc;
 
diff --git a/tests/ui/async-await/async-await-let-else.drop_tracking_mir.stderr b/tests/ui/async-await/async-await-let-else.stderr
index e3fcceaa392..9a1c1782233 100644
--- a/tests/ui/async-await/async-await-let-else.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/async-await-let-else.stderr
@@ -1,25 +1,25 @@
 error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:48:13
+  --> $DIR/async-await-let-else.rs:45:13
    |
 LL |     is_send(foo(Some(true)));
    |             ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:11:15
+  --> $DIR/async-await-let-else.rs:8:15
    |
 LL |         let r = Rc::new(());
    |             - has type `Rc<()>` which is not `Send`
 LL |         bar().await
    |               ^^^^^ await occurs here, with `r` maybe used later
 note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
+  --> $DIR/async-await-let-else.rs:16:15
    |
 LL | fn is_send<T: Send>(_: T) {}
    |               ^^^^ required by this bound in `is_send`
 
 error[E0277]: `Rc<()>` cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:50:13
+  --> $DIR/async-await-let-else.rs:47:13
    |
 LL | async fn foo2(x: Option<bool>) {
    |                                - within this `impl Future<Output = ()>`
@@ -31,7 +31,7 @@ LL |     is_send(foo2(Some(true)));
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
 note: required because it's used within this `async fn` body
-  --> $DIR/async-await-let-else.rs:27:29
+  --> $DIR/async-await-let-else.rs:24:29
    |
 LL |   async fn bar2<T>(_: T) -> ! {
    |  _____________________________^
@@ -40,7 +40,7 @@ LL | | }
    | |_^
    = note: required because it captures the following types: `impl Future<Output = !>`
 note: required because it's used within this `async fn` body
-  --> $DIR/async-await-let-else.rs:21:32
+  --> $DIR/async-await-let-else.rs:18:32
    |
 LL |   async fn foo2(x: Option<bool>) {
    |  ________________________________^
@@ -50,47 +50,47 @@ LL | |     };
 LL | | }
    | |_^
 note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
+  --> $DIR/async-await-let-else.rs:16:15
    |
 LL | fn is_send<T: Send>(_: T) {}
    |               ^^^^ required by this bound in `is_send`
 
 error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:52:13
+  --> $DIR/async-await-let-else.rs:49:13
    |
 LL |     is_send(foo3(Some(true)));
    |             ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:33:29
+  --> $DIR/async-await-let-else.rs:30:29
    |
 LL |         (Rc::new(()), bar().await);
    |          -----------        ^^^^^ await occurs here, with `Rc::new(())` maybe used later
    |          |
    |          has type `Rc<()>` which is not `Send`
 note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
+  --> $DIR/async-await-let-else.rs:16:15
    |
 LL | fn is_send<T: Send>(_: T) {}
    |               ^^^^ required by this bound in `is_send`
 
 error: future cannot be sent between threads safely
-  --> $DIR/async-await-let-else.rs:54:13
+  --> $DIR/async-await-let-else.rs:51:13
    |
 LL |     is_send(foo4(Some(true)));
    |             ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/async-await-let-else.rs:41:15
+  --> $DIR/async-await-let-else.rs:38:15
    |
 LL |         let r = Rc::new(());
    |             - has type `Rc<()>` which is not `Send`
 LL |         bar().await;
    |               ^^^^^ await occurs here, with `r` maybe used later
 note: required by a bound in `is_send`
-  --> $DIR/async-await-let-else.rs:19:15
+  --> $DIR/async-await-let-else.rs:16:15
    |
 LL | fn is_send<T: Send>(_: T) {}
    |               ^^^^ required by this bound in `is_send`
diff --git a/tests/ui/async-await/async-error-span.drop_tracking.stderr b/tests/ui/async-await/async-error-span.drop_tracking.stderr
deleted file mode 100644
index 99a674a2684..00000000000
--- a/tests/ui/async-await/async-error-span.drop_tracking.stderr
+++ /dev/null
@@ -1,25 +0,0 @@
-error[E0277]: `()` is not a future
-  --> $DIR/async-error-span.rs:10:20
-   |
-LL | fn get_future() -> impl Future<Output = ()> {
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not a future
-   |
-   = help: the trait `Future` is not implemented for `()`
-   = note: () must be a future or must implement `IntoFuture` to be awaited
-
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/async-error-span.rs:16:9
-   |
-LL |     let a;
-   |         ^ cannot infer type
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/async-error-span.rs:19:18
-   |
-LL |     get_future().await;
-   |                  ^^^^^
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0277, E0698.
-For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/async-error-span.no_drop_tracking.stderr b/tests/ui/async-await/async-error-span.no_drop_tracking.stderr
deleted file mode 100644
index 99a674a2684..00000000000
--- a/tests/ui/async-await/async-error-span.no_drop_tracking.stderr
+++ /dev/null
@@ -1,25 +0,0 @@
-error[E0277]: `()` is not a future
-  --> $DIR/async-error-span.rs:10:20
-   |
-LL | fn get_future() -> impl Future<Output = ()> {
-   |                    ^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not a future
-   |
-   = help: the trait `Future` is not implemented for `()`
-   = note: () must be a future or must implement `IntoFuture` to be awaited
-
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/async-error-span.rs:16:9
-   |
-LL |     let a;
-   |         ^ cannot infer type
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/async-error-span.rs:19:18
-   |
-LL |     get_future().await;
-   |                  ^^^^^
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0277, E0698.
-For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/async-error-span.rs b/tests/ui/async-await/async-error-span.rs
index c9ecf359e3d..c8127df625e 100644
--- a/tests/ui/async-await/async-error-span.rs
+++ b/tests/ui/async-await/async-error-span.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2018
 
 // Regression test for issue #62382.
@@ -13,9 +10,7 @@ fn get_future() -> impl Future<Output = ()> {
 }
 
 async fn foo() {
-    let a;
-    //[no_drop_tracking,drop_tracking]~^ ERROR type inside `async fn` body must be known in this context
-    //[drop_tracking_mir]~^^ ERROR type annotations needed
+    let a; //~ ERROR type annotations needed
     get_future().await;
 }
 
diff --git a/tests/ui/async-await/async-error-span.drop_tracking_mir.stderr b/tests/ui/async-await/async-error-span.stderr
index 2f29ee6cdb0..2ec968ffc03 100644
--- a/tests/ui/async-await/async-error-span.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/async-error-span.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `()` is not a future
-  --> $DIR/async-error-span.rs:10:20
+  --> $DIR/async-error-span.rs:7:20
    |
 LL | fn get_future() -> impl Future<Output = ()> {
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^ `()` is not a future
@@ -8,7 +8,7 @@ LL | fn get_future() -> impl Future<Output = ()> {
    = note: () must be a future or must implement `IntoFuture` to be awaited
 
 error[E0282]: type annotations needed
-  --> $DIR/async-error-span.rs:16:9
+  --> $DIR/async-error-span.rs:13:9
    |
 LL |     let a;
    |         ^
diff --git a/tests/ui/async-await/async-fn-nonsend.drop_tracking.stderr b/tests/ui/async-await/async-fn-nonsend.drop_tracking.stderr
deleted file mode 100644
index 0515edaeda3..00000000000
--- a/tests/ui/async-await/async-fn-nonsend.drop_tracking.stderr
+++ /dev/null
@@ -1,49 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:72:17
-   |
-LL |     assert_send(non_send_temporary_in_match());
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_send_temporary_in_match` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-fn-nonsend.rs:36:26
-   |
-LL |     match Some(non_send()) {
-   |           ---------------- has type `Option<impl Debug>` which is not `Send`
-LL |         Some(_) => fut().await,
-   |                          ^^^^^ await occurs here, with `Some(non_send())` maybe used later
-...
-LL | }
-   | - `Some(non_send())` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/async-fn-nonsend.rs:67:24
-   |
-LL | fn assert_send(_: impl Send) {}
-   |                        ^^^^ required by this bound in `assert_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:74:17
-   |
-LL |     assert_send(non_sync_with_method_call());
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `dyn std::fmt::Write`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-fn-nonsend.rs:49:15
-   |
-LL |     let f: &mut std::fmt::Formatter = &mut get_formatter();
-   |                                            --------------- has type `Formatter<'_>` which is not `Send`
-...
-LL |         fut().await;
-   |               ^^^^^ await occurs here, with `get_formatter()` maybe used later
-LL |     }
-LL | }
-   | - `get_formatter()` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/async-fn-nonsend.rs:67:24
-   |
-LL | fn assert_send(_: impl Send) {}
-   |                        ^^^^ required by this bound in `assert_send`
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/async-await/async-fn-nonsend.no_drop_tracking.stderr b/tests/ui/async-await/async-fn-nonsend.no_drop_tracking.stderr
deleted file mode 100644
index b29d2e192f4..00000000000
--- a/tests/ui/async-await/async-fn-nonsend.no_drop_tracking.stderr
+++ /dev/null
@@ -1,120 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:70:17
-   |
-LL |     assert_send(local_dropped_before_await());
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `local_dropped_before_await` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-fn-nonsend.rs:27:11
-   |
-LL |     let x = non_send();
-   |         - has type `impl Debug` which is not `Send`
-LL |     drop(x);
-LL |     fut().await;
-   |           ^^^^^ await occurs here, with `x` maybe used later
-LL | }
-   | - `x` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/async-fn-nonsend.rs:67:24
-   |
-LL | fn assert_send(_: impl Send) {}
-   |                        ^^^^ required by this bound in `assert_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:72:17
-   |
-LL |     assert_send(non_send_temporary_in_match());
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_send_temporary_in_match` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-fn-nonsend.rs:36:26
-   |
-LL |     match Some(non_send()) {
-   |                ---------- has type `impl Debug` which is not `Send`
-LL |         Some(_) => fut().await,
-   |                          ^^^^^ await occurs here, with `non_send()` maybe used later
-...
-LL | }
-   | - `non_send()` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/async-fn-nonsend.rs:67:24
-   |
-LL | fn assert_send(_: impl Send) {}
-   |                        ^^^^ required by this bound in `assert_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:74:17
-   |
-LL |     assert_send(non_sync_with_method_call());
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `dyn std::fmt::Write`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-fn-nonsend.rs:49:15
-   |
-LL |     let f: &mut std::fmt::Formatter = &mut get_formatter();
-   |                                            --------------- has type `Formatter<'_>` which is not `Send`
-...
-LL |         fut().await;
-   |               ^^^^^ await occurs here, with `get_formatter()` maybe used later
-LL |     }
-LL | }
-   | - `get_formatter()` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/async-fn-nonsend.rs:67:24
-   |
-LL | fn assert_send(_: impl Send) {}
-   |                        ^^^^ required by this bound in `assert_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:76:17
-   |
-LL |     assert_send(non_sync_with_method_call_panic());
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call_panic` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `dyn std::fmt::Write`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-fn-nonsend.rs:56:15
-   |
-LL |     let f: &mut std::fmt::Formatter = panic!();
-   |         - has type `&mut Formatter<'_>` which is not `Send`
-LL |     if non_sync().fmt(f).unwrap() == () {
-LL |         fut().await;
-   |               ^^^^^ await occurs here, with `f` maybe used later
-LL |     }
-LL | }
-   | - `f` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/async-fn-nonsend.rs:67:24
-   |
-LL | fn assert_send(_: impl Send) {}
-   |                        ^^^^ required by this bound in `assert_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:78:17
-   |
-LL |     assert_send(non_sync_with_method_call_infinite_loop());
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call_infinite_loop` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `dyn std::fmt::Write`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/async-fn-nonsend.rs:63:15
-   |
-LL |     let f: &mut std::fmt::Formatter = loop {};
-   |         - has type `&mut Formatter<'_>` which is not `Send`
-LL |     if non_sync().fmt(f).unwrap() == () {
-LL |         fut().await;
-   |               ^^^^^ await occurs here, with `f` maybe used later
-LL |     }
-LL | }
-   | - `f` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/async-fn-nonsend.rs:67:24
-   |
-LL | fn assert_send(_: impl Send) {}
-   |                        ^^^^ required by this bound in `assert_send`
-
-error: aborting due to 5 previous errors
-
diff --git a/tests/ui/async-await/async-fn-nonsend.rs b/tests/ui/async-await/async-fn-nonsend.rs
index ed440bd0182..c5453b67ef5 100644
--- a/tests/ui/async-await/async-fn-nonsend.rs
+++ b/tests/ui/async-await/async-fn-nonsend.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2018
 // compile-flags: --crate-type lib
 
@@ -68,13 +65,10 @@ fn assert_send(_: impl Send) {}
 
 pub fn pass_assert() {
     assert_send(local_dropped_before_await());
-    //[no_drop_tracking]~^ ERROR future cannot be sent between threads safely
     assert_send(non_send_temporary_in_match());
     //~^ ERROR future cannot be sent between threads safely
     assert_send(non_sync_with_method_call());
     //~^ ERROR future cannot be sent between threads safely
     assert_send(non_sync_with_method_call_panic());
-    //[no_drop_tracking]~^ ERROR future cannot be sent between threads safely
     assert_send(non_sync_with_method_call_infinite_loop());
-    //[no_drop_tracking]~^ ERROR future cannot be sent between threads safely
 }
diff --git a/tests/ui/async-await/async-fn-nonsend.drop_tracking_mir.stderr b/tests/ui/async-await/async-fn-nonsend.stderr
index 219945e0971..0ced6c36f47 100644
--- a/tests/ui/async-await/async-fn-nonsend.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/async-fn-nonsend.stderr
@@ -1,32 +1,32 @@
 error: future cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:72:17
+  --> $DIR/async-fn-nonsend.rs:68:17
    |
 LL |     assert_send(non_send_temporary_in_match());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_send_temporary_in_match` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/async-fn-nonsend.rs:36:26
+  --> $DIR/async-fn-nonsend.rs:33:26
    |
 LL |     match Some(non_send()) {
    |           ---------------- has type `Option<impl Debug>` which is not `Send`
 LL |         Some(_) => fut().await,
    |                          ^^^^^ await occurs here, with `Some(non_send())` maybe used later
 note: required by a bound in `assert_send`
-  --> $DIR/async-fn-nonsend.rs:67:24
+  --> $DIR/async-fn-nonsend.rs:64:24
    |
 LL | fn assert_send(_: impl Send) {}
    |                        ^^^^ required by this bound in `assert_send`
 
 error: future cannot be sent between threads safely
-  --> $DIR/async-fn-nonsend.rs:74:17
+  --> $DIR/async-fn-nonsend.rs:70:17
    |
 LL |     assert_send(non_sync_with_method_call());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ future returned by `non_sync_with_method_call` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `dyn std::fmt::Write`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/async-fn-nonsend.rs:49:15
+  --> $DIR/async-fn-nonsend.rs:46:15
    |
 LL |     let f: &mut std::fmt::Formatter = &mut get_formatter();
    |                                            --------------- has type `Formatter<'_>` which is not `Send`
@@ -34,7 +34,7 @@ LL |     let f: &mut std::fmt::Formatter = &mut get_formatter();
 LL |         fut().await;
    |               ^^^^^ await occurs here, with `get_formatter()` maybe used later
 note: required by a bound in `assert_send`
-  --> $DIR/async-fn-nonsend.rs:67:24
+  --> $DIR/async-fn-nonsend.rs:64:24
    |
 LL | fn assert_send(_: impl Send) {}
    |                        ^^^^ required by this bound in `assert_send`
diff --git a/tests/ui/async-await/async-is-unwindsafe.stderr b/tests/ui/async-await/async-is-unwindsafe.stderr
index c21f8cfa51f..eaa45538050 100644
--- a/tests/ui/async-await/async-is-unwindsafe.stderr
+++ b/tests/ui/async-await/async-is-unwindsafe.stderr
@@ -1,18 +1,17 @@
 error[E0277]: the type `&mut Context<'_>` may not be safely transferred across an unwind boundary
-  --> $DIR/async-is-unwindsafe.rs:12:19
+  --> $DIR/async-is-unwindsafe.rs:12:5
    |
 LL |       is_unwindsafe(async {
-   |  ___________________^
+   |  _____^^^^^^^^^^^^^_-
+   | |     |
+   | |     `&mut Context<'_>` may not be safely transferred across an unwind boundary
 LL | |
 LL | |         use std::ptr::null;
 LL | |         use std::task::{Context, RawWaker, RawWakerVTable, Waker};
 ...  |
 LL | |         drop(cx_ref);
 LL | |     });
-   | |     ^
-   | |     |
-   | |_____`&mut Context<'_>` may not be safely transferred across an unwind boundary
-   |       within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`
+   | |_____- within this `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`
    |
    = help: within `{async block@$DIR/async-is-unwindsafe.rs:12:19: 29:6}`, the trait `UnwindSafe` is not implemented for `&mut Context<'_>`
    = note: `UnwindSafe` is implemented for `&Context<'_>`, but not for `&mut Context<'_>`
@@ -24,9 +23,6 @@ LL |         let cx_ref = &mut cx;
 LL |
 LL |         async {}.await; // this needs an inner await point
    |                  ^^^^^ await occurs here, with `cx_ref` maybe used later
-...
-LL |     });
-   |     - `cx_ref` is later dropped here
 note: required by a bound in `is_unwindsafe`
   --> $DIR/async-is-unwindsafe.rs:3:26
    |
diff --git a/tests/ui/async-await/await-sequence.rs b/tests/ui/async-await/await-sequence.rs
index 726c4284ec1..79f68dd606c 100644
--- a/tests/ui/async-await/await-sequence.rs
+++ b/tests/ui/async-await/await-sequence.rs
@@ -1,5 +1,4 @@
 // edition:2021
-// compile-flags: -Z drop-tracking
 // build-pass
 
 use std::collections::HashMap;
diff --git a/tests/ui/async-await/awaiting-unsized-param.rs b/tests/ui/async-await/awaiting-unsized-param.rs
new file mode 100644
index 00000000000..e8b18bf37f8
--- /dev/null
+++ b/tests/ui/async-await/awaiting-unsized-param.rs
@@ -0,0 +1,13 @@
+// edition: 2021
+
+#![feature(unsized_fn_params, unsized_locals)]
+//~^ WARN the feature `unsized_locals` is incomplete
+
+use std::future::Future;
+
+async fn bug<T>(mut f: dyn Future<Output = T> + Unpin) -> T {
+    //~^ ERROR the size for values of type `(dyn Future<Output = T> + Unpin + 'static)` cannot be known at compilation time
+    (&mut f).await
+}
+
+fn main() {}
diff --git a/tests/ui/async-await/awaiting-unsized-param.stderr b/tests/ui/async-await/awaiting-unsized-param.stderr
new file mode 100644
index 00000000000..47a5dcebf25
--- /dev/null
+++ b/tests/ui/async-await/awaiting-unsized-param.stderr
@@ -0,0 +1,21 @@
+warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/awaiting-unsized-param.rs:3:31
+   |
+LL | #![feature(unsized_fn_params, unsized_locals)]
+   |                               ^^^^^^^^^^^^^^
+   |
+   = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the size for values of type `(dyn Future<Output = T> + Unpin + 'static)` cannot be known at compilation time
+  --> $DIR/awaiting-unsized-param.rs:8:17
+   |
+LL | async fn bug<T>(mut f: dyn Future<Output = T> + Unpin) -> T {
+   |                 ^^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `(dyn Future<Output = T> + Unpin + 'static)`
+   = note: all values captured by value by a closure must have a statically known size
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/const-async-fn-in-main.rs b/tests/ui/async-await/const-async-fn-in-main.rs
new file mode 100644
index 00000000000..5d1aa4d83f3
--- /dev/null
+++ b/tests/ui/async-await/const-async-fn-in-main.rs
@@ -0,0 +1,7 @@
+// edition:2021
+// Check what happens when a const async fn is in the main function (#102796)
+
+fn main() {
+    const async fn a() {}
+//~^ ERROR functions cannot be both `const` and `async`
+}
diff --git a/tests/ui/async-await/const-async-fn-in-main.stderr b/tests/ui/async-await/const-async-fn-in-main.stderr
new file mode 100644
index 00000000000..10b15170922
--- /dev/null
+++ b/tests/ui/async-await/const-async-fn-in-main.stderr
@@ -0,0 +1,11 @@
+error: functions cannot be both `const` and `async`
+  --> $DIR/const-async-fn-in-main.rs:5:5
+   |
+LL |     const async fn a() {}
+   |     ^^^^^-^^^^^----------
+   |     |     |
+   |     |     `async` because of this
+   |     `const` because of this
+
+error: aborting due to previous error
+
diff --git a/tests/ui/async-await/default-struct-update.rs b/tests/ui/async-await/default-struct-update.rs
index daee8469a14..f4757e7cbae 100644
--- a/tests/ui/async-await/default-struct-update.rs
+++ b/tests/ui/async-await/default-struct-update.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // build-pass
 // edition:2018
 
diff --git a/tests/ui/async-await/drop-and-assign.rs b/tests/ui/async-await/drop-and-assign.rs
index e520dfbdcce..ef39033a9d4 100644
--- a/tests/ui/async-await/drop-and-assign.rs
+++ b/tests/ui/async-await/drop-and-assign.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2021
 // build-pass
 
diff --git a/tests/ui/async-await/drop-track-bad-field-in-fru.rs b/tests/ui/async-await/drop-track-bad-field-in-fru.rs
index 28ad7767583..667b288e676 100644
--- a/tests/ui/async-await/drop-track-bad-field-in-fru.rs
+++ b/tests/ui/async-await/drop-track-bad-field-in-fru.rs
@@ -1,4 +1,3 @@
-// compile-flags: -Zdrop-tracking
 // edition: 2021
 
 fn main() {}
diff --git a/tests/ui/async-await/drop-track-bad-field-in-fru.stderr b/tests/ui/async-await/drop-track-bad-field-in-fru.stderr
index b49b15db64c..721e0106293 100644
--- a/tests/ui/async-await/drop-track-bad-field-in-fru.stderr
+++ b/tests/ui/async-await/drop-track-bad-field-in-fru.stderr
@@ -1,5 +1,5 @@
 error[E0559]: variant `Option<_>::None` has no field named `value`
-  --> $DIR/drop-track-bad-field-in-fru.rs:7:12
+  --> $DIR/drop-track-bad-field-in-fru.rs:6:12
    |
 LL |     None { value: (), ..Default::default() }.await;
    |            ^^^^^ `Option<_>::None` does not have this field
@@ -7,7 +7,7 @@ LL |     None { value: (), ..Default::default() }.await;
    = note: all struct fields are already assigned
 
 error[E0277]: `Option<_>` is not a future
-  --> $DIR/drop-track-bad-field-in-fru.rs:7:46
+  --> $DIR/drop-track-bad-field-in-fru.rs:6:46
    |
 LL |     None { value: (), ..Default::default() }.await;
    |                                             -^^^^^
diff --git a/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking.stderr b/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking.stderr
deleted file mode 100644
index 80402d8424d..00000000000
--- a/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking.stderr
+++ /dev/null
@@ -1,25 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/drop-track-field-assign-nonsend.rs:45:17
-   |
-LL |     assert_send(agent.handle());
-   |                 ^^^^^^^^^^^^^^ future returned by `handle` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<String>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/drop-track-field-assign-nonsend.rs:23:39
-   |
-LL |         let mut info = self.info_result.clone();
-   |             -------- has type `InfoResult` which is not `Send`
-...
-LL |         let _ = send_element(element).await;
-   |                                       ^^^^^ await occurs here, with `mut info` maybe used later
-LL |     }
-   |     - `mut info` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/drop-track-field-assign-nonsend.rs:40:19
-   |
-LL | fn assert_send<T: Send>(_: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/drop-track-field-assign-nonsend.no_drop_tracking.stderr b/tests/ui/async-await/drop-track-field-assign-nonsend.no_drop_tracking.stderr
deleted file mode 100644
index 80402d8424d..00000000000
--- a/tests/ui/async-await/drop-track-field-assign-nonsend.no_drop_tracking.stderr
+++ /dev/null
@@ -1,25 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/drop-track-field-assign-nonsend.rs:45:17
-   |
-LL |     assert_send(agent.handle());
-   |                 ^^^^^^^^^^^^^^ future returned by `handle` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<String>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/drop-track-field-assign-nonsend.rs:23:39
-   |
-LL |         let mut info = self.info_result.clone();
-   |             -------- has type `InfoResult` which is not `Send`
-...
-LL |         let _ = send_element(element).await;
-   |                                       ^^^^^ await occurs here, with `mut info` maybe used later
-LL |     }
-   |     - `mut info` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/drop-track-field-assign-nonsend.rs:40:19
-   |
-LL | fn assert_send<T: Send>(_: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/drop-track-field-assign-nonsend.rs b/tests/ui/async-await/drop-track-field-assign-nonsend.rs
index 3e22280008f..19315ef19f9 100644
--- a/tests/ui/async-await/drop-track-field-assign-nonsend.rs
+++ b/tests/ui/async-await/drop-track-field-assign-nonsend.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // Derived from an ICE found in tokio-xmpp during a crater run.
 // edition:2021
 
diff --git a/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking_mir.stderr b/tests/ui/async-await/drop-track-field-assign-nonsend.stderr
index d9141cf4e36..6c235916d64 100644
--- a/tests/ui/async-await/drop-track-field-assign-nonsend.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/drop-track-field-assign-nonsend.stderr
@@ -1,12 +1,12 @@
 error: future cannot be sent between threads safely
-  --> $DIR/drop-track-field-assign-nonsend.rs:45:17
+  --> $DIR/drop-track-field-assign-nonsend.rs:42:17
    |
 LL |     assert_send(agent.handle());
    |                 ^^^^^^^^^^^^^^ future returned by `handle` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<String>`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/drop-track-field-assign-nonsend.rs:23:39
+  --> $DIR/drop-track-field-assign-nonsend.rs:20:39
    |
 LL |         let mut info = self.info_result.clone();
    |             -------- has type `InfoResult` which is not `Send`
@@ -14,7 +14,7 @@ LL |         let mut info = self.info_result.clone();
 LL |         let _ = send_element(element).await;
    |                                       ^^^^^ await occurs here, with `mut info` maybe used later
 note: required by a bound in `assert_send`
-  --> $DIR/drop-track-field-assign-nonsend.rs:40:19
+  --> $DIR/drop-track-field-assign-nonsend.rs:37:19
    |
 LL | fn assert_send<T: Send>(_: T) {}
    |                   ^^^^ required by this bound in `assert_send`
diff --git a/tests/ui/async-await/drop-track-field-assign.rs b/tests/ui/async-await/drop-track-field-assign.rs
index b79d2af066a..4887eff7efa 100644
--- a/tests/ui/async-await/drop-track-field-assign.rs
+++ b/tests/ui/async-await/drop-track-field-assign.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // Derived from an ICE found in tokio-xmpp during a crater run.
 // edition:2021
 // build-pass
diff --git a/tests/ui/async-await/drop-tracking-unresolved-typeck-results.rs b/tests/ui/async-await/drop-tracking-unresolved-typeck-results.rs
index 7f729429581..9f80b9c6e9f 100644
--- a/tests/ui/async-await/drop-tracking-unresolved-typeck-results.rs
+++ b/tests/ui/async-await/drop-tracking-unresolved-typeck-results.rs
@@ -1,4 +1,3 @@
-// compile-flags: -Zdrop-tracking
 // incremental
 // edition: 2021
 
@@ -99,8 +98,6 @@ fn main() {
     send(async {
         //~^ ERROR implementation of `FnOnce` is not general enough
         //~| ERROR implementation of `FnOnce` is not general enough
-        //~| ERROR implementation of `FnOnce` is not general enough
-        //~| ERROR implementation of `FnOnce` is not general enough
         Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await
     });
 }
diff --git a/tests/ui/async-await/drop-tracking-unresolved-typeck-results.stderr b/tests/ui/async-await/drop-tracking-unresolved-typeck-results.stderr
index aa9a22e9e72..cfb0ebe38b6 100644
--- a/tests/ui/async-await/drop-tracking-unresolved-typeck-results.stderr
+++ b/tests/ui/async-await/drop-tracking-unresolved-typeck-results.stderr
@@ -1,26 +1,9 @@
 error: implementation of `FnOnce` is not general enough
-  --> $DIR/drop-tracking-unresolved-typeck-results.rs:99:5
+  --> $DIR/drop-tracking-unresolved-typeck-results.rs:98:5
    |
 LL | /     send(async {
 LL | |
 LL | |
-LL | |
-LL | |
-LL | |         Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await
-LL | |     });
-   | |______^ implementation of `FnOnce` is not general enough
-   |
-   = note: `fn(&'0 ()) -> std::future::Ready<&'0 ()> {std::future::ready::<&'0 ()>}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
-   = note: ...but it actually implements `FnOnce<(&(),)>`
-
-error: implementation of `FnOnce` is not general enough
-  --> $DIR/drop-tracking-unresolved-typeck-results.rs:99:5
-   |
-LL | /     send(async {
-LL | |
-LL | |
-LL | |
-LL | |
 LL | |         Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await
 LL | |     });
    | |______^ implementation of `FnOnce` is not general enough
@@ -29,28 +12,11 @@ LL | |     });
    = note: ...but it actually implements `FnOnce<(&(),)>`
 
 error: implementation of `FnOnce` is not general enough
-  --> $DIR/drop-tracking-unresolved-typeck-results.rs:99:5
+  --> $DIR/drop-tracking-unresolved-typeck-results.rs:98:5
    |
 LL | /     send(async {
 LL | |
 LL | |
-LL | |
-LL | |
-LL | |         Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await
-LL | |     });
-   | |______^ implementation of `FnOnce` is not general enough
-   |
-   = note: `fn(&'0 ()) -> std::future::Ready<&'0 ()> {std::future::ready::<&'0 ()>}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
-   = note: ...but it actually implements `FnOnce<(&(),)>`
-
-error: implementation of `FnOnce` is not general enough
-  --> $DIR/drop-tracking-unresolved-typeck-results.rs:99:5
-   |
-LL | /     send(async {
-LL | |
-LL | |
-LL | |
-LL | |
 LL | |         Next(&Buffered(Map(Empty(PhantomData), ready::<&()>), FuturesOrdered(PhantomData), 0)).await
 LL | |     });
    | |______^ implementation of `FnOnce` is not general enough
@@ -58,5 +24,5 @@ LL | |     });
    = note: `fn(&'0 ()) -> std::future::Ready<&'0 ()> {std::future::ready::<&'0 ()>}` must implement `FnOnce<(&'1 (),)>`, for any two lifetimes `'0` and `'1`...
    = note: ...but it actually implements `FnOnce<(&(),)>`
 
-error: aborting due to 4 previous errors
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/async-await/feature-self-return-type.rs b/tests/ui/async-await/feature-self-return-type.rs
index 41f887430c1..ae6f766d247 100644
--- a/tests/ui/async-await/feature-self-return-type.rs
+++ b/tests/ui/async-await/feature-self-return-type.rs
@@ -1,5 +1,4 @@
 // edition:2018
-#![feature(impl_trait_projections)]
 
 // This test checks that we emit the correct borrowck error when `Self` is used as a return type.
 // See #61949 for context.
diff --git a/tests/ui/async-await/feature-self-return-type.stderr b/tests/ui/async-await/feature-self-return-type.stderr
index 747c54b6694..dc160bfbf61 100644
--- a/tests/ui/async-await/feature-self-return-type.stderr
+++ b/tests/ui/async-await/feature-self-return-type.stderr
@@ -1,5 +1,5 @@
 error[E0597]: `bar` does not live long enough
-  --> $DIR/feature-self-return-type.rs:22:18
+  --> $DIR/feature-self-return-type.rs:21:18
    |
 LL |     let x = {
    |         - borrow later stored here
diff --git a/tests/ui/async-await/field-assign-nonsend.drop_tracking.stderr b/tests/ui/async-await/field-assign-nonsend.drop_tracking.stderr
deleted file mode 100644
index e2e64c9ae0c..00000000000
--- a/tests/ui/async-await/field-assign-nonsend.drop_tracking.stderr
+++ /dev/null
@@ -1,25 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/field-assign-nonsend.rs:45:17
-   |
-LL |     assert_send(agent.handle());
-   |                 ^^^^^^^^^^^^^^ future returned by `handle` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<String>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/field-assign-nonsend.rs:23:39
-   |
-LL |         let mut info = self.info_result.clone();
-   |             -------- has type `InfoResult` which is not `Send`
-...
-LL |         let _ = send_element(element).await;
-   |                                       ^^^^^ await occurs here, with `mut info` maybe used later
-LL |     }
-   |     - `mut info` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/field-assign-nonsend.rs:40:19
-   |
-LL | fn assert_send<T: Send>(_: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/field-assign-nonsend.no_drop_tracking.stderr b/tests/ui/async-await/field-assign-nonsend.no_drop_tracking.stderr
deleted file mode 100644
index e2e64c9ae0c..00000000000
--- a/tests/ui/async-await/field-assign-nonsend.no_drop_tracking.stderr
+++ /dev/null
@@ -1,25 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/field-assign-nonsend.rs:45:17
-   |
-LL |     assert_send(agent.handle());
-   |                 ^^^^^^^^^^^^^^ future returned by `handle` is not `Send`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<String>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/field-assign-nonsend.rs:23:39
-   |
-LL |         let mut info = self.info_result.clone();
-   |             -------- has type `InfoResult` which is not `Send`
-...
-LL |         let _ = send_element(element).await;
-   |                                       ^^^^^ await occurs here, with `mut info` maybe used later
-LL |     }
-   |     - `mut info` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/field-assign-nonsend.rs:40:19
-   |
-LL | fn assert_send<T: Send>(_: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/field-assign-nonsend.rs b/tests/ui/async-await/field-assign-nonsend.rs
index 3e22280008f..19315ef19f9 100644
--- a/tests/ui/async-await/field-assign-nonsend.rs
+++ b/tests/ui/async-await/field-assign-nonsend.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // Derived from an ICE found in tokio-xmpp during a crater run.
 // edition:2021
 
diff --git a/tests/ui/async-await/field-assign-nonsend.drop_tracking_mir.stderr b/tests/ui/async-await/field-assign-nonsend.stderr
index d1df8e91afa..3037d702447 100644
--- a/tests/ui/async-await/field-assign-nonsend.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/field-assign-nonsend.stderr
@@ -1,12 +1,12 @@
 error: future cannot be sent between threads safely
-  --> $DIR/field-assign-nonsend.rs:45:17
+  --> $DIR/field-assign-nonsend.rs:42:17
    |
 LL |     assert_send(agent.handle());
    |                 ^^^^^^^^^^^^^^ future returned by `handle` is not `Send`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<String>`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/field-assign-nonsend.rs:23:39
+  --> $DIR/field-assign-nonsend.rs:20:39
    |
 LL |         let mut info = self.info_result.clone();
    |             -------- has type `InfoResult` which is not `Send`
@@ -14,7 +14,7 @@ LL |         let mut info = self.info_result.clone();
 LL |         let _ = send_element(element).await;
    |                                       ^^^^^ await occurs here, with `mut info` maybe used later
 note: required by a bound in `assert_send`
-  --> $DIR/field-assign-nonsend.rs:40:19
+  --> $DIR/field-assign-nonsend.rs:37:19
    |
 LL | fn assert_send<T: Send>(_: T) {}
    |                   ^^^^ required by this bound in `assert_send`
diff --git a/tests/ui/async-await/field-assign.rs b/tests/ui/async-await/field-assign.rs
index b79d2af066a..4887eff7efa 100644
--- a/tests/ui/async-await/field-assign.rs
+++ b/tests/ui/async-await/field-assign.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // Derived from an ICE found in tokio-xmpp during a crater run.
 // edition:2021
 // build-pass
diff --git a/tests/ui/async-await/in-trait/async-associated-types.rs b/tests/ui/async-await/in-trait/async-associated-types.rs
index 974f5aaff83..3e2739a164f 100644
--- a/tests/ui/async-await/in-trait/async-associated-types.rs
+++ b/tests/ui/async-await/in-trait/async-associated-types.rs
@@ -2,7 +2,6 @@
 // edition: 2021
 
 #![feature(async_fn_in_trait)]
-#![feature(impl_trait_projections)]
 #![allow(incomplete_features)]
 
 use std::fmt::Debug;
diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs
index 85d17ddff94..2fe6b473df6 100644
--- a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs
+++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.rs
@@ -1,6 +1,6 @@
 // edition: 2021
 // build-fail
-//~^^ ERROR overflow evaluating the requirement `<A as Second>::{opaque#0} == _`
+//~^^ ERROR cycle detected when computing layout of
 
 #![feature(async_fn_in_trait)]
 
diff --git a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr
index 3f487a6e5fe..41e84466a14 100644
--- a/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr
+++ b/tests/ui/async-await/in-trait/indirect-recursion-issue-112047.stderr
@@ -1,5 +1,10 @@
-error[E0275]: overflow evaluating the requirement `<A as Second>::{opaque#0} == _`
+error[E0391]: cycle detected when computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:35:27: 37:6}`
+   |
+   = note: ...which requires computing layout of `<<A as First>::Second as Second>::{opaque#0}`...
+   = note: ...which again requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:35:27: 37:6}`, completing the cycle
+   = note: cycle used when computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:8:13: 10:6}`
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0275`.
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/async-await/issue-61949-self-return-type.rs b/tests/ui/async-await/issue-61949-self-return-type.rs
deleted file mode 100644
index d73dbc6e828..00000000000
--- a/tests/ui/async-await/issue-61949-self-return-type.rs
+++ /dev/null
@@ -1,28 +0,0 @@
-// edition:2018
-// gate-test-impl_trait_projections
-
-// This test checks that `Self` is prohibited as a return type. See #61949 for context.
-
-pub struct Foo<'a> {
-    pub bar: &'a i32,
-}
-
-impl<'a> Foo<'a> {
-    pub async fn new(_bar: &'a i32) -> Self {
-    //~^ ERROR `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
-        Foo {
-            bar: &22
-        }
-    }
-}
-
-async fn foo() {
-    let x = {
-        let bar = 22;
-        Foo::new(&bar).await
-        //~^ ERROR `bar` does not live long enough
-    };
-    drop(x);
-}
-
-fn main() { }
diff --git a/tests/ui/async-await/issue-61949-self-return-type.stderr b/tests/ui/async-await/issue-61949-self-return-type.stderr
deleted file mode 100644
index ac85ed2887a..00000000000
--- a/tests/ui/async-await/issue-61949-self-return-type.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-error[E0658]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
-  --> $DIR/issue-61949-self-return-type.rs:11:40
-   |
-LL |     pub async fn new(_bar: &'a i32) -> Self {
-   |                                        ^^^^ help: consider spelling out the type instead: `Foo<'a>`
-   |
-   = note: see issue #103532 <https://github.com/rust-lang/rust/issues/103532> for more information
-   = help: add `#![feature(impl_trait_projections)]` to the crate attributes to enable
-
-error[E0597]: `bar` does not live long enough
-  --> $DIR/issue-61949-self-return-type.rs:22:18
-   |
-LL |     let x = {
-   |         - borrow later stored here
-LL |         let bar = 22;
-   |             --- binding `bar` declared here
-LL |         Foo::new(&bar).await
-   |                  ^^^^ borrowed value does not live long enough
-LL |
-LL |     };
-   |     - `bar` dropped here while still borrowed
-
-error: aborting due to 2 previous errors
-
-Some errors have detailed explanations: E0597, E0658.
-For more information about an error, try `rustc --explain E0597`.
diff --git a/tests/ui/async-await/issue-64130-1-sync.drop_tracking.stderr b/tests/ui/async-await/issue-64130-1-sync.drop_tracking.stderr
deleted file mode 100644
index 56aa035f44b..00000000000
--- a/tests/ui/async-await/issue-64130-1-sync.drop_tracking.stderr
+++ /dev/null
@@ -1,25 +0,0 @@
-error: future cannot be shared between threads safely
-  --> $DIR/issue-64130-1-sync.rs:25:13
-   |
-LL |     is_sync(bar());
-   |             ^^^^^ future returned by `bar` is not `Sync`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Sync` is not implemented for `Foo`
-note: future is not `Sync` as this value is used across an await
-  --> $DIR/issue-64130-1-sync.rs:18:11
-   |
-LL |     let x = Foo;
-   |         - has type `Foo` which is not `Sync`
-LL |     baz().await;
-   |           ^^^^^ await occurs here, with `x` maybe used later
-LL |     drop(x);
-LL | }
-   | - `x` is later dropped here
-note: required by a bound in `is_sync`
-  --> $DIR/issue-64130-1-sync.rs:14:15
-   |
-LL | fn is_sync<T: Sync>(t: T) { }
-   |               ^^^^ required by this bound in `is_sync`
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/issue-64130-1-sync.no_drop_tracking.stderr b/tests/ui/async-await/issue-64130-1-sync.no_drop_tracking.stderr
deleted file mode 100644
index 56aa035f44b..00000000000
--- a/tests/ui/async-await/issue-64130-1-sync.no_drop_tracking.stderr
+++ /dev/null
@@ -1,25 +0,0 @@
-error: future cannot be shared between threads safely
-  --> $DIR/issue-64130-1-sync.rs:25:13
-   |
-LL |     is_sync(bar());
-   |             ^^^^^ future returned by `bar` is not `Sync`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Sync` is not implemented for `Foo`
-note: future is not `Sync` as this value is used across an await
-  --> $DIR/issue-64130-1-sync.rs:18:11
-   |
-LL |     let x = Foo;
-   |         - has type `Foo` which is not `Sync`
-LL |     baz().await;
-   |           ^^^^^ await occurs here, with `x` maybe used later
-LL |     drop(x);
-LL | }
-   | - `x` is later dropped here
-note: required by a bound in `is_sync`
-  --> $DIR/issue-64130-1-sync.rs:14:15
-   |
-LL | fn is_sync<T: Sync>(t: T) { }
-   |               ^^^^ required by this bound in `is_sync`
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/issue-64130-1-sync.rs b/tests/ui/async-await/issue-64130-1-sync.rs
index 44646e0e5f2..7769085a0db 100644
--- a/tests/ui/async-await/issue-64130-1-sync.rs
+++ b/tests/ui/async-await/issue-64130-1-sync.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 #![feature(negative_impls)]
 // edition:2018
 
diff --git a/tests/ui/async-await/issue-64130-1-sync.drop_tracking_mir.stderr b/tests/ui/async-await/issue-64130-1-sync.stderr
index ea1bfb9f9ac..207e085d273 100644
--- a/tests/ui/async-await/issue-64130-1-sync.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/issue-64130-1-sync.stderr
@@ -1,19 +1,19 @@
 error: future cannot be shared between threads safely
-  --> $DIR/issue-64130-1-sync.rs:25:13
+  --> $DIR/issue-64130-1-sync.rs:22:13
    |
 LL |     is_sync(bar());
    |             ^^^^^ future returned by `bar` is not `Sync`
    |
    = help: within `impl Future<Output = ()>`, the trait `Sync` is not implemented for `Foo`
 note: future is not `Sync` as this value is used across an await
-  --> $DIR/issue-64130-1-sync.rs:18:11
+  --> $DIR/issue-64130-1-sync.rs:15:11
    |
 LL |     let x = Foo;
    |         - has type `Foo` which is not `Sync`
 LL |     baz().await;
    |           ^^^^^ await occurs here, with `x` maybe used later
 note: required by a bound in `is_sync`
-  --> $DIR/issue-64130-1-sync.rs:14:15
+  --> $DIR/issue-64130-1-sync.rs:11:15
    |
 LL | fn is_sync<T: Sync>(t: T) { }
    |               ^^^^ required by this bound in `is_sync`
diff --git a/tests/ui/async-await/issue-64130-2-send.drop_tracking.stderr b/tests/ui/async-await/issue-64130-2-send.drop_tracking.stderr
deleted file mode 100644
index d1717ad3310..00000000000
--- a/tests/ui/async-await/issue-64130-2-send.drop_tracking.stderr
+++ /dev/null
@@ -1,28 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/issue-64130-2-send.rs:24:13
-   |
-LL |     is_send(bar());
-   |             ^^^^^ future returned by `bar` is not `Send`
-   |
-   = note: the trait bound `Unique<Foo>: Send` is not satisfied
-note: future is not `Send` as this value is used across an await
-  --> $DIR/issue-64130-2-send.rs:18:11
-   |
-LL |     let x = Box::new(Foo);
-   |         - has type `Box<Foo>` which is not `Send`
-LL |     baz().await;
-   |           ^^^^^ await occurs here, with `x` maybe used later
-LL | }
-   | - `x` is later dropped here
-note: required by a bound in `is_send`
-  --> $DIR/issue-64130-2-send.rs:14:15
-   |
-LL | fn is_send<T: Send>(t: T) { }
-   |               ^^^^ required by this bound in `is_send`
-help: consider borrowing here
-   |
-LL |     is_send(&bar());
-   |             +
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/issue-64130-2-send.no_drop_tracking.stderr b/tests/ui/async-await/issue-64130-2-send.no_drop_tracking.stderr
deleted file mode 100644
index d1717ad3310..00000000000
--- a/tests/ui/async-await/issue-64130-2-send.no_drop_tracking.stderr
+++ /dev/null
@@ -1,28 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/issue-64130-2-send.rs:24:13
-   |
-LL |     is_send(bar());
-   |             ^^^^^ future returned by `bar` is not `Send`
-   |
-   = note: the trait bound `Unique<Foo>: Send` is not satisfied
-note: future is not `Send` as this value is used across an await
-  --> $DIR/issue-64130-2-send.rs:18:11
-   |
-LL |     let x = Box::new(Foo);
-   |         - has type `Box<Foo>` which is not `Send`
-LL |     baz().await;
-   |           ^^^^^ await occurs here, with `x` maybe used later
-LL | }
-   | - `x` is later dropped here
-note: required by a bound in `is_send`
-  --> $DIR/issue-64130-2-send.rs:14:15
-   |
-LL | fn is_send<T: Send>(t: T) { }
-   |               ^^^^ required by this bound in `is_send`
-help: consider borrowing here
-   |
-LL |     is_send(&bar());
-   |             +
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/issue-64130-2-send.rs b/tests/ui/async-await/issue-64130-2-send.rs
index d6d855bac07..0195afe6b39 100644
--- a/tests/ui/async-await/issue-64130-2-send.rs
+++ b/tests/ui/async-await/issue-64130-2-send.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 #![feature(negative_impls)]
 // edition:2018
 
@@ -14,8 +11,9 @@ impl !Send for Foo {}
 fn is_send<T: Send>(t: T) { }
 
 async fn bar() {
-    let x = Box::new(Foo);
+    let x = Foo;
     baz().await;
+    drop(x);
 }
 
 async fn baz() { }
diff --git a/tests/ui/async-await/issue-64130-2-send.drop_tracking_mir.stderr b/tests/ui/async-await/issue-64130-2-send.stderr
index 45e43525a20..a433c76ae70 100644
--- a/tests/ui/async-await/issue-64130-2-send.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/issue-64130-2-send.stderr
@@ -1,26 +1,22 @@
 error: future cannot be sent between threads safely
-  --> $DIR/issue-64130-2-send.rs:24:13
+  --> $DIR/issue-64130-2-send.rs:22:13
    |
 LL |     is_send(bar());
    |             ^^^^^ future returned by `bar` is not `Send`
    |
-   = note: the trait bound `Unique<Foo>: Send` is not satisfied
+   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Foo`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/issue-64130-2-send.rs:18:11
+  --> $DIR/issue-64130-2-send.rs:15:11
    |
-LL |     let x = Box::new(Foo);
-   |         - has type `Box<Foo>` which is not `Send`
+LL |     let x = Foo;
+   |         - has type `Foo` which is not `Send`
 LL |     baz().await;
    |           ^^^^^ await occurs here, with `x` maybe used later
 note: required by a bound in `is_send`
-  --> $DIR/issue-64130-2-send.rs:14:15
+  --> $DIR/issue-64130-2-send.rs:11:15
    |
 LL | fn is_send<T: Send>(t: T) { }
    |               ^^^^ required by this bound in `is_send`
-help: consider borrowing here
-   |
-LL |     is_send(&bar());
-   |             +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/async-await/issue-64130-3-other.drop_tracking.stderr b/tests/ui/async-await/issue-64130-3-other.drop_tracking.stderr
deleted file mode 100644
index b69f06da1cd..00000000000
--- a/tests/ui/async-await/issue-64130-3-other.drop_tracking.stderr
+++ /dev/null
@@ -1,27 +0,0 @@
-error[E0277]: the trait bound `Foo: Qux` is not satisfied in `impl Future<Output = ()>`
-  --> $DIR/issue-64130-3-other.rs:27:12
-   |
-LL | async fn bar() {
-   |                - within this `impl Future<Output = ()>`
-...
-LL |     is_qux(bar());
-   |            ^^^^^ within `impl Future<Output = ()>`, the trait `Qux` is not implemented for `Foo`
-   |
-note: future does not implement `Qux` as this value is used across an await
-  --> $DIR/issue-64130-3-other.rs:21:11
-   |
-LL |     let x = Box::new(Foo);
-   |         - has type `Box<Foo>` which does not implement `Qux`
-LL |     baz().await;
-   |           ^^^^^ await occurs here, with `x` maybe used later
-LL | }
-   | - `x` is later dropped here
-note: required by a bound in `is_qux`
-  --> $DIR/issue-64130-3-other.rs:17:14
-   |
-LL | fn is_qux<T: Qux>(t: T) {}
-   |              ^^^ required by this bound in `is_qux`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/issue-64130-3-other.no_drop_tracking.stderr b/tests/ui/async-await/issue-64130-3-other.no_drop_tracking.stderr
deleted file mode 100644
index b69f06da1cd..00000000000
--- a/tests/ui/async-await/issue-64130-3-other.no_drop_tracking.stderr
+++ /dev/null
@@ -1,27 +0,0 @@
-error[E0277]: the trait bound `Foo: Qux` is not satisfied in `impl Future<Output = ()>`
-  --> $DIR/issue-64130-3-other.rs:27:12
-   |
-LL | async fn bar() {
-   |                - within this `impl Future<Output = ()>`
-...
-LL |     is_qux(bar());
-   |            ^^^^^ within `impl Future<Output = ()>`, the trait `Qux` is not implemented for `Foo`
-   |
-note: future does not implement `Qux` as this value is used across an await
-  --> $DIR/issue-64130-3-other.rs:21:11
-   |
-LL |     let x = Box::new(Foo);
-   |         - has type `Box<Foo>` which does not implement `Qux`
-LL |     baz().await;
-   |           ^^^^^ await occurs here, with `x` maybe used later
-LL | }
-   | - `x` is later dropped here
-note: required by a bound in `is_qux`
-  --> $DIR/issue-64130-3-other.rs:17:14
-   |
-LL | fn is_qux<T: Qux>(t: T) {}
-   |              ^^^ required by this bound in `is_qux`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/issue-64130-3-other.rs b/tests/ui/async-await/issue-64130-3-other.rs
index 92d3b7c81fb..074d67aa3fb 100644
--- a/tests/ui/async-await/issue-64130-3-other.rs
+++ b/tests/ui/async-await/issue-64130-3-other.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 #![feature(auto_traits)]
 #![feature(negative_impls)]
 // edition:2018
@@ -17,8 +14,9 @@ impl !Qux for Foo {}
 fn is_qux<T: Qux>(t: T) {}
 
 async fn bar() {
-    let x = Box::new(Foo);
+    let x = Foo;
     baz().await;
+    drop(x);
 }
 
 async fn baz() {}
diff --git a/tests/ui/async-await/issue-64130-3-other.drop_tracking_mir.stderr b/tests/ui/async-await/issue-64130-3-other.stderr
index 1298371241c..573da1034c5 100644
--- a/tests/ui/async-await/issue-64130-3-other.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/issue-64130-3-other.stderr
@@ -1,5 +1,5 @@
 error[E0277]: the trait bound `Foo: Qux` is not satisfied in `impl Future<Output = ()>`
-  --> $DIR/issue-64130-3-other.rs:27:12
+  --> $DIR/issue-64130-3-other.rs:25:12
    |
 LL | async fn bar() {
    |                - within this `impl Future<Output = ()>`
@@ -8,14 +8,14 @@ LL |     is_qux(bar());
    |            ^^^^^ within `impl Future<Output = ()>`, the trait `Qux` is not implemented for `Foo`
    |
 note: future does not implement `Qux` as this value is used across an await
-  --> $DIR/issue-64130-3-other.rs:21:11
+  --> $DIR/issue-64130-3-other.rs:18:11
    |
-LL |     let x = Box::new(Foo);
-   |         - has type `Box<Foo>` which does not implement `Qux`
+LL |     let x = Foo;
+   |         - has type `Foo` which does not implement `Qux`
 LL |     baz().await;
    |           ^^^^^ await occurs here, with `x` maybe used later
 note: required by a bound in `is_qux`
-  --> $DIR/issue-64130-3-other.rs:17:14
+  --> $DIR/issue-64130-3-other.rs:14:14
    |
 LL | fn is_qux<T: Qux>(t: T) {}
    |              ^^^ required by this bound in `is_qux`
diff --git a/tests/ui/async-await/issue-64130-4-async-move.drop-tracking.stderr b/tests/ui/async-await/issue-64130-4-async-move.drop-tracking.stderr
deleted file mode 100644
index 884619f4dd6..00000000000
--- a/tests/ui/async-await/issue-64130-4-async-move.drop-tracking.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/issue-64130-4-async-move.rs:20:17
-   |
-LL | pub fn foo() -> impl Future + Send {
-   |                 ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
-   |
-   = help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/issue-64130-4-async-move.rs:27:31
-   |
-LL |         match client.status() {
-   |               ------ has type `&Client` which is not `Send`
-LL |             200 => {
-LL |                 let _x = get().await;
-   |                               ^^^^^^ await occurs here, with `client` maybe used later
-...
-LL |     }
-   |     - `client` is later dropped here
-help: consider moving this into a `let` binding to create a shorter lived borrow
-  --> $DIR/issue-64130-4-async-move.rs:25:15
-   |
-LL |         match client.status() {
-   |               ^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr b/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr
deleted file mode 100644
index 60b7551ff8a..00000000000
--- a/tests/ui/async-await/issue-64130-4-async-move.no_drop_tracking.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/issue-64130-4-async-move.rs:21:17
-   |
-LL | pub fn foo() -> impl Future + Send {
-   |                 ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
-   |
-   = help: the trait `Sync` is not implemented for `(dyn Any + Send + 'static)`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/issue-64130-4-async-move.rs:27:23
-   |
-LL |         match client.status() {
-   |               ------ has type `&Client` which is not `Send`
-LL |             200 => {
-LL |                 get().await;
-   |                       ^^^^^ await occurs here, with `client` maybe used later
-...
-LL |     }
-   |     - `client` is later dropped here
-help: consider moving this into a `let` binding to create a shorter lived borrow
-  --> $DIR/issue-64130-4-async-move.rs:25:15
-   |
-LL |         match client.status() {
-   |               ^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/issue-64130-4-async-move.rs b/tests/ui/async-await/issue-64130-4-async-move.rs
index 5d68a808b17..359813f6379 100644
--- a/tests/ui/async-await/issue-64130-4-async-move.rs
+++ b/tests/ui/async-await/issue-64130-4-async-move.rs
@@ -1,9 +1,5 @@
 // edition:2018
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-// [drop_tracking_mir] check-pass
-// [drop_tracking] check-pass
+// check-pass
 
 use std::any::Any;
 use std::future::Future;
@@ -19,7 +15,6 @@ impl Client {
 async fn get() {}
 
 pub fn foo() -> impl Future + Send {
-    //[no_drop_tracking]~^ ERROR future cannot be sent between threads safely
     let client = Client(Box::new(true));
     async move {
         match client.status() {
diff --git a/tests/ui/async-await/issue-64130-non-send-future-diags.stderr b/tests/ui/async-await/issue-64130-non-send-future-diags.stderr
index e044e2ca011..cb02fcf5ce7 100644
--- a/tests/ui/async-await/issue-64130-non-send-future-diags.stderr
+++ b/tests/ui/async-await/issue-64130-non-send-future-diags.stderr
@@ -12,8 +12,6 @@ LL |     let g = x.lock().unwrap();
    |         - has type `MutexGuard<'_, u32>` which is not `Send`
 LL |     baz().await;
    |           ^^^^^ await occurs here, with `g` maybe used later
-LL | }
-   | - `g` is later dropped here
 note: required by a bound in `is_send`
   --> $DIR/issue-64130-non-send-future-diags.rs:9:15
    |
diff --git a/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking.stderr b/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking.stderr
deleted file mode 100644
index c4c0c43fc13..00000000000
--- a/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking.stderr
+++ /dev/null
@@ -1,30 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/issue-67252-unnamed-future.rs:21:11
-   |
-LL |       spawn(async {
-   |  ___________^
-LL | |         let a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
-LL | |         AFuture.await;
-LL | |         drop(a);
-LL | |     });
-   | |_____^ future created by async block is not `Send`
-   |
-   = help: within `{async block@$DIR/issue-67252-unnamed-future.rs:21:11: 25:6}`, the trait `Send` is not implemented for `*mut ()`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/issue-67252-unnamed-future.rs:23:17
-   |
-LL |         let a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
-   |             - has type `*mut ()` which is not `Send`
-LL |         AFuture.await;
-   |                 ^^^^^ await occurs here, with `a` maybe used later
-LL |         drop(a);
-LL |     });
-   |     - `a` is later dropped here
-note: required by a bound in `spawn`
-  --> $DIR/issue-67252-unnamed-future.rs:9:13
-   |
-LL | fn spawn<T: Send>(_: T) {}
-   |             ^^^^ required by this bound in `spawn`
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/issue-67252-unnamed-future.no_drop_tracking.stderr b/tests/ui/async-await/issue-67252-unnamed-future.no_drop_tracking.stderr
deleted file mode 100644
index c4c0c43fc13..00000000000
--- a/tests/ui/async-await/issue-67252-unnamed-future.no_drop_tracking.stderr
+++ /dev/null
@@ -1,30 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/issue-67252-unnamed-future.rs:21:11
-   |
-LL |       spawn(async {
-   |  ___________^
-LL | |         let a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
-LL | |         AFuture.await;
-LL | |         drop(a);
-LL | |     });
-   | |_____^ future created by async block is not `Send`
-   |
-   = help: within `{async block@$DIR/issue-67252-unnamed-future.rs:21:11: 25:6}`, the trait `Send` is not implemented for `*mut ()`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/issue-67252-unnamed-future.rs:23:17
-   |
-LL |         let a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
-   |             - has type `*mut ()` which is not `Send`
-LL |         AFuture.await;
-   |                 ^^^^^ await occurs here, with `a` maybe used later
-LL |         drop(a);
-LL |     });
-   |     - `a` is later dropped here
-note: required by a bound in `spawn`
-  --> $DIR/issue-67252-unnamed-future.rs:9:13
-   |
-LL | fn spawn<T: Send>(_: T) {}
-   |             ^^^^ required by this bound in `spawn`
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/issue-67252-unnamed-future.rs b/tests/ui/async-await/issue-67252-unnamed-future.rs
index bb9ad77cef3..60717d99346 100644
--- a/tests/ui/async-await/issue-67252-unnamed-future.rs
+++ b/tests/ui/async-await/issue-67252-unnamed-future.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2018
 use std::future::Future;
 use std::pin::Pin;
@@ -21,7 +18,7 @@ async fn foo() {
     spawn(async { //~ ERROR future cannot be sent between threads safely
         let a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
         AFuture.await;
-        drop(a);
+        let _a = a;
     });
 }
 
diff --git a/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking_mir.stderr b/tests/ui/async-await/issue-67252-unnamed-future.stderr
index 0c4d8586ca6..069befa9121 100644
--- a/tests/ui/async-await/issue-67252-unnamed-future.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/issue-67252-unnamed-future.stderr
@@ -1,19 +1,19 @@
 error: future cannot be sent between threads safely
-  --> $DIR/issue-67252-unnamed-future.rs:21:5
+  --> $DIR/issue-67252-unnamed-future.rs:18:5
    |
 LL |     spawn(async {
    |     ^^^^^ future created by async block is not `Send`
    |
-   = help: within `{async block@$DIR/issue-67252-unnamed-future.rs:21:11: 25:6}`, the trait `Send` is not implemented for `*mut ()`
+   = help: within `{async block@$DIR/issue-67252-unnamed-future.rs:18:11: 22:6}`, the trait `Send` is not implemented for `*mut ()`
 note: future is not `Send` as this value is used across an await
-  --> $DIR/issue-67252-unnamed-future.rs:23:17
+  --> $DIR/issue-67252-unnamed-future.rs:20:17
    |
 LL |         let a = std::ptr::null_mut::<()>(); // `*mut ()` is not `Send`
    |             - has type `*mut ()` which is not `Send`
 LL |         AFuture.await;
    |                 ^^^^^ await occurs here, with `a` maybe used later
 note: required by a bound in `spawn`
-  --> $DIR/issue-67252-unnamed-future.rs:9:13
+  --> $DIR/issue-67252-unnamed-future.rs:6:13
    |
 LL | fn spawn<T: Send>(_: T) {}
    |             ^^^^ required by this bound in `spawn`
diff --git a/tests/ui/async-await/issue-68112.drop_tracking.stderr b/tests/ui/async-await/issue-68112.drop_tracking.stderr
deleted file mode 100644
index bd648de3067..00000000000
--- a/tests/ui/async-await/issue-68112.drop_tracking.stderr
+++ /dev/null
@@ -1,82 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/issue-68112.rs:37:18
-   |
-LL |     require_send(send_fut);
-   |                  ^^^^^^^^ future created by async block is not `Send`
-   |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
-note: future is not `Send` as it awaits another future which is not `Send`
-  --> $DIR/issue-68112.rs:34:17
-   |
-LL |         let _ = non_send_fut.await;
-   |                 ^^^^^^^^^^^^ await occurs here on type `impl Future<Output = Arc<RefCell<i32>>>`, which is not `Send`
-note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:14:25
-   |
-LL | fn require_send(_: impl Send) {}
-   |                         ^^^^ required by this bound in `require_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/issue-68112.rs:46:18
-   |
-LL |     require_send(send_fut);
-   |                  ^^^^^^^^ future created by async block is not `Send`
-   |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
-note: future is not `Send` as it awaits another future which is not `Send`
-  --> $DIR/issue-68112.rs:43:17
-   |
-LL |         let _ = make_non_send_future1().await;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `impl Future<Output = Arc<RefCell<i32>>>`, which is not `Send`
-note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:14:25
-   |
-LL | fn require_send(_: impl Send) {}
-   |                         ^^^^ required by this bound in `require_send`
-
-error[E0277]: `RefCell<i32>` cannot be shared between threads safely
-  --> $DIR/issue-68112.rs:65:18
-   |
-LL |     require_send(send_fut);
-   |     ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
-   = note: required for `Arc<RefCell<i32>>` to implement `Send`
-note: required because it's used within this `async fn` body
-  --> $DIR/issue-68112.rs:50:31
-   |
-LL |   async fn ready2<T>(t: T) -> T {
-   |  _______________________________^
-LL | |     t
-LL | | }
-   | |_^
-note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
-  --> $DIR/issue-68112.rs:53:31
-   |
-LL | fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> {
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: required because it captures the following types: `ResumeTy`, `impl Future<Output = Arc<RefCell<i32>>>`, `()`, `Ready<i32>`
-note: required because it's used within this `async` block
-  --> $DIR/issue-68112.rs:60:20
-   |
-LL |       let send_fut = async {
-   |  ____________________^
-LL | |         let non_send_fut = make_non_send_future2();
-LL | |         let _ = non_send_fut.await;
-LL | |         ready(0).await;
-LL | |     };
-   | |_____^
-note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:14:25
-   |
-LL | fn require_send(_: impl Send) {}
-   |                         ^^^^ required by this bound in `require_send`
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/issue-68112.no_drop_tracking.stderr b/tests/ui/async-await/issue-68112.no_drop_tracking.stderr
deleted file mode 100644
index 35b7341f63a..00000000000
--- a/tests/ui/async-await/issue-68112.no_drop_tracking.stderr
+++ /dev/null
@@ -1,82 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/issue-68112.rs:37:18
-   |
-LL |     require_send(send_fut);
-   |                  ^^^^^^^^ future created by async block is not `Send`
-   |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
-note: future is not `Send` as it awaits another future which is not `Send`
-  --> $DIR/issue-68112.rs:34:17
-   |
-LL |         let _ = non_send_fut.await;
-   |                 ^^^^^^^^^^^^ await occurs here on type `impl Future<Output = Arc<RefCell<i32>>>`, which is not `Send`
-note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:14:25
-   |
-LL | fn require_send(_: impl Send) {}
-   |                         ^^^^ required by this bound in `require_send`
-
-error: future cannot be sent between threads safely
-  --> $DIR/issue-68112.rs:46:18
-   |
-LL |     require_send(send_fut);
-   |                  ^^^^^^^^ future created by async block is not `Send`
-   |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
-note: future is not `Send` as it awaits another future which is not `Send`
-  --> $DIR/issue-68112.rs:43:17
-   |
-LL |         let _ = make_non_send_future1().await;
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `impl Future<Output = Arc<RefCell<i32>>>`, which is not `Send`
-note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:14:25
-   |
-LL | fn require_send(_: impl Send) {}
-   |                         ^^^^ required by this bound in `require_send`
-
-error[E0277]: `RefCell<i32>` cannot be shared between threads safely
-  --> $DIR/issue-68112.rs:65:18
-   |
-LL |     require_send(send_fut);
-   |     ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
-   = note: required for `Arc<RefCell<i32>>` to implement `Send`
-note: required because it's used within this `async fn` body
-  --> $DIR/issue-68112.rs:50:31
-   |
-LL |   async fn ready2<T>(t: T) -> T {
-   |  _______________________________^
-LL | |     t
-LL | | }
-   | |_^
-note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
-  --> $DIR/issue-68112.rs:53:31
-   |
-LL | fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> {
-   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: required because it captures the following types: `ResumeTy`, `impl Future<Output = Arc<RefCell<i32>>>`, `()`, `i32`, `Ready<i32>`
-note: required because it's used within this `async` block
-  --> $DIR/issue-68112.rs:60:20
-   |
-LL |       let send_fut = async {
-   |  ____________________^
-LL | |         let non_send_fut = make_non_send_future2();
-LL | |         let _ = non_send_fut.await;
-LL | |         ready(0).await;
-LL | |     };
-   | |_____^
-note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:14:25
-   |
-LL | fn require_send(_: impl Send) {}
-   |                         ^^^^ required by this bound in `require_send`
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/issue-68112.rs b/tests/ui/async-await/issue-68112.rs
index 19119ae0fc1..fd6089e0c03 100644
--- a/tests/ui/async-await/issue-68112.rs
+++ b/tests/ui/async-await/issue-68112.rs
@@ -1,7 +1,4 @@
 // edition:2018
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 
 use std::{
     cell::RefCell,
diff --git a/tests/ui/async-await/issue-68112.drop_tracking_mir.stderr b/tests/ui/async-await/issue-68112.stderr
index 7a9242cbaf5..17b619ebee3 100644
--- a/tests/ui/async-await/issue-68112.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/issue-68112.stderr
@@ -1,5 +1,5 @@
 error: future cannot be sent between threads safely
-  --> $DIR/issue-68112.rs:37:5
+  --> $DIR/issue-68112.rs:34:5
    |
 LL |     require_send(send_fut);
    |     ^^^^^^^^^^^^ future created by async block is not `Send`
@@ -7,18 +7,18 @@ LL |     require_send(send_fut);
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
 note: future is not `Send` as it awaits another future which is not `Send`
-  --> $DIR/issue-68112.rs:34:17
+  --> $DIR/issue-68112.rs:31:17
    |
 LL |         let _ = non_send_fut.await;
    |                 ^^^^^^^^^^^^ await occurs here on type `impl Future<Output = Arc<RefCell<i32>>>`, which is not `Send`
 note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:14:25
+  --> $DIR/issue-68112.rs:11:25
    |
 LL | fn require_send(_: impl Send) {}
    |                         ^^^^ required by this bound in `require_send`
 
 error: future cannot be sent between threads safely
-  --> $DIR/issue-68112.rs:46:5
+  --> $DIR/issue-68112.rs:43:5
    |
 LL |     require_send(send_fut);
    |     ^^^^^^^^^^^^ future created by async block is not `Send`
@@ -26,18 +26,18 @@ LL |     require_send(send_fut);
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
 note: future is not `Send` as it awaits another future which is not `Send`
-  --> $DIR/issue-68112.rs:43:17
+  --> $DIR/issue-68112.rs:40:17
    |
 LL |         let _ = make_non_send_future1().await;
    |                 ^^^^^^^^^^^^^^^^^^^^^^^ await occurs here on type `impl Future<Output = Arc<RefCell<i32>>>`, which is not `Send`
 note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:14:25
+  --> $DIR/issue-68112.rs:11:25
    |
 LL | fn require_send(_: impl Send) {}
    |                         ^^^^ required by this bound in `require_send`
 
 error[E0277]: `RefCell<i32>` cannot be shared between threads safely
-  --> $DIR/issue-68112.rs:65:5
+  --> $DIR/issue-68112.rs:62:5
    |
 LL |     require_send(send_fut);
    |     ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
@@ -46,7 +46,7 @@ LL |     require_send(send_fut);
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Arc<RefCell<i32>>` to implement `Send`
 note: required because it's used within this `async fn` body
-  --> $DIR/issue-68112.rs:50:31
+  --> $DIR/issue-68112.rs:47:31
    |
 LL |   async fn ready2<T>(t: T) -> T {
    |  _______________________________^
@@ -54,13 +54,13 @@ LL | |     t
 LL | | }
    | |_^
 note: required because it appears within the type `impl Future<Output = Arc<RefCell<i32>>>`
-  --> $DIR/issue-68112.rs:53:31
+  --> $DIR/issue-68112.rs:50:31
    |
 LL | fn make_non_send_future2() -> impl Future<Output = Arc<RefCell<i32>>> {
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: required because it captures the following types: `impl Future<Output = Arc<RefCell<i32>>>`, `Ready<i32>`
 note: required because it's used within this `async` block
-  --> $DIR/issue-68112.rs:60:20
+  --> $DIR/issue-68112.rs:57:20
    |
 LL |       let send_fut = async {
    |  ____________________^
@@ -70,7 +70,7 @@ LL | |         ready(0).await;
 LL | |     };
    | |_____^
 note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:14:25
+  --> $DIR/issue-68112.rs:11:25
    |
 LL | fn require_send(_: impl Send) {}
    |                         ^^^^ required by this bound in `require_send`
diff --git a/tests/ui/async-await/issue-70818.drop_tracking.stderr b/tests/ui/async-await/issue-70818.drop_tracking.stderr
deleted file mode 100644
index ab0698c3ec2..00000000000
--- a/tests/ui/async-await/issue-70818.drop_tracking.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/issue-70818.rs:7:38
-   |
-LL | fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
-   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
-   |
-note: captured value is not `Send`
-  --> $DIR/issue-70818.rs:9:18
-   |
-LL |     async { (ty, ty1) }
-   |                  ^^^ has type `U` which is not `Send`
-help: consider restricting type parameter `U`
-   |
-LL | fn foo<T: Send, U: std::marker::Send>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
-   |                  +++++++++++++++++++
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/issue-70818.no_drop_tracking.stderr b/tests/ui/async-await/issue-70818.no_drop_tracking.stderr
deleted file mode 100644
index ab0698c3ec2..00000000000
--- a/tests/ui/async-await/issue-70818.no_drop_tracking.stderr
+++ /dev/null
@@ -1,18 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/issue-70818.rs:7:38
-   |
-LL | fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
-   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
-   |
-note: captured value is not `Send`
-  --> $DIR/issue-70818.rs:9:18
-   |
-LL |     async { (ty, ty1) }
-   |                  ^^^ has type `U` which is not `Send`
-help: consider restricting type parameter `U`
-   |
-LL | fn foo<T: Send, U: std::marker::Send>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
-   |                  +++++++++++++++++++
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/issue-70818.rs b/tests/ui/async-await/issue-70818.rs
index 2941de0f577..019c56eb2fa 100644
--- a/tests/ui/async-await/issue-70818.rs
+++ b/tests/ui/async-await/issue-70818.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2018
 
 use std::future::Future;
diff --git a/tests/ui/async-await/issue-70818.drop_tracking_mir.stderr b/tests/ui/async-await/issue-70818.stderr
index ab0698c3ec2..20109d4d116 100644
--- a/tests/ui/async-await/issue-70818.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/issue-70818.stderr
@@ -1,11 +1,11 @@
 error: future cannot be sent between threads safely
-  --> $DIR/issue-70818.rs:7:38
+  --> $DIR/issue-70818.rs:4:38
    |
 LL | fn foo<T: Send, U>(ty: T, ty1: U) -> impl Future<Output = (T, U)> + Send {
    |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
    |
 note: captured value is not `Send`
-  --> $DIR/issue-70818.rs:9:18
+  --> $DIR/issue-70818.rs:6:18
    |
 LL |     async { (ty, ty1) }
    |                  ^^^ has type `U` which is not `Send`
diff --git a/tests/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr b/tests/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
deleted file mode 100644
index f80bb4242aa..00000000000
--- a/tests/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr
+++ /dev/null
@@ -1,41 +0,0 @@
-error[E0277]: `*mut ()` cannot be shared between threads safely
-  --> $DIR/issue-70935-complex-spans.rs:18:23
-   |
-LL | fn foo(x: NotSync) -> impl Future + Send {
-   |                       ^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be shared between threads safely
-   |
-   = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()`
-note: required because it appears within the type `PhantomData<*mut ()>`
-  --> $SRC_DIR/core/src/marker.rs:LL:COL
-note: required because it appears within the type `NotSync`
-  --> $DIR/issue-70935-complex-spans.rs:12:8
-   |
-LL | struct NotSync(PhantomData<*mut ()>);
-   |        ^^^^^^^
-   = note: required for `&NotSync` to implement `Send`
-note: required because it's used within this closure
-  --> $DIR/issue-70935-complex-spans.rs:22:13
-   |
-LL |         baz(|| async {
-   |             ^^
-note: required because it's used within this `async fn` body
-  --> $DIR/issue-70935-complex-spans.rs:15:67
-   |
-LL |   async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
-   |  ___________________________________________________________________^
-LL | | }
-   | |_^
-   = note: required because it captures the following types: `ResumeTy`, `impl Future<Output = ()>`, `()`
-note: required because it's used within this `async` block
-  --> $DIR/issue-70935-complex-spans.rs:21:5
-   |
-LL | /     async move {
-LL | |         baz(|| async {
-LL | |             foo(x.clone());
-LL | |         }).await;
-LL | |     }
-   | |_____^
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr b/tests/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr
deleted file mode 100644
index b33aa407f4a..00000000000
--- a/tests/ui/async-await/issue-70935-complex-spans.no_drop_tracking.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/issue-70935-complex-spans.rs:18:23
-   |
-LL | fn foo(x: NotSync) -> impl Future + Send {
-   |                       ^^^^^^^^^^^^^^^^^^ future created by async block is not `Send`
-   |
-   = help: within `NotSync`, the trait `Sync` is not implemented for `*mut ()`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/issue-70935-complex-spans.rs:24:12
-   |
-LL |           baz(|| async {
-   |  _____________-
-LL | |             foo(x.clone());
-LL | |         }).await;
-   | |         -  ^^^^^- the value is later dropped here
-   | |         |  |
-   | |_________|  await occurs here, with the value maybe used later
-   |           has type `{closure@$DIR/issue-70935-complex-spans.rs:22:13: 22:15}` which is not `Send`
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/issue-70935-complex-spans.rs b/tests/ui/async-await/issue-70935-complex-spans.rs
index 9ebde1d3977..4af73739584 100644
--- a/tests/ui/async-await/issue-70935-complex-spans.rs
+++ b/tests/ui/async-await/issue-70935-complex-spans.rs
@@ -1,7 +1,4 @@
 // edition:2018
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // #70935: Check if we do not emit snippet
 // with newlines which lead complex diagnostics.
 
@@ -16,8 +13,7 @@ async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
 }
 
 fn foo(x: NotSync) -> impl Future + Send {
-    //[no_drop_tracking]~^ ERROR future cannot be sent between threads safely
-    //[drop_tracking,drop_tracking_mir]~^^ ERROR `*mut ()` cannot be shared between threads
+    //~^ ERROR `*mut ()` cannot be shared between threads safely
     async move {
         baz(|| async {
             foo(x.clone());
diff --git a/tests/ui/async-await/issue-70935-complex-spans.drop_tracking_mir.stderr b/tests/ui/async-await/issue-70935-complex-spans.stderr
index eb9d93e229f..ab834daa85d 100644
--- a/tests/ui/async-await/issue-70935-complex-spans.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/issue-70935-complex-spans.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `*mut ()` cannot be shared between threads safely
-  --> $DIR/issue-70935-complex-spans.rs:18:23
+  --> $DIR/issue-70935-complex-spans.rs:15:23
    |
 LL | fn foo(x: NotSync) -> impl Future + Send {
    |                       ^^^^^^^^^^^^^^^^^^ `*mut ()` cannot be shared between threads safely
@@ -8,18 +8,18 @@ LL | fn foo(x: NotSync) -> impl Future + Send {
 note: required because it appears within the type `PhantomData<*mut ()>`
   --> $SRC_DIR/core/src/marker.rs:LL:COL
 note: required because it appears within the type `NotSync`
-  --> $DIR/issue-70935-complex-spans.rs:12:8
+  --> $DIR/issue-70935-complex-spans.rs:9:8
    |
 LL | struct NotSync(PhantomData<*mut ()>);
    |        ^^^^^^^
    = note: required for `&NotSync` to implement `Send`
 note: required because it's used within this closure
-  --> $DIR/issue-70935-complex-spans.rs:22:13
+  --> $DIR/issue-70935-complex-spans.rs:18:13
    |
 LL |         baz(|| async {
    |             ^^
 note: required because it's used within this `async fn` body
-  --> $DIR/issue-70935-complex-spans.rs:15:67
+  --> $DIR/issue-70935-complex-spans.rs:12:67
    |
 LL |   async fn baz<T>(_c: impl FnMut() -> T) where T: Future<Output=()> {
    |  ___________________________________________________________________^
@@ -27,7 +27,7 @@ LL | | }
    | |_^
    = note: required because it captures the following types: `impl Future<Output = ()>`
 note: required because it's used within this `async` block
-  --> $DIR/issue-70935-complex-spans.rs:21:5
+  --> $DIR/issue-70935-complex-spans.rs:17:5
    |
 LL | /     async move {
 LL | |         baz(|| async {
diff --git a/tests/ui/async-await/issue-71137.stderr b/tests/ui/async-await/issue-71137.stderr
index a344246d6bf..443af010c4a 100644
--- a/tests/ui/async-await/issue-71137.stderr
+++ b/tests/ui/async-await/issue-71137.stderr
@@ -12,9 +12,6 @@ LL |     let mut guard = m.lock().unwrap();
    |         --------- has type `MutexGuard<'_, i32>` which is not `Send`
 LL |     (async { "right"; }).await;
    |                          ^^^^^ await occurs here, with `mut guard` maybe used later
-LL |     *guard += 1;
-LL |   }
-   |   - `mut guard` is later dropped here
 note: required by a bound in `fake_spawn`
   --> $DIR/issue-71137.rs:8:27
    |
diff --git a/tests/ui/async-await/issue-73137.rs b/tests/ui/async-await/issue-73137.rs
index dcbe7765a9e..c43ce2cadba 100644
--- a/tests/ui/async-await/issue-73137.rs
+++ b/tests/ui/async-await/issue-73137.rs
@@ -2,9 +2,6 @@
 
 // run-pass
 // edition:2018
-// revisions: normal drop-tracking
-// [normal]compile-flags: -Zdrop-tracking=no
-// [drop-tracking]compile-flags: -Zdrop-tracking
 
 #![allow(dead_code)]
 use std::future::Future;
diff --git a/tests/ui/async-await/issue-73741-type-err-drop-tracking.drop_tracking.stderr b/tests/ui/async-await/issue-73741-type-err-drop-tracking.drop_tracking.stderr
deleted file mode 100644
index 6d19c3beb2f..00000000000
--- a/tests/ui/async-await/issue-73741-type-err-drop-tracking.drop_tracking.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0070]: invalid left-hand side of assignment
-  --> $DIR/issue-73741-type-err-drop-tracking.rs:11:7
-   |
-LL |     1 = 2;
-   |     - ^
-   |     |
-   |     cannot assign to this expression
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0070`.
diff --git a/tests/ui/async-await/issue-73741-type-err-drop-tracking.drop_tracking_mir.stderr b/tests/ui/async-await/issue-73741-type-err-drop-tracking.drop_tracking_mir.stderr
deleted file mode 100644
index 6d19c3beb2f..00000000000
--- a/tests/ui/async-await/issue-73741-type-err-drop-tracking.drop_tracking_mir.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0070]: invalid left-hand side of assignment
-  --> $DIR/issue-73741-type-err-drop-tracking.rs:11:7
-   |
-LL |     1 = 2;
-   |     - ^
-   |     |
-   |     cannot assign to this expression
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0070`.
diff --git a/tests/ui/async-await/issue-73741-type-err-drop-tracking.no_drop_tracking.stderr b/tests/ui/async-await/issue-73741-type-err-drop-tracking.no_drop_tracking.stderr
deleted file mode 100644
index 6d19c3beb2f..00000000000
--- a/tests/ui/async-await/issue-73741-type-err-drop-tracking.no_drop_tracking.stderr
+++ /dev/null
@@ -1,11 +0,0 @@
-error[E0070]: invalid left-hand side of assignment
-  --> $DIR/issue-73741-type-err-drop-tracking.rs:11:7
-   |
-LL |     1 = 2;
-   |     - ^
-   |     |
-   |     cannot assign to this expression
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0070`.
diff --git a/tests/ui/async-await/issue-73741-type-err-drop-tracking.rs b/tests/ui/async-await/issue-73741-type-err-drop-tracking.rs
deleted file mode 100644
index 1fa8d69143a..00000000000
--- a/tests/ui/async-await/issue-73741-type-err-drop-tracking.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-// edition:2018
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-//
-// Regression test for issue #73741
-// Ensures that we don't emit spurious errors when
-// a type error ocurrs in an `async fn`
-
-async fn weird() {
-    1 = 2; //~ ERROR invalid left-hand side
-
-    let mut loop_count = 0;
-    async {}.await
-}
-
-fn main() {}
diff --git a/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr b/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr
deleted file mode 100644
index 8adc94d9f49..00000000000
--- a/tests/ui/async-await/issue-86507.drop_tracking_mir.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/issue-86507.rs:20:13
-   |
-LL | /             Box::pin(
-LL | |                 async move {
-LL | |                     let x = x;
-LL | |                 }
-LL | |             )
-   | |_____________^ future created by async block is not `Send`
-   |
-note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
-  --> $DIR/issue-86507.rs:22:29
-   |
-LL |                     let x = x;
-   |                             ^ has type `&T` which is not `Send`, because `T` is not `Sync`
-   = note: required for the cast from `Pin<Box<{async block@$DIR/issue-86507.rs:21:17: 23:18}>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
-help: consider further restricting this bound
-   |
-LL |     fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
-   |                                       +++++++++++++++++++
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/issue-86507.no_drop_tracking.stderr b/tests/ui/async-await/issue-86507.no_drop_tracking.stderr
deleted file mode 100644
index 8adc94d9f49..00000000000
--- a/tests/ui/async-await/issue-86507.no_drop_tracking.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/issue-86507.rs:20:13
-   |
-LL | /             Box::pin(
-LL | |                 async move {
-LL | |                     let x = x;
-LL | |                 }
-LL | |             )
-   | |_____________^ future created by async block is not `Send`
-   |
-note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
-  --> $DIR/issue-86507.rs:22:29
-   |
-LL |                     let x = x;
-   |                             ^ has type `&T` which is not `Send`, because `T` is not `Sync`
-   = note: required for the cast from `Pin<Box<{async block@$DIR/issue-86507.rs:21:17: 23:18}>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
-help: consider further restricting this bound
-   |
-LL |     fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
-   |                                       +++++++++++++++++++
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/issue-86507.rs b/tests/ui/async-await/issue-86507.rs
index 63c298dbe3d..317f0317664 100644
--- a/tests/ui/async-await/issue-86507.rs
+++ b/tests/ui/async-await/issue-86507.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2018
 
 use ::core::pin::Pin;
diff --git a/tests/ui/async-await/issue-86507.drop_tracking.stderr b/tests/ui/async-await/issue-86507.stderr
index 8adc94d9f49..d5a3f72cf25 100644
--- a/tests/ui/async-await/issue-86507.drop_tracking.stderr
+++ b/tests/ui/async-await/issue-86507.stderr
@@ -1,5 +1,5 @@
 error: future cannot be sent between threads safely
-  --> $DIR/issue-86507.rs:20:13
+  --> $DIR/issue-86507.rs:17:13
    |
 LL | /             Box::pin(
 LL | |                 async move {
@@ -9,11 +9,11 @@ LL | |             )
    | |_____________^ future created by async block is not `Send`
    |
 note: captured value is not `Send` because `&` references cannot be sent unless their referent is `Sync`
-  --> $DIR/issue-86507.rs:22:29
+  --> $DIR/issue-86507.rs:19:29
    |
 LL |                     let x = x;
    |                             ^ has type `&T` which is not `Send`, because `T` is not `Sync`
-   = note: required for the cast from `Pin<Box<{async block@$DIR/issue-86507.rs:21:17: 23:18}>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
+   = note: required for the cast from `Pin<Box<{async block@$DIR/issue-86507.rs:18:17: 20:18}>>` to `Pin<Box<(dyn Future<Output = ()> + Send + 'async_trait)>>`
 help: consider further restricting this bound
    |
 LL |     fn bar<'me, 'async_trait, T: Send + std::marker::Sync>(x: &'me T)
diff --git a/tests/ui/async-await/issue-93197.rs b/tests/ui/async-await/issue-93197.rs
index c627fe17afb..05ec013d0af 100644
--- a/tests/ui/async-await/issue-93197.rs
+++ b/tests/ui/async-await/issue-93197.rs
@@ -1,7 +1,6 @@
 // Regression test for #93197
 // check-pass
 // edition:2021
-// compile-flags: -Zdrop-tracking
 
 #![feature(try_blocks)]
 
diff --git a/tests/ui/async-await/issue-93648.rs b/tests/ui/async-await/issue-93648.rs
index ec2249ca592..b27a79a428b 100644
--- a/tests/ui/async-await/issue-93648.rs
+++ b/tests/ui/async-await/issue-93648.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2021
 // build-pass
 
diff --git a/tests/ui/async-await/issues/auxiliary/issue_67893.rs b/tests/ui/async-await/issues/auxiliary/issue_67893.rs
index d5394469806..efde4d2864d 100644
--- a/tests/ui/async-await/issues/auxiliary/issue_67893.rs
+++ b/tests/ui/async-await/issues/auxiliary/issue_67893.rs
@@ -1,13 +1,12 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2018
 
 use std::sync::{Arc, Mutex};
 
+fn make_arc() -> Arc<Mutex<()>> { unimplemented!() }
+
 pub async fn f(_: ()) {}
 
 pub async fn run() {
-    let x: Arc<Mutex<()>> = unimplemented!();
+    let x: Arc<Mutex<()>> = make_arc();
     f(*x.lock().unwrap()).await;
 }
diff --git a/tests/ui/async-await/issues/issue-107280.rs b/tests/ui/async-await/issues/issue-107280.rs
index 85fce87403a..81ae9553cf0 100644
--- a/tests/ui/async-await/issues/issue-107280.rs
+++ b/tests/ui/async-await/issues/issue-107280.rs
@@ -3,11 +3,6 @@
 async fn foo() {
     inner::<false>().await
     //~^ ERROR: function takes 2 generic arguments but 1 generic argument was supplied
-    //~| ERROR: type inside `async fn` body must be known in this context
-    //~| ERROR: type inside `async fn` body must be known in this context
-    //~| ERROR: type inside `async fn` body must be known in this context
-    //~| ERROR: type inside `async fn` body must be known in this context
-    //~| ERROR: type inside `async fn` body must be known in this context
 }
 
 async fn inner<T, const PING: bool>() {}
diff --git a/tests/ui/async-await/issues/issue-107280.stderr b/tests/ui/async-await/issues/issue-107280.stderr
index 2e69862a0e0..c5fd5c5bf0a 100644
--- a/tests/ui/async-await/issues/issue-107280.stderr
+++ b/tests/ui/async-await/issues/issue-107280.stderr
@@ -7,7 +7,7 @@ LL |     inner::<false>().await
    |     expected 2 generic arguments
    |
 note: function defined here, with 2 generic parameters: `T`, `PING`
-  --> $DIR/issue-107280.rs:13:10
+  --> $DIR/issue-107280.rs:8:10
    |
 LL | async fn inner<T, const PING: bool>() {}
    |          ^^^^^ -  ----------------
@@ -16,67 +16,6 @@ help: add missing generic argument
 LL |     inner::<false, PING>().await
    |                  ++++++
 
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/issue-107280.rs:4:5
-   |
-LL |     inner::<false>().await
-   |     ^^^^^^^^^^^^^^ cannot infer the value of const parameter `PING` declared on the function `inner`
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/issue-107280.rs:4:22
-   |
-LL |     inner::<false>().await
-   |                      ^^^^^
-
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/issue-107280.rs:4:5
-   |
-LL |     inner::<false>().await
-   |     ^^^^^^^^^^^^^^ cannot infer the value of const parameter `PING` declared on the function `inner`
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/issue-107280.rs:4:22
-   |
-LL |     inner::<false>().await
-   |                      ^^^^^
-
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/issue-107280.rs:4:5
-   |
-LL |     inner::<false>().await
-   |     ^^^^^^^^^^^^^^ cannot infer the value of const parameter `PING` declared on the function `inner`
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/issue-107280.rs:4:22
-   |
-LL |     inner::<false>().await
-   |                      ^^^^^
-
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/issue-107280.rs:4:5
-   |
-LL |     inner::<false>().await
-   |     ^^^^^^^^^^^^^^ cannot infer the value of const parameter `PING` declared on the function `inner`
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/issue-107280.rs:4:22
-   |
-LL |     inner::<false>().await
-   |                      ^^^^^
-
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/issue-107280.rs:4:5
-   |
-LL |     inner::<false>().await
-   |     ^^^^^^^^^^^^^^ cannot infer the value of const parameter `PING` declared on the function `inner`
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/issue-107280.rs:4:22
-   |
-LL |     inner::<false>().await
-   |                      ^^^^^
-
-error: aborting due to 6 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0107, E0698.
-For more information about an error, try `rustc --explain E0107`.
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr b/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr
deleted file mode 100644
index c734de73f65..00000000000
--- a/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.no_drop_tracking.stderr
+++ /dev/null
@@ -1,32 +0,0 @@
-error: future cannot be sent between threads safely
-  --> $DIR/issue-65436-raw-ptr-not-send.rs:17:17
-   |
-LL |       assert_send(async {
-   |  _________________^
-LL | |
-LL | |         bar(Foo(std::ptr::null())).await;
-LL | |     })
-   | |_____^ future created by async block is not `Send`
-   |
-   = help: within `{async block@$DIR/issue-65436-raw-ptr-not-send.rs:17:17: 20:6}`, the trait `Send` is not implemented for `*const u8`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/issue-65436-raw-ptr-not-send.rs:19:36
-   |
-LL |         bar(Foo(std::ptr::null())).await;
-   |                 ----------------   ^^^^^- `std::ptr::null()` is later dropped here
-   |                 |                  |
-   |                 |                  await occurs here, with `std::ptr::null()` maybe used later
-   |                 has type `*const u8` which is not `Send`
-help: consider moving this into a `let` binding to create a shorter lived borrow
-  --> $DIR/issue-65436-raw-ptr-not-send.rs:19:13
-   |
-LL |         bar(Foo(std::ptr::null())).await;
-   |             ^^^^^^^^^^^^^^^^^^^^^
-note: required by a bound in `assert_send`
-  --> $DIR/issue-65436-raw-ptr-not-send.rs:14:19
-   |
-LL | fn assert_send<T: Send>(_: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-
-error: aborting due to previous error
-
diff --git a/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs b/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs
index d7ef929517c..ef6f105f34a 100644
--- a/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs
+++ b/tests/ui/async-await/issues/issue-65436-raw-ptr-not-send.rs
@@ -1,9 +1,5 @@
 // edition:2018
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-// [drop_tracking] check-pass
-// [drop_tracking_mir] check-pass
+// check-pass
 
 struct Foo(*const u8);
 
@@ -15,7 +11,6 @@ fn assert_send<T: Send>(_: T) {}
 
 fn main() {
     assert_send(async {
-        //[no_drop_tracking]~^ ERROR future cannot be sent between threads safely
         bar(Foo(std::ptr::null())).await;
     })
 }
diff --git a/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs b/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs
index 80d824d3b2e..caed762691e 100644
--- a/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs
+++ b/tests/ui/async-await/issues/issue-67611-static-mut-refs.rs
@@ -1,10 +1,6 @@
 // build-pass
 // edition:2018
 
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-
 #![feature(if_let_guard)]
 
 static mut A: [i32; 5] = [1, 2, 3, 4, 5];
diff --git a/tests/ui/async-await/issues/issue-67893.rs b/tests/ui/async-await/issues/issue-67893.rs
index d73772e5fa0..359c75f170c 100644
--- a/tests/ui/async-await/issues/issue-67893.rs
+++ b/tests/ui/async-await/issues/issue-67893.rs
@@ -7,5 +7,5 @@ fn g(_: impl Send) {}
 
 fn main() {
     g(issue_67893::run())
-    //~^ ERROR future cannot be sent between threads safely
+    //~^ ERROR `MutexGuard<'_, ()>` cannot be sent between threads safely
 }
diff --git a/tests/ui/async-await/issues/issue-67893.stderr b/tests/ui/async-await/issues/issue-67893.stderr
index c941b9eeb29..f36269e8f36 100644
--- a/tests/ui/async-await/issues/issue-67893.stderr
+++ b/tests/ui/async-await/issues/issue-67893.stderr
@@ -1,18 +1,27 @@
-error: future cannot be sent between threads safely
+error[E0277]: `MutexGuard<'_, ()>` cannot be sent between threads safely
   --> $DIR/issue-67893.rs:9:7
    |
 LL |     g(issue_67893::run())
-   |       ^^^^^^^^^^^^^^^^^^ future is not `Send`
+   |     - ^^^^^^^^^^^^^^^^^^ `MutexGuard<'_, ()>` cannot be sent between threads safely
+   |     |
+   |     required by a bound introduced by this call
+   |
+  ::: $DIR/auxiliary/issue_67893.rs:9:20
+   |
+LL | pub async fn run() {
+   |                    - within this `impl Future<Output = ()>`
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `MutexGuard<'_, ()>`
-note: future is not `Send` as this value is used across an await
-  --> $DIR/auxiliary/issue_67893.rs:12:27
+   = note: required because it captures the following types: `Arc<Mutex<()>>`, `MutexGuard<'_, ()>`, `impl Future<Output = ()>`
+note: required because it's used within this `async fn` body
+  --> $DIR/auxiliary/issue_67893.rs:9:20
    |
-LL |     f(*x.lock().unwrap()).await;
-   |        -----------------  ^^^^^- `x.lock().unwrap()` is later dropped here
-   |        |                  |
-   |        |                  await occurs here, with `x.lock().unwrap()` maybe used later
-   |        has type `MutexGuard<'_, ()>` which is not `Send`
+LL |   pub async fn run() {
+   |  ____________________^
+LL | |     let x: Arc<Mutex<()>> = make_arc();
+LL | |     f(*x.lock().unwrap()).await;
+LL | | }
+   | |_^
 note: required by a bound in `g`
   --> $DIR/issue-67893.rs:6:14
    |
@@ -21,3 +30,4 @@ LL | fn g(_: impl Send) {}
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/issues/issue-78600.rs b/tests/ui/async-await/issues/issue-78600.rs
index 8aaeaecf3e1..4303fc7952f 100644
--- a/tests/ui/async-await/issues/issue-78600.rs
+++ b/tests/ui/async-await/issues/issue-78600.rs
@@ -1,10 +1,10 @@
+// check-pass
 // edition:2018
 
 struct S<'a>(&'a i32);
 
 impl<'a> S<'a> {
     async fn new(i: &'a i32) -> Result<Self, ()> {
-        //~^ ERROR: `async fn`
         Ok(S(&22))
     }
 }
diff --git a/tests/ui/async-await/issues/issue-78600.stderr b/tests/ui/async-await/issues/issue-78600.stderr
deleted file mode 100644
index 37eafa996c5..00000000000
--- a/tests/ui/async-await/issues/issue-78600.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0658]: `async fn` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
-  --> $DIR/issue-78600.rs:6:33
-   |
-LL |     async fn new(i: &'a i32) -> Result<Self, ()> {
-   |                                 ^^^^^^^----^^^^^
-   |                                        |
-   |                                        help: consider spelling out the type instead: `S<'a>`
-   |
-   = note: see issue #103532 <https://github.com/rust-lang/rust/issues/103532> for more information
-   = help: add `#![feature(impl_trait_projections)]` to the crate attributes to enable
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/async-await/mutually-recursive-async-impl-trait-type.drop_tracking.stderr b/tests/ui/async-await/mutually-recursive-async-impl-trait-type.drop_tracking.stderr
deleted file mode 100644
index 8a7317bb95a..00000000000
--- a/tests/ui/async-await/mutually-recursive-async-impl-trait-type.drop_tracking.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/mutually-recursive-async-impl-trait-type.rs:9:18
-   |
-LL | async fn rec_1() {
-   |                  ^ recursive `async fn`
-   |
-   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
-   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
-
-error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/mutually-recursive-async-impl-trait-type.rs:13:18
-   |
-LL | async fn rec_2() {
-   |                  ^ recursive `async fn`
-   |
-   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
-   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0733`.
diff --git a/tests/ui/async-await/mutually-recursive-async-impl-trait-type.no_drop_tracking.stderr b/tests/ui/async-await/mutually-recursive-async-impl-trait-type.no_drop_tracking.stderr
deleted file mode 100644
index 8a7317bb95a..00000000000
--- a/tests/ui/async-await/mutually-recursive-async-impl-trait-type.no_drop_tracking.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/mutually-recursive-async-impl-trait-type.rs:9:18
-   |
-LL | async fn rec_1() {
-   |                  ^ recursive `async fn`
-   |
-   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
-   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
-
-error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/mutually-recursive-async-impl-trait-type.rs:13:18
-   |
-LL | async fn rec_2() {
-   |                  ^ recursive `async fn`
-   |
-   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
-   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0733`.
diff --git a/tests/ui/async-await/mutually-recursive-async-impl-trait-type.rs b/tests/ui/async-await/mutually-recursive-async-impl-trait-type.rs
index a241f30e73e..bb2a61f03ce 100644
--- a/tests/ui/async-await/mutually-recursive-async-impl-trait-type.rs
+++ b/tests/ui/async-await/mutually-recursive-async-impl-trait-type.rs
@@ -1,7 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-
 // edition:2018
 // Test that impl trait does not allow creating recursive types that are
 // otherwise forbidden when using `async` and `await`.
diff --git a/tests/ui/async-await/mutually-recursive-async-impl-trait-type.drop_tracking_mir.stderr b/tests/ui/async-await/mutually-recursive-async-impl-trait-type.stderr
index 8a7317bb95a..f789ad2a05c 100644
--- a/tests/ui/async-await/mutually-recursive-async-impl-trait-type.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/mutually-recursive-async-impl-trait-type.stderr
@@ -1,5 +1,5 @@
 error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/mutually-recursive-async-impl-trait-type.rs:9:18
+  --> $DIR/mutually-recursive-async-impl-trait-type.rs:5:18
    |
 LL | async fn rec_1() {
    |                  ^ recursive `async fn`
@@ -8,7 +8,7 @@ LL | async fn rec_1() {
    = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
 
 error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/mutually-recursive-async-impl-trait-type.rs:13:18
+  --> $DIR/mutually-recursive-async-impl-trait-type.rs:9:18
    |
 LL | async fn rec_2() {
    |                  ^ recursive `async fn`
diff --git a/tests/ui/async-await/non-trivial-drop.rs b/tests/ui/async-await/non-trivial-drop.rs
index 258da0756de..3fed7c972a1 100644
--- a/tests/ui/async-await/non-trivial-drop.rs
+++ b/tests/ui/async-await/non-trivial-drop.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // build-pass
 // edition:2018
 
diff --git a/tests/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr b/tests/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr
deleted file mode 100644
index 17b4ef7bdc6..00000000000
--- a/tests/ui/async-await/partial-drop-partial-reinit.drop_tracking.stderr
+++ /dev/null
@@ -1,35 +0,0 @@
-error[E0277]: `NotSend` cannot be sent between threads safely
-  --> $DIR/partial-drop-partial-reinit.rs:9:16
-   |
-LL |     gimme_send(foo());
-   |     ---------- ^^^^^ `NotSend` cannot be sent between threads safely
-   |     |
-   |     required by a bound introduced by this call
-...
-LL | async fn foo() {
-   |                - within this `impl Future<Output = ()>`
-   |
-   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `NotSend`
-   = note: required because it appears within the type `(NotSend,)`
-   = note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `()`, `impl Future<Output = ()>`
-note: required because it's used within this `async fn` body
-  --> $DIR/partial-drop-partial-reinit.rs:31:16
-   |
-LL |   async fn foo() {
-   |  ________________^
-LL | |
-LL | |
-LL | |     let mut x = (NotSend {},);
-...  |
-LL | |     bar().await;
-LL | | }
-   | |_^
-note: required by a bound in `gimme_send`
-  --> $DIR/partial-drop-partial-reinit.rs:17:18
-   |
-LL | fn gimme_send<T: Send>(t: T) {
-   |                  ^^^^ required by this bound in `gimme_send`
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/async-await/partial-drop-partial-reinit.rs b/tests/ui/async-await/partial-drop-partial-reinit.rs
index 7d097e72fb4..75acb442e7a 100644
--- a/tests/ui/async-await/partial-drop-partial-reinit.rs
+++ b/tests/ui/async-await/partial-drop-partial-reinit.rs
@@ -1,7 +1,4 @@
 // edition:2021
-// revisions: no_drop_tracking drop_tracking
-// [drop_tracking] compile-flags: -Zdrop-tracking=yes
-// [no_drop_tracking] compile-flags: -Zdrop-tracking=no
 #![feature(negative_impls)]
 #![allow(unused)]
 
diff --git a/tests/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr b/tests/ui/async-await/partial-drop-partial-reinit.stderr
index 34d8a159f10..85e1830c78e 100644
--- a/tests/ui/async-await/partial-drop-partial-reinit.no_drop_tracking.stderr
+++ b/tests/ui/async-await/partial-drop-partial-reinit.stderr
@@ -1,5 +1,5 @@
 error[E0277]: `NotSend` cannot be sent between threads safely
-  --> $DIR/partial-drop-partial-reinit.rs:9:16
+  --> $DIR/partial-drop-partial-reinit.rs:6:16
    |
 LL |     gimme_send(foo());
    |     ---------- ^^^^^ `NotSend` cannot be sent between threads safely
@@ -11,9 +11,9 @@ LL | async fn foo() {
    |
    = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `NotSend`
    = note: required because it appears within the type `(NotSend,)`
-   = note: required because it captures the following types: `ResumeTy`, `(NotSend,)`, `impl Future<Output = ()>`, `()`
+   = note: required because it captures the following types: `(NotSend,)`, `impl Future<Output = ()>`
 note: required because it's used within this `async fn` body
-  --> $DIR/partial-drop-partial-reinit.rs:31:16
+  --> $DIR/partial-drop-partial-reinit.rs:28:16
    |
 LL |   async fn foo() {
    |  ________________^
@@ -25,7 +25,7 @@ LL | |     bar().await;
 LL | | }
    | |_^
 note: required by a bound in `gimme_send`
-  --> $DIR/partial-drop-partial-reinit.rs:17:18
+  --> $DIR/partial-drop-partial-reinit.rs:14:18
    |
 LL | fn gimme_send<T: Send>(t: T) {
    |                  ^^^^ required by this bound in `gimme_send`
diff --git a/tests/ui/async-await/recursive-async-impl-trait-type.drop_tracking.stderr b/tests/ui/async-await/recursive-async-impl-trait-type.drop_tracking.stderr
deleted file mode 100644
index 7e63a8da552..00000000000
--- a/tests/ui/async-await/recursive-async-impl-trait-type.drop_tracking.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/recursive-async-impl-trait-type.rs:8:40
-   |
-LL | async fn recursive_async_function() -> () {
-   |                                        ^^ recursive `async fn`
-   |
-   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
-   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0733`.
diff --git a/tests/ui/async-await/recursive-async-impl-trait-type.no_drop_tracking.stderr b/tests/ui/async-await/recursive-async-impl-trait-type.no_drop_tracking.stderr
deleted file mode 100644
index 7e63a8da552..00000000000
--- a/tests/ui/async-await/recursive-async-impl-trait-type.no_drop_tracking.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/recursive-async-impl-trait-type.rs:8:40
-   |
-LL | async fn recursive_async_function() -> () {
-   |                                        ^^ recursive `async fn`
-   |
-   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`
-   = note: consider using the `async_recursion` crate: https://crates.io/crates/async_recursion
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0733`.
diff --git a/tests/ui/async-await/recursive-async-impl-trait-type.rs b/tests/ui/async-await/recursive-async-impl-trait-type.rs
index 60b34d3a174..edc4cb8ac5d 100644
--- a/tests/ui/async-await/recursive-async-impl-trait-type.rs
+++ b/tests/ui/async-await/recursive-async-impl-trait-type.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2018
 // Test that impl trait does not allow creating recursive types that are
 // otherwise forbidden when using `async` and `await`.
diff --git a/tests/ui/async-await/recursive-async-impl-trait-type.drop_tracking_mir.stderr b/tests/ui/async-await/recursive-async-impl-trait-type.stderr
index 7e63a8da552..63f64f44557 100644
--- a/tests/ui/async-await/recursive-async-impl-trait-type.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/recursive-async-impl-trait-type.stderr
@@ -1,5 +1,5 @@
 error[E0733]: recursion in an `async fn` requires boxing
-  --> $DIR/recursive-async-impl-trait-type.rs:8:40
+  --> $DIR/recursive-async-impl-trait-type.rs:5:40
    |
 LL | async fn recursive_async_function() -> () {
    |                                        ^^ recursive `async fn`
diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.current.stderr b/tests/ui/async-await/return-type-notation/issue-110963-early.current.stderr
index 1b847b59eb5..77385e966ce 100644
--- a/tests/ui/async-await/return-type-notation/issue-110963-early.current.stderr
+++ b/tests/ui/async-await/return-type-notation/issue-110963-early.current.stderr
@@ -7,7 +7,7 @@ LL | #![feature(return_type_notation)]
    = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: higher-ranked lifetime error
+error[E0308]: mismatched types
   --> $DIR/issue-110963-early.rs:17:5
    |
 LL | /     spawn(async move {
@@ -16,11 +16,17 @@ LL | |         if !hc.check().await {
 LL | |             log_health_check_failure().await;
 LL | |         }
 LL | |     });
-   | |______^
+   | |______^ one type is more general than the other
    |
-   = note: could not prove `[async block@$DIR/issue-110963-early.rs:17:11: 22:6]: Send`
+   = note: expected trait `Send`
+              found trait `for<'a> Send`
+note: the lifetime requirement is introduced here
+  --> $DIR/issue-110963-early.rs:37:17
+   |
+LL |     F: Future + Send + 'static,
+   |                 ^^^^
 
-error: higher-ranked lifetime error
+error[E0308]: mismatched types
   --> $DIR/issue-110963-early.rs:17:5
    |
 LL | /     spawn(async move {
@@ -29,9 +35,16 @@ LL | |         if !hc.check().await {
 LL | |             log_health_check_failure().await;
 LL | |         }
 LL | |     });
-   | |______^
+   | |______^ one type is more general than the other
+   |
+   = note: expected trait `Send`
+              found trait `for<'a> Send`
+note: the lifetime requirement is introduced here
+  --> $DIR/issue-110963-early.rs:37:17
    |
-   = note: could not prove `[async block@$DIR/issue-110963-early.rs:17:11: 22:6]: Send`
+LL |     F: Future + Send + 'static,
+   |                 ^^^^
 
 error: aborting due to 2 previous errors; 1 warning emitted
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.next.stderr b/tests/ui/async-await/return-type-notation/issue-110963-early.next.stderr
index 1b847b59eb5..77385e966ce 100644
--- a/tests/ui/async-await/return-type-notation/issue-110963-early.next.stderr
+++ b/tests/ui/async-await/return-type-notation/issue-110963-early.next.stderr
@@ -7,7 +7,7 @@ LL | #![feature(return_type_notation)]
    = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: higher-ranked lifetime error
+error[E0308]: mismatched types
   --> $DIR/issue-110963-early.rs:17:5
    |
 LL | /     spawn(async move {
@@ -16,11 +16,17 @@ LL | |         if !hc.check().await {
 LL | |             log_health_check_failure().await;
 LL | |         }
 LL | |     });
-   | |______^
+   | |______^ one type is more general than the other
    |
-   = note: could not prove `[async block@$DIR/issue-110963-early.rs:17:11: 22:6]: Send`
+   = note: expected trait `Send`
+              found trait `for<'a> Send`
+note: the lifetime requirement is introduced here
+  --> $DIR/issue-110963-early.rs:37:17
+   |
+LL |     F: Future + Send + 'static,
+   |                 ^^^^
 
-error: higher-ranked lifetime error
+error[E0308]: mismatched types
   --> $DIR/issue-110963-early.rs:17:5
    |
 LL | /     spawn(async move {
@@ -29,9 +35,16 @@ LL | |         if !hc.check().await {
 LL | |             log_health_check_failure().await;
 LL | |         }
 LL | |     });
-   | |______^
+   | |______^ one type is more general than the other
+   |
+   = note: expected trait `Send`
+              found trait `for<'a> Send`
+note: the lifetime requirement is introduced here
+  --> $DIR/issue-110963-early.rs:37:17
    |
-   = note: could not prove `[async block@$DIR/issue-110963-early.rs:17:11: 22:6]: Send`
+LL |     F: Future + Send + 'static,
+   |                 ^^^^
 
 error: aborting due to 2 previous errors; 1 warning emitted
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr b/tests/ui/async-await/return-type-notation/issue-110963-early.stderr
index 4ca5519c438..969094a2c58 100644
--- a/tests/ui/async-await/return-type-notation/issue-110963-early.stderr
+++ b/tests/ui/async-await/return-type-notation/issue-110963-early.stderr
@@ -7,7 +7,7 @@ LL | #![feature(return_type_notation)]
    = note: see issue #109417 <https://github.com/rust-lang/rust/issues/109417> for more information
    = note: `#[warn(incomplete_features)]` on by default
 
-error: higher-ranked lifetime error
+error[E0308]: mismatched types
   --> $DIR/issue-110963-early.rs:15:5
    |
 LL | /     spawn(async move {
@@ -16,11 +16,17 @@ LL | |         if !hc.check().await {
 LL | |             log_health_check_failure().await;
 LL | |         }
 LL | |     });
-   | |______^
+   | |______^ one type is more general than the other
    |
-   = note: could not prove `{async block@$DIR/issue-110963-early.rs:15:11: 20:6}: Send`
+   = note: expected trait `Send`
+              found trait `for<'a> Send`
+note: the lifetime requirement is introduced here
+  --> $DIR/issue-110963-early.rs:35:17
+   |
+LL |     F: Future + Send + 'static,
+   |                 ^^^^
 
-error: higher-ranked lifetime error
+error[E0308]: mismatched types
   --> $DIR/issue-110963-early.rs:15:5
    |
 LL | /     spawn(async move {
@@ -29,9 +35,16 @@ LL | |         if !hc.check().await {
 LL | |             log_health_check_failure().await;
 LL | |         }
 LL | |     });
-   | |______^
+   | |______^ one type is more general than the other
+   |
+   = note: expected trait `Send`
+              found trait `for<'a> Send`
+note: the lifetime requirement is introduced here
+  --> $DIR/issue-110963-early.rs:35:17
    |
-   = note: could not prove `{async block@$DIR/issue-110963-early.rs:15:11: 20:6}: Send`
+LL |     F: Future + Send + 'static,
+   |                 ^^^^
 
 error: aborting due to 2 previous errors; 1 warning emitted
 
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/async-await/unresolved_type_param.drop_tracking.stderr b/tests/ui/async-await/unresolved_type_param.drop_tracking.stderr
deleted file mode 100644
index 6b4a3a36395..00000000000
--- a/tests/ui/async-await/unresolved_type_param.drop_tracking.stderr
+++ /dev/null
@@ -1,39 +0,0 @@
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/unresolved_type_param.rs:12:5
-   |
-LL |     bar().await;
-   |     ^^^ cannot infer type for type parameter `T` declared on the function `bar`
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/unresolved_type_param.rs:12:11
-   |
-LL |     bar().await;
-   |           ^^^^^
-
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/unresolved_type_param.rs:12:5
-   |
-LL |     bar().await;
-   |     ^^^ cannot infer type for type parameter `T` declared on the function `bar`
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/unresolved_type_param.rs:12:11
-   |
-LL |     bar().await;
-   |           ^^^^^
-
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/unresolved_type_param.rs:12:5
-   |
-LL |     bar().await;
-   |     ^^^ cannot infer type for type parameter `T` declared on the function `bar`
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/unresolved_type_param.rs:12:11
-   |
-LL |     bar().await;
-   |           ^^^^^
-
-error: aborting due to 3 previous errors
-
-For more information about this error, try `rustc --explain E0698`.
diff --git a/tests/ui/async-await/unresolved_type_param.no_drop_tracking.stderr b/tests/ui/async-await/unresolved_type_param.no_drop_tracking.stderr
deleted file mode 100644
index 6642e90acd8..00000000000
--- a/tests/ui/async-await/unresolved_type_param.no_drop_tracking.stderr
+++ /dev/null
@@ -1,63 +0,0 @@
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/unresolved_type_param.rs:12:5
-   |
-LL |     bar().await;
-   |     ^^^ cannot infer type for type parameter `T` declared on the function `bar`
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/unresolved_type_param.rs:12:11
-   |
-LL |     bar().await;
-   |           ^^^^^
-
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/unresolved_type_param.rs:12:5
-   |
-LL |     bar().await;
-   |     ^^^ cannot infer type for type parameter `T` declared on the function `bar`
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/unresolved_type_param.rs:12:11
-   |
-LL |     bar().await;
-   |           ^^^^^
-
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/unresolved_type_param.rs:12:5
-   |
-LL |     bar().await;
-   |     ^^^ cannot infer type for type parameter `T` declared on the function `bar`
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/unresolved_type_param.rs:12:11
-   |
-LL |     bar().await;
-   |           ^^^^^
-
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/unresolved_type_param.rs:12:5
-   |
-LL |     bar().await;
-   |     ^^^ cannot infer type for type parameter `T` declared on the function `bar`
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/unresolved_type_param.rs:12:11
-   |
-LL |     bar().await;
-   |           ^^^^^
-
-error[E0698]: type inside `async fn` body must be known in this context
-  --> $DIR/unresolved_type_param.rs:12:5
-   |
-LL |     bar().await;
-   |     ^^^ cannot infer type for type parameter `T` declared on the function `bar`
-   |
-note: the type is part of the `async fn` body because of this `await`
-  --> $DIR/unresolved_type_param.rs:12:11
-   |
-LL |     bar().await;
-   |           ^^^^^
-
-error: aborting due to 5 previous errors
-
-For more information about this error, try `rustc --explain E0698`.
diff --git a/tests/ui/async-await/unresolved_type_param.rs b/tests/ui/async-await/unresolved_type_param.rs
index ca0a92b9434..dd5aa0dd077 100644
--- a/tests/ui/async-await/unresolved_type_param.rs
+++ b/tests/ui/async-await/unresolved_type_param.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // Provoke an unresolved type error (T).
 // Error message should pinpoint the type parameter T as needing to be bound
 // (rather than give a general error message)
@@ -10,27 +7,6 @@ async fn bar<T>() -> () {}
 
 async fn foo() {
     bar().await;
-    //[drop_tracking_mir]~^ ERROR type annotations needed
-    //[drop_tracking_mir]~| NOTE cannot infer type of the type parameter `T`
-    //[no_drop_tracking,drop_tracking]~^^^ ERROR type inside `async fn` body must be known in this context
-    //[no_drop_tracking,drop_tracking]~| ERROR type inside `async fn` body must be known in this context
-    //[no_drop_tracking,drop_tracking]~| ERROR type inside `async fn` body must be known in this context
-    //[no_drop_tracking,drop_tracking]~| NOTE cannot infer type for type parameter `T`
-    //[no_drop_tracking,drop_tracking]~| NOTE cannot infer type for type parameter `T`
-    //[no_drop_tracking,drop_tracking]~| NOTE cannot infer type for type parameter `T`
-    //[no_drop_tracking,drop_tracking]~| NOTE the type is part of the `async fn` body because of this `await`
-    //[no_drop_tracking,drop_tracking]~| NOTE the type is part of the `async fn` body because of this `await`
-    //[no_drop_tracking,drop_tracking]~| NOTE the type is part of the `async fn` body because of this `await`
-    //[no_drop_tracking,drop_tracking]~| NOTE in this expansion of desugaring of `await`
-    //[no_drop_tracking,drop_tracking]~| NOTE in this expansion of desugaring of `await`
-    //[no_drop_tracking,drop_tracking]~| NOTE in this expansion of desugaring of `await`
-    //[no_drop_tracking]~^^^^^^^^^^^^^^^ ERROR type inside `async fn` body must be known in this context
-    //[no_drop_tracking]~| ERROR type inside `async fn` body must be known in this context
-    //[no_drop_tracking]~| NOTE cannot infer type for type parameter `T`
-    //[no_drop_tracking]~| NOTE cannot infer type for type parameter `T`
-    //[no_drop_tracking]~| NOTE the type is part of the `async fn` body because of this `await`
-    //[no_drop_tracking]~| NOTE the type is part of the `async fn` body because of this `await`
-    //[no_drop_tracking]~| NOTE in this expansion of desugaring of `await`
-    //[no_drop_tracking]~| NOTE in this expansion of desugaring of `await`
+    //~^ ERROR type annotations needed
 }
 fn main() {}
diff --git a/tests/ui/async-await/unresolved_type_param.drop_tracking_mir.stderr b/tests/ui/async-await/unresolved_type_param.stderr
index 95c79946831..45aa766065e 100644
--- a/tests/ui/async-await/unresolved_type_param.drop_tracking_mir.stderr
+++ b/tests/ui/async-await/unresolved_type_param.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/unresolved_type_param.rs:12:5
+  --> $DIR/unresolved_type_param.rs:9:5
    |
 LL |     bar().await;
    |     ^^^ cannot infer type of the type parameter `T` declared on the function `bar`
diff --git a/tests/ui/async-await/unsized-across-await.rs b/tests/ui/async-await/unsized-across-await.rs
new file mode 100644
index 00000000000..32cb4f88eae
--- /dev/null
+++ b/tests/ui/async-await/unsized-across-await.rs
@@ -0,0 +1,16 @@
+// edition: 2021
+
+#![feature(unsized_locals)]
+//~^ WARN the feature `unsized_locals` is incomplete
+
+async fn f() {}
+
+async fn g(x: Box<dyn std::fmt::Display>) {
+    let _x = *x;
+    //~^ ERROR the size for values of type `dyn std::fmt::Display` cannot be known at compilation time
+    f().await;
+}
+
+fn main() {
+    let _a = g(Box::new(5));
+}
diff --git a/tests/ui/async-await/unsized-across-await.stderr b/tests/ui/async-await/unsized-across-await.stderr
new file mode 100644
index 00000000000..649b12ce5a5
--- /dev/null
+++ b/tests/ui/async-await/unsized-across-await.stderr
@@ -0,0 +1,21 @@
+warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/unsized-across-await.rs:3:12
+   |
+LL | #![feature(unsized_locals)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the size for values of type `dyn std::fmt::Display` cannot be known at compilation time
+  --> $DIR/unsized-across-await.rs:9:9
+   |
+LL |     let _x = *x;
+   |         ^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `dyn std::fmt::Display`
+   = note: all values live across `await` must have a statically known size
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/borrowck/async-reference-generality.rs b/tests/ui/borrowck/async-reference-generality.rs
index 487d1ac81bf..668df9ea710 100644
--- a/tests/ui/borrowck/async-reference-generality.rs
+++ b/tests/ui/borrowck/async-reference-generality.rs
@@ -1,5 +1,4 @@
-// check-fail
-// known-bug: #99492
+// check-pass
 // edition: 2021
 
 use std::marker::PhantomData;
diff --git a/tests/ui/borrowck/async-reference-generality.stderr b/tests/ui/borrowck/async-reference-generality.stderr
deleted file mode 100644
index af720ad2931..00000000000
--- a/tests/ui/borrowck/async-reference-generality.stderr
+++ /dev/null
@@ -1,27 +0,0 @@
-error[E0308]: mismatched types
-  --> $DIR/async-reference-generality.rs:23:5
-   |
-LL | /     async {
-LL | |         let _x = Struct::<Empty<&'static ()>, _>(PhantomData);
-LL | |         async {}.await;
-LL | |     }
-   | |_____^ one type is more general than the other
-   |
-   = note: expected reference `&()`
-              found reference `&()`
-
-error[E0308]: mismatched types
-  --> $DIR/async-reference-generality.rs:23:5
-   |
-LL | /     async {
-LL | |         let _x = Struct::<Empty<&'static ()>, _>(PhantomData);
-LL | |         async {}.await;
-LL | |     }
-   | |_____^ one type is more general than the other
-   |
-   = note: expected reference `&()`
-              found reference `&()`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs
deleted file mode 100644
index addbe5d658a..00000000000
--- a/tests/ui/borrowck/erase-error-in-mir-drop-tracking.rs
+++ /dev/null
@@ -1,23 +0,0 @@
-// compile-flags: -Zdrop-tracking-mir
-// edition:2021
-
-use std::future::Future;
-
-trait Client {
-    type Connecting<'a>: Future + Send
-    where
-        Self: 'a;
-
-    fn connect(&'_ self) -> Self::Connecting<'a>;
-    //~^ ERROR use of undeclared lifetime name `'a`
-}
-
-fn call_connect<C>(c: &'_ C) -> impl '_ + Future + Send
-where
-    C: Client + Send + Sync,
-{
-    async move { c.connect().await }
-    //~^ ERROR `C` does not live long enough
-}
-
-fn main() {}
diff --git a/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr b/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr
deleted file mode 100644
index 53abe3dc952..00000000000
--- a/tests/ui/borrowck/erase-error-in-mir-drop-tracking.stderr
+++ /dev/null
@@ -1,24 +0,0 @@
-error[E0261]: use of undeclared lifetime name `'a`
-  --> $DIR/erase-error-in-mir-drop-tracking.rs:11:46
-   |
-LL |     fn connect(&'_ self) -> Self::Connecting<'a>;
-   |                                              ^^ undeclared lifetime
-   |
-help: consider introducing lifetime `'a` here
-   |
-LL |     fn connect<'a>(&'_ self) -> Self::Connecting<'a>;
-   |               ++++
-help: consider introducing lifetime `'a` here
-   |
-LL | trait Client<'a> {
-   |             ++++
-
-error: `C` does not live long enough
-  --> $DIR/erase-error-in-mir-drop-tracking.rs:19:5
-   |
-LL |     async move { c.connect().await }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0261`.
diff --git a/tests/ui/closures/capture-unsized-by-move.rs b/tests/ui/closures/capture-unsized-by-move.rs
new file mode 100644
index 00000000000..1148e34ac67
--- /dev/null
+++ b/tests/ui/closures/capture-unsized-by-move.rs
@@ -0,0 +1,10 @@
+// compile-flags: --crate-type=lib
+
+#![feature(unsized_fn_params)]
+
+pub fn f(k: dyn std::fmt::Display) {
+    let k2 = move || {
+        k.to_string();
+        //~^ ERROR the size for values of type `(dyn std::fmt::Display + 'static)` cannot be known at compilation time
+    };
+}
diff --git a/tests/ui/closures/capture-unsized-by-move.stderr b/tests/ui/closures/capture-unsized-by-move.stderr
new file mode 100644
index 00000000000..d7fafc8cadd
--- /dev/null
+++ b/tests/ui/closures/capture-unsized-by-move.stderr
@@ -0,0 +1,14 @@
+error[E0277]: the size for values of type `(dyn std::fmt::Display + 'static)` cannot be known at compilation time
+  --> $DIR/capture-unsized-by-move.rs:7:9
+   |
+LL |     let k2 = move || {
+   |                   -- this closure captures all values by move
+LL |         k.to_string();
+   |         ^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `(dyn std::fmt::Display + 'static)`
+   = note: all values captured by value by a closure must have a statically known size
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/closures/capture-unsized-by-ref.rs b/tests/ui/closures/capture-unsized-by-ref.rs
new file mode 100644
index 00000000000..c9e4a5903d9
--- /dev/null
+++ b/tests/ui/closures/capture-unsized-by-ref.rs
@@ -0,0 +1,10 @@
+// build-pass
+// compile-flags: --crate-type=lib
+
+#![feature(unsized_fn_params)]
+
+pub fn f(k: dyn std::fmt::Display) {
+    let k2 = || {
+        k.to_string();
+    };
+}
diff --git a/tests/ui/closures/issue-112547.rs b/tests/ui/closures/issue-112547.rs
new file mode 100644
index 00000000000..8ecb2abccd4
--- /dev/null
+++ b/tests/ui/closures/issue-112547.rs
@@ -0,0 +1,15 @@
+#![feature(non_lifetime_binders)]
+        //~^ WARNING the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+
+pub fn bar()
+where
+    for<const N: usize = {
+    (||1usize)()
+}> V: IntoIterator
+//~^ ERROR cannot find type `V` in this scope [E0412]
+{
+}
+
+fn main() {
+    bar();
+}
diff --git a/tests/ui/closures/issue-112547.stderr b/tests/ui/closures/issue-112547.stderr
new file mode 100644
index 00000000000..d86b05dc6a7
--- /dev/null
+++ b/tests/ui/closures/issue-112547.stderr
@@ -0,0 +1,23 @@
+error[E0412]: cannot find type `V` in this scope
+  --> $DIR/issue-112547.rs:8:4
+   |
+LL | }> V: IntoIterator
+   |    ^ not found in this scope
+   |
+help: you might be missing a type parameter
+   |
+LL | pub fn bar<V>()
+   |           +++
+
+warning: the feature `non_lifetime_binders` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/issue-112547.rs:1:12
+   |
+LL | #![feature(non_lifetime_binders)]
+   |            ^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #108185 <https://github.com/rust-lang/rust/issues/108185> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0412`.
diff --git a/tests/ui/codegen/issue-79865-llvm-miscompile.rs b/tests/ui/codegen/issue-79865-llvm-miscompile.rs
new file mode 100644
index 00000000000..b77f09f8e9a
--- /dev/null
+++ b/tests/ui/codegen/issue-79865-llvm-miscompile.rs
@@ -0,0 +1,38 @@
+// run-pass
+// only-x86_64
+// compile-flags: -C opt-level=3
+
+// Regression test for issue #79865.
+// The assertion will fail when compiled with Rust 1.56..=1.59
+// due to a LLVM miscompilation.
+
+use std::arch::x86_64::*;
+
+fn main() {
+    if is_x86_feature_detected!("avx") {
+        let res: [f64; 4] = unsafe { std::mem::transmute::<_, _>(first()) };
+        assert_eq!(res, [22.0, 44.0, 66.0, 88.0]);
+    }
+}
+
+#[target_feature(enable = "avx")]
+unsafe fn first() -> __m256d {
+    second()
+}
+
+unsafe fn second() -> __m256d {
+    let v0 = _mm256_setr_pd(1.0, 2.0, 3.0, 4.0);
+    let v1 = _mm256_setr_pd(10.0, 20.0, 30.0, 40.0);
+
+    // needs to be called twice to hit the miscompilation
+    let (add, _) = add_sub(v0, v1);
+    let (add, _) = add_sub(add, add);
+    add
+}
+
+#[inline(never)] // needed to hit the miscompilation
+unsafe fn add_sub(v1: __m256d, v0: __m256d) -> (__m256d, __m256d) {
+    let add = _mm256_add_pd(v0, v1);
+    let sub = _mm256_sub_pd(v0, v1);
+    (add, sub)
+}
diff --git a/tests/ui/codegen/subtyping-enforces-type-equality.stderr b/tests/ui/codegen/subtyping-enforces-type-equality.stderr
deleted file mode 100644
index 870ca0f839f..00000000000
--- a/tests/ui/codegen/subtyping-enforces-type-equality.stderr
+++ /dev/null
@@ -1 +0,0 @@
-WARN rustc_codegen_ssa::mir::locals Unexpected initial operand type. See the issues/114858
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs
index 08f7c5cb542..7174d1ec4f2 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.rs
@@ -10,10 +10,12 @@ struct CantParam(ImplementsConstParamTy);
 impl std::marker::ConstParamTy for CantParam {}
 //~^ error: the type `CantParam` does not `#[derive(Eq)]`
 //~| error: the type `CantParam` does not `#[derive(PartialEq)]`
+//~| the trait bound `CantParam: Eq` is not satisfied
 
 #[derive(std::marker::ConstParamTy)]
 //~^ error: the type `CantParamDerive` does not `#[derive(Eq)]`
 //~| error: the type `CantParamDerive` does not `#[derive(PartialEq)]`
+//~| the trait bound `CantParamDerive: Eq` is not satisfied
 struct CantParamDerive(ImplementsConstParamTy);
 
 fn check<T: std::marker::ConstParamTy>() {}
diff --git a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
index 43c5b96dc7c..2cf7cc07dbe 100644
--- a/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
+++ b/tests/ui/const-generics/adt_const_params/const_param_ty_impl_no_structural_eq.stderr
@@ -1,3 +1,17 @@
+error[E0277]: the trait bound `CantParam: Eq` is not satisfied
+  --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:36
+   |
+LL | impl std::marker::ConstParamTy for CantParam {}
+   |                                    ^^^^^^^^^ the trait `Eq` is not implemented for `CantParam`
+   |
+note: required by a bound in `ConstParamTy`
+  --> $SRC_DIR/core/src/marker.rs:LL:COL
+help: consider annotating `CantParam` with `#[derive(Eq)]`
+   |
+LL + #[derive(Eq)]
+LL | struct CantParam(ImplementsConstParamTy);
+   |
+
 error[E0277]: the type `CantParam` does not `#[derive(PartialEq)]`
   --> $DIR/const_param_ty_impl_no_structural_eq.rs:10:36
    |
@@ -16,8 +30,23 @@ LL | impl std::marker::ConstParamTy for CantParam {}
 note: required by a bound in `ConstParamTy`
   --> $SRC_DIR/core/src/marker.rs:LL:COL
 
+error[E0277]: the trait bound `CantParamDerive: Eq` is not satisfied
+  --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:10
+   |
+LL | #[derive(std::marker::ConstParamTy)]
+   |          ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Eq` is not implemented for `CantParamDerive`
+   |
+note: required by a bound in `ConstParamTy`
+  --> $SRC_DIR/core/src/marker.rs:LL:COL
+   = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: consider annotating `CantParamDerive` with `#[derive(Eq)]`
+   |
+LL + #[derive(Eq)]
+LL | struct CantParamDerive(ImplementsConstParamTy);
+   |
+
 error[E0277]: the type `CantParamDerive` does not `#[derive(PartialEq)]`
-  --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10
+  --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:10
    |
 LL | #[derive(std::marker::ConstParamTy)]
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralPartialEq` is not implemented for `CantParamDerive`
@@ -27,7 +56,7 @@ note: required by a bound in `ConstParamTy`
    = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error[E0277]: the type `CantParamDerive` does not `#[derive(Eq)]`
-  --> $DIR/const_param_ty_impl_no_structural_eq.rs:14:10
+  --> $DIR/const_param_ty_impl_no_structural_eq.rs:15:10
    |
 LL | #[derive(std::marker::ConstParamTy)]
    |          ^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `StructuralEq` is not implemented for `CantParamDerive`
@@ -36,6 +65,6 @@ note: required by a bound in `ConstParamTy`
   --> $SRC_DIR/core/src/marker.rs:LL:COL
    = note: this error originates in the derive macro `std::marker::ConstParamTy` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 4 previous errors
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs
new file mode 100644
index 00000000000..a83830178d4
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.rs
@@ -0,0 +1,44 @@
+// Test that when adt_const_params is not enabled, we suggest adding the feature only when
+// it would be possible for the type to be used as a const generic or when it's likely
+// possible for the user to fix their type to be used.
+
+// Can never be used as const generics.
+fn uwu_0<const N: &'static mut ()>() {}
+//~^ ERROR: forbidden as the type of a const generic
+
+// Needs the feature but can be used, so suggest adding the feature.
+fn owo_0<const N: &'static u32>() {}
+//~^ ERROR: forbidden as the type of a const generic
+//~^^ HELP: add `#![feature(adt_const_params)]`
+
+// Can only be used in const generics with changes.
+struct Meow {
+    meow: u8,
+}
+
+fn meow_0<const N: Meow>() {}
+//~^ ERROR: forbidden as the type of a const generic
+//~^^ HELP: add `#![feature(adt_const_params)]`
+fn meow_1<const N: &'static Meow>() {}
+//~^ ERROR: forbidden as the type of a const generic
+//~^^ HELP: add `#![feature(adt_const_params)]`
+fn meow_2<const N: [Meow; 100]>() {}
+//~^ ERROR: forbidden as the type of a const generic
+//~^^ HELP: add `#![feature(adt_const_params)]`
+fn meow_3<const N: (Meow, u8)>() {}
+//~^ ERROR: forbidden as the type of a const generic
+//~^^ HELP: add `#![feature(adt_const_params)]`
+
+// This is suboptimal that it thinks it can be used
+// but better to suggest the feature to the user.
+fn meow_4<const N: (Meow, String)>() {}
+//~^ ERROR: forbidden as the type of a const generic
+//~^^ HELP: add `#![feature(adt_const_params)]`
+
+// Non-local ADT that does not impl `ConstParamTy`
+fn nya_0<const N: String>() {}
+//~^ ERROR: forbidden as the type of a const generic
+fn nya_1<const N: Vec<u32>>() {}
+//~^ ERROR: forbidden as the type of a const generic
+
+fn main() {}
diff --git a/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr
new file mode 100644
index 00000000000..04527e3158e
--- /dev/null
+++ b/tests/ui/const-generics/adt_const_params/suggest_feature_only_when_possible.stderr
@@ -0,0 +1,80 @@
+error: `&'static mut ()` is forbidden as the type of a const generic parameter
+  --> $DIR/suggest_feature_only_when_possible.rs:6:19
+   |
+LL | fn uwu_0<const N: &'static mut ()>() {}
+   |                   ^^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+
+error: `&'static u32` is forbidden as the type of a const generic parameter
+  --> $DIR/suggest_feature_only_when_possible.rs:10:19
+   |
+LL | fn owo_0<const N: &'static u32>() {}
+   |                   ^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+
+error: `Meow` is forbidden as the type of a const generic parameter
+  --> $DIR/suggest_feature_only_when_possible.rs:19:20
+   |
+LL | fn meow_0<const N: Meow>() {}
+   |                    ^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+
+error: `&'static Meow` is forbidden as the type of a const generic parameter
+  --> $DIR/suggest_feature_only_when_possible.rs:22:20
+   |
+LL | fn meow_1<const N: &'static Meow>() {}
+   |                    ^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+
+error: `[Meow; 100]` is forbidden as the type of a const generic parameter
+  --> $DIR/suggest_feature_only_when_possible.rs:25:20
+   |
+LL | fn meow_2<const N: [Meow; 100]>() {}
+   |                    ^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+
+error: `(Meow, u8)` is forbidden as the type of a const generic parameter
+  --> $DIR/suggest_feature_only_when_possible.rs:28:20
+   |
+LL | fn meow_3<const N: (Meow, u8)>() {}
+   |                    ^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+
+error: `(Meow, String)` is forbidden as the type of a const generic parameter
+  --> $DIR/suggest_feature_only_when_possible.rs:34:20
+   |
+LL | fn meow_4<const N: (Meow, String)>() {}
+   |                    ^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
+
+error: `String` is forbidden as the type of a const generic parameter
+  --> $DIR/suggest_feature_only_when_possible.rs:39:19
+   |
+LL | fn nya_0<const N: String>() {}
+   |                   ^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+
+error: `Vec<u32>` is forbidden as the type of a const generic parameter
+  --> $DIR/suggest_feature_only_when_possible.rs:41:19
+   |
+LL | fn nya_1<const N: Vec<u32>>() {}
+   |                   ^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+
+error: aborting due to 9 previous errors
+
diff --git a/tests/ui/const-generics/const-param-elided-lifetime.min.stderr b/tests/ui/const-generics/const-param-elided-lifetime.min.stderr
index 656bc29466f..ffe45285988 100644
--- a/tests/ui/const-generics/const-param-elided-lifetime.min.stderr
+++ b/tests/ui/const-generics/const-param-elided-lifetime.min.stderr
@@ -35,7 +35,7 @@ LL | struct A<const N: &u8>;
    |                   ^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `&u8` is forbidden as the type of a const generic parameter
   --> $DIR/const-param-elided-lifetime.rs:14:15
@@ -44,7 +44,7 @@ LL | impl<const N: &u8> A<N> {
    |               ^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `&u8` is forbidden as the type of a const generic parameter
   --> $DIR/const-param-elided-lifetime.rs:22:15
@@ -53,7 +53,7 @@ LL | impl<const N: &u8> B for A<N> {}
    |               ^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `&u8` is forbidden as the type of a const generic parameter
   --> $DIR/const-param-elided-lifetime.rs:26:17
@@ -62,7 +62,7 @@ LL | fn bar<const N: &u8>() {}
    |                 ^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `&u8` is forbidden as the type of a const generic parameter
   --> $DIR/const-param-elided-lifetime.rs:17:21
@@ -71,7 +71,7 @@ LL |     fn foo<const M: &u8>(&self) {}
    |                     ^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 10 previous errors
 
diff --git a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr
index f829526ca1d..daeeadeed7c 100644
--- a/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr
+++ b/tests/ui/const-generics/const-param-type-depends-on-const-param.min.stderr
@@ -21,7 +21,7 @@ LL | pub struct Dependent<const N: usize, const X: [u8; N]>([(); N]);
    |                                               ^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `[u8; N]` is forbidden as the type of a const generic parameter
   --> $DIR/const-param-type-depends-on-const-param.rs:15:35
@@ -30,7 +30,7 @@ LL | pub struct SelfDependent<const N: [u8; N]>;
    |                                   ^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/const-generics/float-generic.simple.stderr b/tests/ui/const-generics/float-generic.simple.stderr
index 89ca36b0f63..aeb19dc7532 100644
--- a/tests/ui/const-generics/float-generic.simple.stderr
+++ b/tests/ui/const-generics/float-generic.simple.stderr
@@ -5,7 +5,6 @@ LL | fn foo<const F: f32>() {}
    |                 ^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/fn-const-param-call.min.stderr b/tests/ui/const-generics/fn-const-param-call.min.stderr
index d984449e6ca..2d316fba1e9 100644
--- a/tests/ui/const-generics/fn-const-param-call.min.stderr
+++ b/tests/ui/const-generics/fn-const-param-call.min.stderr
@@ -3,12 +3,16 @@ error: using function pointers as const generic parameters is forbidden
    |
 LL | struct Wrapper<const F: fn() -> u32>;
    |                         ^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
 
 error: using function pointers as const generic parameters is forbidden
   --> $DIR/fn-const-param-call.rs:13:15
    |
 LL | impl<const F: fn() -> u32> Wrapper<F> {
    |               ^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/fn-const-param-infer.min.stderr b/tests/ui/const-generics/fn-const-param-infer.min.stderr
index f0767a10994..a7afa484275 100644
--- a/tests/ui/const-generics/fn-const-param-infer.min.stderr
+++ b/tests/ui/const-generics/fn-const-param-infer.min.stderr
@@ -3,6 +3,8 @@ error: using function pointers as const generic parameters is forbidden
    |
 LL | struct Checked<const F: fn(usize) -> bool>;
    |                         ^^^^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr
index 956e9c9c988..64d1e0bcff4 100644
--- a/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/array-size-in-generic-struct-param.min.stderr
@@ -23,7 +23,7 @@ LL | struct B<const CFG: Config> {
    |                     ^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr b/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr
index b8a1027c9eb..4c45339b93b 100644
--- a/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr
+++ b/tests/ui/const-generics/intrinsics-type_name-as-const-argument.min.stderr
@@ -14,7 +14,7 @@ LL | trait Trait<const S: &'static str> {}
    |                      ^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/issues/issue-56445-1.min.stderr b/tests/ui/const-generics/issues/issue-56445-1.min.stderr
index 71a7051f25b..fc10aba0fec 100644
--- a/tests/ui/const-generics/issues/issue-56445-1.min.stderr
+++ b/tests/ui/const-generics/issues/issue-56445-1.min.stderr
@@ -13,7 +13,7 @@ LL | struct Bug<'a, const S: &'a str>(PhantomData<&'a ()>);
    |                         ^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/issues/issue-62878.min.stderr b/tests/ui/const-generics/issues/issue-62878.min.stderr
index 9c0e5179cc4..eb8b9732f58 100644
--- a/tests/ui/const-generics/issues/issue-62878.min.stderr
+++ b/tests/ui/const-generics/issues/issue-62878.min.stderr
@@ -13,7 +13,7 @@ LL | fn foo<const N: usize, const A: [u8; N]>() {}
    |                                 ^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr
index 9f6c7ccf3fe..9d80f1cd01b 100644
--- a/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr
+++ b/tests/ui/const-generics/issues/issue-63322-forbid-dyn.min.stderr
@@ -5,7 +5,7 @@ LL | fn test<const T: &'static dyn A>() {
    |                  ^^^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/issues/issue-68615-adt.min.stderr b/tests/ui/const-generics/issues/issue-68615-adt.min.stderr
index df04c4896b4..c8b9f17196a 100644
--- a/tests/ui/const-generics/issues/issue-68615-adt.min.stderr
+++ b/tests/ui/const-generics/issues/issue-68615-adt.min.stderr
@@ -5,7 +5,7 @@ LL | struct Const<const V: [usize; 0]> {}
    |                       ^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/issues/issue-68615-array.min.stderr b/tests/ui/const-generics/issues/issue-68615-array.min.stderr
index 1b4517087e2..fc6cef9d44e 100644
--- a/tests/ui/const-generics/issues/issue-68615-array.min.stderr
+++ b/tests/ui/const-generics/issues/issue-68615-array.min.stderr
@@ -5,7 +5,7 @@ LL | struct Foo<const V: [usize; 0] > {}
    |                     ^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/issues/issue-71169.min.stderr b/tests/ui/const-generics/issues/issue-71169.min.stderr
index ebfb24bec28..bba92f32a78 100644
--- a/tests/ui/const-generics/issues/issue-71169.min.stderr
+++ b/tests/ui/const-generics/issues/issue-71169.min.stderr
@@ -13,7 +13,7 @@ LL | fn foo<const LEN: usize, const DATA: [u8; LEN]>() {}
    |                                      ^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/issues/issue-71381.min.stderr b/tests/ui/const-generics/issues/issue-71381.min.stderr
index e1e140071fc..e16d3b7a8a4 100644
--- a/tests/ui/const-generics/issues/issue-71381.min.stderr
+++ b/tests/ui/const-generics/issues/issue-71381.min.stderr
@@ -19,12 +19,16 @@ error: using function pointers as const generic parameters is forbidden
    |
 LL |     pub fn call_me<Args: Sized, const IDX: usize, const FN: unsafe extern "C" fn(Args)>(&self) {
    |                                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
 
 error: using function pointers as const generic parameters is forbidden
   --> $DIR/issue-71381.rs:23:19
    |
 LL |         const FN: unsafe extern "C" fn(Args),
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/const-generics/issues/issue-71382.min.stderr b/tests/ui/const-generics/issues/issue-71382.min.stderr
index 715037bd5f1..217166d8479 100644
--- a/tests/ui/const-generics/issues/issue-71382.min.stderr
+++ b/tests/ui/const-generics/issues/issue-71382.min.stderr
@@ -3,6 +3,8 @@ error: using function pointers as const generic parameters is forbidden
    |
 LL |     fn test<const FN: fn()>(&self) {
    |                       ^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/issues/issue-71611.min.stderr b/tests/ui/const-generics/issues/issue-71611.min.stderr
index b33d7cf9850..b01936f4d25 100644
--- a/tests/ui/const-generics/issues/issue-71611.min.stderr
+++ b/tests/ui/const-generics/issues/issue-71611.min.stderr
@@ -11,6 +11,8 @@ error: using function pointers as const generic parameters is forbidden
    |
 LL | fn func<A, const F: fn(inner: A)>(outer: A) {
    |                     ^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/issues/issue-72352.min.stderr b/tests/ui/const-generics/issues/issue-72352.min.stderr
index eedd73c4dcc..b010996b896 100644
--- a/tests/ui/const-generics/issues/issue-72352.min.stderr
+++ b/tests/ui/const-generics/issues/issue-72352.min.stderr
@@ -3,6 +3,8 @@ error: using function pointers as const generic parameters is forbidden
    |
 LL | unsafe fn unsafely_do_the_thing<const F: fn(&CStr) -> usize>(ptr: *const i8) -> usize {
    |                                          ^^^^^^^^^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/issues/issue-73491.min.stderr b/tests/ui/const-generics/issues/issue-73491.min.stderr
index f03354fc472..fdf057bdbe4 100644
--- a/tests/ui/const-generics/issues/issue-73491.min.stderr
+++ b/tests/ui/const-generics/issues/issue-73491.min.stderr
@@ -5,7 +5,7 @@ LL | fn hoge<const IN: [u32; LEN]>() {}
    |                   ^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr b/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr
index 0a7db62472a..bed0a02a726 100644
--- a/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr
+++ b/tests/ui/const-generics/issues/issue-73727-static-reference-array-const-param.min.stderr
@@ -5,7 +5,7 @@ LL | fn a<const X: &'static [u32]>() {}
    |               ^^^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/issues/issue-74101.min.stderr b/tests/ui/const-generics/issues/issue-74101.min.stderr
index 134c248347d..7852ce5bcfc 100644
--- a/tests/ui/const-generics/issues/issue-74101.min.stderr
+++ b/tests/ui/const-generics/issues/issue-74101.min.stderr
@@ -5,7 +5,7 @@ LL | fn test<const N: [u8; 1 + 2]>() {}
    |                  ^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `[u8; 1 + 2]` is forbidden as the type of a const generic parameter
   --> $DIR/issue-74101.rs:9:21
@@ -14,7 +14,7 @@ LL | struct Foo<const N: [u8; 1 + 2]>;
    |                     ^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/issues/issue-74255.min.stderr b/tests/ui/const-generics/issues/issue-74255.min.stderr
index bbcf8682b71..affeca167e9 100644
--- a/tests/ui/const-generics/issues/issue-74255.min.stderr
+++ b/tests/ui/const-generics/issues/issue-74255.min.stderr
@@ -5,7 +5,7 @@ LL |     fn ice_struct_fn<const I: IceEnum>() {}
    |                               ^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/issues/issue-74950.min.stderr b/tests/ui/const-generics/issues/issue-74950.min.stderr
index c37ee93d420..a5dbe10b78a 100644
--- a/tests/ui/const-generics/issues/issue-74950.min.stderr
+++ b/tests/ui/const-generics/issues/issue-74950.min.stderr
@@ -5,7 +5,7 @@ LL | struct Outer<const I: Inner>;
    |                       ^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `Inner` is forbidden as the type of a const generic parameter
   --> $DIR/issue-74950.rs:20:23
@@ -14,7 +14,7 @@ LL | struct Outer<const I: Inner>;
    |                       ^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `Inner` is forbidden as the type of a const generic parameter
   --> $DIR/issue-74950.rs:20:23
@@ -23,7 +23,7 @@ LL | struct Outer<const I: Inner>;
    |                       ^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `Inner` is forbidden as the type of a const generic parameter
   --> $DIR/issue-74950.rs:20:23
@@ -32,7 +32,7 @@ LL | struct Outer<const I: Inner>;
    |                       ^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `Inner` is forbidden as the type of a const generic parameter
   --> $DIR/issue-74950.rs:20:23
@@ -41,7 +41,7 @@ LL | struct Outer<const I: Inner>;
    |                       ^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/const-generics/issues/issue-75047.min.stderr b/tests/ui/const-generics/issues/issue-75047.min.stderr
index 46af19ef395..e316b4624a0 100644
--- a/tests/ui/const-generics/issues/issue-75047.min.stderr
+++ b/tests/ui/const-generics/issues/issue-75047.min.stderr
@@ -5,7 +5,7 @@ LL | struct Foo<const N: [u8; Bar::<u32>::value()]>;
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/lifetime-in-const-param.stderr b/tests/ui/const-generics/lifetime-in-const-param.stderr
index 8fd9068e8ef..c2fcdcf1a71 100644
--- a/tests/ui/const-generics/lifetime-in-const-param.stderr
+++ b/tests/ui/const-generics/lifetime-in-const-param.stderr
@@ -11,7 +11,7 @@ LL | struct S<'a, const N: S2>(&'a ());
    |                       ^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/min_const_generics/complex-types.stderr b/tests/ui/const-generics/min_const_generics/complex-types.stderr
index 4ddbadb5466..8cc75dbaff9 100644
--- a/tests/ui/const-generics/min_const_generics/complex-types.stderr
+++ b/tests/ui/const-generics/min_const_generics/complex-types.stderr
@@ -5,7 +5,7 @@ LL | struct Foo<const N: [u8; 0]>;
    |                     ^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `()` is forbidden as the type of a const generic parameter
   --> $DIR/complex-types.rs:6:21
@@ -14,7 +14,7 @@ LL | struct Bar<const N: ()>;
    |                     ^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `No` is forbidden as the type of a const generic parameter
   --> $DIR/complex-types.rs:11:21
@@ -23,7 +23,7 @@ LL | struct Fez<const N: No>;
    |                     ^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `&'static u8` is forbidden as the type of a const generic parameter
   --> $DIR/complex-types.rs:14:21
@@ -32,7 +32,7 @@ LL | struct Faz<const N: &'static u8>;
    |                     ^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `!` is forbidden as the type of a const generic parameter
   --> $DIR/complex-types.rs:17:21
@@ -41,7 +41,6 @@ LL | struct Fiz<const N: !>;
    |                     ^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
 
 error: `()` is forbidden as the type of a const generic parameter
   --> $DIR/complex-types.rs:20:19
@@ -50,7 +49,7 @@ LL | enum Goo<const N: ()> { A, B }
    |                   ^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `()` is forbidden as the type of a const generic parameter
   --> $DIR/complex-types.rs:23:20
@@ -59,7 +58,7 @@ LL | union Boo<const N: ()> { a: () }
    |                    ^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 7 previous errors
 
diff --git a/tests/ui/const-generics/nested-type.min.stderr b/tests/ui/const-generics/nested-type.min.stderr
index 257a9e31e14..ca5af5f969f 100644
--- a/tests/ui/const-generics/nested-type.min.stderr
+++ b/tests/ui/const-generics/nested-type.min.stderr
@@ -30,7 +30,7 @@ LL | | }]>;
    | |__^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/projection-as-arg-const.stderr b/tests/ui/const-generics/projection-as-arg-const.stderr
index 803ed9c9597..9f727231edf 100644
--- a/tests/ui/const-generics/projection-as-arg-const.stderr
+++ b/tests/ui/const-generics/projection-as-arg-const.stderr
@@ -5,7 +5,6 @@ LL | pub fn foo<const X: <i32 as Identity>::Identity>() {
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/raw-ptr-const-param-deref.min.stderr b/tests/ui/const-generics/raw-ptr-const-param-deref.min.stderr
index 04bc46cb4ab..1eb238255ab 100644
--- a/tests/ui/const-generics/raw-ptr-const-param-deref.min.stderr
+++ b/tests/ui/const-generics/raw-ptr-const-param-deref.min.stderr
@@ -3,12 +3,16 @@ error: using raw pointers as const generic parameters is forbidden
    |
 LL | struct Const<const P: *const u32>;
    |                       ^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
 
 error: using raw pointers as const generic parameters is forbidden
   --> $DIR/raw-ptr-const-param-deref.rs:11:15
    |
 LL | impl<const P: *const u32> Const<P> {
    |               ^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/raw-ptr-const-param.min.stderr b/tests/ui/const-generics/raw-ptr-const-param.min.stderr
index 310422aafcd..13fbc34e51a 100644
--- a/tests/ui/const-generics/raw-ptr-const-param.min.stderr
+++ b/tests/ui/const-generics/raw-ptr-const-param.min.stderr
@@ -3,6 +3,8 @@ error: using raw pointers as const generic parameters is forbidden
    |
 LL | struct Const<const P: *const u32>;
    |                       ^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/slice-const-param-mismatch.min.stderr b/tests/ui/const-generics/slice-const-param-mismatch.min.stderr
index fed802f6adc..3c086f59b27 100644
--- a/tests/ui/const-generics/slice-const-param-mismatch.min.stderr
+++ b/tests/ui/const-generics/slice-const-param-mismatch.min.stderr
@@ -5,7 +5,7 @@ LL | struct ConstString<const T: &'static str>;
    |                             ^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `&'static [u8]` is forbidden as the type of a const generic parameter
   --> $DIR/slice-const-param-mismatch.rs:9:28
@@ -14,7 +14,7 @@ LL | struct ConstBytes<const T: &'static [u8]>;
    |                            ^^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/std/const-generics-range.min.stderr b/tests/ui/const-generics/std/const-generics-range.min.stderr
index 53fca6e884a..d45f749246c 100644
--- a/tests/ui/const-generics/std/const-generics-range.min.stderr
+++ b/tests/ui/const-generics/std/const-generics-range.min.stderr
@@ -5,7 +5,7 @@ LL | struct _Range<const R: std::ops::Range<usize>>;
    |                        ^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `RangeFrom<usize>` is forbidden as the type of a const generic parameter
   --> $DIR/const-generics-range.rs:13:28
@@ -14,7 +14,7 @@ LL | struct _RangeFrom<const R: std::ops::RangeFrom<usize>>;
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `RangeFull` is forbidden as the type of a const generic parameter
   --> $DIR/const-generics-range.rs:18:28
@@ -23,7 +23,7 @@ LL | struct _RangeFull<const R: std::ops::RangeFull>;
    |                            ^^^^^^^^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `RangeInclusive<usize>` is forbidden as the type of a const generic parameter
   --> $DIR/const-generics-range.rs:24:33
@@ -32,7 +32,7 @@ LL | struct _RangeInclusive<const R: std::ops::RangeInclusive<usize>>;
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `RangeTo<usize>` is forbidden as the type of a const generic parameter
   --> $DIR/const-generics-range.rs:29:26
@@ -41,7 +41,7 @@ LL | struct _RangeTo<const R: std::ops::RangeTo<usize>>;
    |                          ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `RangeToInclusive<usize>` is forbidden as the type of a const generic parameter
   --> $DIR/const-generics-range.rs:34:35
@@ -50,7 +50,7 @@ LL | struct _RangeToInclusive<const R: std::ops::RangeToInclusive<usize>>;
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 6 previous errors
 
diff --git a/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr b/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr
index 039c4276c8b..f18e149464d 100644
--- a/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr
+++ b/tests/ui/const-generics/transmute-const-param-static-reference.min.stderr
@@ -5,7 +5,7 @@ LL | struct Const<const P: &'static ()>;
    |                       ^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to previous error
 
diff --git a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr
index b8fbb397979..6490592c1e1 100644
--- a/tests/ui/const-generics/type-dependent/issue-71348.min.stderr
+++ b/tests/ui/const-generics/type-dependent/issue-71348.min.stderr
@@ -5,7 +5,7 @@ LL | trait Get<'a, const N: &'static str> {
    |                        ^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `&'static str` is forbidden as the type of a const generic parameter
   --> $DIR/issue-71348.rs:18:25
@@ -14,7 +14,7 @@ LL |     fn ask<'a, const N: &'static str>(&'a self) -> &'a <Self as Get<N>>::Ta
    |                         ^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/const-generics/type-dependent/issue-71382.stderr b/tests/ui/const-generics/type-dependent/issue-71382.stderr
index ad522aead90..3f42feea562 100644
--- a/tests/ui/const-generics/type-dependent/issue-71382.stderr
+++ b/tests/ui/const-generics/type-dependent/issue-71382.stderr
@@ -3,6 +3,8 @@ error: using function pointers as const generic parameters is forbidden
    |
 LL |     fn test<const FN: fn() -> u8>(&self) -> u8 {
    |                       ^^^^^^^^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/consts/const_in_pattern/issue-65466.rs b/tests/ui/consts/const_in_pattern/issue-65466.rs
index 2b421f4c705..d45c32e170a 100644
--- a/tests/ui/consts/const_in_pattern/issue-65466.rs
+++ b/tests/ui/consts/const_in_pattern/issue-65466.rs
@@ -15,7 +15,8 @@ const C: &[O<B>] = &[O::None];
 fn main() {
     let x = O::None;
     match &[x][..] {
-        C => (),
+        C => (), //~WARN: the type must implement `PartialEq`
+        //~| previously accepted
         _ => (),
     }
 }
diff --git a/tests/ui/consts/const_in_pattern/issue-65466.stderr b/tests/ui/consts/const_in_pattern/issue-65466.stderr
new file mode 100644
index 00000000000..9c80cb3a849
--- /dev/null
+++ b/tests/ui/consts/const_in_pattern/issue-65466.stderr
@@ -0,0 +1,23 @@
+warning: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
+  --> $DIR/issue-65466.rs:18:9
+   |
+LL |         C => (),
+   |         ^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
+   = note: `#[warn(const_patterns_without_partial_eq)]` on by default
+
+warning: 1 warning emitted
+
+Future incompatibility report: Future breakage diagnostic:
+warning: to use a constant of type `&[O<B>]` in a pattern, the type must implement `PartialEq`
+  --> $DIR/issue-65466.rs:18:9
+   |
+LL |         C => (),
+   |         ^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
+   = note: `#[warn(const_patterns_without_partial_eq)]` on by default
+
diff --git a/tests/ui/did_you_mean/bad-assoc-expr.stderr b/tests/ui/did_you_mean/bad-assoc-expr.stderr
index c295cac9aa4..b83078e21b6 100644
--- a/tests/ui/did_you_mean/bad-assoc-expr.stderr
+++ b/tests/ui/did_you_mean/bad-assoc-expr.stderr
@@ -2,60 +2,104 @@ error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-expr.rs:3:5
    |
 LL |     [i32; 4]::clone(&a);
-   |     ^^^^^^^^^^^^^^^ help: try: `<[i32; 4]>::clone`
+   |     ^^^^^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |     <[i32; 4]>::clone(&a);
+   |     +        +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-expr.rs:6:5
    |
 LL |     [i32]::as_ref(&a);
-   |     ^^^^^^^^^^^^^ help: try: `<[i32]>::as_ref`
+   |     ^^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |     <[i32]>::as_ref(&a);
+   |     +     +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-expr.rs:9:5
    |
 LL |     (u8)::clone(&0);
-   |     ^^^^^^^^^^^ help: try: `<(u8)>::clone`
+   |     ^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |     <(u8)>::clone(&0);
+   |     +    +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-expr.rs:12:5
    |
 LL |     (u8, u8)::clone(&(0, 0));
-   |     ^^^^^^^^^^^^^^^ help: try: `<(u8, u8)>::clone`
+   |     ^^^^^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |     <(u8, u8)>::clone(&(0, 0));
+   |     +        +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-expr.rs:15:6
    |
 LL |     &(u8)::clone(&0);
-   |      ^^^^^^^^^^^ help: try: `<(u8)>::clone`
+   |      ^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |     &<(u8)>::clone(&0);
+   |      +    +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-expr.rs:18:10
    |
 LL |     10 + (u8)::clone(&0);
-   |          ^^^^^^^^^^^ help: try: `<(u8)>::clone`
+   |          ^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |     10 + <(u8)>::clone(&0);
+   |          +    +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-expr.rs:32:13
    |
 LL |     let _ = ty!()::clone(&0);
-   |             ^^^^^^^^^^^^ help: try: `<ty!()>::clone`
+   |             ^^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |     let _ = <ty!()>::clone(&0);
+   |             +     +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-expr.rs:34:5
    |
 LL |     ty!()::clone(&0);
-   |     ^^^^^^^^^^^^ help: try: `<ty!()>::clone`
+   |     ^^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |     <ty!()>::clone(&0);
+   |     +     +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-expr.rs:23:19
    |
 LL |     ($ty: ty) => ($ty::clone(&0))
-   |                   ^^^^^^^^^^ help: try: `<$ty>::clone`
+   |                   ^^^
 ...
 LL |     expr!(u8);
    |     --------- in this macro invocation
    |
    = note: this error originates in the macro `expr` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |     ($ty: ty) => (<$ty>::clone(&0))
+   |                   +   +
 
 error: aborting due to 9 previous errors
 
diff --git a/tests/ui/did_you_mean/bad-assoc-pat.stderr b/tests/ui/did_you_mean/bad-assoc-pat.stderr
index 19d173f1b42..8bdeb8ffdd0 100644
--- a/tests/ui/did_you_mean/bad-assoc-pat.stderr
+++ b/tests/ui/did_you_mean/bad-assoc-pat.stderr
@@ -2,42 +2,71 @@ error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-pat.rs:3:9
    |
 LL |         [u8]::AssocItem => {}
-   |         ^^^^^^^^^^^^^^^ help: try: `<[u8]>::AssocItem`
+   |         ^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |         <[u8]>::AssocItem => {}
+   |         +    +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-pat.rs:6:9
    |
 LL |         (u8, u8)::AssocItem => {}
-   |         ^^^^^^^^^^^^^^^^^^^ help: try: `<(u8, u8)>::AssocItem`
+   |         ^^^^^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |         <(u8, u8)>::AssocItem => {}
+   |         +        +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-pat.rs:9:9
    |
 LL |         _::AssocItem => {}
-   |         ^^^^^^^^^^^^ help: try: `<_>::AssocItem`
+   |         ^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |         <_>::AssocItem => {}
+   |         + +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-pat.rs:14:10
    |
 LL |         &(u8,)::AssocItem => {}
-   |          ^^^^^^^^^^^^^^^^ help: try: `<(u8,)>::AssocItem`
+   |          ^^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |         &<(u8,)>::AssocItem => {}
+   |          +     +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-pat.rs:32:9
    |
 LL |         ty!()::AssocItem => {}
-   |         ^^^^^^^^^^^^^^^^ help: try: `<ty!()>::AssocItem`
+   |         ^^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |         <ty!()>::AssocItem => {}
+   |         +     +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-pat.rs:21:19
    |
 LL |     ($ty: ty) => ($ty::AssocItem)
-   |                   ^^^^^^^^^^^^^^ help: try: `<$ty>::AssocItem`
+   |                   ^^^
 ...
 LL |         pat!(u8) => {}
    |         -------- in this macro invocation
    |
    = note: this error originates in the macro `pat` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |     ($ty: ty) => (<$ty>::AssocItem)
+   |                   +   +
 
 error[E0599]: no associated item named `AssocItem` found for slice `[u8]` in the current scope
   --> $DIR/bad-assoc-pat.rs:3:15
diff --git a/tests/ui/did_you_mean/bad-assoc-ty.stderr b/tests/ui/did_you_mean/bad-assoc-ty.stderr
index 55096e95df7..efa6bb66824 100644
--- a/tests/ui/did_you_mean/bad-assoc-ty.stderr
+++ b/tests/ui/did_you_mean/bad-assoc-ty.stderr
@@ -2,60 +2,104 @@ error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-ty.rs:1:10
    |
 LL | type A = [u8; 4]::AssocTy;
-   |          ^^^^^^^^^^^^^^^^ help: try: `<[u8; 4]>::AssocTy`
+   |          ^^^^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL | type A = <[u8; 4]>::AssocTy;
+   |          +       +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-ty.rs:5:10
    |
 LL | type B = [u8]::AssocTy;
-   |          ^^^^^^^^^^^^^ help: try: `<[u8]>::AssocTy`
+   |          ^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL | type B = <[u8]>::AssocTy;
+   |          +    +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-ty.rs:9:10
    |
 LL | type C = (u8)::AssocTy;
-   |          ^^^^^^^^^^^^^ help: try: `<(u8)>::AssocTy`
+   |          ^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL | type C = <(u8)>::AssocTy;
+   |          +    +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-ty.rs:13:10
    |
 LL | type D = (u8, u8)::AssocTy;
-   |          ^^^^^^^^^^^^^^^^^ help: try: `<(u8, u8)>::AssocTy`
+   |          ^^^^^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL | type D = <(u8, u8)>::AssocTy;
+   |          +        +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-ty.rs:17:10
    |
 LL | type E = _::AssocTy;
-   |          ^^^^^^^^^^ help: try: `<_>::AssocTy`
+   |          ^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL | type E = <_>::AssocTy;
+   |          + +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-ty.rs:21:19
    |
 LL | type F = &'static (u8)::AssocTy;
-   |                   ^^^^^^^^^^^^^ help: try: `<(u8)>::AssocTy`
+   |                   ^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL | type F = &'static <(u8)>::AssocTy;
+   |                   +    +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-ty.rs:27:10
    |
 LL | type G = dyn 'static + (Send)::AssocTy;
-   |          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `<dyn 'static + (Send)>::AssocTy`
+   |          ^^^^^^^^^^^^^^^^^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL | type G = <dyn 'static + (Send)>::AssocTy;
+   |          +                    +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-ty.rs:46:10
    |
 LL | type I = ty!()::AssocTy;
-   |          ^^^^^^^^^^^^^^ help: try: `<ty!()>::AssocTy`
+   |          ^^^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL | type I = <ty!()>::AssocTy;
+   |          +     +
 
 error: missing angle brackets in associated item path
   --> $DIR/bad-assoc-ty.rs:39:19
    |
 LL |     ($ty: ty) => ($ty::AssocTy);
-   |                   ^^^^^^^^^^^^ help: try: `<$ty>::AssocTy`
+   |                   ^^^
 ...
 LL | type J = ty!(u8);
    |          ------- in this macro invocation
    |
    = note: this error originates in the macro `ty` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |     ($ty: ty) => (<$ty>::AssocTy);
+   |                   +   +
 
 error[E0223]: ambiguous associated type
   --> $DIR/bad-assoc-ty.rs:1:10
diff --git a/tests/ui/error-codes/E0094.rs b/tests/ui/error-codes/E0094.rs
index a2ec932c124..97ebcff99dc 100644
--- a/tests/ui/error-codes/E0094.rs
+++ b/tests/ui/error-codes/E0094.rs
@@ -1,4 +1,4 @@
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 extern "rust-intrinsic" {
     #[rustc_safe_intrinsic]
diff --git a/tests/ui/error-codes/E0374.stderr b/tests/ui/error-codes/E0374.stderr
index 68e15e6f8fe..a7792043067 100644
--- a/tests/ui/error-codes/E0374.stderr
+++ b/tests/ui/error-codes/E0374.stderr
@@ -1,8 +1,10 @@
-error[E0374]: the trait `CoerceUnsized` may only be implemented for a coercion between structures with one field being coerced, none found
+error[E0374]: the trait `CoerceUnsized` may only be implemented for a coercion between structures
   --> $DIR/E0374.rs:8:1
    |
 LL | impl<T, U> CoerceUnsized<Foo<U>> for Foo<T>
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: expected a single field to be coerced, none found
 
 error: aborting due to previous error
 
diff --git a/tests/ui/error-codes/E0377.stderr b/tests/ui/error-codes/E0377.stderr
index bf7d8c8d39d..664e499ec23 100644
--- a/tests/ui/error-codes/E0377.stderr
+++ b/tests/ui/error-codes/E0377.stderr
@@ -1,8 +1,10 @@
-error[E0377]: the trait `CoerceUnsized` may only be implemented for a coercion between structures with the same definition; expected `Foo`, found `Bar`
+error[E0377]: the trait `CoerceUnsized` may only be implemented for a coercion between structures
   --> $DIR/E0377.rs:12:1
    |
 LL | impl<T, U> CoerceUnsized<Bar<U>> for Foo<T> where T: CoerceUnsized<U> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: expected coercion between the same definition; expected `Foo`, found `Bar`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/extern/extern-with-type-bounds.rs b/tests/ui/extern/extern-with-type-bounds.rs
index a72aa4171a1..99e9801fd40 100644
--- a/tests/ui/extern/extern-with-type-bounds.rs
+++ b/tests/ui/extern/extern-with-type-bounds.rs
@@ -1,4 +1,4 @@
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 extern "rust-intrinsic" {
     // Real example from libcore
diff --git a/tests/ui/feature-gates/feature-gate-adt_const_params.stderr b/tests/ui/feature-gates/feature-gate-adt_const_params.stderr
index d8f089a28b7..13b9b84f0be 100644
--- a/tests/ui/feature-gates/feature-gate-adt_const_params.stderr
+++ b/tests/ui/feature-gates/feature-gate-adt_const_params.stderr
@@ -5,7 +5,7 @@ LL | struct Foo<const NAME: &'static str>;
    |                        ^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to previous error
 
diff --git a/tests/ui/feature-gates/feature-gate-proc_macro_byte_character.rs b/tests/ui/feature-gates/feature-gate-proc_macro_byte_character.rs
new file mode 100644
index 00000000000..0648ce0ee20
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-proc_macro_byte_character.rs
@@ -0,0 +1,10 @@
+// force-host
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::Literal;
+
+fn test() {
+    Literal::byte_character(b'a'); //~ ERROR use of unstable library feature 'proc_macro_byte_character'
+}
diff --git a/tests/ui/feature-gates/feature-gate-proc_macro_byte_character.stderr b/tests/ui/feature-gates/feature-gate-proc_macro_byte_character.stderr
new file mode 100644
index 00000000000..00691538938
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-proc_macro_byte_character.stderr
@@ -0,0 +1,12 @@
+error[E0658]: use of unstable library feature 'proc_macro_byte_character'
+  --> $DIR/feature-gate-proc_macro_byte_character.rs:9:5
+   |
+LL |     Literal::byte_character(b'a');
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #115268 <https://github.com/rust-lang/rust/issues/115268> for more information
+   = help: add `#![feature(proc_macro_byte_character)]` to the crate attributes to enable
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/foreign/foreign-fn-linkname.rs b/tests/ui/foreign/foreign-fn-linkname.rs
index f6d820594f9..d1d6e703e3d 100644
--- a/tests/ui/foreign/foreign-fn-linkname.rs
+++ b/tests/ui/foreign/foreign-fn-linkname.rs
@@ -2,6 +2,9 @@
 // ignore-wasm32-bare no libc to test ffi with
 // ignore-sgx no libc
 
+// Ensure no false positive on "unused extern crate" lint
+#![deny(unused_extern_crates)]
+
 #![feature(rustc_private)]
 
 extern crate libc;
diff --git a/tests/ui/generator/addassign-yield.rs b/tests/ui/generator/addassign-yield.rs
index 7211367afee..66f22bf31fc 100644
--- a/tests/ui/generator/addassign-yield.rs
+++ b/tests/ui/generator/addassign-yield.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // run-pass
 // Regression test for broken MIR error (#61442)
 // Due to the two possible evaluation orders for
diff --git a/tests/ui/generator/auto-trait-regions.drop_tracking.stderr b/tests/ui/generator/auto-trait-regions.drop_tracking.stderr
deleted file mode 100644
index b2a5b92ed0f..00000000000
--- a/tests/ui/generator/auto-trait-regions.drop_tracking.stderr
+++ /dev/null
@@ -1,55 +0,0 @@
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/auto-trait-regions.rs:48:24
-   |
-LL |         let a = A(&mut true, &mut true, No);
-   |                        ^^^^                - temporary value is freed at the end of this statement
-   |                        |
-   |                        creates a temporary value which is freed while still in use
-...
-LL |         assert_foo(a);
-   |                    - borrow later used here
-   |
-help: consider using a `let` binding to create a longer lived value
-   |
-LL ~         let binding = true;
-LL ~         let a = A(&mut binding, &mut true, No);
-   |
-
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/auto-trait-regions.rs:48:35
-   |
-LL |         let a = A(&mut true, &mut true, No);
-   |                                   ^^^^     - temporary value is freed at the end of this statement
-   |                                   |
-   |                                   creates a temporary value which is freed while still in use
-...
-LL |         assert_foo(a);
-   |                    - borrow later used here
-   |
-help: consider using a `let` binding to create a longer lived value
-   |
-LL ~         let binding = true;
-LL ~         let a = A(&mut true, &mut binding, No);
-   |
-
-error: implementation of `Foo` is not general enough
-  --> $DIR/auto-trait-regions.rs:34:5
-   |
-LL |     assert_foo(gen);
-   |     ^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
-   |
-   = note: `&'0 OnlyFooIfStaticRef` must implement `Foo`, for any lifetime `'0`...
-   = note: ...but `Foo` is actually implemented for the type `&'static OnlyFooIfStaticRef`
-
-error: implementation of `Foo` is not general enough
-  --> $DIR/auto-trait-regions.rs:54:5
-   |
-LL |     assert_foo(gen);
-   |     ^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
-   |
-   = note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1`...
-   = note: ...but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2`
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr b/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr
deleted file mode 100644
index b2a5b92ed0f..00000000000
--- a/tests/ui/generator/auto-trait-regions.drop_tracking_mir.stderr
+++ /dev/null
@@ -1,55 +0,0 @@
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/auto-trait-regions.rs:48:24
-   |
-LL |         let a = A(&mut true, &mut true, No);
-   |                        ^^^^                - temporary value is freed at the end of this statement
-   |                        |
-   |                        creates a temporary value which is freed while still in use
-...
-LL |         assert_foo(a);
-   |                    - borrow later used here
-   |
-help: consider using a `let` binding to create a longer lived value
-   |
-LL ~         let binding = true;
-LL ~         let a = A(&mut binding, &mut true, No);
-   |
-
-error[E0716]: temporary value dropped while borrowed
-  --> $DIR/auto-trait-regions.rs:48:35
-   |
-LL |         let a = A(&mut true, &mut true, No);
-   |                                   ^^^^     - temporary value is freed at the end of this statement
-   |                                   |
-   |                                   creates a temporary value which is freed while still in use
-...
-LL |         assert_foo(a);
-   |                    - borrow later used here
-   |
-help: consider using a `let` binding to create a longer lived value
-   |
-LL ~         let binding = true;
-LL ~         let a = A(&mut true, &mut binding, No);
-   |
-
-error: implementation of `Foo` is not general enough
-  --> $DIR/auto-trait-regions.rs:34:5
-   |
-LL |     assert_foo(gen);
-   |     ^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
-   |
-   = note: `&'0 OnlyFooIfStaticRef` must implement `Foo`, for any lifetime `'0`...
-   = note: ...but `Foo` is actually implemented for the type `&'static OnlyFooIfStaticRef`
-
-error: implementation of `Foo` is not general enough
-  --> $DIR/auto-trait-regions.rs:54:5
-   |
-LL |     assert_foo(gen);
-   |     ^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
-   |
-   = note: `Foo` would have to be implemented for the type `A<'0, '1>`, for any two lifetimes `'0` and `'1`...
-   = note: ...but `Foo` is actually implemented for the type `A<'_, '2>`, for some specific lifetime `'2`
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/generator/auto-trait-regions.rs b/tests/ui/generator/auto-trait-regions.rs
index 350f3cc34ce..aa4218e13a4 100644
--- a/tests/ui/generator/auto-trait-regions.rs
+++ b/tests/ui/generator/auto-trait-regions.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 #![feature(generators)]
 #![feature(auto_traits)]
 #![feature(negative_impls)]
diff --git a/tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr b/tests/ui/generator/auto-trait-regions.stderr
index b2a5b92ed0f..a9a0bde2ba0 100644
--- a/tests/ui/generator/auto-trait-regions.no_drop_tracking.stderr
+++ b/tests/ui/generator/auto-trait-regions.stderr
@@ -1,5 +1,5 @@
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/auto-trait-regions.rs:48:24
+  --> $DIR/auto-trait-regions.rs:45:24
    |
 LL |         let a = A(&mut true, &mut true, No);
    |                        ^^^^                - temporary value is freed at the end of this statement
@@ -16,7 +16,7 @@ LL ~         let a = A(&mut binding, &mut true, No);
    |
 
 error[E0716]: temporary value dropped while borrowed
-  --> $DIR/auto-trait-regions.rs:48:35
+  --> $DIR/auto-trait-regions.rs:45:35
    |
 LL |         let a = A(&mut true, &mut true, No);
    |                                   ^^^^     - temporary value is freed at the end of this statement
@@ -33,7 +33,7 @@ LL ~         let a = A(&mut true, &mut binding, No);
    |
 
 error: implementation of `Foo` is not general enough
-  --> $DIR/auto-trait-regions.rs:34:5
+  --> $DIR/auto-trait-regions.rs:31:5
    |
 LL |     assert_foo(gen);
    |     ^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
@@ -42,7 +42,7 @@ LL |     assert_foo(gen);
    = note: ...but `Foo` is actually implemented for the type `&'static OnlyFooIfStaticRef`
 
 error: implementation of `Foo` is not general enough
-  --> $DIR/auto-trait-regions.rs:54:5
+  --> $DIR/auto-trait-regions.rs:51:5
    |
 LL |     assert_foo(gen);
    |     ^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
diff --git a/tests/ui/generator/borrowing.drop_tracking.stderr b/tests/ui/generator/borrowing.drop_tracking.stderr
deleted file mode 100644
index 96e3c327f8b..00000000000
--- a/tests/ui/generator/borrowing.drop_tracking.stderr
+++ /dev/null
@@ -1,31 +0,0 @@
-error[E0597]: `a` does not live long enough
-  --> $DIR/borrowing.rs:13:33
-   |
-LL |     let _b = {
-   |         -- borrow later stored here
-LL |         let a = 3;
-LL |         Pin::new(&mut || yield &a).resume(())
-   |                       --        ^ borrowed value does not live long enough
-   |                       |
-   |                       value captured here by generator
-LL |
-LL |     };
-   |     - `a` dropped here while still borrowed
-
-error[E0597]: `a` does not live long enough
-  --> $DIR/borrowing.rs:20:20
-   |
-LL |     let _b = {
-   |         -- borrow later stored here
-LL |         let a = 3;
-LL |         || {
-   |         -- value captured here by generator
-LL |             yield &a
-   |                    ^ borrowed value does not live long enough
-...
-LL |     };
-   |     - `a` dropped here while still borrowed
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/generator/borrowing.no_drop_tracking.stderr b/tests/ui/generator/borrowing.no_drop_tracking.stderr
deleted file mode 100644
index 96e3c327f8b..00000000000
--- a/tests/ui/generator/borrowing.no_drop_tracking.stderr
+++ /dev/null
@@ -1,31 +0,0 @@
-error[E0597]: `a` does not live long enough
-  --> $DIR/borrowing.rs:13:33
-   |
-LL |     let _b = {
-   |         -- borrow later stored here
-LL |         let a = 3;
-LL |         Pin::new(&mut || yield &a).resume(())
-   |                       --        ^ borrowed value does not live long enough
-   |                       |
-   |                       value captured here by generator
-LL |
-LL |     };
-   |     - `a` dropped here while still borrowed
-
-error[E0597]: `a` does not live long enough
-  --> $DIR/borrowing.rs:20:20
-   |
-LL |     let _b = {
-   |         -- borrow later stored here
-LL |         let a = 3;
-LL |         || {
-   |         -- value captured here by generator
-LL |             yield &a
-   |                    ^ borrowed value does not live long enough
-...
-LL |     };
-   |     - `a` dropped here while still borrowed
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0597`.
diff --git a/tests/ui/generator/borrowing.rs b/tests/ui/generator/borrowing.rs
index 29f39437f8f..d36592583cd 100644
--- a/tests/ui/generator/borrowing.rs
+++ b/tests/ui/generator/borrowing.rs
@@ -1,7 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-
 #![feature(generators, generator_trait)]
 
 use std::ops::Generator;
diff --git a/tests/ui/generator/borrowing.drop_tracking_mir.stderr b/tests/ui/generator/borrowing.stderr
index 8fbad276db4..03a69fe3623 100644
--- a/tests/ui/generator/borrowing.drop_tracking_mir.stderr
+++ b/tests/ui/generator/borrowing.stderr
@@ -1,5 +1,5 @@
 error[E0597]: `a` does not live long enough
-  --> $DIR/borrowing.rs:13:33
+  --> $DIR/borrowing.rs:9:33
    |
 LL |         Pin::new(&mut || yield &a).resume(())
    |                       ----------^
@@ -21,7 +21,7 @@ LL |         let x = Pin::new(&mut || yield &a).resume(()); x
    |         +++++++                                      +++
 
 error[E0597]: `a` does not live long enough
-  --> $DIR/borrowing.rs:20:20
+  --> $DIR/borrowing.rs:16:20
    |
 LL |     let _b = {
    |         -- borrow later stored here
diff --git a/tests/ui/generator/clone-impl.stderr b/tests/ui/generator/clone-impl.stderr
index edd3eb7e3da..870216398b1 100644
--- a/tests/ui/generator/clone-impl.stderr
+++ b/tests/ui/generator/clone-impl.stderr
@@ -1,11 +1,11 @@
 error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{generator@$DIR/clone-impl.rs:36:23: 36:30}`
-  --> $DIR/clone-impl.rs:42:16
+  --> $DIR/clone-impl.rs:42:5
    |
 LL |     let gen_clone_0 = move || {
    |                       ------- within this `{generator@$DIR/clone-impl.rs:36:23: 36:30}`
 ...
 LL |     check_copy(&gen_clone_0);
-   |                ^^^^^^^^^^^^ within `{generator@$DIR/clone-impl.rs:36:23: 36:30}`, the trait `Copy` is not implemented for `Vec<u32>`
+   |     ^^^^^^^^^^ within `{generator@$DIR/clone-impl.rs:36:23: 36:30}`, the trait `Copy` is not implemented for `Vec<u32>`
    |
 note: captured value does not implement `Copy`
   --> $DIR/clone-impl.rs:40:14
@@ -19,13 +19,13 @@ LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
 error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{generator@$DIR/clone-impl.rs:36:23: 36:30}`
-  --> $DIR/clone-impl.rs:42:16
+  --> $DIR/clone-impl.rs:42:5
    |
 LL |     let gen_clone_0 = move || {
    |                       ------- within this `{generator@$DIR/clone-impl.rs:36:23: 36:30}`
 ...
 LL |     check_copy(&gen_clone_0);
-   |                ^^^^^^^^^^^^ within `{generator@$DIR/clone-impl.rs:36:23: 36:30}`, the trait `Copy` is not implemented for `Vec<char>`
+   |     ^^^^^^^^^^ within `{generator@$DIR/clone-impl.rs:36:23: 36:30}`, the trait `Copy` is not implemented for `Vec<char>`
    |
 note: generator does not implement `Copy` as this value is used across a yield
   --> $DIR/clone-impl.rs:38:9
@@ -34,9 +34,6 @@ LL |         let v = vec!['a'];
    |             - has type `Vec<char>` which does not implement `Copy`
 LL |         yield;
    |         ^^^^^ yield occurs here, with `v` maybe used later
-...
-LL |     };
-   |     - `v` is later dropped here
 note: required by a bound in `check_copy`
   --> $DIR/clone-impl.rs:72:18
    |
@@ -44,13 +41,13 @@ LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
 error[E0277]: the trait bound `Vec<u32>: Copy` is not satisfied in `{generator@$DIR/clone-impl.rs:46:23: 46:30}`
-  --> $DIR/clone-impl.rs:58:16
+  --> $DIR/clone-impl.rs:58:5
    |
 LL |     let gen_clone_1 = move || {
    |                       ------- within this `{generator@$DIR/clone-impl.rs:46:23: 46:30}`
 ...
 LL |     check_copy(&gen_clone_1);
-   |                ^^^^^^^^^^^^ within `{generator@$DIR/clone-impl.rs:46:23: 46:30}`, the trait `Copy` is not implemented for `Vec<u32>`
+   |     ^^^^^^^^^^ within `{generator@$DIR/clone-impl.rs:46:23: 46:30}`, the trait `Copy` is not implemented for `Vec<u32>`
    |
 note: captured value does not implement `Copy`
   --> $DIR/clone-impl.rs:56:14
@@ -64,13 +61,13 @@ LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
 error[E0277]: the trait bound `Vec<char>: Copy` is not satisfied in `{generator@$DIR/clone-impl.rs:46:23: 46:30}`
-  --> $DIR/clone-impl.rs:58:16
+  --> $DIR/clone-impl.rs:58:5
    |
 LL |     let gen_clone_1 = move || {
    |                       ------- within this `{generator@$DIR/clone-impl.rs:46:23: 46:30}`
 ...
 LL |     check_copy(&gen_clone_1);
-   |                ^^^^^^^^^^^^ within `{generator@$DIR/clone-impl.rs:46:23: 46:30}`, the trait `Copy` is not implemented for `Vec<char>`
+   |     ^^^^^^^^^^ within `{generator@$DIR/clone-impl.rs:46:23: 46:30}`, the trait `Copy` is not implemented for `Vec<char>`
    |
 note: generator does not implement `Copy` as this value is used across a yield
   --> $DIR/clone-impl.rs:52:9
@@ -80,9 +77,6 @@ LL |         let v = vec!['a'];
 ...
 LL |         yield;
    |         ^^^^^ yield occurs here, with `v` maybe used later
-...
-LL |     };
-   |     - `v` is later dropped here
 note: required by a bound in `check_copy`
   --> $DIR/clone-impl.rs:72:18
    |
@@ -90,13 +84,13 @@ LL | fn check_copy<T: Copy>(_x: &T) {}
    |                  ^^^^ required by this bound in `check_copy`
 
 error[E0277]: the trait bound `NonClone: Copy` is not satisfied in `{generator@$DIR/clone-impl.rs:62:25: 62:32}`
-  --> $DIR/clone-impl.rs:66:16
+  --> $DIR/clone-impl.rs:66:5
    |
 LL |     let gen_non_clone = move || {
    |                         ------- within this `{generator@$DIR/clone-impl.rs:62:25: 62:32}`
 ...
 LL |     check_copy(&gen_non_clone);
-   |                ^^^^^^^^^^^^^^ within `{generator@$DIR/clone-impl.rs:62:25: 62:32}`, the trait `Copy` is not implemented for `NonClone`
+   |     ^^^^^^^^^^ within `{generator@$DIR/clone-impl.rs:62:25: 62:32}`, the trait `Copy` is not implemented for `NonClone`
    |
 note: captured value does not implement `Copy`
   --> $DIR/clone-impl.rs:64:14
@@ -115,13 +109,13 @@ LL | struct NonClone;
    |
 
 error[E0277]: the trait bound `NonClone: Clone` is not satisfied in `{generator@$DIR/clone-impl.rs:62:25: 62:32}`
-  --> $DIR/clone-impl.rs:68:17
+  --> $DIR/clone-impl.rs:68:5
    |
 LL |     let gen_non_clone = move || {
    |                         ------- within this `{generator@$DIR/clone-impl.rs:62:25: 62:32}`
 ...
 LL |     check_clone(&gen_non_clone);
-   |                 ^^^^^^^^^^^^^^ within `{generator@$DIR/clone-impl.rs:62:25: 62:32}`, the trait `Clone` is not implemented for `NonClone`
+   |     ^^^^^^^^^^^ within `{generator@$DIR/clone-impl.rs:62:25: 62:32}`, the trait `Clone` is not implemented for `NonClone`
    |
 note: captured value does not implement `Clone`
   --> $DIR/clone-impl.rs:64:14
diff --git a/tests/ui/generator/derived-drop-parent-expr.rs b/tests/ui/generator/derived-drop-parent-expr.rs
index 4bd34346a18..e381924517d 100644
--- a/tests/ui/generator/derived-drop-parent-expr.rs
+++ b/tests/ui/generator/derived-drop-parent-expr.rs
@@ -1,5 +1,4 @@
 // build-pass
-// compile-flags:-Zdrop-tracking
 
 //! Like drop-tracking-parent-expression, but also tests that this doesn't ICE when building MIR
 #![feature(generators)]
diff --git a/tests/ui/generator/drop-control-flow.rs b/tests/ui/generator/drop-control-flow.rs
index c6efda9541f..1c25c06ba4c 100644
--- a/tests/ui/generator/drop-control-flow.rs
+++ b/tests/ui/generator/drop-control-flow.rs
@@ -1,5 +1,4 @@
 // build-pass
-// compile-flags: -Zdrop-tracking
 
 // A test to ensure generators capture values that were conditionally dropped,
 // and also that values that are dropped along all paths to a yield do not get
diff --git a/tests/ui/generator/drop-track-addassign-yield.rs b/tests/ui/generator/drop-track-addassign-yield.rs
index 71cfb170bf6..1e64f1d2ec7 100644
--- a/tests/ui/generator/drop-track-addassign-yield.rs
+++ b/tests/ui/generator/drop-track-addassign-yield.rs
@@ -1,5 +1,4 @@
 // run-pass
-// compile-flags: -Zdrop-tracking
 
 // Based on addassign-yield.rs, but with drop tracking enabled. Originally we did not implement
 // the fake_read callback on ExprUseVisitor which caused this case to break.
diff --git a/tests/ui/generator/drop-tracking-error-body.rs b/tests/ui/generator/drop-tracking-error-body.rs
deleted file mode 100644
index f99d9ab6bf8..00000000000
--- a/tests/ui/generator/drop-tracking-error-body.rs
+++ /dev/null
@@ -1,18 +0,0 @@
-// compile-flags: -Zdrop-tracking-mir --edition=2021
-
-#![feature(generators)]
-
-pub async fn async_bad_body() {
-    match true {} //~ ERROR non-exhaustive patterns: type `bool` is non-empty
-}
-
-pub fn generator_bad_body() {
-    || {
-        // 'non-exhaustive pattern' only seems to be reported once, so this annotation doesn't work
-        // keep the function around so we can make sure it doesn't ICE
-        match true {}; // ERROR non-exhaustive patterns: type `bool` is non-empty
-        yield ();
-    };
-}
-
-fn main() {}
diff --git a/tests/ui/generator/drop-tracking-error-body.stderr b/tests/ui/generator/drop-tracking-error-body.stderr
deleted file mode 100644
index 28a6892336f..00000000000
--- a/tests/ui/generator/drop-tracking-error-body.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0004]: non-exhaustive patterns: type `bool` is non-empty
-  --> $DIR/drop-tracking-error-body.rs:6:11
-   |
-LL |     match true {}
-   |           ^^^^
-   |
-   = note: the matched value is of type `bool`
-help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
-   |
-LL ~     match true {
-LL +         _ => todo!(),
-LL ~     }
-   |
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/generator/drop-tracking-parent-expression.drop_tracking.stderr b/tests/ui/generator/drop-tracking-parent-expression.drop_tracking.stderr
deleted file mode 100644
index 190e60d5bfc..00000000000
--- a/tests/ui/generator/drop-tracking-parent-expression.drop_tracking.stderr
+++ /dev/null
@@ -1,128 +0,0 @@
-error: generator cannot be sent between threads safely
-  --> $DIR/drop-tracking-parent-expression.rs:27:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `derived_drop::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/drop-tracking-parent-expression.rs:25:22
-   |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `derived_drop::Client` which is not `Send`
-...
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/drop-tracking-parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/drop-tracking-parent-expression.rs:27:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `significant_drop::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/drop-tracking-parent-expression.rs:25:22
-   |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `significant_drop::Client` which is not `Send`
-...
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/drop-tracking-parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/drop-tracking-parent-expression.rs:27:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `insignificant_dtor::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/drop-tracking-parent-expression.rs:25:22
-   |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `insignificant_dtor::Client` which is not `Send`
-...
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/drop-tracking-parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 3 previous errors
-
diff --git a/tests/ui/generator/drop-tracking-parent-expression.no_drop_tracking.stderr b/tests/ui/generator/drop-tracking-parent-expression.no_drop_tracking.stderr
deleted file mode 100644
index 2d141b6b49f..00000000000
--- a/tests/ui/generator/drop-tracking-parent-expression.no_drop_tracking.stderr
+++ /dev/null
@@ -1,334 +0,0 @@
-error: generator cannot be sent between threads safely
-  --> $DIR/drop-tracking-parent-expression.rs:27:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `copy::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/drop-tracking-parent-expression.rs:25:22
-   |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `copy::Client` which is not `Send`
-...
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/drop-tracking-parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/drop-tracking-parent-expression.rs:40:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:37:21: 37:28}`, the trait `Send` is not implemented for `copy::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/drop-tracking-parent-expression.rs:38:22
-   |
-LL |               let g = move || match drop($name::Client::default()) {
-   |                                          ------------------------ has type `copy::Client` which is not `Send`
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/drop-tracking-parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/drop-tracking-parent-expression.rs:27:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `derived_drop::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/drop-tracking-parent-expression.rs:25:22
-   |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `derived_drop::Client` which is not `Send`
-...
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/drop-tracking-parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/drop-tracking-parent-expression.rs:40:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:37:21: 37:28}`, the trait `Send` is not implemented for `derived_drop::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/drop-tracking-parent-expression.rs:38:22
-   |
-LL |               let g = move || match drop($name::Client::default()) {
-   |                                          ------------------------ has type `derived_drop::Client` which is not `Send`
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/drop-tracking-parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/drop-tracking-parent-expression.rs:27:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `significant_drop::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/drop-tracking-parent-expression.rs:25:22
-   |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `significant_drop::Client` which is not `Send`
-...
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/drop-tracking-parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/drop-tracking-parent-expression.rs:40:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:37:21: 37:28}`, the trait `Send` is not implemented for `significant_drop::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/drop-tracking-parent-expression.rs:38:22
-   |
-LL |               let g = move || match drop($name::Client::default()) {
-   |                                          ------------------------ has type `significant_drop::Client` which is not `Send`
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/drop-tracking-parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/drop-tracking-parent-expression.rs:27:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `insignificant_dtor::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/drop-tracking-parent-expression.rs:25:22
-   |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `insignificant_dtor::Client` which is not `Send`
-...
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/drop-tracking-parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/drop-tracking-parent-expression.rs:40:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:37:21: 37:28}`, the trait `Send` is not implemented for `insignificant_dtor::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/drop-tracking-parent-expression.rs:38:22
-   |
-LL |               let g = move || match drop($name::Client::default()) {
-   |                                          ------------------------ has type `insignificant_dtor::Client` which is not `Send`
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/drop-tracking-parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 8 previous errors
-
diff --git a/tests/ui/generator/drop-tracking-parent-expression.rs b/tests/ui/generator/drop-tracking-parent-expression.rs
index ed9ac6d11ad..198b14528aa 100644
--- a/tests/ui/generator/drop-tracking-parent-expression.rs
+++ b/tests/ui/generator/drop-tracking-parent-expression.rs
@@ -1,7 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-
 #![feature(generators, negative_impls, rustc_attrs)]
 
 macro_rules! type_combinations {
@@ -21,14 +17,13 @@ macro_rules! type_combinations {
             let g = move || match drop($name::Client { ..$name::Client::default() }) {
             //~^ `significant_drop::Client` which is not `Send`
             //~| `insignificant_dtor::Client` which is not `Send`
-            //[no_drop_tracking,drop_tracking]~| `derived_drop::Client` which is not `Send`
+            //~| `derived_drop::Client` which is not `Send`
                 _ => yield,
             };
             assert_send(g);
             //~^ ERROR cannot be sent between threads
             //~| ERROR cannot be sent between threads
             //~| ERROR cannot be sent between threads
-            //[no_drop_tracking]~| ERROR cannot be sent between threads
         }
 
         // Simple owned value. This works because the Client is considered moved into `drop`,
@@ -38,10 +33,6 @@ macro_rules! type_combinations {
                 _ => yield,
             };
             assert_send(g);
-            //[no_drop_tracking]~^ ERROR cannot be sent between threads
-            //[no_drop_tracking]~| ERROR cannot be sent between threads
-            //[no_drop_tracking]~| ERROR cannot be sent between threads
-            //[no_drop_tracking]~| ERROR cannot be sent between threads
         }
     )* }
 }
diff --git a/tests/ui/generator/drop-tracking-parent-expression.drop_tracking_mir.stderr b/tests/ui/generator/drop-tracking-parent-expression.stderr
index 25553e6bb60..e85bb1347a7 100644
--- a/tests/ui/generator/drop-tracking-parent-expression.drop_tracking_mir.stderr
+++ b/tests/ui/generator/drop-tracking-parent-expression.stderr
@@ -1,5 +1,5 @@
 error: generator cannot be sent between threads safely
-  --> $DIR/drop-tracking-parent-expression.rs:27:13
+  --> $DIR/drop-tracking-parent-expression.rs:23:13
    |
 LL |               assert_send(g);
    |               ^^^^^^^^^^^ generator is not `Send`
@@ -13,9 +13,9 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `derived_drop::Client`
+   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `derived_drop::Client`
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/drop-tracking-parent-expression.rs:25:22
+  --> $DIR/drop-tracking-parent-expression.rs:21:22
    |
 LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
    |                                                            ------------------------ has type `derived_drop::Client` which is not `Send`
@@ -32,14 +32,14 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
 note: required by a bound in `assert_send`
-  --> $DIR/drop-tracking-parent-expression.rs:49:19
+  --> $DIR/drop-tracking-parent-expression.rs:40:19
    |
 LL | fn assert_send<T: Send>(_thing: T) {}
    |                   ^^^^ required by this bound in `assert_send`
    = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: generator cannot be sent between threads safely
-  --> $DIR/drop-tracking-parent-expression.rs:27:13
+  --> $DIR/drop-tracking-parent-expression.rs:23:13
    |
 LL |               assert_send(g);
    |               ^^^^^^^^^^^ generator is not `Send`
@@ -53,9 +53,9 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `significant_drop::Client`
+   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `significant_drop::Client`
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/drop-tracking-parent-expression.rs:25:22
+  --> $DIR/drop-tracking-parent-expression.rs:21:22
    |
 LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
    |                                                            ------------------------ has type `significant_drop::Client` which is not `Send`
@@ -72,14 +72,14 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
 note: required by a bound in `assert_send`
-  --> $DIR/drop-tracking-parent-expression.rs:49:19
+  --> $DIR/drop-tracking-parent-expression.rs:40:19
    |
 LL | fn assert_send<T: Send>(_thing: T) {}
    |                   ^^^^ required by this bound in `assert_send`
    = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: generator cannot be sent between threads safely
-  --> $DIR/drop-tracking-parent-expression.rs:27:13
+  --> $DIR/drop-tracking-parent-expression.rs:23:13
    |
 LL |               assert_send(g);
    |               ^^^^^^^^^^^ generator is not `Send`
@@ -93,9 +93,9 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `insignificant_dtor::Client`
+   = help: within `{generator@$DIR/drop-tracking-parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `insignificant_dtor::Client`
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/drop-tracking-parent-expression.rs:25:22
+  --> $DIR/drop-tracking-parent-expression.rs:21:22
    |
 LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
    |                                                            ------------------------ has type `insignificant_dtor::Client` which is not `Send`
@@ -112,7 +112,7 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
 note: required by a bound in `assert_send`
-  --> $DIR/drop-tracking-parent-expression.rs:49:19
+  --> $DIR/drop-tracking-parent-expression.rs:40:19
    |
 LL | fn assert_send<T: Send>(_thing: T) {}
    |                   ^^^^ required by this bound in `assert_send`
diff --git a/tests/ui/generator/drop-tracking-yielding-in-match-guards.rs b/tests/ui/generator/drop-tracking-yielding-in-match-guards.rs
index cbc291701cb..92e0136d51b 100644
--- a/tests/ui/generator/drop-tracking-yielding-in-match-guards.rs
+++ b/tests/ui/generator/drop-tracking-yielding-in-match-guards.rs
@@ -1,8 +1,5 @@
 // build-pass
 // edition:2018
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 
 #![feature(generators)]
 
diff --git a/tests/ui/generator/drop-yield-twice.stderr b/tests/ui/generator/drop-yield-twice.stderr
index 6a28e463189..39a906f0bf4 100644
--- a/tests/ui/generator/drop-yield-twice.stderr
+++ b/tests/ui/generator/drop-yield-twice.stderr
@@ -1,14 +1,8 @@
 error: generator cannot be sent between threads safely
-  --> $DIR/drop-yield-twice.rs:7:17
+  --> $DIR/drop-yield-twice.rs:7:5
    |
-LL |       assert_send(|| {
-   |  _________________^
-LL | |         let guard = Foo(42);
-LL | |         yield;
-LL | |         drop(guard);
-LL | |         yield;
-LL | |     })
-   | |_____^ generator is not `Send`
+LL |     assert_send(|| {
+   |     ^^^^^^^^^^^ generator is not `Send`
    |
    = help: within `{generator@$DIR/drop-yield-twice.rs:7:17: 7:19}`, the trait `Send` is not implemented for `Foo`
 note: generator is not `Send` as this value is used across a yield
@@ -18,9 +12,6 @@ LL |         let guard = Foo(42);
    |             ----- has type `Foo` which is not `Send`
 LL |         yield;
    |         ^^^^^ yield occurs here, with `guard` maybe used later
-...
-LL |     })
-   |     - `guard` is later dropped here
 note: required by a bound in `assert_send`
   --> $DIR/drop-yield-twice.rs:15:19
    |
diff --git a/tests/ui/generator/issue-102645.rs b/tests/ui/generator/issue-102645.rs
index 35acd5cd727..677cc69d3f2 100644
--- a/tests/ui/generator/issue-102645.rs
+++ b/tests/ui/generator/issue-102645.rs
@@ -1,5 +1,3 @@
-// compile-flags: -Zdrop-tracking
-
 #![feature(generators, generator_trait)]
 
 use std::ops::Generator;
diff --git a/tests/ui/generator/issue-102645.stderr b/tests/ui/generator/issue-102645.stderr
index 3f9a4c2f3c5..5d28dfc45b3 100644
--- a/tests/ui/generator/issue-102645.stderr
+++ b/tests/ui/generator/issue-102645.stderr
@@ -1,5 +1,5 @@
 error[E0061]: this method takes 1 argument but 0 arguments were supplied
-  --> $DIR/issue-102645.rs:16:22
+  --> $DIR/issue-102645.rs:14:22
    |
 LL |     Pin::new(&mut b).resume();
    |                      ^^^^^^-- an argument of type `()` is missing
diff --git a/tests/ui/generator/issue-105084.rs b/tests/ui/generator/issue-105084.rs
index ff9357b76a0..50b5da6e6ad 100644
--- a/tests/ui/generator/issue-105084.rs
+++ b/tests/ui/generator/issue-105084.rs
@@ -1,11 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-// [no_drop_tracking] known-bug: #105084
-// [no_drop_tracking] check-pass
-// [drop_tracking] known-bug: #105084
-// [drop_tracking] check-pass
-
 #![feature(generators)]
 #![feature(generator_clone)]
 #![feature(generator_trait)]
@@ -37,13 +29,13 @@ fn main() {
     // As it is not taken into account for trait computation,
     // the generator is `Copy`.
     let mut h = copy(g);
-    //[drop_tracking_mir]~^ ERROR the trait bound `Box<(i32, ())>: Copy` is not satisfied in
+    //~^ ERROR the trait bound `Box<(i32, ())>: Copy` is not satisfied in
 
     // We now have 2 boxes with the same backing allocation:
     // one inside `g` and one inside `h`.
     // Proceed and drop `t` in `g`.
     Pin::new(&mut g).resume(());
-    //[drop_tracking_mir]~^ ERROR borrow of moved value: `g`
+    //~^ ERROR borrow of moved value: `g`
 
     // Proceed and drop `t` in `h` -> double free!
     Pin::new(&mut h).resume(());
diff --git a/tests/ui/generator/issue-105084.drop_tracking_mir.stderr b/tests/ui/generator/issue-105084.stderr
index c0ee3237ad1..573c31f1134 100644
--- a/tests/ui/generator/issue-105084.drop_tracking_mir.stderr
+++ b/tests/ui/generator/issue-105084.stderr
@@ -1,8 +1,8 @@
 error[E0382]: borrow of moved value: `g`
-  --> $DIR/issue-105084.rs:45:14
+  --> $DIR/issue-105084.rs:37:14
    |
 LL |     let mut g = || {
-   |         ----- move occurs because `g` has type `{generator@$DIR/issue-105084.rs:22:17: 22:19}`, which does not implement the `Copy` trait
+   |         ----- move occurs because `g` has type `{generator@$DIR/issue-105084.rs:14:17: 14:19}`, which does not implement the `Copy` trait
 ...
 LL |     let mut h = copy(g);
    |                      - value moved here
@@ -11,7 +11,7 @@ LL |     Pin::new(&mut g).resume(());
    |              ^^^^^^ value borrowed here after move
    |
 note: consider changing this parameter type in function `copy` to borrow instead if owning the value isn't necessary
-  --> $DIR/issue-105084.rs:17:21
+  --> $DIR/issue-105084.rs:9:21
    |
 LL | fn copy<T: Copy>(x: T) -> T {
    |    ----             ^ this parameter takes ownership of the value
@@ -22,17 +22,17 @@ help: consider cloning the value if the performance cost is acceptable
 LL |     let mut h = copy(g.clone());
    |                       ++++++++
 
-error[E0277]: the trait bound `Box<(i32, ())>: Copy` is not satisfied in `{generator@$DIR/issue-105084.rs:22:17: 22:19}`
-  --> $DIR/issue-105084.rs:39:17
+error[E0277]: the trait bound `Box<(i32, ())>: Copy` is not satisfied in `{generator@$DIR/issue-105084.rs:14:17: 14:19}`
+  --> $DIR/issue-105084.rs:31:17
    |
 LL |     let mut g = || {
-   |                 -- within this `{generator@$DIR/issue-105084.rs:22:17: 22:19}`
+   |                 -- within this `{generator@$DIR/issue-105084.rs:14:17: 14:19}`
 ...
 LL |     let mut h = copy(g);
-   |                 ^^^^ within `{generator@$DIR/issue-105084.rs:22:17: 22:19}`, the trait `Copy` is not implemented for `Box<(i32, ())>`
+   |                 ^^^^ within `{generator@$DIR/issue-105084.rs:14:17: 14:19}`, the trait `Copy` is not implemented for `Box<(i32, ())>`
    |
 note: generator does not implement `Copy` as this value is used across a yield
-  --> $DIR/issue-105084.rs:29:22
+  --> $DIR/issue-105084.rs:21:22
    |
 LL |         Box::new((5, yield));
    |         -------------^^^^^--
@@ -40,7 +40,7 @@ LL |         Box::new((5, yield));
    |         |            yield occurs here, with `Box::new((5, yield))` maybe used later
    |         has type `Box<(i32, ())>` which does not implement `Copy`
 note: required by a bound in `copy`
-  --> $DIR/issue-105084.rs:17:12
+  --> $DIR/issue-105084.rs:9:12
    |
 LL | fn copy<T: Copy>(x: T) -> T {
    |            ^^^^ required by this bound in `copy`
diff --git a/tests/ui/generator/issue-110929-generator-conflict-error-ice.rs b/tests/ui/generator/issue-110929-generator-conflict-error-ice.rs
index 9408acc15f9..a45479e5300 100644
--- a/tests/ui/generator/issue-110929-generator-conflict-error-ice.rs
+++ b/tests/ui/generator/issue-110929-generator-conflict-error-ice.rs
@@ -1,5 +1,4 @@
 // edition:2021
-// compile-flags: -Zdrop-tracking-mir=yes
 #![feature(generators)]
 
 fn main() {
diff --git a/tests/ui/generator/issue-110929-generator-conflict-error-ice.stderr b/tests/ui/generator/issue-110929-generator-conflict-error-ice.stderr
index 4d72ebe79eb..66f0e3d94bd 100644
--- a/tests/ui/generator/issue-110929-generator-conflict-error-ice.stderr
+++ b/tests/ui/generator/issue-110929-generator-conflict-error-ice.stderr
@@ -1,5 +1,5 @@
 error[E0499]: cannot borrow `*x` as mutable more than once at a time
-  --> $DIR/issue-110929-generator-conflict-error-ice.rs:9:9
+  --> $DIR/issue-110929-generator-conflict-error-ice.rs:8:9
    |
 LL |         let _c = || yield *&mut *x;
    |                  --             -- first borrow occurs due to use of `*x` in generator
diff --git a/tests/ui/generator/issue-57017.no_drop_tracking.stderr b/tests/ui/generator/issue-57017.no_drop_tracking.stderr
deleted file mode 100644
index cd5cf12cc49..00000000000
--- a/tests/ui/generator/issue-57017.no_drop_tracking.stderr
+++ /dev/null
@@ -1,248 +0,0 @@
-error: generator cannot be sent between threads safely
-  --> $DIR/issue-57017.rs:32:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         derived_drop => { #[derive(Default)] pub struct Client { pub nickname: String } };
-LL | |         significant_drop => {
-...  |
-LL | |         }
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: the trait `Sync` is not implemented for `copy::unsync::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-57017.rs:30:28
-   |
-LL |               let g = move || match drop(&$name::unsync::Client::default()) {
-   |                                          --------------------------------- has type `&copy::unsync::Client` which is not `Send`
-LL |                   _status => yield,
-   |                              ^^^^^ yield occurs here, with `&$name::unsync::Client::default()` maybe used later
-LL |               };
-   |               - `&$name::unsync::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         derived_drop => { #[derive(Default)] pub struct Client { pub nickname: String } };
-LL | |         significant_drop => {
-...  |
-LL | |         }
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/issue-57017.rs:52:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/issue-57017.rs:44:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         derived_drop => { #[derive(Default)] pub struct Client { pub nickname: String } };
-LL | |         significant_drop => {
-...  |
-LL | |         }
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/issue-57017.rs:41:21: 41:28}`, the trait `Send` is not implemented for `copy::unsend::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-57017.rs:42:28
-   |
-LL |               let g = move || match drop($name::unsend::Client::default()) {
-   |                                          -------------------------------- has type `copy::unsend::Client` which is not `Send`
-LL |                   _status => yield,
-   |                              ^^^^^ yield occurs here, with `$name::unsend::Client::default()` maybe used later
-LL |               };
-   |               - `$name::unsend::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         derived_drop => { #[derive(Default)] pub struct Client { pub nickname: String } };
-LL | |         significant_drop => {
-...  |
-LL | |         }
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/issue-57017.rs:52:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/issue-57017.rs:32:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         derived_drop => { #[derive(Default)] pub struct Client { pub nickname: String } };
-LL | |         significant_drop => {
-...  |
-LL | |         }
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: the trait `Sync` is not implemented for `derived_drop::unsync::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-57017.rs:30:28
-   |
-LL |               let g = move || match drop(&$name::unsync::Client::default()) {
-   |                                          --------------------------------- has type `&derived_drop::unsync::Client` which is not `Send`
-LL |                   _status => yield,
-   |                              ^^^^^ yield occurs here, with `&$name::unsync::Client::default()` maybe used later
-LL |               };
-   |               - `&$name::unsync::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         derived_drop => { #[derive(Default)] pub struct Client { pub nickname: String } };
-LL | |         significant_drop => {
-...  |
-LL | |         }
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/issue-57017.rs:52:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/issue-57017.rs:44:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         derived_drop => { #[derive(Default)] pub struct Client { pub nickname: String } };
-LL | |         significant_drop => {
-...  |
-LL | |         }
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/issue-57017.rs:41:21: 41:28}`, the trait `Send` is not implemented for `derived_drop::unsend::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-57017.rs:42:28
-   |
-LL |               let g = move || match drop($name::unsend::Client::default()) {
-   |                                          -------------------------------- has type `derived_drop::unsend::Client` which is not `Send`
-LL |                   _status => yield,
-   |                              ^^^^^ yield occurs here, with `$name::unsend::Client::default()` maybe used later
-LL |               };
-   |               - `$name::unsend::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         derived_drop => { #[derive(Default)] pub struct Client { pub nickname: String } };
-LL | |         significant_drop => {
-...  |
-LL | |         }
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/issue-57017.rs:52:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/issue-57017.rs:32:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         derived_drop => { #[derive(Default)] pub struct Client { pub nickname: String } };
-LL | |         significant_drop => {
-...  |
-LL | |         }
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: the trait `Sync` is not implemented for `significant_drop::unsync::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-57017.rs:30:28
-   |
-LL |               let g = move || match drop(&$name::unsync::Client::default()) {
-   |                                          --------------------------------- has type `&significant_drop::unsync::Client` which is not `Send`
-LL |                   _status => yield,
-   |                              ^^^^^ yield occurs here, with `&$name::unsync::Client::default()` maybe used later
-LL |               };
-   |               - `&$name::unsync::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         derived_drop => { #[derive(Default)] pub struct Client { pub nickname: String } };
-LL | |         significant_drop => {
-...  |
-LL | |         }
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/issue-57017.rs:52:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/issue-57017.rs:44:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         derived_drop => { #[derive(Default)] pub struct Client { pub nickname: String } };
-LL | |         significant_drop => {
-...  |
-LL | |         }
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/issue-57017.rs:41:21: 41:28}`, the trait `Send` is not implemented for `significant_drop::unsend::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-57017.rs:42:28
-   |
-LL |               let g = move || match drop($name::unsend::Client::default()) {
-   |                                          -------------------------------- has type `significant_drop::unsend::Client` which is not `Send`
-LL |                   _status => yield,
-   |                              ^^^^^ yield occurs here, with `$name::unsend::Client::default()` maybe used later
-LL |               };
-   |               - `$name::unsend::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         derived_drop => { #[derive(Default)] pub struct Client { pub nickname: String } };
-LL | |         significant_drop => {
-...  |
-LL | |         }
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/issue-57017.rs:52:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 6 previous errors
-
diff --git a/tests/ui/generator/issue-57017.rs b/tests/ui/generator/issue-57017.rs
index 381897c77a5..bb2d6679b67 100644
--- a/tests/ui/generator/issue-57017.rs
+++ b/tests/ui/generator/issue-57017.rs
@@ -1,9 +1,4 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-// [drop_tracking] build-pass
-// [drop_tracking_mir] build-pass
-
+// build-pass
 #![feature(generators, negative_impls)]
 #![allow(dropping_references, dropping_copy_types)]
 
@@ -30,9 +25,6 @@ macro_rules! type_combinations {
                 _status => yield,
             };
             assert_send(g);
-            //[no_drop_tracking]~^ ERROR generator cannot be sent between threads safely
-            //[no_drop_tracking]~| ERROR generator cannot be sent between threads safely
-            //[no_drop_tracking]~| ERROR generator cannot be sent between threads safely
         }
 
         // This tests that `Client` is properly considered to be dropped after moving it into the
@@ -42,9 +34,6 @@ macro_rules! type_combinations {
                 _status => yield,
             };
             assert_send(g);
-            //[no_drop_tracking]~^ ERROR generator cannot be sent between threads safely
-            //[no_drop_tracking]~| ERROR generator cannot be sent between threads safely
-            //[no_drop_tracking]~| ERROR generator cannot be sent between threads safely
         }
     )* }
 }
diff --git a/tests/ui/generator/issue-57478.no_drop_tracking.stderr b/tests/ui/generator/issue-57478.no_drop_tracking.stderr
deleted file mode 100644
index df931f5e04e..00000000000
--- a/tests/ui/generator/issue-57478.no_drop_tracking.stderr
+++ /dev/null
@@ -1,31 +0,0 @@
-error: generator cannot be sent between threads safely
-  --> $DIR/issue-57478.rs:13:17
-   |
-LL |       assert_send(|| {
-   |  _________________^
-LL | |
-LL | |         let guard = Foo;
-LL | |         drop(guard);
-LL | |         yield;
-LL | |     })
-   | |_____^ generator is not `Send`
-   |
-   = help: within `{generator@$DIR/issue-57478.rs:13:17: 13:19}`, the trait `Send` is not implemented for `Foo`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-57478.rs:17:9
-   |
-LL |         let guard = Foo;
-   |             ----- has type `Foo` which is not `Send`
-LL |         drop(guard);
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `guard` maybe used later
-LL |     })
-   |     - `guard` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/issue-57478.rs:21:19
-   |
-LL | fn assert_send<T: Send>(_: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-
-error: aborting due to previous error
-
diff --git a/tests/ui/generator/issue-57478.rs b/tests/ui/generator/issue-57478.rs
index 3c23b599271..39710febdb9 100644
--- a/tests/ui/generator/issue-57478.rs
+++ b/tests/ui/generator/issue-57478.rs
@@ -1,8 +1,4 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-// [drop_tracking] check-pass
-// [drop_tracking_mir] check-pass
+// check-pass
 
 #![feature(negative_impls, generators)]
 
@@ -11,7 +7,6 @@ impl !Send for Foo {}
 
 fn main() {
     assert_send(|| {
-        //[no_drop_tracking]~^ ERROR generator cannot be sent between threads safely
         let guard = Foo;
         drop(guard);
         yield;
diff --git a/tests/ui/generator/issue-68112.drop_tracking.stderr b/tests/ui/generator/issue-68112.drop_tracking.stderr
deleted file mode 100644
index 282eac1b686..00000000000
--- a/tests/ui/generator/issue-68112.drop_tracking.stderr
+++ /dev/null
@@ -1,66 +0,0 @@
-error: generator cannot be sent between threads safely
-  --> $DIR/issue-68112.rs:43:18
-   |
-LL |     require_send(send_gen);
-   |                  ^^^^^^^^ generator is not `Send`
-   |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-68112.rs:39:9
-   |
-LL |         let _non_send_gen = make_non_send_generator();
-   |             ------------- has type `impl Generator<Return = Arc<RefCell<i32>>>` which is not `Send`
-LL |
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
-...
-LL |     };
-   |     - `_non_send_gen` is later dropped here
-note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:25:25
-   |
-LL | fn require_send(_: impl Send) {}
-   |                         ^^^^ required by this bound in `require_send`
-
-error[E0277]: `RefCell<i32>` cannot be shared between threads safely
-  --> $DIR/issue-68112.rs:67:18
-   |
-LL |     require_send(send_gen);
-   |     ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
-   = note: required for `Arc<RefCell<i32>>` to implement `Send`
-note: required because it's used within this generator
-  --> $DIR/issue-68112.rs:52:5
-   |
-LL |     || {
-   |     ^^
-note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
-  --> $DIR/issue-68112.rs:49:30
-   |
-LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
-  --> $DIR/issue-68112.rs:57:34
-   |
-LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: required because it captures the following types: `impl Generator<Return = Arc<RefCell<i32>>>`, `()`
-note: required because it's used within this generator
-  --> $DIR/issue-68112.rs:63:20
-   |
-LL |     let send_gen = || {
-   |                    ^^
-note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:25:25
-   |
-LL | fn require_send(_: impl Send) {}
-   |                         ^^^^ required by this bound in `require_send`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generator/issue-68112.no_drop_tracking.stderr b/tests/ui/generator/issue-68112.no_drop_tracking.stderr
deleted file mode 100644
index 282eac1b686..00000000000
--- a/tests/ui/generator/issue-68112.no_drop_tracking.stderr
+++ /dev/null
@@ -1,66 +0,0 @@
-error: generator cannot be sent between threads safely
-  --> $DIR/issue-68112.rs:43:18
-   |
-LL |     require_send(send_gen);
-   |                  ^^^^^^^^ generator is not `Send`
-   |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-68112.rs:39:9
-   |
-LL |         let _non_send_gen = make_non_send_generator();
-   |             ------------- has type `impl Generator<Return = Arc<RefCell<i32>>>` which is not `Send`
-LL |
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
-...
-LL |     };
-   |     - `_non_send_gen` is later dropped here
-note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:25:25
-   |
-LL | fn require_send(_: impl Send) {}
-   |                         ^^^^ required by this bound in `require_send`
-
-error[E0277]: `RefCell<i32>` cannot be shared between threads safely
-  --> $DIR/issue-68112.rs:67:18
-   |
-LL |     require_send(send_gen);
-   |     ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
-   = note: required for `Arc<RefCell<i32>>` to implement `Send`
-note: required because it's used within this generator
-  --> $DIR/issue-68112.rs:52:5
-   |
-LL |     || {
-   |     ^^
-note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
-  --> $DIR/issue-68112.rs:49:30
-   |
-LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
-  --> $DIR/issue-68112.rs:57:34
-   |
-LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: required because it captures the following types: `impl Generator<Return = Arc<RefCell<i32>>>`, `()`
-note: required because it's used within this generator
-  --> $DIR/issue-68112.rs:63:20
-   |
-LL |     let send_gen = || {
-   |                    ^^
-note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:25:25
-   |
-LL | fn require_send(_: impl Send) {}
-   |                         ^^^^ required by this bound in `require_send`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generator/issue-68112.rs b/tests/ui/generator/issue-68112.rs
index 48b53b7693d..9dd68726f92 100644
--- a/tests/ui/generator/issue-68112.rs
+++ b/tests/ui/generator/issue-68112.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 #![feature(generators, generator_trait)]
 
 use std::{
@@ -39,7 +36,7 @@ fn test1() {
         yield;
         //~^ NOTE yield occurs here
         //~| NOTE value is used across a yield
-    }; //[no_drop_tracking,drop_tracking]~ NOTE later dropped here
+    };
     require_send(send_gen);
     //~^ ERROR generator cannot be sent between threads
     //~| NOTE not `Send`
@@ -68,7 +65,6 @@ fn test2() {
     //~^ ERROR `RefCell<i32>` cannot be shared between threads safely
     //~| NOTE `RefCell<i32>` cannot be shared between threads safely
     //~| NOTE required for
-    //[no_drop_tracking,drop_tracking]~| NOTE required by a bound introduced by this call
     //~| NOTE captures the following types
     //~| NOTE use `std::sync::RwLock` instead
 }
diff --git a/tests/ui/generator/issue-68112.drop_tracking_mir.stderr b/tests/ui/generator/issue-68112.stderr
index a83522b714d..8080048222f 100644
--- a/tests/ui/generator/issue-68112.drop_tracking_mir.stderr
+++ b/tests/ui/generator/issue-68112.stderr
@@ -1,5 +1,5 @@
 error: generator cannot be sent between threads safely
-  --> $DIR/issue-68112.rs:43:5
+  --> $DIR/issue-68112.rs:40:5
    |
 LL |     require_send(send_gen);
    |     ^^^^^^^^^^^^ generator is not `Send`
@@ -7,7 +7,7 @@ LL |     require_send(send_gen);
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/issue-68112.rs:39:9
+  --> $DIR/issue-68112.rs:36:9
    |
 LL |         let _non_send_gen = make_non_send_generator();
    |             ------------- has type `impl Generator<Return = Arc<RefCell<i32>>>` which is not `Send`
@@ -15,13 +15,13 @@ LL |
 LL |         yield;
    |         ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
 note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:25:25
+  --> $DIR/issue-68112.rs:22:25
    |
 LL | fn require_send(_: impl Send) {}
    |                         ^^^^ required by this bound in `require_send`
 
 error[E0277]: `RefCell<i32>` cannot be shared between threads safely
-  --> $DIR/issue-68112.rs:67:5
+  --> $DIR/issue-68112.rs:64:5
    |
 LL |     require_send(send_gen);
    |     ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
@@ -30,28 +30,28 @@ LL |     require_send(send_gen);
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Arc<RefCell<i32>>` to implement `Send`
 note: required because it's used within this generator
-  --> $DIR/issue-68112.rs:52:5
+  --> $DIR/issue-68112.rs:49:5
    |
 LL |     || {
    |     ^^
 note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
-  --> $DIR/issue-68112.rs:49:30
+  --> $DIR/issue-68112.rs:46:30
    |
 LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: required because it appears within the type `impl Generator<Return = Arc<RefCell<i32>>>`
-  --> $DIR/issue-68112.rs:57:34
+  --> $DIR/issue-68112.rs:54:34
    |
 LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: required because it captures the following types: `impl Generator<Return = Arc<RefCell<i32>>>`
 note: required because it's used within this generator
-  --> $DIR/issue-68112.rs:63:20
+  --> $DIR/issue-68112.rs:60:20
    |
 LL |     let send_gen = || {
    |                    ^^
 note: required by a bound in `require_send`
-  --> $DIR/issue-68112.rs:25:25
+  --> $DIR/issue-68112.rs:22:25
    |
 LL | fn require_send(_: impl Send) {}
    |                         ^^^^ required by this bound in `require_send`
diff --git a/tests/ui/generator/issue-93161.rs b/tests/ui/generator/issue-93161.rs
index 8d3f7c62f39..ae8603b7c09 100644
--- a/tests/ui/generator/issue-93161.rs
+++ b/tests/ui/generator/issue-93161.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2021
 // run-pass
 
diff --git a/tests/ui/generator/not-send-sync.drop_tracking.stderr b/tests/ui/generator/not-send-sync.drop_tracking.stderr
deleted file mode 100644
index 53f62dc4ea2..00000000000
--- a/tests/ui/generator/not-send-sync.drop_tracking.stderr
+++ /dev/null
@@ -1,60 +0,0 @@
-error: generator cannot be shared between threads safely
-  --> $DIR/not-send-sync.rs:17:17
-   |
-LL |       assert_sync(|| {
-   |  _________________^
-LL | |
-LL | |         let a = NotSync;
-LL | |         yield;
-LL | |         drop(a);
-LL | |     });
-   | |_____^ generator is not `Sync`
-   |
-   = help: within `{generator@$DIR/not-send-sync.rs:17:17: 17:19}`, the trait `Sync` is not implemented for `NotSync`
-note: generator is not `Sync` as this value is used across a yield
-  --> $DIR/not-send-sync.rs:20:9
-   |
-LL |         let a = NotSync;
-   |             - has type `NotSync` which is not `Sync`
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `a` maybe used later
-LL |         drop(a);
-LL |     });
-   |     - `a` is later dropped here
-note: required by a bound in `assert_sync`
-  --> $DIR/not-send-sync.rs:14:23
-   |
-LL |     fn assert_sync<T: Sync>(_: T) {}
-   |                       ^^^^ required by this bound in `assert_sync`
-
-error: generator cannot be sent between threads safely
-  --> $DIR/not-send-sync.rs:24:17
-   |
-LL |       assert_send(|| {
-   |  _________________^
-LL | |
-LL | |         let a = NotSend;
-LL | |         yield;
-LL | |         drop(a);
-LL | |     });
-   | |_____^ generator is not `Send`
-   |
-   = help: within `{generator@$DIR/not-send-sync.rs:24:17: 24:19}`, the trait `Send` is not implemented for `NotSend`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/not-send-sync.rs:27:9
-   |
-LL |         let a = NotSend;
-   |             - has type `NotSend` which is not `Send`
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `a` maybe used later
-LL |         drop(a);
-LL |     });
-   |     - `a` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/not-send-sync.rs:15:23
-   |
-LL |     fn assert_send<T: Send>(_: T) {}
-   |                       ^^^^ required by this bound in `assert_send`
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/generator/not-send-sync.no_drop_tracking.stderr b/tests/ui/generator/not-send-sync.no_drop_tracking.stderr
deleted file mode 100644
index 53f62dc4ea2..00000000000
--- a/tests/ui/generator/not-send-sync.no_drop_tracking.stderr
+++ /dev/null
@@ -1,60 +0,0 @@
-error: generator cannot be shared between threads safely
-  --> $DIR/not-send-sync.rs:17:17
-   |
-LL |       assert_sync(|| {
-   |  _________________^
-LL | |
-LL | |         let a = NotSync;
-LL | |         yield;
-LL | |         drop(a);
-LL | |     });
-   | |_____^ generator is not `Sync`
-   |
-   = help: within `{generator@$DIR/not-send-sync.rs:17:17: 17:19}`, the trait `Sync` is not implemented for `NotSync`
-note: generator is not `Sync` as this value is used across a yield
-  --> $DIR/not-send-sync.rs:20:9
-   |
-LL |         let a = NotSync;
-   |             - has type `NotSync` which is not `Sync`
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `a` maybe used later
-LL |         drop(a);
-LL |     });
-   |     - `a` is later dropped here
-note: required by a bound in `assert_sync`
-  --> $DIR/not-send-sync.rs:14:23
-   |
-LL |     fn assert_sync<T: Sync>(_: T) {}
-   |                       ^^^^ required by this bound in `assert_sync`
-
-error: generator cannot be sent between threads safely
-  --> $DIR/not-send-sync.rs:24:17
-   |
-LL |       assert_send(|| {
-   |  _________________^
-LL | |
-LL | |         let a = NotSend;
-LL | |         yield;
-LL | |         drop(a);
-LL | |     });
-   | |_____^ generator is not `Send`
-   |
-   = help: within `{generator@$DIR/not-send-sync.rs:24:17: 24:19}`, the trait `Send` is not implemented for `NotSend`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/not-send-sync.rs:27:9
-   |
-LL |         let a = NotSend;
-   |             - has type `NotSend` which is not `Send`
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `a` maybe used later
-LL |         drop(a);
-LL |     });
-   |     - `a` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/not-send-sync.rs:15:23
-   |
-LL |     fn assert_send<T: Send>(_: T) {}
-   |                       ^^^^ required by this bound in `assert_send`
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/generator/not-send-sync.rs b/tests/ui/generator/not-send-sync.rs
index 8794db452b4..16c8cd47629 100644
--- a/tests/ui/generator/not-send-sync.rs
+++ b/tests/ui/generator/not-send-sync.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 #![feature(generators)]
 #![feature(negative_impls)]
 
diff --git a/tests/ui/generator/not-send-sync.drop_tracking_mir.stderr b/tests/ui/generator/not-send-sync.stderr
index 2438e7846b1..13ce687e0bb 100644
--- a/tests/ui/generator/not-send-sync.drop_tracking_mir.stderr
+++ b/tests/ui/generator/not-send-sync.stderr
@@ -1,39 +1,39 @@
 error: generator cannot be shared between threads safely
-  --> $DIR/not-send-sync.rs:17:5
+  --> $DIR/not-send-sync.rs:14:5
    |
 LL |     assert_sync(|| {
    |     ^^^^^^^^^^^ generator is not `Sync`
    |
-   = help: within `{generator@$DIR/not-send-sync.rs:17:17: 17:19}`, the trait `Sync` is not implemented for `NotSync`
+   = help: within `{generator@$DIR/not-send-sync.rs:14:17: 14:19}`, the trait `Sync` is not implemented for `NotSync`
 note: generator is not `Sync` as this value is used across a yield
-  --> $DIR/not-send-sync.rs:20:9
+  --> $DIR/not-send-sync.rs:17:9
    |
 LL |         let a = NotSync;
    |             - has type `NotSync` which is not `Sync`
 LL |         yield;
    |         ^^^^^ yield occurs here, with `a` maybe used later
 note: required by a bound in `assert_sync`
-  --> $DIR/not-send-sync.rs:14:23
+  --> $DIR/not-send-sync.rs:11:23
    |
 LL |     fn assert_sync<T: Sync>(_: T) {}
    |                       ^^^^ required by this bound in `assert_sync`
 
 error: generator cannot be sent between threads safely
-  --> $DIR/not-send-sync.rs:24:5
+  --> $DIR/not-send-sync.rs:21:5
    |
 LL |     assert_send(|| {
    |     ^^^^^^^^^^^ generator is not `Send`
    |
-   = help: within `{generator@$DIR/not-send-sync.rs:24:17: 24:19}`, the trait `Send` is not implemented for `NotSend`
+   = help: within `{generator@$DIR/not-send-sync.rs:21:17: 21:19}`, the trait `Send` is not implemented for `NotSend`
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/not-send-sync.rs:27:9
+  --> $DIR/not-send-sync.rs:24:9
    |
 LL |         let a = NotSend;
    |             - has type `NotSend` which is not `Send`
 LL |         yield;
    |         ^^^^^ yield occurs here, with `a` maybe used later
 note: required by a bound in `assert_send`
-  --> $DIR/not-send-sync.rs:15:23
+  --> $DIR/not-send-sync.rs:12:23
    |
 LL |     fn assert_send<T: Send>(_: T) {}
    |                       ^^^^ required by this bound in `assert_send`
diff --git a/tests/ui/generator/parent-expression.drop_tracking.stderr b/tests/ui/generator/parent-expression.drop_tracking.stderr
deleted file mode 100644
index f55c8d58fd0..00000000000
--- a/tests/ui/generator/parent-expression.drop_tracking.stderr
+++ /dev/null
@@ -1,128 +0,0 @@
-error: generator cannot be sent between threads safely
-  --> $DIR/parent-expression.rs:27:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `derived_drop::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/parent-expression.rs:25:22
-   |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `derived_drop::Client` which is not `Send`
-...
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/parent-expression.rs:27:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `significant_drop::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/parent-expression.rs:25:22
-   |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `significant_drop::Client` which is not `Send`
-...
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/parent-expression.rs:27:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `insignificant_dtor::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/parent-expression.rs:25:22
-   |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `insignificant_dtor::Client` which is not `Send`
-...
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 3 previous errors
-
diff --git a/tests/ui/generator/parent-expression.no_drop_tracking.stderr b/tests/ui/generator/parent-expression.no_drop_tracking.stderr
deleted file mode 100644
index 5750d2d0afd..00000000000
--- a/tests/ui/generator/parent-expression.no_drop_tracking.stderr
+++ /dev/null
@@ -1,334 +0,0 @@
-error: generator cannot be sent between threads safely
-  --> $DIR/parent-expression.rs:27:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `copy::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/parent-expression.rs:25:22
-   |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `copy::Client` which is not `Send`
-...
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/parent-expression.rs:40:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/parent-expression.rs:37:21: 37:28}`, the trait `Send` is not implemented for `copy::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/parent-expression.rs:38:22
-   |
-LL |               let g = move || match drop($name::Client::default()) {
-   |                                          ------------------------ has type `copy::Client` which is not `Send`
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/parent-expression.rs:27:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `derived_drop::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/parent-expression.rs:25:22
-   |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `derived_drop::Client` which is not `Send`
-...
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/parent-expression.rs:40:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/parent-expression.rs:37:21: 37:28}`, the trait `Send` is not implemented for `derived_drop::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/parent-expression.rs:38:22
-   |
-LL |               let g = move || match drop($name::Client::default()) {
-   |                                          ------------------------ has type `derived_drop::Client` which is not `Send`
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/parent-expression.rs:27:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `significant_drop::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/parent-expression.rs:25:22
-   |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `significant_drop::Client` which is not `Send`
-...
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/parent-expression.rs:40:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/parent-expression.rs:37:21: 37:28}`, the trait `Send` is not implemented for `significant_drop::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/parent-expression.rs:38:22
-   |
-LL |               let g = move || match drop($name::Client::default()) {
-   |                                          ------------------------ has type `significant_drop::Client` which is not `Send`
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/parent-expression.rs:27:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `insignificant_dtor::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/parent-expression.rs:25:22
-   |
-LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
-   |                                                            ------------------------ has type `insignificant_dtor::Client` which is not `Send`
-...
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: generator cannot be sent between threads safely
-  --> $DIR/parent-expression.rs:40:25
-   |
-LL |               assert_send(g);
-   |                           ^ generator is not `Send`
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-   |
-   = help: within `{generator@$DIR/parent-expression.rs:37:21: 37:28}`, the trait `Send` is not implemented for `insignificant_dtor::Client`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/parent-expression.rs:38:22
-   |
-LL |               let g = move || match drop($name::Client::default()) {
-   |                                          ------------------------ has type `insignificant_dtor::Client` which is not `Send`
-LL |                   _ => yield,
-   |                        ^^^^^ yield occurs here, with `$name::Client::default()` maybe used later
-LL |               };
-   |               - `$name::Client::default()` is later dropped here
-...
-LL | /     type_combinations!(
-LL | |         // OK
-LL | |         copy => { #[derive(Copy, Clone, Default)] pub struct Client; };
-LL | |         // NOT OK: MIR borrowck thinks that this is used after the yield, even though
-...  |
-LL | |         };
-LL | |     );
-   | |_____- in this macro invocation
-note: required by a bound in `assert_send`
-  --> $DIR/parent-expression.rs:49:19
-   |
-LL | fn assert_send<T: Send>(_thing: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-   = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-error: aborting due to 8 previous errors
-
diff --git a/tests/ui/generator/parent-expression.rs b/tests/ui/generator/parent-expression.rs
index 239034e3d4e..198b14528aa 100644
--- a/tests/ui/generator/parent-expression.rs
+++ b/tests/ui/generator/parent-expression.rs
@@ -1,7 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-
 #![feature(generators, negative_impls, rustc_attrs)]
 
 macro_rules! type_combinations {
@@ -28,7 +24,6 @@ macro_rules! type_combinations {
             //~^ ERROR cannot be sent between threads
             //~| ERROR cannot be sent between threads
             //~| ERROR cannot be sent between threads
-            //[no_drop_tracking]~^^^^ ERROR cannot be sent between threads
         }
 
         // Simple owned value. This works because the Client is considered moved into `drop`,
@@ -38,10 +33,6 @@ macro_rules! type_combinations {
                 _ => yield,
             };
             assert_send(g);
-            //[no_drop_tracking]~^ ERROR cannot be sent between threads
-            //[no_drop_tracking]~| ERROR cannot be sent between threads
-            //[no_drop_tracking]~| ERROR cannot be sent between threads
-            //[no_drop_tracking]~| ERROR cannot be sent between threads
         }
     )* }
 }
diff --git a/tests/ui/generator/parent-expression.drop_tracking_mir.stderr b/tests/ui/generator/parent-expression.stderr
index 11bfb9902b0..25a3b051b1f 100644
--- a/tests/ui/generator/parent-expression.drop_tracking_mir.stderr
+++ b/tests/ui/generator/parent-expression.stderr
@@ -1,5 +1,5 @@
 error: generator cannot be sent between threads safely
-  --> $DIR/parent-expression.rs:27:13
+  --> $DIR/parent-expression.rs:23:13
    |
 LL |               assert_send(g);
    |               ^^^^^^^^^^^ generator is not `Send`
@@ -13,9 +13,9 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `{generator@$DIR/parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `derived_drop::Client`
+   = help: within `{generator@$DIR/parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `derived_drop::Client`
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/parent-expression.rs:25:22
+  --> $DIR/parent-expression.rs:21:22
    |
 LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
    |                                                            ------------------------ has type `derived_drop::Client` which is not `Send`
@@ -32,14 +32,14 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
 note: required by a bound in `assert_send`
-  --> $DIR/parent-expression.rs:49:19
+  --> $DIR/parent-expression.rs:40:19
    |
 LL | fn assert_send<T: Send>(_thing: T) {}
    |                   ^^^^ required by this bound in `assert_send`
    = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: generator cannot be sent between threads safely
-  --> $DIR/parent-expression.rs:27:13
+  --> $DIR/parent-expression.rs:23:13
    |
 LL |               assert_send(g);
    |               ^^^^^^^^^^^ generator is not `Send`
@@ -53,9 +53,9 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `{generator@$DIR/parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `significant_drop::Client`
+   = help: within `{generator@$DIR/parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `significant_drop::Client`
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/parent-expression.rs:25:22
+  --> $DIR/parent-expression.rs:21:22
    |
 LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
    |                                                            ------------------------ has type `significant_drop::Client` which is not `Send`
@@ -72,14 +72,14 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
 note: required by a bound in `assert_send`
-  --> $DIR/parent-expression.rs:49:19
+  --> $DIR/parent-expression.rs:40:19
    |
 LL | fn assert_send<T: Send>(_thing: T) {}
    |                   ^^^^ required by this bound in `assert_send`
    = note: this error originates in the macro `type_combinations` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: generator cannot be sent between threads safely
-  --> $DIR/parent-expression.rs:27:13
+  --> $DIR/parent-expression.rs:23:13
    |
 LL |               assert_send(g);
    |               ^^^^^^^^^^^ generator is not `Send`
@@ -93,9 +93,9 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
    |
-   = help: within `{generator@$DIR/parent-expression.rs:21:21: 21:28}`, the trait `Send` is not implemented for `insignificant_dtor::Client`
+   = help: within `{generator@$DIR/parent-expression.rs:17:21: 17:28}`, the trait `Send` is not implemented for `insignificant_dtor::Client`
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/parent-expression.rs:25:22
+  --> $DIR/parent-expression.rs:21:22
    |
 LL |               let g = move || match drop($name::Client { ..$name::Client::default() }) {
    |                                                            ------------------------ has type `insignificant_dtor::Client` which is not `Send`
@@ -112,7 +112,7 @@ LL | |         };
 LL | |     );
    | |_____- in this macro invocation
 note: required by a bound in `assert_send`
-  --> $DIR/parent-expression.rs:49:19
+  --> $DIR/parent-expression.rs:40:19
    |
 LL | fn assert_send<T: Send>(_thing: T) {}
    |                   ^^^^ required by this bound in `assert_send`
diff --git a/tests/ui/generator/partial-drop.drop_tracking.stderr b/tests/ui/generator/partial-drop.drop_tracking.stderr
deleted file mode 100644
index b3de7853361..00000000000
--- a/tests/ui/generator/partial-drop.drop_tracking.stderr
+++ /dev/null
@@ -1,61 +0,0 @@
-error: generator cannot be sent between threads safely
-  --> $DIR/partial-drop.rs:17:17
-   |
-LL |       assert_send(|| {
-   |  _________________^
-LL | |
-LL | |         let guard = Bar { foo: Foo, x: 42 };
-LL | |         drop(guard.foo);
-LL | |         yield;
-LL | |     });
-   | |_____^ generator is not `Send`
-   |
-   = help: within `{generator@$DIR/partial-drop.rs:17:17: 17:19}`, the trait `Send` is not implemented for `Foo`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/partial-drop.rs:21:9
-   |
-LL |         let guard = Bar { foo: Foo, x: 42 };
-   |             ----- has type `Bar` which is not `Send`
-LL |         drop(guard.foo);
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `guard` maybe used later
-LL |     });
-   |     - `guard` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/partial-drop.rs:33:19
-   |
-LL | fn assert_send<T: Send>(_: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-
-error: generator cannot be sent between threads safely
-  --> $DIR/partial-drop.rs:24:17
-   |
-LL |       assert_send(|| {
-   |  _________________^
-LL | |
-LL | |         let guard = Bar { foo: Foo, x: 42 };
-LL | |         let Bar { foo, x } = guard;
-LL | |         drop(foo);
-LL | |         yield;
-LL | |     });
-   | |_____^ generator is not `Send`
-   |
-   = help: within `{generator@$DIR/partial-drop.rs:24:17: 24:19}`, the trait `Send` is not implemented for `Foo`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/partial-drop.rs:29:9
-   |
-LL |         let guard = Bar { foo: Foo, x: 42 };
-   |             ----- has type `Bar` which is not `Send`
-...
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `guard` maybe used later
-LL |     });
-   |     - `guard` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/partial-drop.rs:33:19
-   |
-LL | fn assert_send<T: Send>(_: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/generator/partial-drop.no_drop_tracking.stderr b/tests/ui/generator/partial-drop.no_drop_tracking.stderr
deleted file mode 100644
index 34b7101825f..00000000000
--- a/tests/ui/generator/partial-drop.no_drop_tracking.stderr
+++ /dev/null
@@ -1,61 +0,0 @@
-error: generator cannot be sent between threads safely
-  --> $DIR/partial-drop.rs:17:17
-   |
-LL |       assert_send(|| {
-   |  _________________^
-LL | |
-LL | |         let guard = Bar { foo: Foo, x: 42 };
-LL | |         drop(guard.foo);
-LL | |         yield;
-LL | |     });
-   | |_____^ generator is not `Send`
-   |
-   = help: within `{generator@$DIR/partial-drop.rs:17:17: 17:19}`, the trait `Send` is not implemented for `Foo`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/partial-drop.rs:21:9
-   |
-LL |         let guard = Bar { foo: Foo, x: 42 };
-   |             ----- has type `Bar` which is not `Send`
-LL |         drop(guard.foo);
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `guard` maybe used later
-LL |     });
-   |     - `guard` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/partial-drop.rs:33:19
-   |
-LL | fn assert_send<T: Send>(_: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-
-error: generator cannot be sent between threads safely
-  --> $DIR/partial-drop.rs:24:17
-   |
-LL |       assert_send(|| {
-   |  _________________^
-LL | |
-LL | |         let guard = Bar { foo: Foo, x: 42 };
-LL | |         let Bar { foo, x } = guard;
-LL | |         drop(foo);
-LL | |         yield;
-LL | |     });
-   | |_____^ generator is not `Send`
-   |
-   = help: within `{generator@$DIR/partial-drop.rs:24:17: 24:19}`, the trait `Send` is not implemented for `Foo`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/partial-drop.rs:29:9
-   |
-LL |         let Bar { foo, x } = guard;
-   |                   --- has type `Foo` which is not `Send`
-LL |         drop(foo);
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `foo` maybe used later
-LL |     });
-   |     - `foo` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/partial-drop.rs:33:19
-   |
-LL | fn assert_send<T: Send>(_: T) {}
-   |                   ^^^^ required by this bound in `assert_send`
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/generator/partial-drop.rs b/tests/ui/generator/partial-drop.rs
index 1d3ae075d43..868f36adce2 100644
--- a/tests/ui/generator/partial-drop.rs
+++ b/tests/ui/generator/partial-drop.rs
@@ -1,8 +1,4 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-// [drop_tracking_mir] check-pass
-
+// check-pass
 #![feature(negative_impls, generators)]
 
 struct Foo;
@@ -15,14 +11,19 @@ struct Bar {
 
 fn main() {
     assert_send(|| {
-        //[no_drop_tracking,drop_tracking]~^ ERROR generator cannot be sent between threads safely
         let guard = Bar { foo: Foo, x: 42 };
         drop(guard.foo);
         yield;
     });
 
     assert_send(|| {
-        //[no_drop_tracking,drop_tracking]~^ ERROR generator cannot be sent between threads safely
+        let mut guard = Bar { foo: Foo, x: 42 };
+        drop(guard);
+        guard = Bar { foo: Foo, x: 23 };
+        yield;
+    });
+
+    assert_send(|| {
         let guard = Bar { foo: Foo, x: 42 };
         let Bar { foo, x } = guard;
         drop(foo);
diff --git a/tests/ui/generator/print/generator-print-verbose-1.drop_tracking.stderr b/tests/ui/generator/print/generator-print-verbose-1.drop_tracking.stderr
deleted file mode 100644
index 429b202f603..00000000000
--- a/tests/ui/generator/print/generator-print-verbose-1.drop_tracking.stderr
+++ /dev/null
@@ -1,64 +0,0 @@
-error: generator cannot be sent between threads safely
-  --> $DIR/generator-print-verbose-1.rs:40:18
-   |
-LL |     require_send(send_gen);
-   |                  ^^^^^^^^ generator is not `Send`
-   |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/generator-print-verbose-1.rs:38:9
-   |
-LL |         let _non_send_gen = make_non_send_generator();
-   |             ------------- has type `Opaque(DefId(0:34 ~ generator_print_verbose_1[7d1d]::make_non_send_generator::{opaque#0}), [])` which is not `Send`
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
-LL |     };
-   |     - `_non_send_gen` is later dropped here
-note: required by a bound in `require_send`
-  --> $DIR/generator-print-verbose-1.rs:29:25
-   |
-LL | fn require_send(_: impl Send) {}
-   |                         ^^^^ required by this bound in `require_send`
-
-error[E0277]: `RefCell<i32>` cannot be shared between threads safely
-  --> $DIR/generator-print-verbose-1.rs:59:18
-   |
-LL |     require_send(send_gen);
-   |     ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
-   = note: required for `Arc<RefCell<i32>>` to implement `Send`
-note: required because it's used within this generator
-  --> $DIR/generator-print-verbose-1.rs:45:5
-   |
-LL |     || {
-   |     ^^
-note: required because it appears within the type `Opaque(DefId(0:35 ~ generator_print_verbose_1[7d1d]::make_gen2::{opaque#0}), [Arc<RefCell<i32>>])`
-  --> $DIR/generator-print-verbose-1.rs:44:30
-   |
-LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: required because it appears within the type `Opaque(DefId(0:36 ~ generator_print_verbose_1[7d1d]::make_non_send_generator2::{opaque#0}), [])`
-  --> $DIR/generator-print-verbose-1.rs:50:34
-   |
-LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: required because it captures the following types: `Opaque(DefId(0:36 ~ generator_print_verbose_1[7d1d]::make_non_send_generator2::{opaque#0}), [])`, `()`
-note: required because it's used within this generator
-  --> $DIR/generator-print-verbose-1.rs:55:20
-   |
-LL |     let send_gen = || {
-   |                    ^^
-note: required by a bound in `require_send`
-  --> $DIR/generator-print-verbose-1.rs:29:25
-   |
-LL | fn require_send(_: impl Send) {}
-   |                         ^^^^ required by this bound in `require_send`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generator/print/generator-print-verbose-1.no_drop_tracking.stderr b/tests/ui/generator/print/generator-print-verbose-1.no_drop_tracking.stderr
deleted file mode 100644
index 429b202f603..00000000000
--- a/tests/ui/generator/print/generator-print-verbose-1.no_drop_tracking.stderr
+++ /dev/null
@@ -1,64 +0,0 @@
-error: generator cannot be sent between threads safely
-  --> $DIR/generator-print-verbose-1.rs:40:18
-   |
-LL |     require_send(send_gen);
-   |                  ^^^^^^^^ generator is not `Send`
-   |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/generator-print-verbose-1.rs:38:9
-   |
-LL |         let _non_send_gen = make_non_send_generator();
-   |             ------------- has type `Opaque(DefId(0:34 ~ generator_print_verbose_1[7d1d]::make_non_send_generator::{opaque#0}), [])` which is not `Send`
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
-LL |     };
-   |     - `_non_send_gen` is later dropped here
-note: required by a bound in `require_send`
-  --> $DIR/generator-print-verbose-1.rs:29:25
-   |
-LL | fn require_send(_: impl Send) {}
-   |                         ^^^^ required by this bound in `require_send`
-
-error[E0277]: `RefCell<i32>` cannot be shared between threads safely
-  --> $DIR/generator-print-verbose-1.rs:59:18
-   |
-LL |     require_send(send_gen);
-   |     ------------ ^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
-   |     |
-   |     required by a bound introduced by this call
-   |
-   = help: the trait `Sync` is not implemented for `RefCell<i32>`
-   = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
-   = note: required for `Arc<RefCell<i32>>` to implement `Send`
-note: required because it's used within this generator
-  --> $DIR/generator-print-verbose-1.rs:45:5
-   |
-LL |     || {
-   |     ^^
-note: required because it appears within the type `Opaque(DefId(0:35 ~ generator_print_verbose_1[7d1d]::make_gen2::{opaque#0}), [Arc<RefCell<i32>>])`
-  --> $DIR/generator-print-verbose-1.rs:44:30
-   |
-LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
-note: required because it appears within the type `Opaque(DefId(0:36 ~ generator_print_verbose_1[7d1d]::make_non_send_generator2::{opaque#0}), [])`
-  --> $DIR/generator-print-verbose-1.rs:50:34
-   |
-LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   = note: required because it captures the following types: `Opaque(DefId(0:36 ~ generator_print_verbose_1[7d1d]::make_non_send_generator2::{opaque#0}), [])`, `()`
-note: required because it's used within this generator
-  --> $DIR/generator-print-verbose-1.rs:55:20
-   |
-LL |     let send_gen = || {
-   |                    ^^
-note: required by a bound in `require_send`
-  --> $DIR/generator-print-verbose-1.rs:29:25
-   |
-LL | fn require_send(_: impl Send) {}
-   |                         ^^^^ required by this bound in `require_send`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generator/print/generator-print-verbose-1.rs b/tests/ui/generator/print/generator-print-verbose-1.rs
index c7052c7d1b0..e52234c08a3 100644
--- a/tests/ui/generator/print/generator-print-verbose-1.rs
+++ b/tests/ui/generator/print/generator-print-verbose-1.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // compile-flags: -Zverbose
 
 // Same as: tests/ui/generator/issue-68112.stderr
diff --git a/tests/ui/generator/print/generator-print-verbose-1.drop_tracking_mir.stderr b/tests/ui/generator/print/generator-print-verbose-1.stderr
index 01a30fd2f4e..d949543de41 100644
--- a/tests/ui/generator/print/generator-print-verbose-1.drop_tracking_mir.stderr
+++ b/tests/ui/generator/print/generator-print-verbose-1.stderr
@@ -1,5 +1,5 @@
 error: generator cannot be sent between threads safely
-  --> $DIR/generator-print-verbose-1.rs:40:5
+  --> $DIR/generator-print-verbose-1.rs:37:5
    |
 LL |     require_send(send_gen);
    |     ^^^^^^^^^^^^ generator is not `Send`
@@ -7,20 +7,20 @@ LL |     require_send(send_gen);
    = help: the trait `Sync` is not implemented for `RefCell<i32>`
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/generator-print-verbose-1.rs:38:9
+  --> $DIR/generator-print-verbose-1.rs:35:9
    |
 LL |         let _non_send_gen = make_non_send_generator();
    |             ------------- has type `Opaque(DefId(0:34 ~ generator_print_verbose_1[7d1d]::make_non_send_generator::{opaque#0}), [])` which is not `Send`
 LL |         yield;
    |         ^^^^^ yield occurs here, with `_non_send_gen` maybe used later
 note: required by a bound in `require_send`
-  --> $DIR/generator-print-verbose-1.rs:29:25
+  --> $DIR/generator-print-verbose-1.rs:26:25
    |
 LL | fn require_send(_: impl Send) {}
    |                         ^^^^ required by this bound in `require_send`
 
 error[E0277]: `RefCell<i32>` cannot be shared between threads safely
-  --> $DIR/generator-print-verbose-1.rs:59:5
+  --> $DIR/generator-print-verbose-1.rs:56:5
    |
 LL |     require_send(send_gen);
    |     ^^^^^^^^^^^^ `RefCell<i32>` cannot be shared between threads safely
@@ -29,28 +29,28 @@ LL |     require_send(send_gen);
    = note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
    = note: required for `Arc<RefCell<i32>>` to implement `Send`
 note: required because it's used within this generator
-  --> $DIR/generator-print-verbose-1.rs:45:5
+  --> $DIR/generator-print-verbose-1.rs:42:5
    |
 LL |     || {
    |     ^^
 note: required because it appears within the type `Opaque(DefId(0:35 ~ generator_print_verbose_1[7d1d]::make_gen2::{opaque#0}), [Arc<RefCell<i32>>])`
-  --> $DIR/generator-print-verbose-1.rs:44:30
+  --> $DIR/generator-print-verbose-1.rs:41:30
    |
 LL | pub fn make_gen2<T>(t: T) -> impl Generator<Return = T> {
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: required because it appears within the type `Opaque(DefId(0:36 ~ generator_print_verbose_1[7d1d]::make_non_send_generator2::{opaque#0}), [])`
-  --> $DIR/generator-print-verbose-1.rs:50:34
+  --> $DIR/generator-print-verbose-1.rs:47:34
    |
 LL | fn make_non_send_generator2() -> impl Generator<Return = Arc<RefCell<i32>>> {
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: required because it captures the following types: `Opaque(DefId(0:36 ~ generator_print_verbose_1[7d1d]::make_non_send_generator2::{opaque#0}), [])`
 note: required because it's used within this generator
-  --> $DIR/generator-print-verbose-1.rs:55:20
+  --> $DIR/generator-print-verbose-1.rs:52:20
    |
 LL |     let send_gen = || {
    |                    ^^
 note: required by a bound in `require_send`
-  --> $DIR/generator-print-verbose-1.rs:29:25
+  --> $DIR/generator-print-verbose-1.rs:26:25
    |
 LL | fn require_send(_: impl Send) {}
    |                         ^^^^ required by this bound in `require_send`
diff --git a/tests/ui/generator/print/generator-print-verbose-2.drop_tracking.stderr b/tests/ui/generator/print/generator-print-verbose-2.drop_tracking.stderr
deleted file mode 100644
index 53b4cadacd0..00000000000
--- a/tests/ui/generator/print/generator-print-verbose-2.drop_tracking.stderr
+++ /dev/null
@@ -1,60 +0,0 @@
-error: generator cannot be shared between threads safely
-  --> $DIR/generator-print-verbose-2.rs:20:17
-   |
-LL |       assert_sync(|| {
-   |  _________________^
-LL | |
-LL | |         let a = NotSync;
-LL | |         yield;
-LL | |         drop(a);
-LL | |     });
-   | |_____^ generator is not `Sync`
-   |
-   = help: within `{main::{closure#0} upvar_tys=() {NotSync, ()}}`, the trait `Sync` is not implemented for `NotSync`
-note: generator is not `Sync` as this value is used across a yield
-  --> $DIR/generator-print-verbose-2.rs:23:9
-   |
-LL |         let a = NotSync;
-   |             - has type `NotSync` which is not `Sync`
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `a` maybe used later
-LL |         drop(a);
-LL |     });
-   |     - `a` is later dropped here
-note: required by a bound in `assert_sync`
-  --> $DIR/generator-print-verbose-2.rs:17:23
-   |
-LL |     fn assert_sync<T: Sync>(_: T) {}
-   |                       ^^^^ required by this bound in `assert_sync`
-
-error: generator cannot be sent between threads safely
-  --> $DIR/generator-print-verbose-2.rs:27:17
-   |
-LL |       assert_send(|| {
-   |  _________________^
-LL | |
-LL | |         let a = NotSend;
-LL | |         yield;
-LL | |         drop(a);
-LL | |     });
-   | |_____^ generator is not `Send`
-   |
-   = help: within `{main::{closure#1} upvar_tys=() {NotSend, ()}}`, the trait `Send` is not implemented for `NotSend`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/generator-print-verbose-2.rs:30:9
-   |
-LL |         let a = NotSend;
-   |             - has type `NotSend` which is not `Send`
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `a` maybe used later
-LL |         drop(a);
-LL |     });
-   |     - `a` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/generator-print-verbose-2.rs:18:23
-   |
-LL |     fn assert_send<T: Send>(_: T) {}
-   |                       ^^^^ required by this bound in `assert_send`
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/generator/print/generator-print-verbose-2.no_drop_tracking.stderr b/tests/ui/generator/print/generator-print-verbose-2.no_drop_tracking.stderr
deleted file mode 100644
index 53b4cadacd0..00000000000
--- a/tests/ui/generator/print/generator-print-verbose-2.no_drop_tracking.stderr
+++ /dev/null
@@ -1,60 +0,0 @@
-error: generator cannot be shared between threads safely
-  --> $DIR/generator-print-verbose-2.rs:20:17
-   |
-LL |       assert_sync(|| {
-   |  _________________^
-LL | |
-LL | |         let a = NotSync;
-LL | |         yield;
-LL | |         drop(a);
-LL | |     });
-   | |_____^ generator is not `Sync`
-   |
-   = help: within `{main::{closure#0} upvar_tys=() {NotSync, ()}}`, the trait `Sync` is not implemented for `NotSync`
-note: generator is not `Sync` as this value is used across a yield
-  --> $DIR/generator-print-verbose-2.rs:23:9
-   |
-LL |         let a = NotSync;
-   |             - has type `NotSync` which is not `Sync`
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `a` maybe used later
-LL |         drop(a);
-LL |     });
-   |     - `a` is later dropped here
-note: required by a bound in `assert_sync`
-  --> $DIR/generator-print-verbose-2.rs:17:23
-   |
-LL |     fn assert_sync<T: Sync>(_: T) {}
-   |                       ^^^^ required by this bound in `assert_sync`
-
-error: generator cannot be sent between threads safely
-  --> $DIR/generator-print-verbose-2.rs:27:17
-   |
-LL |       assert_send(|| {
-   |  _________________^
-LL | |
-LL | |         let a = NotSend;
-LL | |         yield;
-LL | |         drop(a);
-LL | |     });
-   | |_____^ generator is not `Send`
-   |
-   = help: within `{main::{closure#1} upvar_tys=() {NotSend, ()}}`, the trait `Send` is not implemented for `NotSend`
-note: generator is not `Send` as this value is used across a yield
-  --> $DIR/generator-print-verbose-2.rs:30:9
-   |
-LL |         let a = NotSend;
-   |             - has type `NotSend` which is not `Send`
-LL |         yield;
-   |         ^^^^^ yield occurs here, with `a` maybe used later
-LL |         drop(a);
-LL |     });
-   |     - `a` is later dropped here
-note: required by a bound in `assert_send`
-  --> $DIR/generator-print-verbose-2.rs:18:23
-   |
-LL |     fn assert_send<T: Send>(_: T) {}
-   |                       ^^^^ required by this bound in `assert_send`
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/generator/print/generator-print-verbose-2.rs b/tests/ui/generator/print/generator-print-verbose-2.rs
index ab29db6e09c..e53a7ef8cc1 100644
--- a/tests/ui/generator/print/generator-print-verbose-2.rs
+++ b/tests/ui/generator/print/generator-print-verbose-2.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // compile-flags: -Zverbose
 
 // Same as test/ui/generator/not-send-sync.rs
diff --git a/tests/ui/generator/print/generator-print-verbose-2.drop_tracking_mir.stderr b/tests/ui/generator/print/generator-print-verbose-2.stderr
index 937881340c6..8ff7557619f 100644
--- a/tests/ui/generator/print/generator-print-verbose-2.drop_tracking_mir.stderr
+++ b/tests/ui/generator/print/generator-print-verbose-2.stderr
@@ -1,39 +1,39 @@
 error: generator cannot be shared between threads safely
-  --> $DIR/generator-print-verbose-2.rs:20:5
+  --> $DIR/generator-print-verbose-2.rs:17:5
    |
 LL |     assert_sync(|| {
    |     ^^^^^^^^^^^ generator is not `Sync`
    |
    = help: within `{main::{closure#0} upvar_tys=() {main::{closure#0}}}`, the trait `Sync` is not implemented for `NotSync`
 note: generator is not `Sync` as this value is used across a yield
-  --> $DIR/generator-print-verbose-2.rs:23:9
+  --> $DIR/generator-print-verbose-2.rs:20:9
    |
 LL |         let a = NotSync;
    |             - has type `NotSync` which is not `Sync`
 LL |         yield;
    |         ^^^^^ yield occurs here, with `a` maybe used later
 note: required by a bound in `assert_sync`
-  --> $DIR/generator-print-verbose-2.rs:17:23
+  --> $DIR/generator-print-verbose-2.rs:14:23
    |
 LL |     fn assert_sync<T: Sync>(_: T) {}
    |                       ^^^^ required by this bound in `assert_sync`
 
 error: generator cannot be sent between threads safely
-  --> $DIR/generator-print-verbose-2.rs:27:5
+  --> $DIR/generator-print-verbose-2.rs:24:5
    |
 LL |     assert_send(|| {
    |     ^^^^^^^^^^^ generator is not `Send`
    |
    = help: within `{main::{closure#1} upvar_tys=() {main::{closure#1}}}`, the trait `Send` is not implemented for `NotSend`
 note: generator is not `Send` as this value is used across a yield
-  --> $DIR/generator-print-verbose-2.rs:30:9
+  --> $DIR/generator-print-verbose-2.rs:27:9
    |
 LL |         let a = NotSend;
    |             - has type `NotSend` which is not `Send`
 LL |         yield;
    |         ^^^^^ yield occurs here, with `a` maybe used later
 note: required by a bound in `assert_send`
-  --> $DIR/generator-print-verbose-2.rs:18:23
+  --> $DIR/generator-print-verbose-2.rs:15:23
    |
 LL |     fn assert_send<T: Send>(_: T) {}
    |                       ^^^^ required by this bound in `assert_send`
diff --git a/tests/ui/generator/retain-resume-ref.drop_tracking.stderr b/tests/ui/generator/retain-resume-ref.drop_tracking.stderr
deleted file mode 100644
index 7122a951e80..00000000000
--- a/tests/ui/generator/retain-resume-ref.drop_tracking.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0499]: cannot borrow `thing` as mutable more than once at a time
-  --> $DIR/retain-resume-ref.rs:27:25
-   |
-LL |     gen.as_mut().resume(&mut thing);
-   |                         ---------- first mutable borrow occurs here
-LL |     gen.as_mut().resume(&mut thing);
-   |                  ------ ^^^^^^^^^^ second mutable borrow occurs here
-   |                  |
-   |                  first borrow later used by call
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0499`.
diff --git a/tests/ui/generator/retain-resume-ref.no_drop_tracking.stderr b/tests/ui/generator/retain-resume-ref.no_drop_tracking.stderr
deleted file mode 100644
index 7122a951e80..00000000000
--- a/tests/ui/generator/retain-resume-ref.no_drop_tracking.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0499]: cannot borrow `thing` as mutable more than once at a time
-  --> $DIR/retain-resume-ref.rs:27:25
-   |
-LL |     gen.as_mut().resume(&mut thing);
-   |                         ---------- first mutable borrow occurs here
-LL |     gen.as_mut().resume(&mut thing);
-   |                  ------ ^^^^^^^^^^ second mutable borrow occurs here
-   |                  |
-   |                  first borrow later used by call
-
-error: aborting due to previous error
-
-For more information about this error, try `rustc --explain E0499`.
diff --git a/tests/ui/generator/retain-resume-ref.rs b/tests/ui/generator/retain-resume-ref.rs
index 0050d98d03b..0606ea71cdf 100644
--- a/tests/ui/generator/retain-resume-ref.rs
+++ b/tests/ui/generator/retain-resume-ref.rs
@@ -1,7 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-
 //! This test ensures that a mutable reference cannot be passed as a resume argument twice.
 
 #![feature(generators, generator_trait)]
diff --git a/tests/ui/generator/retain-resume-ref.drop_tracking_mir.stderr b/tests/ui/generator/retain-resume-ref.stderr
index 736ed1fb608..bc715c7030e 100644
--- a/tests/ui/generator/retain-resume-ref.drop_tracking_mir.stderr
+++ b/tests/ui/generator/retain-resume-ref.stderr
@@ -1,5 +1,5 @@
 error[E0499]: cannot borrow `thing` as mutable more than once at a time
-  --> $DIR/retain-resume-ref.rs:27:25
+  --> $DIR/retain-resume-ref.rs:23:25
    |
 LL |     gen.as_mut().resume(&mut thing);
    |                         ---------- first mutable borrow occurs here
diff --git a/tests/ui/generator/static-mut-reference-across-yield.rs b/tests/ui/generator/static-mut-reference-across-yield.rs
index 4784ff49be2..0fa6d9cdc77 100644
--- a/tests/ui/generator/static-mut-reference-across-yield.rs
+++ b/tests/ui/generator/static-mut-reference-across-yield.rs
@@ -1,8 +1,6 @@
 // build-pass
-// revisions: mir thir drop_tracking drop_tracking_mir
+// revisions: mir thir
 // [thir]compile-flags: -Zthir-unsafeck
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 
 #![feature(generators)]
 
diff --git a/tests/ui/generator/unresolved-ct-var-drop-tracking.rs b/tests/ui/generator/unresolved-ct-var-drop-tracking.rs
deleted file mode 100644
index a6589348d30..00000000000
--- a/tests/ui/generator/unresolved-ct-var-drop-tracking.rs
+++ /dev/null
@@ -1,15 +0,0 @@
-// incremental
-// edition:2021
-// compile-flags: -Zdrop-tracking
-
-fn main() {
-    let _ = async {
-        let s = std::array::from_fn(|_| ()).await;
-        //~^ ERROR `[(); _]` is not a future
-        //~| ERROR type inside `async` block must be known in this context
-        //~| ERROR type inside `async` block must be known in this context
-        //~| ERROR type inside `async` block must be known in this context
-        //~| ERROR type inside `async` block must be known in this context
-        //~| ERROR type inside `async` block must be known in this context
-    };
-}
diff --git a/tests/ui/generator/unresolved-ct-var-drop-tracking.stderr b/tests/ui/generator/unresolved-ct-var-drop-tracking.stderr
deleted file mode 100644
index dec0141ab67..00000000000
--- a/tests/ui/generator/unresolved-ct-var-drop-tracking.stderr
+++ /dev/null
@@ -1,78 +0,0 @@
-error[E0277]: `[(); _]` is not a future
-  --> $DIR/unresolved-ct-var-drop-tracking.rs:7:45
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                 ----------------------------^^^^^
-   |                 |                          ||
-   |                 |                          |`[(); _]` is not a future
-   |                 |                          help: remove the `.await`
-   |                 this call returns `[(); _]`
-   |
-   = help: the trait `Future` is not implemented for `[(); _]`
-   = note: [(); _] must be a future or must implement `IntoFuture` to be awaited
-   = note: required for `[(); _]` to implement `IntoFuture`
-
-error[E0698]: type inside `async` block must be known in this context
-  --> $DIR/unresolved-ct-var-drop-tracking.rs:7:17
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                 ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
-   |
-note: the type is part of the `async` block because of this `await`
-  --> $DIR/unresolved-ct-var-drop-tracking.rs:7:45
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                                             ^^^^^
-
-error[E0698]: type inside `async` block must be known in this context
-  --> $DIR/unresolved-ct-var-drop-tracking.rs:7:17
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                 ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
-   |
-note: the type is part of the `async` block because of this `await`
-  --> $DIR/unresolved-ct-var-drop-tracking.rs:7:45
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                                             ^^^^^
-
-error[E0698]: type inside `async` block must be known in this context
-  --> $DIR/unresolved-ct-var-drop-tracking.rs:7:17
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                 ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
-   |
-note: the type is part of the `async` block because of this `await`
-  --> $DIR/unresolved-ct-var-drop-tracking.rs:7:45
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                                             ^^^^^
-
-error[E0698]: type inside `async` block must be known in this context
-  --> $DIR/unresolved-ct-var-drop-tracking.rs:7:17
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                 ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
-   |
-note: the type is part of the `async` block because of this `await`
-  --> $DIR/unresolved-ct-var-drop-tracking.rs:7:45
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                                             ^^^^^
-
-error[E0698]: type inside `async` block must be known in this context
-  --> $DIR/unresolved-ct-var-drop-tracking.rs:7:17
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                 ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
-   |
-note: the type is part of the `async` block because of this `await`
-  --> $DIR/unresolved-ct-var-drop-tracking.rs:7:45
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                                             ^^^^^
-
-error: aborting due to 6 previous errors
-
-Some errors have detailed explanations: E0277, E0698.
-For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/generator/unresolved-ct-var.rs b/tests/ui/generator/unresolved-ct-var.rs
index 0a1570fc239..0316385fba9 100644
--- a/tests/ui/generator/unresolved-ct-var.rs
+++ b/tests/ui/generator/unresolved-ct-var.rs
@@ -5,10 +5,5 @@ fn main() {
     let _ = async {
         let s = std::array::from_fn(|_| ()).await;
         //~^ ERROR `[(); _]` is not a future
-        //~| ERROR type inside `async` block must be known in this context
-        //~| ERROR type inside `async` block must be known in this context
-        //~| ERROR type inside `async` block must be known in this context
-        //~| ERROR type inside `async` block must be known in this context
-        //~| ERROR type inside `async` block must be known in this context
     };
 }
diff --git a/tests/ui/generator/unresolved-ct-var.stderr b/tests/ui/generator/unresolved-ct-var.stderr
index ace254178b7..9badc1dc291 100644
--- a/tests/ui/generator/unresolved-ct-var.stderr
+++ b/tests/ui/generator/unresolved-ct-var.stderr
@@ -12,67 +12,6 @@ LL |         let s = std::array::from_fn(|_| ()).await;
    = note: [(); _] must be a future or must implement `IntoFuture` to be awaited
    = note: required for `[(); _]` to implement `IntoFuture`
 
-error[E0698]: type inside `async` block must be known in this context
-  --> $DIR/unresolved-ct-var.rs:6:17
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                 ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
-   |
-note: the type is part of the `async` block because of this `await`
-  --> $DIR/unresolved-ct-var.rs:6:45
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                                             ^^^^^
-
-error[E0698]: type inside `async` block must be known in this context
-  --> $DIR/unresolved-ct-var.rs:6:17
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                 ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
-   |
-note: the type is part of the `async` block because of this `await`
-  --> $DIR/unresolved-ct-var.rs:6:45
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                                             ^^^^^
-
-error[E0698]: type inside `async` block must be known in this context
-  --> $DIR/unresolved-ct-var.rs:6:17
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                 ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
-   |
-note: the type is part of the `async` block because of this `await`
-  --> $DIR/unresolved-ct-var.rs:6:45
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                                             ^^^^^
-
-error[E0698]: type inside `async` block must be known in this context
-  --> $DIR/unresolved-ct-var.rs:6:17
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                 ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
-   |
-note: the type is part of the `async` block because of this `await`
-  --> $DIR/unresolved-ct-var.rs:6:45
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                                             ^^^^^
-
-error[E0698]: type inside `async` block must be known in this context
-  --> $DIR/unresolved-ct-var.rs:6:17
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                 ^^^^^^^^^^^^^^^^^^^ cannot infer the value of const parameter `N` declared on the function `from_fn`
-   |
-note: the type is part of the `async` block because of this `await`
-  --> $DIR/unresolved-ct-var.rs:6:45
-   |
-LL |         let s = std::array::from_fn(|_| ()).await;
-   |                                             ^^^^^
-
-error: aborting due to 6 previous errors
+error: aborting due to previous error
 
-Some errors have detailed explanations: E0277, E0698.
-For more information about an error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generator/unsized-capture-across-yield.rs b/tests/ui/generator/unsized-capture-across-yield.rs
new file mode 100644
index 00000000000..7bcb0800ccf
--- /dev/null
+++ b/tests/ui/generator/unsized-capture-across-yield.rs
@@ -0,0 +1,22 @@
+#![feature(generator_trait)]
+#![feature(generators)]
+#![feature(unsized_locals)]
+//~^ WARN the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
+
+use std::ops::Generator;
+
+fn capture() -> impl Generator {
+    let b: [u8] = *(Box::new([]) as Box<[u8]>);
+    move || {
+        println!("{:?}", &b);
+        //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
+
+        yield;
+
+        for elem in b.iter() {}
+    }
+}
+
+fn main() {
+    capture();
+}
diff --git a/tests/ui/generator/unsized-capture-across-yield.stderr b/tests/ui/generator/unsized-capture-across-yield.stderr
new file mode 100644
index 00000000000..8a5b968a561
--- /dev/null
+++ b/tests/ui/generator/unsized-capture-across-yield.stderr
@@ -0,0 +1,23 @@
+warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/unsized-capture-across-yield.rs:3:12
+   |
+LL | #![feature(unsized_locals)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/unsized-capture-across-yield.rs:11:27
+   |
+LL |     move || {
+   |          -- this closure captures all values by move
+LL |         println!("{:?}", &b);
+   |                           ^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+   = note: all values captured by value by a closure must have a statically known size
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generator/unsized-local-across-yield.rs b/tests/ui/generator/unsized-local-across-yield.rs
new file mode 100644
index 00000000000..f761f45c2af
--- /dev/null
+++ b/tests/ui/generator/unsized-local-across-yield.rs
@@ -0,0 +1,21 @@
+#![feature(generator_trait)]
+#![feature(generators)]
+#![feature(unsized_locals)]
+//~^ WARN the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
+
+use std::ops::Generator;
+
+fn across() -> impl Generator {
+    move || {
+        let b: [u8] = *(Box::new([]) as Box<[u8]>);
+        //~^ ERROR the size for values of type `[u8]` cannot be known at compilation time
+
+        yield;
+
+        for elem in b.iter() {}
+    }
+}
+
+fn main() {
+    across();
+}
diff --git a/tests/ui/generator/unsized-local-across-yield.stderr b/tests/ui/generator/unsized-local-across-yield.stderr
new file mode 100644
index 00000000000..1942f266e6c
--- /dev/null
+++ b/tests/ui/generator/unsized-local-across-yield.stderr
@@ -0,0 +1,21 @@
+warning: the feature `unsized_locals` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/unsized-local-across-yield.rs:3:12
+   |
+LL | #![feature(unsized_locals)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #48055 <https://github.com/rust-lang/rust/issues/48055> for more information
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the size for values of type `[u8]` cannot be known at compilation time
+  --> $DIR/unsized-local-across-yield.rs:10:13
+   |
+LL |         let b: [u8] = *(Box::new([]) as Box<[u8]>);
+   |             ^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `[u8]`
+   = note: all values live across `yield` must have a statically known size
+
+error: aborting due to previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/generic-associated-types/bugs/issue-100013.stderr b/tests/ui/generic-associated-types/bugs/issue-100013.stderr
index 86dbad84d99..93c69422f00 100644
--- a/tests/ui/generic-associated-types/bugs/issue-100013.stderr
+++ b/tests/ui/generic-associated-types/bugs/issue-100013.stderr
@@ -7,16 +7,6 @@ LL | |         async {}.await; // a yield point
 LL | |     }
    | |_____^
    |
-note: the lifetime defined here...
-  --> $DIR/issue-100013.rs:16:38
-   |
-LL |         let x = None::<I::Future<'_, '_>>; // a type referencing GAT
-   |                                      ^^
-note: ...must outlive the lifetime defined here
-  --> $DIR/issue-100013.rs:16:34
-   |
-LL |         let x = None::<I::Future<'_, '_>>; // a type referencing GAT
-   |                                  ^^
    = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
 
 error: lifetime bound not satisfied
@@ -28,16 +18,6 @@ LL | |         async {}.await; // a yield point
 LL | |     }
    | |_____^
    |
-note: the lifetime `'b` defined here...
-  --> $DIR/issue-100013.rs:21:14
-   |
-LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send {
-   |              ^^
-note: ...must outlive the lifetime `'a` defined here
-  --> $DIR/issue-100013.rs:21:10
-   |
-LL | fn call2<'a, 'b, I: FutureIterator>() -> impl Send {
-   |          ^^
    = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
 
 error: lifetime may not live long enough
@@ -62,16 +42,6 @@ LL | |         async {}.await; // a yield point
 LL | |     }
    | |_____^
    |
-note: the lifetime `'b` defined here...
-  --> $DIR/issue-100013.rs:28:18
-   |
-LL | fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send {
-   |                  ^^
-note: ...must outlive the lifetime `'a` defined here
-  --> $DIR/issue-100013.rs:28:10
-   |
-LL | fn call3<'a: 'b, 'b, I: FutureIterator>() -> impl Send {
-   |          ^^
    = note: this is a known limitation that will be removed in the future (see issue #100013 <https://github.com/rust-lang/rust/issues/100013> for more information)
 
 error: aborting due to 4 previous errors
diff --git a/tests/ui/generic-const-items/elided-lifetimes.stderr b/tests/ui/generic-const-items/elided-lifetimes.stderr
index 8cd3f9ee7a9..e7df8ca5cfd 100644
--- a/tests/ui/generic-const-items/elided-lifetimes.stderr
+++ b/tests/ui/generic-const-items/elided-lifetimes.stderr
@@ -28,7 +28,7 @@ LL | const I<const S: &str>: &str = "";
    |                  ^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/generics/issue-83556.rs b/tests/ui/generics/issue-83556.rs
new file mode 100644
index 00000000000..7cea1c8631f
--- /dev/null
+++ b/tests/ui/generics/issue-83556.rs
@@ -0,0 +1,4 @@
+struct Foo<T, 'a>(&'a ());
+//~^ ERROR lifetime parameters must be declared prior to
+
+fn main() {}
diff --git a/tests/ui/generics/issue-83556.stderr b/tests/ui/generics/issue-83556.stderr
new file mode 100644
index 00000000000..93affaffe60
--- /dev/null
+++ b/tests/ui/generics/issue-83556.stderr
@@ -0,0 +1,8 @@
+error: lifetime parameters must be declared prior to type and const parameters
+  --> $DIR/issue-83556.rs:1:15
+   |
+LL | struct Foo<T, 'a>(&'a ());
+   |           ----^^- help: reorder the parameters: lifetimes, then consts and types: `<'a, T>`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/impl-trait/bound-normalization-fail.rs b/tests/ui/impl-trait/bound-normalization-fail.rs
index 3329592478d..566a4a7adcc 100644
--- a/tests/ui/impl-trait/bound-normalization-fail.rs
+++ b/tests/ui/impl-trait/bound-normalization-fail.rs
@@ -39,8 +39,7 @@ mod lifetimes {
 
     /// Missing bound constraining `Assoc`, `T::Assoc` can't be normalized further.
     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
-        //~^ ERROR `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
-        //~| ERROR: type mismatch
+        //~^ ERROR: type mismatch
         Foo(())
     }
 }
diff --git a/tests/ui/impl-trait/bound-normalization-fail.stderr b/tests/ui/impl-trait/bound-normalization-fail.stderr
index f04a753a0e8..fcac9ac34db 100644
--- a/tests/ui/impl-trait/bound-normalization-fail.stderr
+++ b/tests/ui/impl-trait/bound-normalization-fail.stderr
@@ -19,21 +19,12 @@ help: consider constraining the associated type `<T as impl_trait::Trait>::Assoc
 LL |     fn foo_fail<T: Trait<Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
    |                         ++++++++++++
 
-error[E0658]: `impl Trait` return type cannot contain a projection or `Self` that references lifetimes from a parent scope
-  --> $DIR/bound-normalization-fail.rs:41:41
-   |
-LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
-   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #103532 <https://github.com/rust-lang/rust/issues/103532> for more information
-   = help: add `#![feature(impl_trait_projections)]` to the crate attributes to enable
-
 error[E0271]: type mismatch resolving `<Foo<()> as FooLike>::Output == <T as Trait<'a>>::Assoc`
   --> $DIR/bound-normalization-fail.rs:41:41
    |
 LL |     fn foo2_fail<'a, T: Trait<'a>>() -> impl FooLike<Output = T::Assoc> {
    |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type mismatch resolving `<Foo<()> as FooLike>::Output == <T as Trait<'a>>::Assoc`
-...
+LL |
 LL |         Foo(())
    |         ------- return type was inferred to be `Foo<()>` here
    |
@@ -49,7 +40,6 @@ help: consider constraining the associated type `<T as lifetimes::Trait<'a>>::As
 LL |     fn foo2_fail<'a, T: Trait<'a, Assoc = ()>>() -> impl FooLike<Output = T::Assoc> {
    |                                 ++++++++++++
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0271, E0658.
-For more information about an error, try `rustc --explain E0271`.
+For more information about this error, try `rustc --explain E0271`.
diff --git a/tests/ui/impl-trait/capture-lifetime-not-in-hir.rs b/tests/ui/impl-trait/capture-lifetime-not-in-hir.rs
new file mode 100644
index 00000000000..9c067cb6934
--- /dev/null
+++ b/tests/ui/impl-trait/capture-lifetime-not-in-hir.rs
@@ -0,0 +1,21 @@
+#![feature(rustc_attrs)]
+#![rustc_variance_of_opaques]
+
+trait Bar<'a> {
+    type Assoc: From<()>;
+}
+
+fn foo<'a, T: Bar<'a>>() -> impl Into<T::Assoc> {
+    //~^ ERROR [o, o]
+    // captures both T and 'a invariantly
+    ()
+}
+
+fn foo2<'a, T: Bar<'a>>() -> impl Into<T::Assoc> + 'a {
+    //~^ ERROR [o, o, o]
+    // captures both T and 'a invariantly, and also duplicates `'a`
+    // i.e. the opaque looks like `impl Into<<T as Bar<'a>>::Assoc> + 'a_duplicated`
+    ()
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/capture-lifetime-not-in-hir.stderr b/tests/ui/impl-trait/capture-lifetime-not-in-hir.stderr
new file mode 100644
index 00000000000..9d52001b024
--- /dev/null
+++ b/tests/ui/impl-trait/capture-lifetime-not-in-hir.stderr
@@ -0,0 +1,14 @@
+error: [o, o]
+  --> $DIR/capture-lifetime-not-in-hir.rs:8:29
+   |
+LL | fn foo<'a, T: Bar<'a>>() -> impl Into<T::Assoc> {
+   |                             ^^^^^^^^^^^^^^^^^^^
+
+error: [o, o, o]
+  --> $DIR/capture-lifetime-not-in-hir.rs:14:30
+   |
+LL | fn foo2<'a, T: Bar<'a>>() -> impl Into<T::Assoc> + 'a {
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/impl-trait/feature-self-return-type.rs b/tests/ui/impl-trait/feature-self-return-type.rs
index 51877e9cc3c..7555df1b2c7 100644
--- a/tests/ui/impl-trait/feature-self-return-type.rs
+++ b/tests/ui/impl-trait/feature-self-return-type.rs
@@ -1,5 +1,4 @@
 // edition:2018
-#![feature(impl_trait_projections)]
 
 // This test checks that we emit the correct borrowck error when `Self` or a projection is used as
 // a return type.  See #61949 for context.
diff --git a/tests/ui/impl-trait/feature-self-return-type.stderr b/tests/ui/impl-trait/feature-self-return-type.stderr
index b9b8d00ce30..e7113a9dfb1 100644
--- a/tests/ui/impl-trait/feature-self-return-type.stderr
+++ b/tests/ui/impl-trait/feature-self-return-type.stderr
@@ -1,5 +1,5 @@
 error[E0597]: `bar` does not live long enough
-  --> $DIR/feature-self-return-type.rs:23:22
+  --> $DIR/feature-self-return-type.rs:22:22
    |
 LL |         let x = {
    |             - borrow later stored here
@@ -12,7 +12,7 @@ LL |         };
    |         - `bar` dropped here while still borrowed
 
 error[E0597]: `y` does not live long enough
-  --> $DIR/feature-self-return-type.rs:63:17
+  --> $DIR/feature-self-return-type.rs:62:17
    |
 LL |         let x = {
    |             - borrow later stored here
@@ -25,7 +25,7 @@ LL |         };
    |         - `y` dropped here while still borrowed
 
 error[E0597]: `y` does not live long enough
-  --> $DIR/feature-self-return-type.rs:95:17
+  --> $DIR/feature-self-return-type.rs:94:17
    |
 LL |         let x = {
    |             - borrow later stored here
diff --git a/tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs b/tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs
new file mode 100644
index 00000000000..e62662f2f07
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/anonymize-binders-for-refine.rs
@@ -0,0 +1,13 @@
+// compile-flags: --crate-type=lib
+// check-pass
+
+#![feature(return_position_impl_trait_in_trait)]
+#![deny(refining_impl_trait)]
+
+pub trait Tr<T> {
+    fn foo() -> impl for<'a> Tr<&'a Self>;
+}
+
+impl<T> Tr<T> for () {
+    fn foo() -> impl for<'a> Tr<&'a Self> {}
+}
diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs
new file mode 100644
index 00000000000..5e14a7f8e72
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.rs
@@ -0,0 +1,26 @@
+#![feature(return_position_impl_trait_in_trait)]
+
+trait Extend {
+    fn extend<'a: 'a>(_: &'a str) -> (impl Sized + 'a, &'static str);
+}
+
+impl Extend for () {
+    fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
+    //~^ ERROR in type `&'static &'a ()`, reference has a longer lifetime than the data it references
+    where
+        'a: 'static,
+    {
+        (None, s)
+    }
+}
+
+// This indirection is not necessary for reproduction,
+// but it makes this test future-proof against #114936.
+fn extend<T: Extend>(s: &str) -> &'static str {
+    <T as Extend>::extend(s).1
+}
+
+fn main() {
+    let use_after_free = extend::<()>(&String::from("temporary"));
+    println!("{}", use_after_free);
+}
diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr
new file mode 100644
index 00000000000..1d947310e12
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf-via-param.stderr
@@ -0,0 +1,16 @@
+error[E0491]: in type `&'static &'a ()`, reference has a longer lifetime than the data it references
+  --> $DIR/rpitit-hidden-types-self-implied-wf-via-param.rs:8:38
+   |
+LL |     fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
+   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the pointer is valid for the static lifetime
+note: but the referenced data is only valid for the lifetime `'a` as defined here
+  --> $DIR/rpitit-hidden-types-self-implied-wf-via-param.rs:8:15
+   |
+LL |     fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
+   |               ^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0491`.
diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs
new file mode 100644
index 00000000000..c1885af4e5e
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.rs
@@ -0,0 +1,23 @@
+#![feature(return_position_impl_trait_in_trait)]
+
+trait Extend {
+    fn extend(_: &str) -> (impl Sized + '_, &'static str);
+}
+
+impl Extend for () {
+    fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) {
+        //~^ ERROR in type `&'static &()`, reference has a longer lifetime than the data it references
+        (None, s)
+    }
+}
+
+// This indirection is not necessary for reproduction,
+// but it makes this test future-proof against #114936.
+fn extend<T: Extend>(s: &str) -> &'static str {
+    <T as Extend>::extend(s).1
+}
+
+fn main() {
+    let use_after_free = extend::<()>(&String::from("temporary"));
+    println!("{}", use_after_free);
+}
diff --git a/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr
new file mode 100644
index 00000000000..7b63e72acbf
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/rpitit-hidden-types-self-implied-wf.stderr
@@ -0,0 +1,16 @@
+error[E0491]: in type `&'static &()`, reference has a longer lifetime than the data it references
+  --> $DIR/rpitit-hidden-types-self-implied-wf.rs:8:27
+   |
+LL |     fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) {
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: the pointer is valid for the static lifetime
+note: but the referenced data is only valid for the anonymous lifetime defined here
+  --> $DIR/rpitit-hidden-types-self-implied-wf.rs:8:18
+   |
+LL |     fn extend(s: &str) -> (Option<&'static &'_ ()>, &'static str) {
+   |                  ^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0491`.
diff --git a/tests/ui/impl-trait/issue-55872-2.drop_tracking.stderr b/tests/ui/impl-trait/issue-55872-2.drop_tracking.stderr
deleted file mode 100644
index 477c964bd40..00000000000
--- a/tests/ui/impl-trait/issue-55872-2.drop_tracking.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/issue-55872-2.rs:17:9
-   |
-LL |         async {}
-   |         ^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/tests/ui/impl-trait/issue-55872-2.no_drop_tracking.stderr b/tests/ui/impl-trait/issue-55872-2.no_drop_tracking.stderr
deleted file mode 100644
index 477c964bd40..00000000000
--- a/tests/ui/impl-trait/issue-55872-2.no_drop_tracking.stderr
+++ /dev/null
@@ -1,8 +0,0 @@
-error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/issue-55872-2.rs:17:9
-   |
-LL |         async {}
-   |         ^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/tests/ui/impl-trait/issue-55872-2.rs b/tests/ui/impl-trait/issue-55872-2.rs
index 7a5cb3b3dfc..8a96fdc5c63 100644
--- a/tests/ui/impl-trait/issue-55872-2.rs
+++ b/tests/ui/impl-trait/issue-55872-2.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2018
 
 #![feature(impl_trait_in_assoc_type)]
@@ -16,7 +13,7 @@ impl<S> Bar for S {
     fn foo<T>() -> Self::E {
         async {}
         //~^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-        //[drop_tracking_mir]~^^ ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
+        //~| ERROR type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
     }
 }
 
diff --git a/tests/ui/impl-trait/issue-55872-2.drop_tracking_mir.stderr b/tests/ui/impl-trait/issue-55872-2.stderr
index c14bb5cc914..3e70f1cf800 100644
--- a/tests/ui/impl-trait/issue-55872-2.drop_tracking_mir.stderr
+++ b/tests/ui/impl-trait/issue-55872-2.stderr
@@ -1,11 +1,11 @@
 error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/issue-55872-2.rs:17:9
+  --> $DIR/issue-55872-2.rs:14:9
    |
 LL |         async {}
    |         ^^^^^^^^
 
 error: type parameter `T` is part of concrete type but not used in parameter list for the `impl Trait` type alias
-  --> $DIR/issue-55872-2.rs:17:9
+  --> $DIR/issue-55872-2.rs:14:9
    |
 LL |         async {}
    |         ^^^^^^^^
diff --git a/tests/ui/impl-trait/opaque-cast-field-access-in-future.rs b/tests/ui/impl-trait/opaque-cast-field-access-in-future.rs
new file mode 100644
index 00000000000..3e3bc09a62a
--- /dev/null
+++ b/tests/ui/impl-trait/opaque-cast-field-access-in-future.rs
@@ -0,0 +1,27 @@
+// edition: 2021
+
+use std::future::Future;
+
+async fn bop() {
+    fold(run(), |mut foo| async move {
+        &mut foo.bar;
+    })
+}
+
+fn fold<Fut, F, U>(_: Foo<U>, f: F)
+where
+    F: FnMut(Foo<U>) -> Fut,
+{
+    loop {}
+}
+
+struct Foo<F> {
+    bar: Vec<F>,
+}
+
+fn run() -> Foo<impl Future<Output = ()>> {
+    //~^ ERROR type annotations needed
+    loop {}
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr b/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr
new file mode 100644
index 00000000000..ee4343b110f
--- /dev/null
+++ b/tests/ui/impl-trait/opaque-cast-field-access-in-future.stderr
@@ -0,0 +1,9 @@
+error[E0282]: type annotations needed
+  --> $DIR/opaque-cast-field-access-in-future.rs:22:17
+   |
+LL | fn run() -> Foo<impl Future<Output = ()>> {
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0282`.
diff --git a/tests/ui/impl-trait/recursive-generator.rs b/tests/ui/impl-trait/recursive-generator.rs
index e876f0fb43f..000af70c454 100644
--- a/tests/ui/impl-trait/recursive-generator.rs
+++ b/tests/ui/impl-trait/recursive-generator.rs
@@ -7,7 +7,6 @@ fn foo() -> impl Generator<Yield = (), Return = ()> {
     //~| NOTE recursive opaque type
     //~| NOTE in this expansion of desugaring of
     || {
-    //~^ NOTE returning here
         let mut gen = Box::pin(foo());
         //~^ NOTE generator captures itself here
         let mut r = gen.as_mut().resume(());
diff --git a/tests/ui/impl-trait/recursive-generator.stderr b/tests/ui/impl-trait/recursive-generator.stderr
index 9d8139ef114..86e193d9599 100644
--- a/tests/ui/impl-trait/recursive-generator.stderr
+++ b/tests/ui/impl-trait/recursive-generator.stderr
@@ -1,18 +1,11 @@
 error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-generator.rs:5:13
    |
-LL |   fn foo() -> impl Generator<Yield = (), Return = ()> {
-   |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive opaque type
+LL | fn foo() -> impl Generator<Yield = (), Return = ()> {
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ recursive opaque type
 ...
-LL | /     || {
-LL | |
-LL | |         let mut gen = Box::pin(foo());
-   | |             ------- generator captures itself here
-LL | |
-...  |
-LL | |         }
-LL | |     }
-   | |_____- returning here with type `{generator@$DIR/recursive-generator.rs:9:5: 9:7}`
+LL |         let mut gen = Box::pin(foo());
+   |             ------- generator captures itself here
 
 error: aborting due to previous error
 
diff --git a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.drop_tracking.stderr b/tests/ui/impl-trait/recursive-impl-trait-type-indirect.drop_tracking.stderr
deleted file mode 100644
index 4d4090f27fc..00000000000
--- a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.drop_tracking.stderr
+++ /dev/null
@@ -1,152 +0,0 @@
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:11:22
-   |
-LL | fn option(i: i32) -> impl Sized {
-   |                      ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     if i < 0 { None } else { Some((option(i - 1), i)) }
-   |                ----          ------------------------ returning here with type `Option<(impl Sized, i32)>`
-   |                |
-   |                returning here with type `Option<(impl Sized, i32)>`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:16:15
-   |
-LL | fn tuple() -> impl Sized {
-   |               ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     (tuple(),)
-   |     ---------- returning here with type `(impl Sized,)`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:21:15
-   |
-LL | fn array() -> impl Sized {
-   |               ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     [array()]
-   |     --------- returning here with type `[impl Sized; 1]`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:26:13
-   |
-LL | fn ptr() -> impl Sized {
-   |             ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     &ptr() as *const _
-   |     ------------------ returning here with type `*const impl Sized`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:31:16
-   |
-LL | fn fn_ptr() -> impl Sized {
-   |                ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     fn_ptr as fn() -> _
-   |     ------------------- returning here with type `fn() -> impl Sized`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:36:25
-   |
-LL |   fn closure_capture() -> impl Sized {
-   |                           ^^^^^^^^^^ recursive opaque type
-...
-LL | /     move || {
-LL | |         x;
-   | |         - closure captures itself here
-LL | |     }
-   | |_____- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:39:5: 39:12}`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:44:29
-   |
-LL |   fn closure_ref_capture() -> impl Sized {
-   |                               ^^^^^^^^^^ recursive opaque type
-...
-LL | /     move || {
-LL | |         &x;
-   | |          - closure captures itself here
-LL | |     }
-   | |_____- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:47:5: 47:12}`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:52:21
-   |
-LL | fn closure_sig() -> impl Sized {
-   |                     ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     || closure_sig()
-   |     ---------------- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:54:5: 54:7}`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:57:23
-   |
-LL | fn generator_sig() -> impl Sized {
-   |                       ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     || generator_sig()
-   |     ------------------ returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:59:5: 59:7}`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:62:27
-   |
-LL |   fn generator_capture() -> impl Sized {
-   |                             ^^^^^^^^^^ recursive opaque type
-...
-LL | /     move || {
-LL | |         yield;
-LL | |         x;
-   | |         - generator captures itself here
-LL | |     }
-   | |_____- returning here with type `{generator@$DIR/recursive-impl-trait-type-indirect.rs:65:5: 65:12}`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:71:35
-   |
-LL | fn substs_change<T: 'static>() -> impl Sized {
-   |                                   ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     (substs_change::<&T>(),)
-   |     ------------------------ returning here with type `(impl Sized,)`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:76:24
-   |
-LL |   fn generator_hold() -> impl Sized {
-   |                          ^^^^^^^^^^ recursive opaque type
-LL |
-LL | /     move || {
-LL | |         let x = generator_hold();
-   | |             - generator captures itself here
-LL | |         yield;
-LL | |         x;
-LL | |     }
-   | |_____- returning here with type `{generator@$DIR/recursive-impl-trait-type-indirect.rs:78:5: 78:12}`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:90:26
-   |
-LL | fn mutual_recursion() -> impl Sync {
-   |                          ^^^^^^^^^ recursive opaque type
-LL |
-LL |     mutual_recursion_b()
-   |     -------------------- returning here with type `impl Sized`
-...
-LL | fn mutual_recursion_b() -> impl Sized {
-   |                            ---------- returning this opaque type `impl Sized`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:95:28
-   |
-LL | fn mutual_recursion() -> impl Sync {
-   |                          --------- returning this opaque type `impl Sync`
-...
-LL | fn mutual_recursion_b() -> impl Sized {
-   |                            ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     mutual_recursion()
-   |     ------------------ returning here with type `impl Sync`
-
-error: aborting due to 14 previous errors
-
-For more information about this error, try `rustc --explain E0720`.
diff --git a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.no_drop_tracking.stderr b/tests/ui/impl-trait/recursive-impl-trait-type-indirect.no_drop_tracking.stderr
deleted file mode 100644
index 4d4090f27fc..00000000000
--- a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.no_drop_tracking.stderr
+++ /dev/null
@@ -1,152 +0,0 @@
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:11:22
-   |
-LL | fn option(i: i32) -> impl Sized {
-   |                      ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     if i < 0 { None } else { Some((option(i - 1), i)) }
-   |                ----          ------------------------ returning here with type `Option<(impl Sized, i32)>`
-   |                |
-   |                returning here with type `Option<(impl Sized, i32)>`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:16:15
-   |
-LL | fn tuple() -> impl Sized {
-   |               ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     (tuple(),)
-   |     ---------- returning here with type `(impl Sized,)`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:21:15
-   |
-LL | fn array() -> impl Sized {
-   |               ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     [array()]
-   |     --------- returning here with type `[impl Sized; 1]`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:26:13
-   |
-LL | fn ptr() -> impl Sized {
-   |             ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     &ptr() as *const _
-   |     ------------------ returning here with type `*const impl Sized`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:31:16
-   |
-LL | fn fn_ptr() -> impl Sized {
-   |                ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     fn_ptr as fn() -> _
-   |     ------------------- returning here with type `fn() -> impl Sized`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:36:25
-   |
-LL |   fn closure_capture() -> impl Sized {
-   |                           ^^^^^^^^^^ recursive opaque type
-...
-LL | /     move || {
-LL | |         x;
-   | |         - closure captures itself here
-LL | |     }
-   | |_____- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:39:5: 39:12}`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:44:29
-   |
-LL |   fn closure_ref_capture() -> impl Sized {
-   |                               ^^^^^^^^^^ recursive opaque type
-...
-LL | /     move || {
-LL | |         &x;
-   | |          - closure captures itself here
-LL | |     }
-   | |_____- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:47:5: 47:12}`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:52:21
-   |
-LL | fn closure_sig() -> impl Sized {
-   |                     ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     || closure_sig()
-   |     ---------------- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:54:5: 54:7}`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:57:23
-   |
-LL | fn generator_sig() -> impl Sized {
-   |                       ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     || generator_sig()
-   |     ------------------ returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:59:5: 59:7}`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:62:27
-   |
-LL |   fn generator_capture() -> impl Sized {
-   |                             ^^^^^^^^^^ recursive opaque type
-...
-LL | /     move || {
-LL | |         yield;
-LL | |         x;
-   | |         - generator captures itself here
-LL | |     }
-   | |_____- returning here with type `{generator@$DIR/recursive-impl-trait-type-indirect.rs:65:5: 65:12}`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:71:35
-   |
-LL | fn substs_change<T: 'static>() -> impl Sized {
-   |                                   ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     (substs_change::<&T>(),)
-   |     ------------------------ returning here with type `(impl Sized,)`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:76:24
-   |
-LL |   fn generator_hold() -> impl Sized {
-   |                          ^^^^^^^^^^ recursive opaque type
-LL |
-LL | /     move || {
-LL | |         let x = generator_hold();
-   | |             - generator captures itself here
-LL | |         yield;
-LL | |         x;
-LL | |     }
-   | |_____- returning here with type `{generator@$DIR/recursive-impl-trait-type-indirect.rs:78:5: 78:12}`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:90:26
-   |
-LL | fn mutual_recursion() -> impl Sync {
-   |                          ^^^^^^^^^ recursive opaque type
-LL |
-LL |     mutual_recursion_b()
-   |     -------------------- returning here with type `impl Sized`
-...
-LL | fn mutual_recursion_b() -> impl Sized {
-   |                            ---------- returning this opaque type `impl Sized`
-
-error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:95:28
-   |
-LL | fn mutual_recursion() -> impl Sync {
-   |                          --------- returning this opaque type `impl Sync`
-...
-LL | fn mutual_recursion_b() -> impl Sized {
-   |                            ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     mutual_recursion()
-   |     ------------------ returning here with type `impl Sync`
-
-error: aborting due to 14 previous errors
-
-For more information about this error, try `rustc --explain E0720`.
diff --git a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.rs b/tests/ui/impl-trait/recursive-impl-trait-type-indirect.rs
index 630372e13ed..ffc0cd9d10c 100644
--- a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.rs
+++ b/tests/ui/impl-trait/recursive-impl-trait-type-indirect.rs
@@ -1,7 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-
 // Test that impl trait does not allow creating recursive types that are
 // otherwise forbidden.
 
diff --git a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.drop_tracking_mir.stderr b/tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
index 7cef19c48fe..1d919fb5240 100644
--- a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.drop_tracking_mir.stderr
+++ b/tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
@@ -1,5 +1,5 @@
 error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:11:22
+  --> $DIR/recursive-impl-trait-type-indirect.rs:7:22
    |
 LL | fn option(i: i32) -> impl Sized {
    |                      ^^^^^^^^^^ recursive opaque type
@@ -10,7 +10,7 @@ LL |     if i < 0 { None } else { Some((option(i - 1), i)) }
    |                returning here with type `Option<(impl Sized, i32)>`
 
 error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:16:15
+  --> $DIR/recursive-impl-trait-type-indirect.rs:12:15
    |
 LL | fn tuple() -> impl Sized {
    |               ^^^^^^^^^^ recursive opaque type
@@ -19,7 +19,7 @@ LL |     (tuple(),)
    |     ---------- returning here with type `(impl Sized,)`
 
 error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:21:15
+  --> $DIR/recursive-impl-trait-type-indirect.rs:17:15
    |
 LL | fn array() -> impl Sized {
    |               ^^^^^^^^^^ recursive opaque type
@@ -28,7 +28,7 @@ LL |     [array()]
    |     --------- returning here with type `[impl Sized; 1]`
 
 error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:26:13
+  --> $DIR/recursive-impl-trait-type-indirect.rs:22:13
    |
 LL | fn ptr() -> impl Sized {
    |             ^^^^^^^^^^ recursive opaque type
@@ -37,7 +37,7 @@ LL |     &ptr() as *const _
    |     ------------------ returning here with type `*const impl Sized`
 
 error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:31:16
+  --> $DIR/recursive-impl-trait-type-indirect.rs:27:16
    |
 LL | fn fn_ptr() -> impl Sized {
    |                ^^^^^^^^^^ recursive opaque type
@@ -46,7 +46,7 @@ LL |     fn_ptr as fn() -> _
    |     ------------------- returning here with type `fn() -> impl Sized`
 
 error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:36:25
+  --> $DIR/recursive-impl-trait-type-indirect.rs:32:25
    |
 LL |   fn closure_capture() -> impl Sized {
    |                           ^^^^^^^^^^ recursive opaque type
@@ -55,10 +55,10 @@ LL | /     move || {
 LL | |         x;
    | |         - closure captures itself here
 LL | |     }
-   | |_____- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:39:5: 39:12}`
+   | |_____- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:35:5: 35:12}`
 
 error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:44:29
+  --> $DIR/recursive-impl-trait-type-indirect.rs:40:29
    |
 LL |   fn closure_ref_capture() -> impl Sized {
    |                               ^^^^^^^^^^ recursive opaque type
@@ -67,28 +67,28 @@ LL | /     move || {
 LL | |         &x;
    | |          - closure captures itself here
 LL | |     }
-   | |_____- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:47:5: 47:12}`
+   | |_____- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:43:5: 43:12}`
 
 error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:52:21
+  --> $DIR/recursive-impl-trait-type-indirect.rs:48:21
    |
 LL | fn closure_sig() -> impl Sized {
    |                     ^^^^^^^^^^ recursive opaque type
 LL |
 LL |     || closure_sig()
-   |     ---------------- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:54:5: 54:7}`
+   |     ---------------- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:50:5: 50:7}`
 
 error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:57:23
+  --> $DIR/recursive-impl-trait-type-indirect.rs:53:23
    |
 LL | fn generator_sig() -> impl Sized {
    |                       ^^^^^^^^^^ recursive opaque type
 LL |
 LL |     || generator_sig()
-   |     ------------------ returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:59:5: 59:7}`
+   |     ------------------ returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:55:5: 55:7}`
 
 error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:62:27
+  --> $DIR/recursive-impl-trait-type-indirect.rs:58:27
    |
 LL |   fn generator_capture() -> impl Sized {
    |                             ^^^^^^^^^^ recursive opaque type
@@ -98,10 +98,10 @@ LL | |         yield;
 LL | |         x;
    | |         - generator captures itself here
 LL | |     }
-   | |_____- returning here with type `{generator@$DIR/recursive-impl-trait-type-indirect.rs:65:5: 65:12}`
+   | |_____- returning here with type `{generator@$DIR/recursive-impl-trait-type-indirect.rs:61:5: 61:12}`
 
 error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:71:35
+  --> $DIR/recursive-impl-trait-type-indirect.rs:67:35
    |
 LL | fn substs_change<T: 'static>() -> impl Sized {
    |                                   ^^^^^^^^^^ recursive opaque type
@@ -110,7 +110,7 @@ LL |     (substs_change::<&T>(),)
    |     ------------------------ returning here with type `(impl Sized,)`
 
 error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:76:24
+  --> $DIR/recursive-impl-trait-type-indirect.rs:72:24
    |
 LL | fn generator_hold() -> impl Sized {
    |                        ^^^^^^^^^^ recursive opaque type
@@ -119,7 +119,7 @@ LL |         let x = generator_hold();
    |             - generator captures itself here
 
 error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:90:26
+  --> $DIR/recursive-impl-trait-type-indirect.rs:86:26
    |
 LL | fn mutual_recursion() -> impl Sync {
    |                          ^^^^^^^^^ recursive opaque type
@@ -131,7 +131,7 @@ LL | fn mutual_recursion_b() -> impl Sized {
    |                            ---------- returning this opaque type `impl Sized`
 
 error[E0720]: cannot resolve opaque type
-  --> $DIR/recursive-impl-trait-type-indirect.rs:95:28
+  --> $DIR/recursive-impl-trait-type-indirect.rs:91:28
    |
 LL | fn mutual_recursion() -> impl Sync {
    |                          --------- returning this opaque type `impl Sync`
diff --git a/tests/ui/intrinsics/feature-gate-safe-intrinsic.rs b/tests/ui/intrinsics/feature-gate-safe-intrinsic.rs
new file mode 100644
index 00000000000..ffaa4d771d9
--- /dev/null
+++ b/tests/ui/intrinsics/feature-gate-safe-intrinsic.rs
@@ -0,0 +1,6 @@
+#[rustc_safe_intrinsic]
+//~^ ERROR the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe
+//~| ERROR attribute should be applied to intrinsic functions
+fn safe() {}
+
+fn main() {}
diff --git a/tests/ui/intrinsics/feature-gate-safe-intrinsic.stderr b/tests/ui/intrinsics/feature-gate-safe-intrinsic.stderr
new file mode 100644
index 00000000000..8aeb56598ec
--- /dev/null
+++ b/tests/ui/intrinsics/feature-gate-safe-intrinsic.stderr
@@ -0,0 +1,20 @@
+error[E0658]: the `#[rustc_safe_intrinsic]` attribute is used internally to mark intrinsics as safe
+  --> $DIR/feature-gate-safe-intrinsic.rs:1:1
+   |
+LL | #[rustc_safe_intrinsic]
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: add `#![feature(rustc_attrs)]` to the crate attributes to enable
+
+error: attribute should be applied to intrinsic functions
+  --> $DIR/feature-gate-safe-intrinsic.rs:1:1
+   |
+LL | #[rustc_safe_intrinsic]
+   | ^^^^^^^^^^^^^^^^^^^^^^^
+...
+LL | fn safe() {}
+   | ------------ not an intrinsic function
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/intrinsics/intrinsic-alignment.rs b/tests/ui/intrinsics/intrinsic-alignment.rs
index 30b8a21269a..6f9df64417e 100644
--- a/tests/ui/intrinsics/intrinsic-alignment.rs
+++ b/tests/ui/intrinsics/intrinsic-alignment.rs
@@ -1,7 +1,7 @@
 // run-pass
 // ignore-wasm32-bare seems not important to test here
 
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 mod rusti {
     extern "rust-intrinsic" {
diff --git a/tests/ui/invalid_dispatch_from_dyn_impls.stderr b/tests/ui/invalid_dispatch_from_dyn_impls.stderr
index b5b32d2f0bd..172ee7ade49 100644
--- a/tests/ui/invalid_dispatch_from_dyn_impls.stderr
+++ b/tests/ui/invalid_dispatch_from_dyn_impls.stderr
@@ -15,11 +15,13 @@ LL | impl<T: ?Sized, U: ?Sized> DispatchFromDyn<MultiplePointers<U>> for Multipl
    = note: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced
    = note: currently, 2 fields need coercions: `ptr1` (`*const T` to `*const U`), `ptr2` (`*const T` to `*const U`)
 
-error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures with a single field being coerced, none found
+error[E0378]: the trait `DispatchFromDyn` may only be implemented for a coercion between structures
   --> $DIR/invalid_dispatch_from_dyn_impls.rs:31:1
    |
 LL | impl<T: ?Sized, U: ?Sized> DispatchFromDyn<NothingToCoerce<T>> for NothingToCoerce<U> {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: expected a single field to be coerced, none found
 
 error[E0378]: structs implementing `DispatchFromDyn` may not have `#[repr(packed)]` or `#[repr(C)]`
   --> $DIR/invalid_dispatch_from_dyn_impls.rs:37:1
diff --git a/tests/ui/issues/issue-27042.stderr b/tests/ui/issues/issue-27042.stderr
index 59ef28481d0..01532de999e 100644
--- a/tests/ui/issues/issue-27042.stderr
+++ b/tests/ui/issues/issue-27042.stderr
@@ -11,11 +11,18 @@ LL | |         while true { break }; // but here we cite the whole loop
 error[E0308]: mismatched types
   --> $DIR/issue-27042.rs:6:16
    |
+LL |     let _: i32 =
+   |         - expected because of this assignment
+LL |         'a: // in this case, the citation is just the `break`:
 LL |         loop { break };
-   |                ^^^^^
-   |                |
-   |                expected `i32`, found `()`
-   |                help: give it a value of the expected type: `break 42`
+   |         ----   ^^^^^ expected `i32`, found `()`
+   |         |
+   |         this loop is expected to be of type `i32`
+   |
+help: give it a value of the expected type
+   |
+LL |         loop { break 42 };
+   |                      ++
 
 error[E0308]: mismatched types
   --> $DIR/issue-27042.rs:8:9
diff --git a/tests/ui/lifetimes/unusual-rib-combinations.stderr b/tests/ui/lifetimes/unusual-rib-combinations.stderr
index 01ec69a6110..92a2ef2f432 100644
--- a/tests/ui/lifetimes/unusual-rib-combinations.stderr
+++ b/tests/ui/lifetimes/unusual-rib-combinations.stderr
@@ -56,7 +56,7 @@ LL | fn d<const C: S>() {}
    |               ^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: `&dyn for<'a> Foo<'a>` is forbidden as the type of a const generic parameter
   --> $DIR/unusual-rib-combinations.rs:29:21
@@ -65,7 +65,7 @@ LL | struct Bar<const N: &'a (dyn for<'a> Foo<'a>)>;
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: the only supported types are integers, `bool` and `char`
-   = help: more complex types are supported with `#![feature(adt_const_params)]`
+   = help: add `#![feature(adt_const_params)]` to the crate attributes to enable more complex and user defined types
 
 error: aborting due to 9 previous errors
 
diff --git a/tests/ui/lint/must_not_suspend/dedup.drop_tracking_mir.stderr b/tests/ui/lint/must_not_suspend/dedup.drop_tracking_mir.stderr
deleted file mode 100644
index cd3baa857ab..00000000000
--- a/tests/ui/lint/must_not_suspend/dedup.drop_tracking_mir.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error: `No` held across a suspend point, but should not be
-  --> $DIR/dedup.rs:19:9
-   |
-LL |     let no = No {};
-   |         ^^
-LL |     wheeee(&no).await;
-   |                 ----- the value is held across this suspend point
-   |
-help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/dedup.rs:19:9
-   |
-LL |     let no = No {};
-   |         ^^
-note: the lint level is defined here
-  --> $DIR/dedup.rs:6:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/tests/ui/lint/must_not_suspend/dedup.no_drop_tracking.stderr b/tests/ui/lint/must_not_suspend/dedup.no_drop_tracking.stderr
deleted file mode 100644
index aff2f7c32b9..00000000000
--- a/tests/ui/lint/must_not_suspend/dedup.no_drop_tracking.stderr
+++ /dev/null
@@ -1,33 +0,0 @@
-error: `No` held across a suspend point, but should not be
-  --> $DIR/dedup.rs:19:9
-   |
-LL |     let no = No {};
-   |         ^^
-LL |     wheeee(&no).await;
-   |                 ----- the value is held across this suspend point
-   |
-help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/dedup.rs:19:9
-   |
-LL |     let no = No {};
-   |         ^^
-note: the lint level is defined here
-  --> $DIR/dedup.rs:6:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
-
-error: `No` held across a suspend point, but should not be
-  --> $DIR/dedup.rs:20:13
-   |
-LL |     wheeee(&no).await;
-   |             ^^  ----- the value is held across this suspend point
-   |
-help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/dedup.rs:20:13
-   |
-LL |     wheeee(&no).await;
-   |             ^^
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/lint/must_not_suspend/dedup.rs b/tests/ui/lint/must_not_suspend/dedup.rs
index 96bdb7715b1..867bdf2ec12 100644
--- a/tests/ui/lint/must_not_suspend/dedup.rs
+++ b/tests/ui/lint/must_not_suspend/dedup.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2018
 #![feature(must_not_suspend)]
 #![deny(must_not_suspend)]
@@ -16,8 +13,9 @@ async fn wheeee<T>(t: T) {
 }
 
 async fn yes() {
-    let no = No {}; //~ ERROR `No` held across
-    wheeee(&no).await; //[no_drop_tracking]~ ERROR `No` held across
+    let no = No {};
+    //~^ ERROR `No` held across
+    wheeee(&no).await;
     drop(no);
 }
 
diff --git a/tests/ui/lint/must_not_suspend/dedup.drop_tracking.stderr b/tests/ui/lint/must_not_suspend/dedup.stderr
index cd3baa857ab..5d5b04a5d95 100644
--- a/tests/ui/lint/must_not_suspend/dedup.drop_tracking.stderr
+++ b/tests/ui/lint/must_not_suspend/dedup.stderr
@@ -1,18 +1,19 @@
 error: `No` held across a suspend point, but should not be
-  --> $DIR/dedup.rs:19:9
+  --> $DIR/dedup.rs:16:9
    |
 LL |     let no = No {};
    |         ^^
+LL |
 LL |     wheeee(&no).await;
    |                 ----- the value is held across this suspend point
    |
 help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/dedup.rs:19:9
+  --> $DIR/dedup.rs:16:9
    |
 LL |     let no = No {};
    |         ^^
 note: the lint level is defined here
-  --> $DIR/dedup.rs:6:9
+  --> $DIR/dedup.rs:3:9
    |
 LL | #![deny(must_not_suspend)]
    |         ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/must_not_suspend/ref-drop-tracking.rs b/tests/ui/lint/must_not_suspend/ref-drop-tracking.rs
deleted file mode 100644
index 1bc4a381257..00000000000
--- a/tests/ui/lint/must_not_suspend/ref-drop-tracking.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-// edition:2018
-// compile-flags: -Zdrop-tracking
-#![feature(must_not_suspend)]
-#![deny(must_not_suspend)]
-
-#[must_not_suspend = "You gotta use Umm's, ya know?"]
-struct Umm {
-    i: i64
-}
-
-struct Bar {
-    u: Umm,
-}
-
-async fn other() {}
-
-impl Bar {
-    async fn uhoh(&mut self) {
-        let guard = &mut self.u; //~ ERROR `Umm` held across
-
-        other().await;
-
-        *guard = Umm {
-            i: 2
-        }
-    }
-}
-
-fn main() {
-}
diff --git a/tests/ui/lint/must_not_suspend/ref-drop-tracking.stderr b/tests/ui/lint/must_not_suspend/ref-drop-tracking.stderr
deleted file mode 100644
index 348880b9c9f..00000000000
--- a/tests/ui/lint/must_not_suspend/ref-drop-tracking.stderr
+++ /dev/null
@@ -1,27 +0,0 @@
-error: reference to `Umm` held across a suspend point, but should not be
-  --> $DIR/ref-drop-tracking.rs:19:13
-   |
-LL |         let guard = &mut self.u;
-   |             ^^^^^
-LL |
-LL |         other().await;
-   |                 ----- the value is held across this suspend point
-   |
-note: You gotta use Umm's, ya know?
-  --> $DIR/ref-drop-tracking.rs:19:13
-   |
-LL |         let guard = &mut self.u;
-   |             ^^^^^
-help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/ref-drop-tracking.rs:19:13
-   |
-LL |         let guard = &mut self.u;
-   |             ^^^^^
-note: the lint level is defined here
-  --> $DIR/ref-drop-tracking.rs:4:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/tests/ui/lint/must_not_suspend/ref.drop_tracking.stderr b/tests/ui/lint/must_not_suspend/ref.drop_tracking.stderr
deleted file mode 100644
index fb18c2be9cb..00000000000
--- a/tests/ui/lint/must_not_suspend/ref.drop_tracking.stderr
+++ /dev/null
@@ -1,27 +0,0 @@
-error: reference to `Umm` held across a suspend point, but should not be
-  --> $DIR/ref.rs:22:13
-   |
-LL |         let guard = &mut self.u;
-   |             ^^^^^
-LL |
-LL |         other().await;
-   |                 ----- the value is held across this suspend point
-   |
-note: You gotta use Umm's, ya know?
-  --> $DIR/ref.rs:22:13
-   |
-LL |         let guard = &mut self.u;
-   |             ^^^^^
-help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/ref.rs:22:13
-   |
-LL |         let guard = &mut self.u;
-   |             ^^^^^
-note: the lint level is defined here
-  --> $DIR/ref.rs:7:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/tests/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr b/tests/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr
deleted file mode 100644
index 6976dd34991..00000000000
--- a/tests/ui/lint/must_not_suspend/ref.no_drop_tracking.stderr
+++ /dev/null
@@ -1,27 +0,0 @@
-error: `Umm` held across a suspend point, but should not be
-  --> $DIR/ref.rs:22:26
-   |
-LL |         let guard = &mut self.u;
-   |                          ^^^^^^
-LL |
-LL |         other().await;
-   |                 ----- the value is held across this suspend point
-   |
-note: You gotta use Umm's, ya know?
-  --> $DIR/ref.rs:22:26
-   |
-LL |         let guard = &mut self.u;
-   |                          ^^^^^^
-help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/ref.rs:22:26
-   |
-LL |         let guard = &mut self.u;
-   |                          ^^^^^^
-note: the lint level is defined here
-  --> $DIR/ref.rs:7:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/tests/ui/lint/must_not_suspend/ref.rs b/tests/ui/lint/must_not_suspend/ref.rs
index d05dcb83ac5..3b6ef39c9fe 100644
--- a/tests/ui/lint/must_not_suspend/ref.rs
+++ b/tests/ui/lint/must_not_suspend/ref.rs
@@ -1,8 +1,4 @@
 // edition:2018
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
-
 #![feature(must_not_suspend)]
 #![deny(must_not_suspend)]
 
@@ -23,7 +19,6 @@ impl Bar {
 
         other().await;
 
-        let _g = &*guard;
         *guard = Umm { i: 2 }
     }
 }
diff --git a/tests/ui/lint/must_not_suspend/ref.drop_tracking_mir.stderr b/tests/ui/lint/must_not_suspend/ref.stderr
index fb18c2be9cb..ed91a4a0bc6 100644
--- a/tests/ui/lint/must_not_suspend/ref.drop_tracking_mir.stderr
+++ b/tests/ui/lint/must_not_suspend/ref.stderr
@@ -1,5 +1,5 @@
 error: reference to `Umm` held across a suspend point, but should not be
-  --> $DIR/ref.rs:22:13
+  --> $DIR/ref.rs:18:13
    |
 LL |         let guard = &mut self.u;
    |             ^^^^^
@@ -8,17 +8,17 @@ LL |         other().await;
    |                 ----- the value is held across this suspend point
    |
 note: You gotta use Umm's, ya know?
-  --> $DIR/ref.rs:22:13
+  --> $DIR/ref.rs:18:13
    |
 LL |         let guard = &mut self.u;
    |             ^^^^^
 help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/ref.rs:22:13
+  --> $DIR/ref.rs:18:13
    |
 LL |         let guard = &mut self.u;
    |             ^^^^^
 note: the lint level is defined here
-  --> $DIR/ref.rs:7:9
+  --> $DIR/ref.rs:3:9
    |
 LL | #![deny(must_not_suspend)]
    |         ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/must_not_suspend/trait.drop_tracking_mir.stderr b/tests/ui/lint/must_not_suspend/trait.drop_tracking_mir.stderr
deleted file mode 100644
index 8c8ad1f3788..00000000000
--- a/tests/ui/lint/must_not_suspend/trait.drop_tracking_mir.stderr
+++ /dev/null
@@ -1,37 +0,0 @@
-error: implementer of `Wow` held across a suspend point, but should not be
-  --> $DIR/trait.rs:24:9
-   |
-LL |     let _guard1 = r#impl();
-   |         ^^^^^^^
-...
-LL |     other().await;
-   |             ----- the value is held across this suspend point
-   |
-help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/trait.rs:24:9
-   |
-LL |     let _guard1 = r#impl();
-   |         ^^^^^^^
-note: the lint level is defined here
-  --> $DIR/trait.rs:6:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
-
-error: boxed `Wow` trait object held across a suspend point, but should not be
-  --> $DIR/trait.rs:25:9
-   |
-LL |     let _guard2 = r#dyn();
-   |         ^^^^^^^
-LL |
-LL |     other().await;
-   |             ----- the value is held across this suspend point
-   |
-help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/trait.rs:25:9
-   |
-LL |     let _guard2 = r#dyn();
-   |         ^^^^^^^
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/lint/must_not_suspend/trait.no_drop_tracking.stderr b/tests/ui/lint/must_not_suspend/trait.no_drop_tracking.stderr
deleted file mode 100644
index 8c8ad1f3788..00000000000
--- a/tests/ui/lint/must_not_suspend/trait.no_drop_tracking.stderr
+++ /dev/null
@@ -1,37 +0,0 @@
-error: implementer of `Wow` held across a suspend point, but should not be
-  --> $DIR/trait.rs:24:9
-   |
-LL |     let _guard1 = r#impl();
-   |         ^^^^^^^
-...
-LL |     other().await;
-   |             ----- the value is held across this suspend point
-   |
-help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/trait.rs:24:9
-   |
-LL |     let _guard1 = r#impl();
-   |         ^^^^^^^
-note: the lint level is defined here
-  --> $DIR/trait.rs:6:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
-
-error: boxed `Wow` trait object held across a suspend point, but should not be
-  --> $DIR/trait.rs:25:9
-   |
-LL |     let _guard2 = r#dyn();
-   |         ^^^^^^^
-LL |
-LL |     other().await;
-   |             ----- the value is held across this suspend point
-   |
-help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/trait.rs:25:9
-   |
-LL |     let _guard2 = r#dyn();
-   |         ^^^^^^^
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/lint/must_not_suspend/trait.rs b/tests/ui/lint/must_not_suspend/trait.rs
index cc3ae298dbb..6c911cb4b0f 100644
--- a/tests/ui/lint/must_not_suspend/trait.rs
+++ b/tests/ui/lint/must_not_suspend/trait.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2018
 #![feature(must_not_suspend)]
 #![deny(must_not_suspend)]
@@ -25,9 +22,6 @@ pub async fn uhoh() {
     let _guard2 = r#dyn(); //~ ERROR boxed `Wow` trait object held across
 
     other().await;
-
-    drop(_guard1);
-    drop(_guard2);
 }
 
 fn main() {
diff --git a/tests/ui/lint/must_not_suspend/trait.drop_tracking.stderr b/tests/ui/lint/must_not_suspend/trait.stderr
index 8c8ad1f3788..2c03f8e822d 100644
--- a/tests/ui/lint/must_not_suspend/trait.drop_tracking.stderr
+++ b/tests/ui/lint/must_not_suspend/trait.stderr
@@ -1,5 +1,5 @@
 error: implementer of `Wow` held across a suspend point, but should not be
-  --> $DIR/trait.rs:24:9
+  --> $DIR/trait.rs:21:9
    |
 LL |     let _guard1 = r#impl();
    |         ^^^^^^^
@@ -8,18 +8,18 @@ LL |     other().await;
    |             ----- the value is held across this suspend point
    |
 help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/trait.rs:24:9
+  --> $DIR/trait.rs:21:9
    |
 LL |     let _guard1 = r#impl();
    |         ^^^^^^^
 note: the lint level is defined here
-  --> $DIR/trait.rs:6:9
+  --> $DIR/trait.rs:3:9
    |
 LL | #![deny(must_not_suspend)]
    |         ^^^^^^^^^^^^^^^^
 
 error: boxed `Wow` trait object held across a suspend point, but should not be
-  --> $DIR/trait.rs:25:9
+  --> $DIR/trait.rs:22:9
    |
 LL |     let _guard2 = r#dyn();
    |         ^^^^^^^
@@ -28,7 +28,7 @@ LL |     other().await;
    |             ----- the value is held across this suspend point
    |
 help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/trait.rs:25:9
+  --> $DIR/trait.rs:22:9
    |
 LL |     let _guard2 = r#dyn();
    |         ^^^^^^^
diff --git a/tests/ui/lint/must_not_suspend/unit.drop_tracking_mir.stderr b/tests/ui/lint/must_not_suspend/unit.drop_tracking_mir.stderr
deleted file mode 100644
index e24cffdd0df..00000000000
--- a/tests/ui/lint/must_not_suspend/unit.drop_tracking_mir.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-error: `Umm` held across a suspend point, but should not be
-  --> $DIR/unit.rs:22:9
-   |
-LL |     let _guard = bar();
-   |         ^^^^^^
-LL |     other().await;
-   |             ----- the value is held across this suspend point
-   |
-note: You gotta use Umm's, ya know?
-  --> $DIR/unit.rs:22:9
-   |
-LL |     let _guard = bar();
-   |         ^^^^^^
-help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/unit.rs:22:9
-   |
-LL |     let _guard = bar();
-   |         ^^^^^^
-note: the lint level is defined here
-  --> $DIR/unit.rs:6:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/tests/ui/lint/must_not_suspend/unit.no_drop_tracking.stderr b/tests/ui/lint/must_not_suspend/unit.no_drop_tracking.stderr
deleted file mode 100644
index e24cffdd0df..00000000000
--- a/tests/ui/lint/must_not_suspend/unit.no_drop_tracking.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-error: `Umm` held across a suspend point, but should not be
-  --> $DIR/unit.rs:22:9
-   |
-LL |     let _guard = bar();
-   |         ^^^^^^
-LL |     other().await;
-   |             ----- the value is held across this suspend point
-   |
-note: You gotta use Umm's, ya know?
-  --> $DIR/unit.rs:22:9
-   |
-LL |     let _guard = bar();
-   |         ^^^^^^
-help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/unit.rs:22:9
-   |
-LL |     let _guard = bar();
-   |         ^^^^^^
-note: the lint level is defined here
-  --> $DIR/unit.rs:6:9
-   |
-LL | #![deny(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
-
-error: aborting due to previous error
-
diff --git a/tests/ui/lint/must_not_suspend/unit.rs b/tests/ui/lint/must_not_suspend/unit.rs
index fbc51b36681..af4a76caa4e 100644
--- a/tests/ui/lint/must_not_suspend/unit.rs
+++ b/tests/ui/lint/must_not_suspend/unit.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2018
 #![feature(must_not_suspend)]
 #![deny(must_not_suspend)]
@@ -10,6 +7,7 @@ struct Umm {
     i: i64
 }
 
+
 fn bar() -> Umm {
     Umm {
         i: 1
diff --git a/tests/ui/lint/must_not_suspend/unit.drop_tracking.stderr b/tests/ui/lint/must_not_suspend/unit.stderr
index e24cffdd0df..11c95c1464a 100644
--- a/tests/ui/lint/must_not_suspend/unit.drop_tracking.stderr
+++ b/tests/ui/lint/must_not_suspend/unit.stderr
@@ -1,5 +1,5 @@
 error: `Umm` held across a suspend point, but should not be
-  --> $DIR/unit.rs:22:9
+  --> $DIR/unit.rs:20:9
    |
 LL |     let _guard = bar();
    |         ^^^^^^
@@ -7,17 +7,17 @@ LL |     other().await;
    |             ----- the value is held across this suspend point
    |
 note: You gotta use Umm's, ya know?
-  --> $DIR/unit.rs:22:9
+  --> $DIR/unit.rs:20:9
    |
 LL |     let _guard = bar();
    |         ^^^^^^
 help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/unit.rs:22:9
+  --> $DIR/unit.rs:20:9
    |
 LL |     let _guard = bar();
    |         ^^^^^^
 note: the lint level is defined here
-  --> $DIR/unit.rs:6:9
+  --> $DIR/unit.rs:3:9
    |
 LL | #![deny(must_not_suspend)]
    |         ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/must_not_suspend/warn.drop_tracking.stderr b/tests/ui/lint/must_not_suspend/warn.drop_tracking.stderr
deleted file mode 100644
index 4f7b40a5efe..00000000000
--- a/tests/ui/lint/must_not_suspend/warn.drop_tracking.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-warning: `Umm` held across a suspend point, but should not be
-  --> $DIR/warn.rs:24:9
-   |
-LL |     let _guard = bar();
-   |         ^^^^^^
-LL |     other().await;
-   |             ----- the value is held across this suspend point
-   |
-note: You gotta use Umm's, ya know?
-  --> $DIR/warn.rs:24:9
-   |
-LL |     let _guard = bar();
-   |         ^^^^^^
-help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/warn.rs:24:9
-   |
-LL |     let _guard = bar();
-   |         ^^^^^^
-note: the lint level is defined here
-  --> $DIR/warn.rs:7:9
-   |
-LL | #![warn(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/lint/must_not_suspend/warn.no_drop_tracking.stderr b/tests/ui/lint/must_not_suspend/warn.no_drop_tracking.stderr
deleted file mode 100644
index 4f7b40a5efe..00000000000
--- a/tests/ui/lint/must_not_suspend/warn.no_drop_tracking.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-warning: `Umm` held across a suspend point, but should not be
-  --> $DIR/warn.rs:24:9
-   |
-LL |     let _guard = bar();
-   |         ^^^^^^
-LL |     other().await;
-   |             ----- the value is held across this suspend point
-   |
-note: You gotta use Umm's, ya know?
-  --> $DIR/warn.rs:24:9
-   |
-LL |     let _guard = bar();
-   |         ^^^^^^
-help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/warn.rs:24:9
-   |
-LL |     let _guard = bar();
-   |         ^^^^^^
-note: the lint level is defined here
-  --> $DIR/warn.rs:7:9
-   |
-LL | #![warn(must_not_suspend)]
-   |         ^^^^^^^^^^^^^^^^
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/lint/must_not_suspend/warn.rs b/tests/ui/lint/must_not_suspend/warn.rs
index 5a4863169ea..2d5dd01e5bf 100644
--- a/tests/ui/lint/must_not_suspend/warn.rs
+++ b/tests/ui/lint/must_not_suspend/warn.rs
@@ -1,6 +1,3 @@
-// revisions: no_drop_tracking drop_tracking drop_tracking_mir
-// [drop_tracking] compile-flags: -Zdrop-tracking
-// [drop_tracking_mir] compile-flags: -Zdrop-tracking-mir
 // edition:2018
 // run-pass
 #![feature(must_not_suspend)]
@@ -21,9 +18,9 @@ fn bar() -> Umm {
 async fn other() {}
 
 pub async fn uhoh() {
-    let _guard = bar(); //~ WARNING `Umm` held across
+    let guard = bar(); //~ WARNING `Umm` held across
     other().await;
-    drop(_guard);
+    drop(guard);
 }
 
 fn main() {
diff --git a/tests/ui/lint/must_not_suspend/warn.drop_tracking_mir.stderr b/tests/ui/lint/must_not_suspend/warn.stderr
index 4f7b40a5efe..e59656e508c 100644
--- a/tests/ui/lint/must_not_suspend/warn.drop_tracking_mir.stderr
+++ b/tests/ui/lint/must_not_suspend/warn.stderr
@@ -1,23 +1,23 @@
 warning: `Umm` held across a suspend point, but should not be
-  --> $DIR/warn.rs:24:9
+  --> $DIR/warn.rs:21:9
    |
-LL |     let _guard = bar();
-   |         ^^^^^^
+LL |     let guard = bar();
+   |         ^^^^^
 LL |     other().await;
    |             ----- the value is held across this suspend point
    |
 note: You gotta use Umm's, ya know?
-  --> $DIR/warn.rs:24:9
+  --> $DIR/warn.rs:21:9
    |
-LL |     let _guard = bar();
-   |         ^^^^^^
+LL |     let guard = bar();
+   |         ^^^^^
 help: consider using a block (`{ ... }`) to shrink the value's scope, ending before the suspend point
-  --> $DIR/warn.rs:24:9
+  --> $DIR/warn.rs:21:9
    |
-LL |     let _guard = bar();
-   |         ^^^^^^
+LL |     let guard = bar();
+   |         ^^^^^
 note: the lint level is defined here
-  --> $DIR/warn.rs:7:9
+  --> $DIR/warn.rs:4:9
    |
 LL | #![warn(must_not_suspend)]
    |         ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/lint/noop-method-call.fixed b/tests/ui/lint/noop-method-call.fixed
index eeb80279fd8..4d9834f7df6 100644
--- a/tests/ui/lint/noop-method-call.fixed
+++ b/tests/ui/lint/noop-method-call.fixed
@@ -1,6 +1,7 @@
 // check-pass
 // run-rustfix
 
+#![feature(rustc_attrs)]
 #![allow(unused)]
 
 use std::borrow::Borrow;
@@ -49,3 +50,15 @@ fn non_generic(non_clone_type: &PlainType<u32>) {
     non_clone_type;
     //~^ WARN call to `.clone()` on a reference in this situation does nothing
 }
+
+struct DiagnosticClone;
+impl Clone for DiagnosticClone {
+    #[rustc_diagnostic_item = "other_clone"]
+    fn clone(&self) -> Self {
+        DiagnosticClone
+    }
+}
+
+fn with_other_diagnostic_item(x: DiagnosticClone) {
+    x.clone();
+}
diff --git a/tests/ui/lint/noop-method-call.rs b/tests/ui/lint/noop-method-call.rs
index 9569a0dfc61..6242a00e033 100644
--- a/tests/ui/lint/noop-method-call.rs
+++ b/tests/ui/lint/noop-method-call.rs
@@ -1,6 +1,7 @@
 // check-pass
 // run-rustfix
 
+#![feature(rustc_attrs)]
 #![allow(unused)]
 
 use std::borrow::Borrow;
@@ -49,3 +50,15 @@ fn non_generic(non_clone_type: &PlainType<u32>) {
     non_clone_type.clone();
     //~^ WARN call to `.clone()` on a reference in this situation does nothing
 }
+
+struct DiagnosticClone;
+impl Clone for DiagnosticClone {
+    #[rustc_diagnostic_item = "other_clone"]
+    fn clone(&self) -> Self {
+        DiagnosticClone
+    }
+}
+
+fn with_other_diagnostic_item(x: DiagnosticClone) {
+    x.clone();
+}
diff --git a/tests/ui/lint/noop-method-call.stderr b/tests/ui/lint/noop-method-call.stderr
index aefc2706fd5..d04f44022ee 100644
--- a/tests/ui/lint/noop-method-call.stderr
+++ b/tests/ui/lint/noop-method-call.stderr
@@ -1,5 +1,5 @@
 warning: call to `.clone()` on a reference in this situation does nothing
-  --> $DIR/noop-method-call.rs:15:25
+  --> $DIR/noop-method-call.rs:16:25
    |
 LL |     let _ = &mut encoded.clone();
    |                         ^^^^^^^^ help: remove this redundant call
@@ -8,7 +8,7 @@ LL |     let _ = &mut encoded.clone();
    = note: `#[warn(noop_method_call)]` on by default
 
 warning: call to `.clone()` on a reference in this situation does nothing
-  --> $DIR/noop-method-call.rs:17:21
+  --> $DIR/noop-method-call.rs:18:21
    |
 LL |     let _ = &encoded.clone();
    |                     ^^^^^^^^ help: remove this redundant call
@@ -16,7 +16,7 @@ LL |     let _ = &encoded.clone();
    = note: the type `[u8]` does not implement `Clone`, so calling `clone` on `&[u8]` copies the reference, which does not do anything and can be removed
 
 warning: call to `.clone()` on a reference in this situation does nothing
-  --> $DIR/noop-method-call.rs:23:71
+  --> $DIR/noop-method-call.rs:24:71
    |
 LL |     let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clone();
    |                                                                       ^^^^^^^^ help: remove this redundant call
@@ -24,7 +24,7 @@ LL |     let non_clone_type_ref_clone: &PlainType<u32> = non_clone_type_ref.clon
    = note: the type `PlainType<u32>` does not implement `Clone`, so calling `clone` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed
 
 warning: call to `.deref()` on a reference in this situation does nothing
-  --> $DIR/noop-method-call.rs:31:63
+  --> $DIR/noop-method-call.rs:32:63
    |
 LL |     let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
    |                                                               ^^^^^^^^ help: remove this redundant call
@@ -32,7 +32,7 @@ LL |     let non_deref_type_deref: &PlainType<u32> = non_deref_type.deref();
    = note: the type `PlainType<u32>` does not implement `Deref`, so calling `deref` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed
 
 warning: call to `.borrow()` on a reference in this situation does nothing
-  --> $DIR/noop-method-call.rs:35:66
+  --> $DIR/noop-method-call.rs:36:66
    |
 LL |     let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
    |                                                                  ^^^^^^^^^ help: remove this redundant call
@@ -40,7 +40,7 @@ LL |     let non_borrow_type_borrow: &PlainType<u32> = non_borrow_type.borrow();
    = note: the type `PlainType<u32>` does not implement `Borrow`, so calling `borrow` on `&PlainType<u32>` copies the reference, which does not do anything and can be removed
 
 warning: call to `.clone()` on a reference in this situation does nothing
-  --> $DIR/noop-method-call.rs:44:19
+  --> $DIR/noop-method-call.rs:45:19
    |
 LL |     non_clone_type.clone();
    |                   ^^^^^^^^ help: remove this redundant call
@@ -48,7 +48,7 @@ LL |     non_clone_type.clone();
    = note: the type `PlainType<T>` does not implement `Clone`, so calling `clone` on `&PlainType<T>` copies the reference, which does not do anything and can be removed
 
 warning: call to `.clone()` on a reference in this situation does nothing
-  --> $DIR/noop-method-call.rs:49:19
+  --> $DIR/noop-method-call.rs:50:19
    |
 LL |     non_clone_type.clone();
    |                   ^^^^^^^^ help: remove this redundant call
diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs
index 7745d4ef4c3..fba8789e999 100644
--- a/tests/ui/lint/reference_casting.rs
+++ b/tests/ui/lint/reference_casting.rs
@@ -36,6 +36,8 @@ unsafe fn ref_to_mut() {
     //~^ ERROR casting `&T` to `&mut T` is undefined behavior
     let _num = &mut *std::mem::transmute::<_, *mut i32>(num);
     //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+    let _num = &mut *(std::mem::transmute::<_, *mut i32>(num) as *mut i32);
+    //~^ ERROR casting `&T` to `&mut T` is undefined behavior
     let _num = &mut *std::cell::UnsafeCell::raw_get(
     //~^ ERROR casting `&T` to `&mut T` is undefined behavior
         num as *const i32 as *const std::cell::UnsafeCell<i32>
@@ -47,8 +49,20 @@ unsafe fn ref_to_mut() {
     let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32;
     let _num = &mut *deferred;
     //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+    let deferred_rebind = deferred;
+    let _num = &mut *deferred_rebind;
+    //~^ ERROR casting `&T` to `&mut T` is undefined behavior
     let _num = &mut *(num as *const _ as usize as *mut i32);
     //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+    let _num = &mut *(std::mem::transmute::<_, *mut _>(num as *const i32) as *mut i32);
+    //~^ ERROR casting `&T` to `&mut T` is undefined behavior
+
+    static NUM: &'static i32 = &2;
+    let num = NUM as *const i32 as *mut i32;
+    let num = num;
+    let num = num;
+    let _num = &mut *num;
+    //~^ ERROR casting `&T` to `&mut T` is undefined behavior
 
     unsafe fn generic_ref_cast_mut<T>(this: &T) -> &mut T {
         &mut *((this as *const _) as *mut _)
@@ -85,6 +99,8 @@ unsafe fn assign_to_ref() {
     //~^ ERROR assigning to `&T` is undefined behavior
     *std::mem::transmute::<_, *mut i32>(num) += 1;
     //~^ ERROR assigning to `&T` is undefined behavior
+    *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1;
+    //~^ ERROR assigning to `&T` is undefined behavior
     std::ptr::write(
     //~^ ERROR assigning to `&T` is undefined behavior
         std::mem::transmute::<*const i32, *mut i32>(num),
@@ -94,6 +110,9 @@ unsafe fn assign_to_ref() {
     let value = num as *const i32 as *mut i32;
     *value = 1;
     //~^ ERROR assigning to `&T` is undefined behavior
+    let value_rebind = value;
+    *value_rebind = 1;
+    //~^ ERROR assigning to `&T` is undefined behavior
     *(num as *const i32).cast::<i32>().cast_mut() = 2;
     //~^ ERROR assigning to `&T` is undefined behavior
     *(num as *const _ as usize as *mut i32) = 2;
@@ -111,6 +130,7 @@ unsafe fn assign_to_ref() {
     }
 }
 
+const RAW_PTR: *mut u8 = 1 as *mut u8;
 unsafe fn no_warn() {
     let num = &3i32;
     let mut_num = &mut 3i32;
@@ -125,6 +145,9 @@ unsafe fn no_warn() {
     let mut value = 3;
     let value: *const i32 = &mut value;
     *(value as *const i16 as *mut i16) = 42;
+    *RAW_PTR = 42; // RAW_PTR is defined outside the function body,
+                   // make sure we don't ICE on it when trying to
+                   // determine if we should lint on it or not.
 
     fn safe_as_mut<T>(x: &std::cell::UnsafeCell<T>) -> &mut T {
         unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) }
diff --git a/tests/ui/lint/reference_casting.stderr b/tests/ui/lint/reference_casting.stderr
index 1189942c809..8f89cf9805b 100644
--- a/tests/ui/lint/reference_casting.stderr
+++ b/tests/ui/lint/reference_casting.stderr
@@ -82,6 +82,14 @@ LL |     let _num = &mut *std::mem::transmute::<_, *mut i32>(num);
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
   --> $DIR/reference_casting.rs:39:16
    |
+LL |     let _num = &mut *(std::mem::transmute::<_, *mut i32>(num) as *mut i32);
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
+
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:41:16
+   |
 LL |       let _num = &mut *std::cell::UnsafeCell::raw_get(
    |  ________________^
 LL | |
@@ -92,7 +100,7 @@ LL | |     );
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:45:16
+  --> $DIR/reference_casting.rs:47:16
    |
 LL |     let deferred = num as *const i32 as *mut i32;
    |                    ----------------------------- casting happend here
@@ -102,7 +110,7 @@ LL |     let _num = &mut *deferred;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:48:16
+  --> $DIR/reference_casting.rs:50:16
    |
 LL |     let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32;
    |                    ---------------------------------------------------------------------------- casting happend here
@@ -112,7 +120,18 @@ LL |     let _num = &mut *deferred;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:50:16
+  --> $DIR/reference_casting.rs:53:16
+   |
+LL |     let deferred = (std::ptr::from_ref(num) as *const i32 as *const i32).cast_mut() as *mut i32;
+   |                    ---------------------------------------------------------------------------- casting happend here
+...
+LL |     let _num = &mut *deferred_rebind;
+   |                ^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
+
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:55:16
    |
 LL |     let _num = &mut *(num as *const _ as usize as *mut i32);
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -120,7 +139,26 @@ LL |     let _num = &mut *(num as *const _ as usize as *mut i32);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:54:9
+  --> $DIR/reference_casting.rs:57:16
+   |
+LL |     let _num = &mut *(std::mem::transmute::<_, *mut _>(num as *const i32) as *mut i32);
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
+
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:64:16
+   |
+LL |     let num = NUM as *const i32 as *mut i32;
+   |               ----------------------------- casting happend here
+...
+LL |     let _num = &mut *num;
+   |                ^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
+
+error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:68:9
    |
 LL |         &mut *((this as *const _) as *mut _)
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -128,7 +166,7 @@ LL |         &mut *((this as *const _) as *mut _)
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:59:18
+  --> $DIR/reference_casting.rs:73:18
    |
 LL |         unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -136,7 +174,7 @@ LL |         unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: casting `&T` to `&mut T` is undefined behavior, even if the reference is unused, consider instead using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:64:18
+  --> $DIR/reference_casting.rs:78:18
    |
 LL |         unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *const _) }
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -144,7 +182,7 @@ LL |         unsafe { &mut *std::cell::UnsafeCell::raw_get(x as *const _ as *con
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:74:5
+  --> $DIR/reference_casting.rs:88:5
    |
 LL |     *(a as *const _ as *mut _) = String::from("Replaced");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -152,7 +190,7 @@ LL |     *(a as *const _ as *mut _) = String::from("Replaced");
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:76:5
+  --> $DIR/reference_casting.rs:90:5
    |
 LL |     *(a as *const _ as *mut String) += " world";
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -160,7 +198,7 @@ LL |     *(a as *const _ as *mut String) += " world";
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:78:5
+  --> $DIR/reference_casting.rs:92:5
    |
 LL |     *std::ptr::from_ref(num).cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -168,7 +206,7 @@ LL |     *std::ptr::from_ref(num).cast_mut() += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:80:5
+  --> $DIR/reference_casting.rs:94:5
    |
 LL |     *std::ptr::from_ref({ num }).cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -176,7 +214,7 @@ LL |     *std::ptr::from_ref({ num }).cast_mut() += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:82:5
+  --> $DIR/reference_casting.rs:96:5
    |
 LL |     *{ std::ptr::from_ref(num) }.cast_mut() += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -184,7 +222,7 @@ LL |     *{ std::ptr::from_ref(num) }.cast_mut() += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:84:5
+  --> $DIR/reference_casting.rs:98:5
    |
 LL |     *(std::ptr::from_ref({ num }) as *mut i32) += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -192,7 +230,7 @@ LL |     *(std::ptr::from_ref({ num }) as *mut i32) += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:86:5
+  --> $DIR/reference_casting.rs:100:5
    |
 LL |     *std::mem::transmute::<_, *mut i32>(num) += 1;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -200,7 +238,15 @@ LL |     *std::mem::transmute::<_, *mut i32>(num) += 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:88:5
+  --> $DIR/reference_casting.rs:102:5
+   |
+LL |     *(std::mem::transmute::<_, *mut i32>(num) as *mut i32) += 1;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
+
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:104:5
    |
 LL | /     std::ptr::write(
 LL | |
@@ -212,7 +258,7 @@ LL | |     );
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:95:5
+  --> $DIR/reference_casting.rs:111:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -222,7 +268,18 @@ LL |     *value = 1;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:97:5
+  --> $DIR/reference_casting.rs:114:5
+   |
+LL |     let value = num as *const i32 as *mut i32;
+   |                 ----------------------------- casting happend here
+...
+LL |     *value_rebind = 1;
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
+
+error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
+  --> $DIR/reference_casting.rs:116:5
    |
 LL |     *(num as *const i32).cast::<i32>().cast_mut() = 2;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -230,7 +287,7 @@ LL |     *(num as *const i32).cast::<i32>().cast_mut() = 2;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:99:5
+  --> $DIR/reference_casting.rs:118:5
    |
 LL |     *(num as *const _ as usize as *mut i32) = 2;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -238,7 +295,7 @@ LL |     *(num as *const _ as usize as *mut i32) = 2;
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:101:5
+  --> $DIR/reference_casting.rs:120:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -249,7 +306,7 @@ LL |     std::ptr::write(value, 2);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:103:5
+  --> $DIR/reference_casting.rs:122:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -260,7 +317,7 @@ LL |     std::ptr::write_unaligned(value, 2);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:105:5
+  --> $DIR/reference_casting.rs:124:5
    |
 LL |     let value = num as *const i32 as *mut i32;
    |                 ----------------------------- casting happend here
@@ -271,12 +328,12 @@ LL |     std::ptr::write_volatile(value, 2);
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
 error: assigning to `&T` is undefined behavior, consider using an `UnsafeCell`
-  --> $DIR/reference_casting.rs:109:9
+  --> $DIR/reference_casting.rs:128:9
    |
 LL |         *(this as *const _ as *mut _) = a;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: for more information, visit <https://doc.rust-lang.org/book/ch15-05-interior-mutability.html>
 
-error: aborting due to 32 previous errors
+error: aborting due to 38 previous errors
 
diff --git a/tests/ui/loops/loop-break-value.rs b/tests/ui/loops/loop-break-value.rs
index 51c9a36a039..c35200520cb 100644
--- a/tests/ui/loops/loop-break-value.rs
+++ b/tests/ui/loops/loop-break-value.rs
@@ -95,4 +95,67 @@ fn main() {
         break LOOP;
         //~^ ERROR cannot find value `LOOP` in this scope
     }
+
+    let _ = 'a: loop {
+        loop {
+            break; // This doesn't affect the expected break type of the 'a loop
+            loop {
+                loop {
+                    break 'a 1;
+                }
+            }
+        }
+        break; //~ ERROR mismatched types
+    };
+
+    let _ = 'a: loop {
+        loop {
+            break; // This doesn't affect the expected break type of the 'a loop
+            loop {
+                loop {
+                    break 'a 1;
+                }
+            }
+        }
+        break 'a; //~ ERROR mismatched types
+    };
+
+    loop {
+        break;
+        let _ = loop {
+            break 2;
+            loop {
+                break;
+            }
+        };
+        break 2; //~ ERROR mismatched types
+    }
+
+    'a: loop {
+        break;
+        let _ = 'a: loop {
+            //~^ WARNING label name `'a` shadows a label name that is already in scope
+            break 2;
+            loop {
+                break 'a; //~ ERROR mismatched types
+            }
+        };
+        break 2; //~ ERROR mismatched types
+    }
+
+    'a: loop {
+        break;
+        let _ = 'a: loop {
+            //~^ WARNING label name `'a` shadows a label name that is already in scope
+            break 'a 2;
+            loop {
+                break 'a; //~ ERROR mismatched types
+            }
+        };
+        break 2; //~ ERROR mismatched types
+    };
+
+    loop { // point at the return type
+        break 2; //~ ERROR mismatched types
+    }
 }
diff --git a/tests/ui/loops/loop-break-value.stderr b/tests/ui/loops/loop-break-value.stderr
index 5525dbb9005..6c83bc7575c 100644
--- a/tests/ui/loops/loop-break-value.stderr
+++ b/tests/ui/loops/loop-break-value.stderr
@@ -1,3 +1,21 @@
+warning: label name `'a` shadows a label name that is already in scope
+  --> $DIR/loop-break-value.rs:136:17
+   |
+LL |     'a: loop {
+   |     -- first declared here
+LL |         break;
+LL |         let _ = 'a: loop {
+   |                 ^^ label `'a` already in scope
+
+warning: label name `'a` shadows a label name that is already in scope
+  --> $DIR/loop-break-value.rs:148:17
+   |
+LL |     'a: loop {
+   |     -- first declared here
+LL |         break;
+LL |         let _ = 'a: loop {
+   |                 ^^ label `'a` already in scope
+
 error[E0425]: cannot find value `LOOP` in this scope
   --> $DIR/loop-break-value.rs:95:15
    |
@@ -134,7 +152,10 @@ error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:4:31
    |
 LL |     let val: ! = loop { break break; };
-   |                               ^^^^^ expected `!`, found `()`
+   |         ---      ----         ^^^^^ expected `!`, found `()`
+   |         |        |
+   |         |        this loop is expected to be of type `!`
+   |         expected because of this assignment
    |
    = note:   expected type `!`
            found unit type `()`
@@ -142,24 +163,38 @@ LL |     let val: ! = loop { break break; };
 error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:11:19
    |
+LL |             break "asdf";
+   |             ------------ expected because of this `break`
+LL |         } else {
 LL |             break 123;
    |                   ^^^ expected `&str`, found integer
 
 error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:16:15
    |
+LL |     let _: i32 = loop {
+   |         -        ---- this loop is expected to be of type `i32`
+   |         |
+   |         expected because of this assignment
 LL |         break "asdf";
    |               ^^^^^^ expected `i32`, found `&str`
 
 error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:21:31
    |
+LL |     let _: i32 = 'outer_loop: loop {
+   |         -                     ---- this loop is expected to be of type `i32`
+   |         |
+   |         expected because of this assignment
+LL |         loop {
 LL |             break 'outer_loop "nope";
    |                               ^^^^^^ expected `i32`, found `&str`
 
 error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:73:26
    |
+LL |                 break;
+   |                 ----- expected because of this `break`
 LL |                 break 'c 123;
    |                          ^^^ expected `()`, found integer
 
@@ -167,7 +202,11 @@ error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:80:15
    |
 LL |         break (break, break);
-   |               ^^^^^^^^^^^^^^ expected `()`, found `(!, !)`
+   |               ^-----^^-----^
+   |               ||      |
+   |               ||      expected because of this `break`
+   |               |expected because of this `break`
+   |               expected `()`, found `(!, !)`
    |
    = note: expected unit type `()`
                   found tuple `(!, !)`
@@ -175,19 +214,119 @@ LL |         break (break, break);
 error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:85:15
    |
+LL |         break;
+   |         ----- expected because of this `break`
 LL |         break 2;
    |               ^ expected `()`, found integer
 
 error[E0308]: mismatched types
   --> $DIR/loop-break-value.rs:90:9
    |
+LL |         break 2;
+   |         ------- expected because of this `break`
 LL |         break;
-   |         ^^^^^
-   |         |
-   |         expected integer, found `()`
-   |         help: give it a value of the expected type: `break value`
+   |         ^^^^^ expected integer, found `()`
+   |
+help: give it a value of the expected type
+   |
+LL |         break value;
+   |               +++++
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:108:9
+   |
+LL |                     break 'a 1;
+   |                     ---------- expected because of this `break`
+...
+LL |         break;
+   |         ^^^^^ expected integer, found `()`
+   |
+help: give it a value of the expected type
+   |
+LL |         break value;
+   |               +++++
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:120:9
+   |
+LL |                     break 'a 1;
+   |                     ---------- expected because of this `break`
+...
+LL |         break 'a;
+   |         ^^^^^^^^ expected integer, found `()`
+   |
+help: give it a value of the expected type
+   |
+LL |         break 'a value;
+   |                  +++++
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:131:15
+   |
+LL |         break;
+   |         ----- expected because of this `break`
+...
+LL |         break 2;
+   |               ^ expected `()`, found integer
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:140:17
+   |
+LL |             break 2;
+   |             ------- expected because of this `break`
+LL |             loop {
+LL |                 break 'a;
+   |                 ^^^^^^^^ expected integer, found `()`
+   |
+help: give it a value of the expected type
+   |
+LL |                 break 'a value;
+   |                          +++++
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:143:15
+   |
+LL |         break;
+   |         ----- expected because of this `break`
+...
+LL |         break 2;
+   |               ^ expected `()`, found integer
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:152:17
+   |
+LL |             break 'a 2;
+   |             ---------- expected because of this `break`
+LL |             loop {
+LL |                 break 'a;
+   |                 ^^^^^^^^ expected integer, found `()`
+   |
+help: give it a value of the expected type
+   |
+LL |                 break 'a value;
+   |                          +++++
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:155:15
+   |
+LL |         break;
+   |         ----- expected because of this `break`
+...
+LL |         break 2;
+   |               ^ expected `()`, found integer
+
+error[E0308]: mismatched types
+  --> $DIR/loop-break-value.rs:159:15
+   |
+LL | fn main() {
+   |           - expected `()` because of this return type
+...
+LL |     loop { // point at the return type
+   |     ---- this loop is expected to be of type `()`
+LL |         break 2;
+   |               ^ expected `()`, found integer
 
-error: aborting due to 17 previous errors; 1 warning emitted
+error: aborting due to 25 previous errors; 3 warnings emitted
 
 Some errors have detailed explanations: E0308, E0425, E0571.
 For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/loops/loop-labeled-break-value.stderr b/tests/ui/loops/loop-labeled-break-value.stderr
index aa04d330f25..694d6c306f6 100644
--- a/tests/ui/loops/loop-labeled-break-value.stderr
+++ b/tests/ui/loops/loop-labeled-break-value.stderr
@@ -2,28 +2,43 @@ error[E0308]: mismatched types
   --> $DIR/loop-labeled-break-value.rs:3:29
    |
 LL |         let _: i32 = loop { break };
-   |                             ^^^^^
-   |                             |
-   |                             expected `i32`, found `()`
-   |                             help: give it a value of the expected type: `break 42`
+   |             -        ----   ^^^^^ expected `i32`, found `()`
+   |             |        |
+   |             |        this loop is expected to be of type `i32`
+   |             expected because of this assignment
+   |
+help: give it a value of the expected type
+   |
+LL |         let _: i32 = loop { break 42 };
+   |                                   ++
 
 error[E0308]: mismatched types
   --> $DIR/loop-labeled-break-value.rs:6:37
    |
 LL |         let _: i32 = 'inner: loop { break 'inner };
-   |                                     ^^^^^^^^^^^^
-   |                                     |
-   |                                     expected `i32`, found `()`
-   |                                     help: give it a value of the expected type: `break 'inner 42`
+   |             -                ----   ^^^^^^^^^^^^ expected `i32`, found `()`
+   |             |                |
+   |             |                this loop is expected to be of type `i32`
+   |             expected because of this assignment
+   |
+help: give it a value of the expected type
+   |
+LL |         let _: i32 = 'inner: loop { break 'inner 42 };
+   |                                                  ++
 
 error[E0308]: mismatched types
   --> $DIR/loop-labeled-break-value.rs:9:45
    |
 LL |         let _: i32 = 'inner2: loop { loop { break 'inner2 } };
-   |                                             ^^^^^^^^^^^^^
-   |                                             |
-   |                                             expected `i32`, found `()`
-   |                                             help: give it a value of the expected type: `break 'inner2 42`
+   |             -                 ----          ^^^^^^^^^^^^^ expected `i32`, found `()`
+   |             |                 |
+   |             |                 this loop is expected to be of type `i32`
+   |             expected because of this assignment
+   |
+help: give it a value of the expected type
+   |
+LL |         let _: i32 = 'inner2: loop { loop { break 'inner2 42 } };
+   |                                                           ++
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/loops/loop-properly-diverging-2.stderr b/tests/ui/loops/loop-properly-diverging-2.stderr
index 5030a2935b9..1d1ae60cda1 100644
--- a/tests/ui/loops/loop-properly-diverging-2.stderr
+++ b/tests/ui/loops/loop-properly-diverging-2.stderr
@@ -2,10 +2,15 @@ error[E0308]: mismatched types
   --> $DIR/loop-properly-diverging-2.rs:2:23
    |
 LL |   let x: i32 = loop { break };
-   |                       ^^^^^
-   |                       |
-   |                       expected `i32`, found `()`
-   |                       help: give it a value of the expected type: `break 42`
+   |       -        ----   ^^^^^ expected `i32`, found `()`
+   |       |        |
+   |       |        this loop is expected to be of type `i32`
+   |       expected because of this assignment
+   |
+help: give it a value of the expected type
+   |
+LL |   let x: i32 = loop { break 42 };
+   |                             ++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/match/issue-72896.rs b/tests/ui/match/issue-72896-non-partial-eq-const.rs
index 3a8b8203731..a3095f0be83 100644
--- a/tests/ui/match/issue-72896.rs
+++ b/tests/ui/match/issue-72896-non-partial-eq-const.rs
@@ -17,7 +17,8 @@ const CONST_SET: EnumSet<Enum8> = EnumSet { __enumset_underlying: 3 };
 
 fn main() {
     match CONST_SET {
-        CONST_SET => { /* ok */ }
+        CONST_SET => { /* ok */ } //~WARN: must implement `PartialEq`
+        //~| previously accepted
         _ => panic!("match fell through?"),
     }
 }
diff --git a/tests/ui/match/issue-72896-non-partial-eq-const.stderr b/tests/ui/match/issue-72896-non-partial-eq-const.stderr
new file mode 100644
index 00000000000..a7fc0cfc054
--- /dev/null
+++ b/tests/ui/match/issue-72896-non-partial-eq-const.stderr
@@ -0,0 +1,23 @@
+warning: to use a constant of type `EnumSet<Enum8>` in a pattern, the type must implement `PartialEq`
+  --> $DIR/issue-72896-non-partial-eq-const.rs:20:9
+   |
+LL |         CONST_SET => { /* ok */ }
+   |         ^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
+   = note: `#[warn(const_patterns_without_partial_eq)]` on by default
+
+warning: 1 warning emitted
+
+Future incompatibility report: Future breakage diagnostic:
+warning: to use a constant of type `EnumSet<Enum8>` in a pattern, the type must implement `PartialEq`
+  --> $DIR/issue-72896-non-partial-eq-const.rs:20:9
+   |
+LL |         CONST_SET => { /* ok */ }
+   |         ^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #116122 <https://github.com/rust-lang/rust/issues/116122>
+   = note: `#[warn(const_patterns_without_partial_eq)]` on by default
+
diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs
deleted file mode 100644
index 0ccd441cc64..00000000000
--- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-// gate-test-packed_bundled_libs
-
-// ignore-wasm32-bare
-// compile-flags: --crate-type rlib
-// error-pattern: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs
-// build-fail
-
-#[link(name = "rust_test_helpers", kind = "static", modifiers = "+bundle,+whole-archive")]
-extern "C" {}
-
-fn main() {}
diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr
deleted file mode 100644
index 8a9fed740b0..00000000000
--- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive-link-attr.stderr
+++ /dev/null
@@ -1,4 +0,0 @@
-error: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs
-
-error: aborting due to previous error
-
diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs
deleted file mode 100644
index 18d4b52a34c..00000000000
--- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-// gate-test-packed_bundled_libs
-
-// ignore-wasm32-bare
-// compile-flags: -l static:+bundle,+whole-archive=rust_test_helpers --crate-type rlib
-// error-pattern: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs
-// build-fail
-
-fn main() {}
diff --git a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr b/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr
deleted file mode 100644
index 8a9fed740b0..00000000000
--- a/tests/ui/native-library-link-flags/mix-bundle-and-whole-archive.stderr
+++ /dev/null
@@ -1,4 +0,0 @@
-error: link modifiers combination `+bundle,+whole-archive` is unstable when generating rlibs
-
-error: aborting due to previous error
-
diff --git a/tests/ui/never_type/issue-52443.stderr b/tests/ui/never_type/issue-52443.stderr
index 99dfce86903..59292ed68a3 100644
--- a/tests/ui/never_type/issue-52443.stderr
+++ b/tests/ui/never_type/issue-52443.stderr
@@ -33,10 +33,12 @@ error[E0308]: mismatched types
   --> $DIR/issue-52443.rs:4:17
    |
 LL |     [(); loop { break }];
-   |                 ^^^^^
-   |                 |
-   |                 expected `usize`, found `()`
-   |                 help: give it a value of the expected type: `break 42`
+   |                 ^^^^^ expected `usize`, found `()`
+   |
+help: give it a value of the expected type
+   |
+LL |     [(); loop { break 42 }];
+   |                       ++
 
 error[E0015]: cannot convert `RangeFrom<usize>` into an iterator in constants
   --> $DIR/issue-52443.rs:9:21
diff --git a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
index 1e3a5328d3d..b3cb7813e19 100644
--- a/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/tests/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -6,7 +6,7 @@ LL |         let mut closure = expect_sig(|p, y| *p = y);
    |
    = note: defining type: test::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) i32)),
+               for<Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon }) i32)),
                (),
            ]
 
diff --git a/tests/ui/nll/closure-requirements/escape-argument.stderr b/tests/ui/nll/closure-requirements/escape-argument.stderr
index bc4ba93f884..4f0156728ac 100644
--- a/tests/ui/nll/closure-requirements/escape-argument.stderr
+++ b/tests/ui/nll/closure-requirements/escape-argument.stderr
@@ -6,7 +6,7 @@ LL |         let mut closure = expect_sig(|p, y| *p = y);
    |
    = note: defining type: test::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) i32)),
+               for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) mut &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) i32)),
                (),
            ]
 
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
index f8383cc42a2..ccf56bf6f37 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
@@ -6,7 +6,7 @@ LL |         |_outlives1, _outlives2, _outlives3, x, y| {
    |
    = note: defining type: supply::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&'?2 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?3 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>, std::cell::Cell<&'?2 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) &'?3 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?4
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr
index 113173d8f76..a16433c9d37 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-ref.stderr
@@ -6,7 +6,7 @@ LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
    |
    = note: defining type: supply::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) &'?2 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) &'?2 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?3
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
index ba15199ab5a..9e0f16c0fc7 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-comparing-against-free.stderr
@@ -6,7 +6,7 @@ LL |     foo(cell, |cell_a, cell_x| {
    |
    = note: defining type: case1::{closure#0} with closure args [
                i32,
-               for<Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>)),
                (),
            ]
 
@@ -36,7 +36,7 @@ LL |     foo(cell, |cell_a, cell_x| {
    |
    = note: defining type: case2::{closure#0} with closure args [
                i32,
-               for<Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>)),
                (),
            ]
    = note: number of external vids: 2
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
index f2bf83c6c59..e4989e32155 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
@@ -6,7 +6,7 @@ LL |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
    |
    = note: defining type: supply::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?2
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
index 2734326ed64..be35e62d070 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
@@ -6,7 +6,7 @@ LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
    |
    = note: defining type: supply::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&'?2 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon }) std::cell::Cell<&'?2 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?3
diff --git a/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr b/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr
index 5ab321eb666..8880dd816a1 100644
--- a/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-approximated-val.stderr
@@ -6,7 +6,7 @@ LL |     establish_relationships(cell_a, cell_b, |outlives1, outlives2, x, y| {
    |
    = note: defining type: test::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?2 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) &'?2 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?3
diff --git a/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr b/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
index 595fd5ff565..47774b63f81 100644
--- a/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-despite-same-free-region.stderr
@@ -6,7 +6,7 @@ LL |         |_outlives1, _outlives2, x, y| {
    |
    = note: defining type: supply::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?2 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) &'?2 u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) u32>, std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?3
diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index 62b0e3eed85..3404bb12827 100644
--- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -6,7 +6,7 @@ LL |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
    |
    = note: defining type: supply::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?1 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) &'?1 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?2
diff --git a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 6f2044d621e..e40648912e3 100644
--- a/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/tests/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -6,7 +6,7 @@ LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y
    |
    = note: defining type: supply::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) &'?1 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) &'?2 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon(None) }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon(None) }) u32>)),
+               for<Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) &'?1 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 2, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) &'?2 u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 4, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) u32>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 5, kind: BrAnon }) std::cell::Cell<&ReLateBound(DebruijnIndex(0), BoundRegion { var: 3, kind: BrAnon }) u32>)),
                (),
            ]
    = note: late-bound region is '?3
diff --git a/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr
index 7635f2ede0a..18fb7195d02 100644
--- a/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr
+++ b/tests/ui/nll/closure-requirements/return-wrong-bound-region.stderr
@@ -6,7 +6,7 @@ LL |     expect_sig(|a, b| b); // ought to return `a`
    |
    = note: defining type: test::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) i32)) -> &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) i32,
+               for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((&ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) i32, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) i32)) -> &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) i32,
                (),
            ]
 
diff --git a/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr b/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
index 660211fe21a..f58d49d8461 100644
--- a/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
+++ b/tests/ui/nll/ty-outlives/ty-param-closure-approximate-lower-bound.stderr
@@ -6,7 +6,7 @@ LL |     twice(cell, value, |a, b| invoke(a, b));
    |
    = note: defining type: generic::<T>::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) T)),
+               for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) T)),
                (),
            ]
    = note: number of external vids: 2
@@ -28,7 +28,7 @@ LL |     twice(cell, value, |a, b| invoke(a, b));
    |
    = note: defining type: generic_fail::<T>::{closure#0} with closure args [
                i16,
-               for<Region(BrAnon(None)), Region(BrAnon(None))> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon(None) }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon(None) }) T)),
+               for<Region(BrAnon), Region(BrAnon)> extern "rust-call" fn((std::option::Option<std::cell::Cell<&'?1 &ReLateBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrAnon }) ()>>, &ReLateBound(DebruijnIndex(0), BoundRegion { var: 1, kind: BrAnon }) T)),
                (),
            ]
    = note: late-bound region is '?2
diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr
index d12bfbf269e..85555c43906 100644
--- a/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr
+++ b/tests/ui/panic-handler/panic-handler-bad-signature-1.stderr
@@ -4,8 +4,8 @@ error[E0308]: `#[panic_handler]` function has wrong type
 LL | fn panic(info: PanicInfo) -> () {}
    |                ^^^^^^^^^ expected `&PanicInfo<'_>`, found `PanicInfo<'_>`
    |
-   = note: expected signature `fn(&PanicInfo<'_>) -> !`
-              found signature `fn(PanicInfo<'_>)`
+   = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> !`
+              found signature `for<'a> fn(PanicInfo<'a>)`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-2.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-2.stderr
index 06e32d5fb84..84eba2a5a63 100644
--- a/tests/ui/panic-handler/panic-handler-bad-signature-2.stderr
+++ b/tests/ui/panic-handler/panic-handler-bad-signature-2.stderr
@@ -4,8 +4,8 @@ error[E0308]: `#[panic_handler]` function has wrong type
 LL | fn panic(info: &'static PanicInfo) -> !
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
    |
-   = note: expected fn pointer `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _`
-              found fn pointer `for<'a> fn(&'static PanicInfo<'a>) -> _`
+   = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _`
+              found signature `for<'a> fn(&'static PanicInfo<'a>) -> _`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-3.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-3.stderr
index 8365f5769eb..cdf55ab6534 100644
--- a/tests/ui/panic-handler/panic-handler-bad-signature-3.stderr
+++ b/tests/ui/panic-handler/panic-handler-bad-signature-3.stderr
@@ -4,7 +4,7 @@ error[E0308]: `#[panic_handler]` function has wrong type
 LL | fn panic() -> ! {
    | ^^^^^^^^^^^^^^^ incorrect number of function parameters
    |
-   = note: expected signature `fn(&PanicInfo<'_>) -> _`
+   = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _`
               found signature `fn() -> _`
 
 error: aborting due to previous error
diff --git a/tests/ui/panic-handler/panic-handler-bad-signature-5.stderr b/tests/ui/panic-handler/panic-handler-bad-signature-5.stderr
index 22b8d5ca811..20c17587590 100644
--- a/tests/ui/panic-handler/panic-handler-bad-signature-5.stderr
+++ b/tests/ui/panic-handler/panic-handler-bad-signature-5.stderr
@@ -4,8 +4,8 @@ error[E0308]: `#[panic_handler]` function has wrong type
 LL | fn panic(info: &PanicInfo<'static>) -> !
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
    |
-   = note: expected fn pointer `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _`
-              found fn pointer `for<'a> fn(&'a PanicInfo<'static>) -> _`
+   = note: expected signature `for<'a, 'b> fn(&'a PanicInfo<'b>) -> _`
+              found signature `for<'a> fn(&'a PanicInfo<'static>) -> _`
 
 error: aborting due to previous error
 
diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.rs b/tests/ui/panics/short-ice-remove-middle-frames-2.rs
index 38a80f8b670..751959f55bb 100644
--- a/tests/ui/panics/short-ice-remove-middle-frames-2.rs
+++ b/tests/ui/panics/short-ice-remove-middle-frames-2.rs
@@ -2,6 +2,7 @@
 // run-fail
 // check-run-results
 // exec-env:RUST_BACKTRACE=1
+// needs-unwind
 // ignore-android FIXME #17520
 // ignore-wasm no panic support
 // ignore-openbsd no support for libbacktrace without filename
diff --git a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
index 2b648a0cad2..664ebaa4c51 100644
--- a/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
+++ b/tests/ui/panics/short-ice-remove-middle-frames-2.run.stderr
@@ -1,4 +1,4 @@
-thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:56:5:
+thread 'main' panicked at $DIR/short-ice-remove-middle-frames-2.rs:57:5:
 debug!!!
 stack backtrace:
    0: std::panicking::begin_panic
diff --git a/tests/ui/panics/short-ice-remove-middle-frames.rs b/tests/ui/panics/short-ice-remove-middle-frames.rs
index c872084f033..134e13233da 100644
--- a/tests/ui/panics/short-ice-remove-middle-frames.rs
+++ b/tests/ui/panics/short-ice-remove-middle-frames.rs
@@ -2,6 +2,7 @@
 // run-fail
 // check-run-results
 // exec-env:RUST_BACKTRACE=1
+// needs-unwind
 // ignore-android FIXME #17520
 // ignore-wasm no panic support
 // ignore-openbsd no support for libbacktrace without filename
diff --git a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr
index 5b372684096..bc252fde1f6 100644
--- a/tests/ui/panics/short-ice-remove-middle-frames.run.stderr
+++ b/tests/ui/panics/short-ice-remove-middle-frames.run.stderr
@@ -1,4 +1,4 @@
-thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:52:5:
+thread 'main' panicked at $DIR/short-ice-remove-middle-frames.rs:53:5:
 debug!!!
 stack backtrace:
    0: std::panicking::begin_panic
diff --git a/tests/ui/parser/issues/issue-89388.stderr b/tests/ui/parser/issues/issue-89388.stderr
index cf28bef0f4a..366d05c2d94 100644
--- a/tests/ui/parser/issues/issue-89388.stderr
+++ b/tests/ui/parser/issues/issue-89388.stderr
@@ -2,7 +2,12 @@ error: missing angle brackets in associated item path
   --> $DIR/issue-89388.rs:5:24
    |
 LL |     let _ = option.map([_]::to_vec);
-   |                        ^^^^^^^^^^^ help: try: `<[_]>::to_vec`
+   |                        ^^^
+   |
+help: types that don't start with an identifier need to be surrounded with angle brackets in qualified paths
+   |
+LL |     let _ = option.map(<[_]>::to_vec);
+   |                        +   +
 
 error: aborting due to previous error
 
diff --git a/tests/ui/proc-macro/auxiliary/api/mod.rs b/tests/ui/proc-macro/auxiliary/api/mod.rs
index 739c25132e7..3bea5d75779 100644
--- a/tests/ui/proc-macro/auxiliary/api/mod.rs
+++ b/tests/ui/proc-macro/auxiliary/api/mod.rs
@@ -4,6 +4,7 @@
 #![crate_type = "proc-macro"]
 #![crate_name = "proc_macro_api_tests"]
 #![feature(proc_macro_span)]
+#![feature(proc_macro_byte_character)]
 #![deny(dead_code)] // catch if a test function is never called
 
 extern crate proc_macro;
diff --git a/tests/ui/proc-macro/auxiliary/api/parse.rs b/tests/ui/proc-macro/auxiliary/api/parse.rs
index 27391f83111..07c9f464961 100644
--- a/tests/ui/proc-macro/auxiliary/api/parse.rs
+++ b/tests/ui/proc-macro/auxiliary/api/parse.rs
@@ -29,12 +29,16 @@ fn test_display_literal() {
     assert_eq!(Literal::character('\'').to_string(), "'\\''");
     assert_eq!(Literal::character('"').to_string(), "'\"'");
     assert_eq!(Literal::character('\u{1}').to_string(), "'\\u{1}'");
+
+    assert_eq!(Literal::byte_character(b'a').to_string(), "b'a'");
+    assert_eq!(Literal::byte_character(0).to_string(), "b'\\x00'");
 }
 
 fn test_parse_literal() {
     assert_eq!("1".parse::<Literal>().unwrap().to_string(), "1");
     assert_eq!("1.0".parse::<Literal>().unwrap().to_string(), "1.0");
     assert_eq!("'a'".parse::<Literal>().unwrap().to_string(), "'a'");
+    assert_eq!("b'a'".parse::<Literal>().unwrap().to_string(), "b'a'");
     assert_eq!("\"\n\"".parse::<Literal>().unwrap().to_string(), "\"\n\"");
     assert_eq!("b\"\"".parse::<Literal>().unwrap().to_string(), "b\"\"");
     assert_eq!("r##\"\"##".parse::<Literal>().unwrap().to_string(), "r##\"\"##");
diff --git a/tests/ui/proc-macro/auxiliary/print-tokens.rs b/tests/ui/proc-macro/auxiliary/print-tokens.rs
new file mode 100644
index 00000000000..3a5767edb15
--- /dev/null
+++ b/tests/ui/proc-macro/auxiliary/print-tokens.rs
@@ -0,0 +1,16 @@
+// force-host
+// no-prefer-dynamic
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::{TokenStream, TokenTree};
+
+#[proc_macro]
+pub fn print_tokens(input: TokenStream) -> TokenStream {
+    println!("{:#?}", input);
+    for token in input {
+        println!("{token}");
+    }
+    TokenStream::new()
+}
diff --git a/tests/ui/proc-macro/literal-to-string.rs b/tests/ui/proc-macro/literal-to-string.rs
new file mode 100644
index 00000000000..494d17cbeea
--- /dev/null
+++ b/tests/ui/proc-macro/literal-to-string.rs
@@ -0,0 +1,26 @@
+// check-pass
+// edition: 2021
+#![feature(c_str_literals)]
+
+// aux-build: print-tokens.rs
+extern crate print_tokens;
+
+fn main() {
+    print_tokens::print_tokens! {
+        1
+        17u8
+        42.
+        3.14f32
+        b'a'
+        b'\xFF'
+        'c'
+        '\x32'
+        "\"str\""
+        r#""raw" str"#
+        r###"very ##"raw"## str"###
+        b"\"byte\" str"
+        br#""raw" "byte" str"#
+        c"\"c\" str"
+        cr#""raw" "c" str"#
+    }
+}
diff --git a/tests/ui/proc-macro/literal-to-string.stdout b/tests/ui/proc-macro/literal-to-string.stdout
new file mode 100644
index 00000000000..7b27fcf798b
--- /dev/null
+++ b/tests/ui/proc-macro/literal-to-string.stdout
@@ -0,0 +1,107 @@
+TokenStream [
+    Literal {
+        kind: Integer,
+        symbol: "1",
+        suffix: None,
+        span: #0 bytes(172..173),
+    },
+    Literal {
+        kind: Integer,
+        symbol: "17",
+        suffix: Some("u8"),
+        span: #0 bytes(182..186),
+    },
+    Literal {
+        kind: Float,
+        symbol: "42.",
+        suffix: None,
+        span: #0 bytes(195..198),
+    },
+    Literal {
+        kind: Float,
+        symbol: "3.14",
+        suffix: Some("f32"),
+        span: #0 bytes(207..214),
+    },
+    Literal {
+        kind: Byte,
+        symbol: "a",
+        suffix: None,
+        span: #0 bytes(223..227),
+    },
+    Literal {
+        kind: Byte,
+        symbol: "\xFF",
+        suffix: None,
+        span: #0 bytes(236..243),
+    },
+    Literal {
+        kind: Char,
+        symbol: "c",
+        suffix: None,
+        span: #0 bytes(252..255),
+    },
+    Literal {
+        kind: Char,
+        symbol: "\x32",
+        suffix: None,
+        span: #0 bytes(264..270),
+    },
+    Literal {
+        kind: Str,
+        symbol: "\\"str\\"",
+        suffix: None,
+        span: #0 bytes(279..288),
+    },
+    Literal {
+        kind: StrRaw(1),
+        symbol: "\"raw\" str",
+        suffix: None,
+        span: #0 bytes(297..311),
+    },
+    Literal {
+        kind: StrRaw(3),
+        symbol: "very ##\"raw\"## str",
+        suffix: None,
+        span: #0 bytes(320..347),
+    },
+    Literal {
+        kind: ByteStr,
+        symbol: "\\"byte\\" str",
+        suffix: None,
+        span: #0 bytes(356..371),
+    },
+    Literal {
+        kind: ByteStrRaw(1),
+        symbol: "\"raw\" \"byte\" str",
+        suffix: None,
+        span: #0 bytes(380..402),
+    },
+    Literal {
+        kind: CStr,
+        symbol: "\\"c\\" str",
+        suffix: None,
+        span: #0 bytes(411..423),
+    },
+    Literal {
+        kind: CStrRaw(1),
+        symbol: "\"raw\" \"c\" str",
+        suffix: None,
+        span: #0 bytes(432..451),
+    },
+]
+1
+17u8
+42.
+3.14f32
+b'a'
+b'\xFF'
+'c'
+'\x32'
+"\"str\""
+r#""raw" str"#
+r###"very ##"raw"## str"###
+b"\"byte\" str"
+br#""raw" "byte" str"#
+c"\"c\" str"
+cr#""raw" "c" str"#
diff --git a/tests/ui/repr/16-bit-repr-c-enum.rs b/tests/ui/repr/16-bit-repr-c-enum.rs
index 2acfde4be46..d4fea2b192b 100644
--- a/tests/ui/repr/16-bit-repr-c-enum.rs
+++ b/tests/ui/repr/16-bit-repr-c-enum.rs
@@ -5,7 +5,7 @@
 // [avr] compile-flags: --target=avr-unknown-gnu-atmega328 --crate-type=rlib
 // [msp430] needs-llvm-components: msp430
 // [msp430] compile-flags: --target=msp430-none-elf --crate-type=rlib
-#![feature(no_core, lang_items, intrinsics, staged_api)]
+#![feature(no_core, lang_items, intrinsics, staged_api, rustc_attrs)]
 #![no_core]
 #![crate_type = "lib"]
 #![stable(feature = "", since = "")]
diff --git a/tests/ui/resolve/associated-fn-called-as-fn.stderr b/tests/ui/resolve/associated-fn-called-as-fn.stderr
index fbdea30d551..7d28b959a1a 100644
--- a/tests/ui/resolve/associated-fn-called-as-fn.stderr
+++ b/tests/ui/resolve/associated-fn-called-as-fn.stderr
@@ -2,13 +2,23 @@ error[E0425]: cannot find function `collect_primary` in this scope
   --> $DIR/associated-fn-called-as-fn.rs:6:30
    |
 LL |                 '0'..='9' => collect_primary(&c),
-   |                              ^^^^^^^^^^^^^^^ help: you might have meant to call the associated function: `Self::collect_primary`
+   |                              ^^^^^^^^^^^^^^^
+   |
+help: you might have meant to call the associated function
+   |
+LL |                 '0'..='9' => Self::collect_primary(&c),
+   |                              ++++++
 
 error[E0425]: cannot find function `collect_primary` in this scope
   --> $DIR/associated-fn-called-as-fn.rs:23:30
    |
 LL |                 '0'..='9' => collect_primary(&c),
-   |                              ^^^^^^^^^^^^^^^ help: you might have meant to call the associated function: `Self::collect_primary`
+   |                              ^^^^^^^^^^^^^^^
+   |
+help: you might have meant to call the associated function
+   |
+LL |                 '0'..='9' => Self::collect_primary(&c),
+   |                              ++++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs
new file mode 100644
index 00000000000..b5f13959081
--- /dev/null
+++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.rs
@@ -0,0 +1,18 @@
+struct Foo {
+    field: u32,
+}
+
+impl Foo {
+    fn field(&self) -> u32 {
+        self.field
+    }
+
+    fn new() -> Foo {
+        field; //~ ERROR cannot find value `field` in this scope
+        Foo { field } //~ ERROR cannot find value `field` in this scope
+    }
+    fn clone(&self) -> Foo {
+        Foo { field } //~ ERROR cannot find value `field` in this scope
+    }
+}
+fn main() {}
diff --git a/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr
new file mode 100644
index 00000000000..3c44c1c249c
--- /dev/null
+++ b/tests/ui/resolve/field-and-method-in-self-not-available-in-assoc-fn.stderr
@@ -0,0 +1,41 @@
+error[E0425]: cannot find value `field` in this scope
+  --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:11:9
+   |
+LL |     field: u32,
+   |     ---------- a field by that name exists in `Self`
+...
+LL |     fn field(&self) -> u32 {
+   |        ----- a method by that name is available on `Self` here
+...
+LL |         field;
+   |         ^^^^^
+
+error[E0425]: cannot find value `field` in this scope
+  --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:12:15
+   |
+LL |     field: u32,
+   |     ---------- a field by that name exists in `Self`
+...
+LL |     fn field(&self) -> u32 {
+   |        ----- a method by that name is available on `Self` here
+...
+LL |         Foo { field }
+   |               ^^^^^
+
+error[E0425]: cannot find value `field` in this scope
+  --> $DIR/field-and-method-in-self-not-available-in-assoc-fn.rs:15:15
+   |
+LL |     fn field(&self) -> u32 {
+   |        ----- a method by that name is available on `Self` here
+...
+LL |         Foo { field }
+   |               ^^^^^
+   |
+help: you might have meant to use the available field
+   |
+LL |         Foo { field: self.field }
+   |               ++++++++++++
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/resolve/issue-103474.stderr b/tests/ui/resolve/issue-103474.stderr
index 415d231552a..e48fb31eccc 100644
--- a/tests/ui/resolve/issue-103474.stderr
+++ b/tests/ui/resolve/issue-103474.stderr
@@ -19,7 +19,7 @@ error[E0425]: cannot find function `first` in this scope
 LL |         first()
    |         ^^^^^ not found in this scope
    |
-help: consider using the associated function
+help: consider using the method on `Self`
    |
 LL |         self.first()
    |         +++++
diff --git a/tests/ui/resolve/issue-14254.stderr b/tests/ui/resolve/issue-14254.stderr
index 690a40f7edd..9284b4babc5 100644
--- a/tests/ui/resolve/issue-14254.stderr
+++ b/tests/ui/resolve/issue-14254.stderr
@@ -8,13 +8,23 @@ error[E0425]: cannot find value `x` in this scope
   --> $DIR/issue-14254.rs:30:9
    |
 LL |         x;
-   |         ^ help: you might have meant to use the available field: `self.x`
+   |         ^
+   |
+help: you might have meant to use the available field
+   |
+LL |         self.x;
+   |         +++++
 
 error[E0425]: cannot find value `y` in this scope
   --> $DIR/issue-14254.rs:32:9
    |
 LL |         y;
-   |         ^ help: you might have meant to use the available field: `self.y`
+   |         ^
+   |
+help: you might have meant to use the available field
+   |
+LL |         self.y;
+   |         +++++
 
 error[E0425]: cannot find value `a` in this scope
   --> $DIR/issue-14254.rs:34:9
@@ -31,7 +41,7 @@ LL |         bah;
 help: you might have meant to refer to the associated function
    |
 LL |         Self::bah;
-   |         ~~~~~~~~~
+   |         ++++++
 
 error[E0425]: cannot find value `b` in this scope
   --> $DIR/issue-14254.rs:38:9
@@ -43,13 +53,23 @@ error[E0425]: cannot find value `x` in this scope
   --> $DIR/issue-14254.rs:47:9
    |
 LL |         x;
-   |         ^ help: you might have meant to use the available field: `self.x`
+   |         ^
+   |
+help: you might have meant to use the available field
+   |
+LL |         self.x;
+   |         +++++
 
 error[E0425]: cannot find value `y` in this scope
   --> $DIR/issue-14254.rs:49:9
    |
 LL |         y;
-   |         ^ help: you might have meant to use the available field: `self.y`
+   |         ^
+   |
+help: you might have meant to use the available field
+   |
+LL |         self.y;
+   |         +++++
 
 error[E0425]: cannot find value `a` in this scope
   --> $DIR/issue-14254.rs:51:9
@@ -66,7 +86,7 @@ LL |         bah;
 help: you might have meant to refer to the associated function
    |
 LL |         Self::bah;
-   |         ~~~~~~~~~
+   |         ++++++
 
 error[E0425]: cannot find value `b` in this scope
   --> $DIR/issue-14254.rs:55:9
@@ -83,7 +103,7 @@ LL |         bah;
 help: you might have meant to refer to the associated function
    |
 LL |         Self::bah;
-   |         ~~~~~~~~~
+   |         ++++++
 
 error[E0425]: cannot find value `bah` in this scope
   --> $DIR/issue-14254.rs:73:9
@@ -94,7 +114,7 @@ LL |         bah;
 help: you might have meant to refer to the associated function
    |
 LL |         Self::bah;
-   |         ~~~~~~~~~
+   |         ++++++
 
 error[E0425]: cannot find value `bah` in this scope
   --> $DIR/issue-14254.rs:82:9
@@ -105,7 +125,7 @@ LL |         bah;
 help: you might have meant to refer to the associated function
    |
 LL |         Self::bah;
-   |         ~~~~~~~~~
+   |         ++++++
 
 error[E0425]: cannot find value `bah` in this scope
   --> $DIR/issue-14254.rs:91:9
@@ -116,7 +136,7 @@ LL |         bah;
 help: you might have meant to refer to the associated function
    |
 LL |         Self::bah;
-   |         ~~~~~~~~~
+   |         ++++++
 
 error[E0425]: cannot find value `bah` in this scope
   --> $DIR/issue-14254.rs:100:9
@@ -127,55 +147,95 @@ LL |         bah;
 help: you might have meant to refer to the associated function
    |
 LL |         Self::bah;
-   |         ~~~~~~~~~
+   |         ++++++
 
 error[E0425]: cannot find function `baz` in this scope
   --> $DIR/issue-14254.rs:19:9
    |
 LL |         baz();
-   |         ^^^ help: you might have meant to call the method: `self.baz`
+   |         ^^^
+   |
+help: you might have meant to call the method
+   |
+LL |         self.baz();
+   |         +++++
 
 error[E0425]: cannot find function `baz` in this scope
   --> $DIR/issue-14254.rs:28:9
    |
 LL |         baz();
-   |         ^^^ help: you might have meant to call the method: `self.baz`
+   |         ^^^
+   |
+help: you might have meant to call the method
+   |
+LL |         self.baz();
+   |         +++++
 
 error[E0425]: cannot find function `baz` in this scope
   --> $DIR/issue-14254.rs:45:9
    |
 LL |         baz();
-   |         ^^^ help: you might have meant to call the method: `self.baz`
+   |         ^^^
+   |
+help: you might have meant to call the method
+   |
+LL |         self.baz();
+   |         +++++
 
 error[E0425]: cannot find function `baz` in this scope
   --> $DIR/issue-14254.rs:62:9
    |
 LL |         baz();
-   |         ^^^ help: you might have meant to call the method: `self.baz`
+   |         ^^^
+   |
+help: you might have meant to call the method
+   |
+LL |         self.baz();
+   |         +++++
 
 error[E0425]: cannot find function `baz` in this scope
   --> $DIR/issue-14254.rs:71:9
    |
 LL |         baz();
-   |         ^^^ help: you might have meant to call the method: `self.baz`
+   |         ^^^
+   |
+help: you might have meant to call the method
+   |
+LL |         self.baz();
+   |         +++++
 
 error[E0425]: cannot find function `baz` in this scope
   --> $DIR/issue-14254.rs:80:9
    |
 LL |         baz();
-   |         ^^^ help: you might have meant to call the method: `self.baz`
+   |         ^^^
+   |
+help: you might have meant to call the method
+   |
+LL |         self.baz();
+   |         +++++
 
 error[E0425]: cannot find function `baz` in this scope
   --> $DIR/issue-14254.rs:89:9
    |
 LL |         baz();
-   |         ^^^ help: you might have meant to call the method: `self.baz`
+   |         ^^^
+   |
+help: you might have meant to call the method
+   |
+LL |         self.baz();
+   |         +++++
 
 error[E0425]: cannot find function `baz` in this scope
   --> $DIR/issue-14254.rs:98:9
    |
 LL |         baz();
-   |         ^^^ help: you might have meant to call the method: `self.baz`
+   |         ^^^
+   |
+help: you might have meant to call the method
+   |
+LL |         self.baz();
+   |         +++++
 
 error: aborting due to 24 previous errors
 
diff --git a/tests/ui/resolve/issue-2356.stderr b/tests/ui/resolve/issue-2356.stderr
index 30f5f059526..5f75ae98870 100644
--- a/tests/ui/resolve/issue-2356.stderr
+++ b/tests/ui/resolve/issue-2356.stderr
@@ -1,8 +1,11 @@
 error[E0425]: cannot find value `whiskers` in this scope
   --> $DIR/issue-2356.rs:39:5
    |
+LL |   whiskers: isize,
+   |   --------------- a field by that name exists in `Self`
+...
 LL |     whiskers -= other;
-   |     ^^^^^^^^ a field by this name exists in `Self`
+   |     ^^^^^^^^
 
 error[E0424]: expected value, found module `self`
   --> $DIR/issue-2356.rs:65:8
@@ -21,13 +24,21 @@ error[E0425]: cannot find value `whiskers` in this scope
   --> $DIR/issue-2356.rs:79:5
    |
 LL |     whiskers = 0;
-   |     ^^^^^^^^ help: you might have meant to use the available field: `self.whiskers`
+   |     ^^^^^^^^
+   |
+help: you might have meant to use the available field
+   |
+LL |     self.whiskers = 0;
+   |     +++++
 
 error[E0425]: cannot find value `whiskers` in this scope
   --> $DIR/issue-2356.rs:84:5
    |
+LL |   whiskers: isize,
+   |   --------------- a field by that name exists in `Self`
+...
 LL |     whiskers = 4;
-   |     ^^^^^^^^ a field by this name exists in `Self`
+   |     ^^^^^^^^
 
 error[E0424]: expected value, found module `self`
   --> $DIR/issue-2356.rs:92:5
@@ -47,19 +58,34 @@ error[E0425]: cannot find function `clone` in this scope
   --> $DIR/issue-2356.rs:24:5
    |
 LL |     clone();
-   |     ^^^^^ help: you might have meant to call the method: `self.clone`
+   |     ^^^^^
+   |
+help: you might have meant to call the method
+   |
+LL |     self.clone();
+   |     +++++
 
 error[E0425]: cannot find function `default` in this scope
   --> $DIR/issue-2356.rs:31:5
    |
 LL |     default();
-   |     ^^^^^^^ help: you might have meant to call the associated function: `Self::default`
+   |     ^^^^^^^
+   |
+help: you might have meant to call the associated function
+   |
+LL |     Self::default();
+   |     ++++++
 
 error[E0425]: cannot find function `shave` in this scope
   --> $DIR/issue-2356.rs:41:5
    |
 LL |     shave(4);
-   |     ^^^^^ help: you might have meant to call the associated function: `Self::shave`
+   |     ^^^^^
+   |
+help: you might have meant to call the associated function
+   |
+LL |     Self::shave(4);
+   |     ++++++
 
 error[E0425]: cannot find function `purr` in this scope
   --> $DIR/issue-2356.rs:43:5
@@ -73,7 +99,7 @@ error[E0425]: cannot find function `static_method` in this scope
 LL |         static_method();
    |         ^^^^^^^^^^^^^ not found in this scope
    |
-help: consider using the associated function
+help: consider using the associated function on `Self`
    |
 LL |         Self::static_method();
    |         ++++++
@@ -102,7 +128,7 @@ error[E0425]: cannot find function `grow_older` in this scope
 LL |     grow_older();
    |     ^^^^^^^^^^ not found in this scope
    |
-help: consider using the associated function
+help: consider using the associated function on `Self`
    |
 LL |     Self::grow_older();
    |     ++++++
diff --git a/tests/ui/resolve/issue-60057.stderr b/tests/ui/resolve/issue-60057.stderr
index 4d915fcd9fe..a2ab8644353 100644
--- a/tests/ui/resolve/issue-60057.stderr
+++ b/tests/ui/resolve/issue-60057.stderr
@@ -1,14 +1,22 @@
 error[E0425]: cannot find value `banana` in this scope
   --> $DIR/issue-60057.rs:8:21
    |
+LL |     banana: u8,
+   |     ---------- a field by that name exists in `Self`
+...
 LL |             banana: banana
-   |                     ^^^^^^ a field by this name exists in `Self`
+   |                     ^^^^^^
 
 error[E0425]: cannot find value `banana` in this scope
   --> $DIR/issue-60057.rs:14:21
    |
 LL |             banana: banana
-   |                     ^^^^^^ help: you might have meant to use the available field: `self.banana`
+   |                     ^^^^^^
+   |
+help: you might have meant to use the available field
+   |
+LL |             banana: self.banana
+   |                     +++++
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/resolve/resolve-assoc-suggestions.stderr b/tests/ui/resolve/resolve-assoc-suggestions.stderr
index 8def9aa2025..3d9d4ffaa10 100644
--- a/tests/ui/resolve/resolve-assoc-suggestions.stderr
+++ b/tests/ui/resolve/resolve-assoc-suggestions.stderr
@@ -14,13 +14,23 @@ error[E0425]: cannot find value `field` in this scope
   --> $DIR/resolve-assoc-suggestions.rs:20:9
    |
 LL |         field;
-   |         ^^^^^ help: you might have meant to use the available field: `self.field`
+   |         ^^^^^
+   |
+help: you might have meant to use the available field
+   |
+LL |         self.field;
+   |         +++++
 
 error[E0412]: cannot find type `Type` in this scope
   --> $DIR/resolve-assoc-suggestions.rs:23:16
    |
 LL |         let _: Type;
-   |                ^^^^ help: you might have meant to use the associated type: `Self::Type`
+   |                ^^^^
+   |
+help: you might have meant to use the associated type
+   |
+LL |         let _: Self::Type;
+   |                ++++++
 
 error[E0531]: cannot find tuple struct or tuple variant `Type` in this scope
   --> $DIR/resolve-assoc-suggestions.rs:25:13
@@ -50,7 +60,12 @@ error[E0425]: cannot find value `method` in this scope
   --> $DIR/resolve-assoc-suggestions.rs:34:9
    |
 LL |         method;
-   |         ^^^^^^ help: you might have meant to refer to the method: `self.method`
+   |         ^^^^^^
+   |
+help: you might have meant to refer to the method
+   |
+LL |         self.method;
+   |         +++++
 
 error: aborting due to 9 previous errors
 
diff --git a/tests/ui/resolve/resolve-speculative-adjustment.stderr b/tests/ui/resolve/resolve-speculative-adjustment.stderr
index be11a7ebeca..fb15472bdae 100644
--- a/tests/ui/resolve/resolve-speculative-adjustment.stderr
+++ b/tests/ui/resolve/resolve-speculative-adjustment.stderr
@@ -8,13 +8,23 @@ error[E0425]: cannot find value `field` in this scope
   --> $DIR/resolve-speculative-adjustment.rs:23:9
    |
 LL |         field;
-   |         ^^^^^ help: you might have meant to use the available field: `self.field`
+   |         ^^^^^
+   |
+help: you might have meant to use the available field
+   |
+LL |         self.field;
+   |         +++++
 
 error[E0425]: cannot find function `method` in this scope
   --> $DIR/resolve-speculative-adjustment.rs:25:9
    |
 LL |         method();
-   |         ^^^^^^ help: you might have meant to call the method: `self.method`
+   |         ^^^^^^
+   |
+help: you might have meant to call the method
+   |
+LL |         self.method();
+   |         +++++
 
 error[E0425]: cannot find function `method` in this scope
   --> $DIR/resolve-speculative-adjustment.rs:19:13
diff --git a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr
index f32e0404e46..0306c8af87d 100644
--- a/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr
+++ b/tests/ui/resolve/typo-suggestion-for-variable-with-name-similar-to-struct-field.stderr
@@ -1,20 +1,20 @@
 error[E0425]: cannot find value `config` in this scope
   --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:7:16
    |
+LL |     config: String,
+   |     -------------- a field by that name exists in `Self`
+...
 LL |         Self { config }
-   |                ^^^^^^
-   |                |
-   |                a field by this name exists in `Self`
-   |                help: a local variable with a similar name exists: `cofig`
+   |                ^^^^^^ help: a local variable with a similar name exists: `cofig`
 
 error[E0425]: cannot find value `config` in this scope
   --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:11:20
    |
+LL |     config: String,
+   |     -------------- a field by that name exists in `Self`
+...
 LL |         println!("{config}");
-   |                    ^^^^^^
-   |                    |
-   |                    a field by this name exists in `Self`
-   |                    help: a local variable with a similar name exists: `cofig`
+   |                    ^^^^^^ help: a local variable with a similar name exists: `cofig`
 
 error[E0425]: cannot find value `config` in this scope
   --> $DIR/typo-suggestion-for-variable-with-name-similar-to-struct-field.rs:15:20
@@ -25,7 +25,7 @@ LL |         println!("{config}");
 help: you might have meant to use the available field
    |
 LL |         println!("{self.config}");
-   |                    ~~~~~~~~~~~
+   |                    +++++
 help: a local variable with a similar name exists
    |
 LL |         println!("{cofig}");
@@ -43,7 +43,7 @@ LL | fn ba() {}
 help: you might have meant to refer to the associated function
    |
 LL |         Self::bah;
-   |         ~~~~~~~~~
+   |         ++++++
 help: a function with a similar name exists
    |
 LL |         ba;
@@ -61,7 +61,7 @@ LL | const BARR: u32 = 3;
 help: you might have meant to use the associated `const`
    |
 LL |         Self::BAR;
-   |         ~~~~~~~~~
+   |         ++++++
 help: a constant with a similar name exists
    |
 LL |         BARR;
@@ -79,7 +79,7 @@ LL | type Bar = String;
 help: you might have meant to use the associated type
    |
 LL |         let foo: Self::Baz = "".to_string();
-   |                  ~~~~~~~~~
+   |                  ++++++
 help: a type alias with a similar name exists
    |
 LL |         let foo: Bar = "".to_string();
@@ -97,7 +97,7 @@ LL | fn ba() {}
 help: you might have meant to call the method
    |
 LL |         self.baz();
-   |         ~~~~~~~~
+   |         +++++
 help: a function with a similar name exists
    |
 LL |         ba();
diff --git a/tests/ui/resolve/unresolved_static_type_field.stderr b/tests/ui/resolve/unresolved_static_type_field.stderr
index 06926b53ddd..035dc9b9656 100644
--- a/tests/ui/resolve/unresolved_static_type_field.stderr
+++ b/tests/ui/resolve/unresolved_static_type_field.stderr
@@ -1,8 +1,11 @@
 error[E0425]: cannot find value `cx` in this scope
   --> $DIR/unresolved_static_type_field.rs:9:11
    |
+LL |     cx: bool,
+   |     -------- a field by that name exists in `Self`
+...
 LL |         f(cx);
-   |           ^^ a field by this name exists in `Self`
+   |           ^^
 
 error: aborting due to previous error
 
diff --git a/tests/ui/self/class-missing-self.stderr b/tests/ui/self/class-missing-self.stderr
index 3c37d819743..ca7a896200f 100644
--- a/tests/ui/self/class-missing-self.stderr
+++ b/tests/ui/self/class-missing-self.stderr
@@ -2,7 +2,12 @@ error[E0425]: cannot find value `meows` in this scope
   --> $DIR/class-missing-self.rs:9:7
    |
 LL |       meows += 1;
-   |       ^^^^^ help: you might have meant to use the available field: `self.meows`
+   |       ^^^^^
+   |
+help: you might have meant to use the available field
+   |
+LL |       self.meows += 1;
+   |       +++++
 
 error[E0425]: cannot find function `sleep` in this scope
   --> $DIR/class-missing-self.rs:10:7
@@ -10,7 +15,7 @@ error[E0425]: cannot find function `sleep` in this scope
 LL |       sleep();
    |       ^^^^^ not found in this scope
    |
-help: consider using the associated function
+help: consider using the method on `Self`
    |
 LL |       self.sleep();
    |       +++++
diff --git a/tests/ui/simd/intrinsic/generic-elements.rs b/tests/ui/simd/intrinsic/generic-elements.rs
index 0ff2203ec72..6ba93e46f75 100644
--- a/tests/ui/simd/intrinsic/generic-elements.rs
+++ b/tests/ui/simd/intrinsic/generic-elements.rs
@@ -1,6 +1,7 @@
 // build-fail
 
-#![feature(repr_simd, platform_intrinsics, rustc_attrs)]
+#![feature(repr_simd, platform_intrinsics, rustc_attrs, adt_const_params)]
+#![allow(incomplete_features)]
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
@@ -35,6 +36,7 @@ extern "platform-intrinsic" {
     fn simd_extract<T, E>(x: T, idx: u32) -> E;
 
     fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
+    fn simd_shuffle_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;
 }
 
 fn main() {
@@ -71,5 +73,29 @@ fn main() {
         //~^ ERROR expected return type of length 4, found `i32x8` with length 8
         simd_shuffle::<_, _, i32x2>(x, x, IDX8);
         //~^ ERROR expected return type of length 8, found `i32x2` with length 2
+
+        const I2: &[u32] = &[0; 2];
+        simd_shuffle_generic::<i32, i32, I2>(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        const I4: &[u32] = &[0; 4];
+        simd_shuffle_generic::<i32, i32, I4>(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+        const I8: &[u32] = &[0; 8];
+        simd_shuffle_generic::<i32, i32, I8>(0, 0);
+        //~^ ERROR expected SIMD input type, found non-SIMD `i32`
+
+        simd_shuffle_generic::<_, f32x2, I2>(x, x);
+//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
+        simd_shuffle_generic::<_, f32x4, I4>(x, x);
+//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
+        simd_shuffle_generic::<_, f32x8, I8>(x, x);
+//~^ ERROR element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
+
+        simd_shuffle_generic::<_, i32x8, I2>(x, x);
+        //~^ ERROR expected return type of length 2, found `i32x8` with length 8
+        simd_shuffle_generic::<_, i32x8, I4>(x, x);
+        //~^ ERROR expected return type of length 4, found `i32x8` with length 8
+        simd_shuffle_generic::<_, i32x2, I8>(x, x);
+        //~^ ERROR expected return type of length 8, found `i32x2` with length 2
     }
 }
diff --git a/tests/ui/simd/intrinsic/generic-elements.stderr b/tests/ui/simd/intrinsic/generic-elements.stderr
index 115d9d4b3f3..26e01344939 100644
--- a/tests/ui/simd/intrinsic/generic-elements.stderr
+++ b/tests/ui/simd/intrinsic/generic-elements.stderr
@@ -1,75 +1,129 @@
 error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:44:9
+  --> $DIR/generic-elements.rs:46:9
    |
 LL |         simd_insert(0, 0, 0);
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_insert` intrinsic: expected inserted type `i32` (element of input `i32x4`), found `f64`
-  --> $DIR/generic-elements.rs:46:9
+  --> $DIR/generic-elements.rs:48:9
    |
 LL |         simd_insert(x, 0, 1.0);
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_extract` intrinsic: expected return type `i32` (element of input `i32x4`), found `f32`
-  --> $DIR/generic-elements.rs:48:9
+  --> $DIR/generic-elements.rs:50:9
    |
 LL |         simd_extract::<_, f32>(x, 0);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:52:9
+  --> $DIR/generic-elements.rs:54:9
    |
 LL |         simd_shuffle::<i32, _, i32>(0, 0, IDX2);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:55:9
+  --> $DIR/generic-elements.rs:57:9
    |
 LL |         simd_shuffle::<i32, _, i32>(0, 0, IDX4);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected SIMD input type, found non-SIMD `i32`
-  --> $DIR/generic-elements.rs:58:9
+  --> $DIR/generic-elements.rs:60:9
    |
 LL |         simd_shuffle::<i32, _, i32>(0, 0, IDX8);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
-  --> $DIR/generic-elements.rs:61:9
+  --> $DIR/generic-elements.rs:63:9
    |
 LL |         simd_shuffle::<_, _, f32x2>(x, x, IDX2);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
-  --> $DIR/generic-elements.rs:63:9
+  --> $DIR/generic-elements.rs:65:9
    |
 LL |         simd_shuffle::<_, _, f32x4>(x, x, IDX4);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
-  --> $DIR/generic-elements.rs:65:9
+  --> $DIR/generic-elements.rs:67:9
    |
 LL |         simd_shuffle::<_, _, f32x8>(x, x, IDX8);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `i32x8` with length 8
-  --> $DIR/generic-elements.rs:68:9
+  --> $DIR/generic-elements.rs:70:9
    |
 LL |         simd_shuffle::<_, _, i32x8>(x, x, IDX2);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 4, found `i32x8` with length 8
-  --> $DIR/generic-elements.rs:70:9
+  --> $DIR/generic-elements.rs:72:9
    |
 LL |         simd_shuffle::<_, _, i32x8>(x, x, IDX4);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 8, found `i32x2` with length 2
-  --> $DIR/generic-elements.rs:72:9
+  --> $DIR/generic-elements.rs:74:9
    |
 LL |         simd_shuffle::<_, _, i32x2>(x, x, IDX8);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 12 previous errors
+error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-elements.rs:78:9
+   |
+LL |         simd_shuffle_generic::<i32, i32, I2>(0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-elements.rs:81:9
+   |
+LL |         simd_shuffle_generic::<i32, i32, I4>(0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected SIMD input type, found non-SIMD `i32`
+  --> $DIR/generic-elements.rs:84:9
+   |
+LL |         simd_shuffle_generic::<i32, i32, I8>(0, 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x2` with element type `f32`
+  --> $DIR/generic-elements.rs:87:9
+   |
+LL |         simd_shuffle_generic::<_, f32x2, I2>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x4` with element type `f32`
+  --> $DIR/generic-elements.rs:89:9
+   |
+LL |         simd_shuffle_generic::<_, f32x4, I4>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return element type `i32` (element of input `i32x4`), found `f32x8` with element type `f32`
+  --> $DIR/generic-elements.rs:91:9
+   |
+LL |         simd_shuffle_generic::<_, f32x8, I8>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 2, found `i32x8` with length 8
+  --> $DIR/generic-elements.rs:94:9
+   |
+LL |         simd_shuffle_generic::<_, i32x8, I2>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 4, found `i32x8` with length 8
+  --> $DIR/generic-elements.rs:96:9
+   |
+LL |         simd_shuffle_generic::<_, i32x8, I4>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0511]: invalid monomorphization of `simd_shuffle_generic` intrinsic: expected return type of length 8, found `i32x2` with length 2
+  --> $DIR/generic-elements.rs:98:9
+   |
+LL |         simd_shuffle_generic::<_, i32x2, I8>(x, x);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 21 previous errors
 
 For more information about this error, try `rustc --explain E0511`.
diff --git a/tests/ui/simd/monomorphize-shuffle-index.generic.stderr b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr
new file mode 100644
index 00000000000..fc66b195674
--- /dev/null
+++ b/tests/ui/simd/monomorphize-shuffle-index.generic.stderr
@@ -0,0 +1,12 @@
+error: overly complex generic constant
+  --> $DIR/monomorphize-shuffle-index.rs:29:45
+   |
+LL |         return simd_shuffle_generic::<_, _, { &Self::I }>(a, b);
+   |                                             ^^--------^^
+   |                                               |
+   |                                               pointer casts are not allowed in generic constants
+   |
+   = help: consider moving this anonymous constant into a `const` function
+
+error: aborting due to previous error
+
diff --git a/tests/ui/simd/monomorphize-shuffle-index.rs b/tests/ui/simd/monomorphize-shuffle-index.rs
index 2467baa08b0..db7953f06dd 100644
--- a/tests/ui/simd/monomorphize-shuffle-index.rs
+++ b/tests/ui/simd/monomorphize-shuffle-index.rs
@@ -1,8 +1,14 @@
-//run-pass
-#![feature(repr_simd, platform_intrinsics)]
+//[old]run-pass
+//[generic_with_fn]run-pass
+// revisions: old generic generic_with_fn
+#![feature(repr_simd, platform_intrinsics, adt_const_params, generic_const_exprs)]
+#![allow(incomplete_features)]
 
 extern "platform-intrinsic" {
+    #[cfg(old)]
     fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
+    #[cfg(any(generic, generic_with_fn))]
+    fn simd_shuffle_generic<T, U, const I: &'static [u32]>(a: T, b: T) -> U;
 }
 
 #[derive(Copy, Clone)]
@@ -11,12 +17,24 @@ struct Simd<T, const N: usize>([T; N]);
 
 trait Shuffle<const N: usize> {
     const I: [u32; N];
-
-    unsafe fn shuffle<T, const M: usize>(&self, a: Simd<T, M>, b: Simd<T, M>) -> Simd<T, N> {
-        simd_shuffle(a, b, Self::I)
+    const J: &'static [u32] = &Self::I;
+
+    unsafe fn shuffle<T, const M: usize>(&self, a: Simd<T, M>, b: Simd<T, M>) -> Simd<T, N>
+    where
+        Thing<{ Self::J }>:,
+    {
+        #[cfg(old)]
+        return simd_shuffle(a, b, Self::I);
+        #[cfg(generic)]
+        return simd_shuffle_generic::<_, _, { &Self::I }>(a, b);
+        //[generic]~^ overly complex generic constant
+        #[cfg(generic_with_fn)]
+        return simd_shuffle_generic::<_, _, { Self::J }>(a, b);
     }
 }
 
+struct Thing<const X: &'static [u32]>;
+
 fn main() {
     struct I1;
     impl Shuffle<4> for I1 {
diff --git a/tests/ui/specialization/specialization-default-types.stderr b/tests/ui/specialization/specialization-default-types.stderr
index ecccf29a107..774ac953617 100644
--- a/tests/ui/specialization/specialization-default-types.stderr
+++ b/tests/ui/specialization/specialization-default-types.stderr
@@ -12,7 +12,7 @@ error[E0308]: mismatched types
   --> $DIR/specialization-default-types.rs:15:9
    |
 LL |     default type Output = Box<T>;
-   |     ----------------------------- expected this associated type
+   |     ----------------------------- associated type is `default` and may be overridden
 LL |     default fn generate(self) -> Self::Output {
    |                                  ------------ expected `<T as Example>::Output` because of return type
 LL |         Box::new(self)
diff --git a/tests/ui/structs-enums/rec-align-u32.rs b/tests/ui/structs-enums/rec-align-u32.rs
index ee704198d19..b3c323d2a29 100644
--- a/tests/ui/structs-enums/rec-align-u32.rs
+++ b/tests/ui/structs-enums/rec-align-u32.rs
@@ -3,7 +3,7 @@
 #![allow(unused_unsafe)]
 // Issue #2303
 
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 use std::mem;
 
diff --git a/tests/ui/structs-enums/rec-align-u64.rs b/tests/ui/structs-enums/rec-align-u64.rs
index c3b201fb1c6..de008bcc01d 100644
--- a/tests/ui/structs-enums/rec-align-u64.rs
+++ b/tests/ui/structs-enums/rec-align-u64.rs
@@ -5,7 +5,7 @@
 
 // Issue #2303
 
-#![feature(intrinsics)]
+#![feature(intrinsics, rustc_attrs)]
 
 use std::mem;
 
diff --git a/tests/ui/suggestions/assoc-const-without-self.stderr b/tests/ui/suggestions/assoc-const-without-self.stderr
index 88d72da70cb..05528d277be 100644
--- a/tests/ui/suggestions/assoc-const-without-self.stderr
+++ b/tests/ui/suggestions/assoc-const-without-self.stderr
@@ -4,7 +4,7 @@ error[E0425]: cannot find value `A_CONST` in this scope
 LL |         A_CONST
    |         ^^^^^^^ not found in this scope
    |
-help: consider using the associated constant
+help: consider using the associated constant on `Self`
    |
 LL |         Self::A_CONST
    |         ++++++
diff --git a/tests/ui/suggestions/assoc-type-in-method-return.stderr b/tests/ui/suggestions/assoc-type-in-method-return.stderr
index 202e4a16ead..df3828ad411 100644
--- a/tests/ui/suggestions/assoc-type-in-method-return.stderr
+++ b/tests/ui/suggestions/assoc-type-in-method-return.stderr
@@ -2,7 +2,12 @@ error[E0412]: cannot find type `Bla` in this scope
   --> $DIR/assoc-type-in-method-return.rs:3:25
    |
 LL |     fn to_bla(&self) -> Bla;
-   |                         ^^^ help: you might have meant to use the associated type: `Self::Bla`
+   |                         ^^^
+   |
+help: you might have meant to use the associated type
+   |
+LL |     fn to_bla(&self) -> Self::Bla;
+   |                         ++++++
 
 error: aborting due to previous error
 
diff --git a/tests/ui/suggestions/assoc_fn_without_self.rs b/tests/ui/suggestions/assoc_fn_without_self.rs
index 778d9847773..35c16ef3e9f 100644
--- a/tests/ui/suggestions/assoc_fn_without_self.rs
+++ b/tests/ui/suggestions/assoc_fn_without_self.rs
@@ -17,4 +17,12 @@ impl S {
         bar(); //~ ERROR cannot find function `bar` in this scope
         baz(2, 3); //~ ERROR cannot find function `baz` in this scope
     }
+    fn d(&self) {
+        fn c() {
+            foo(); //~ ERROR cannot find function `foo` in this scope
+        }
+        foo(); //~ ERROR cannot find function `foo` in this scope
+        bar(); //~ ERROR cannot find function `bar` in this scope
+        baz(2, 3); //~ ERROR cannot find function `baz` in this scope
+    }
 }
diff --git a/tests/ui/suggestions/assoc_fn_without_self.stderr b/tests/ui/suggestions/assoc_fn_without_self.stderr
index febdd67338c..9cee7c7ee5e 100644
--- a/tests/ui/suggestions/assoc_fn_without_self.stderr
+++ b/tests/ui/suggestions/assoc_fn_without_self.stderr
@@ -4,7 +4,7 @@ error[E0425]: cannot find function `foo` in this scope
 LL |         foo();
    |         ^^^ not found in this scope
    |
-help: consider using the associated function
+help: consider using the associated function on `Self`
    |
 LL |         Self::foo();
    |         ++++++
@@ -12,31 +12,68 @@ LL |         Self::foo();
 error[E0425]: cannot find function `bar` in this scope
   --> $DIR/assoc_fn_without_self.rs:17:9
    |
+LL |     fn bar(&self) {}
+   |        --- a method by that name is available on `Self` here
+...
+LL |         bar();
+   |         ^^^ not found in this scope
+
+error[E0425]: cannot find function `baz` in this scope
+  --> $DIR/assoc_fn_without_self.rs:18:9
+   |
+LL |         baz(2, 3);
+   |         ^^^ not found in this scope
+   |
+help: consider using the associated function on `Self`
+   |
+LL |         Self::baz(2, 3);
+   |         ++++++
+
+error[E0425]: cannot find function `foo` in this scope
+  --> $DIR/assoc_fn_without_self.rs:14:13
+   |
+LL |             foo();
+   |             ^^^ not found in this scope
+
+error[E0425]: cannot find function `foo` in this scope
+  --> $DIR/assoc_fn_without_self.rs:24:9
+   |
+LL |         foo();
+   |         ^^^ not found in this scope
+   |
+help: consider using the associated function on `Self`
+   |
+LL |         Self::foo();
+   |         ++++++
+
+error[E0425]: cannot find function `bar` in this scope
+  --> $DIR/assoc_fn_without_self.rs:25:9
+   |
 LL |         bar();
    |         ^^^ not found in this scope
    |
-help: consider using the associated function
+help: consider using the method on `Self`
    |
 LL |         self.bar();
    |         +++++
 
 error[E0425]: cannot find function `baz` in this scope
-  --> $DIR/assoc_fn_without_self.rs:18:9
+  --> $DIR/assoc_fn_without_self.rs:26:9
    |
 LL |         baz(2, 3);
    |         ^^^ not found in this scope
    |
-help: consider using the associated function
+help: consider using the associated function on `Self`
    |
 LL |         Self::baz(2, 3);
    |         ++++++
 
 error[E0425]: cannot find function `foo` in this scope
-  --> $DIR/assoc_fn_without_self.rs:14:13
+  --> $DIR/assoc_fn_without_self.rs:22:13
    |
 LL |             foo();
    |             ^^^ not found in this scope
 
-error: aborting due to 4 previous errors
+error: aborting due to 8 previous errors
 
 For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/suggestions/auxiliary/extern-issue-98562.rs b/tests/ui/suggestions/auxiliary/extern-issue-98562.rs
new file mode 100644
index 00000000000..948e40549c6
--- /dev/null
+++ b/tests/ui/suggestions/auxiliary/extern-issue-98562.rs
@@ -0,0 +1,26 @@
+pub trait TraitE {
+    type I3;
+}
+
+pub trait TraitD {
+    type I3;
+}
+
+pub trait TraitC {
+    type I1;
+    type I2;
+}
+
+pub trait TraitB {
+    type Item;
+}
+
+pub trait TraitA<G1, G2, G3> {
+    fn baz<
+        U: TraitC<I1 = G1, I2 = G2> + TraitD<I3 = G3> + TraitE,
+        V: TraitD<I3 = G1>
+    >(_: U, _: V) -> Self
+    where
+        U: TraitB,
+        <U as TraitB>::Item: Copy;
+}
diff --git a/tests/ui/suggestions/issue-98562.rs b/tests/ui/suggestions/issue-98562.rs
new file mode 100644
index 00000000000..de04050d593
--- /dev/null
+++ b/tests/ui/suggestions/issue-98562.rs
@@ -0,0 +1,12 @@
+// aux-build:extern-issue-98562.rs
+
+extern crate extern_issue_98562;
+use extern_issue_98562::TraitA;
+
+struct X;
+impl TraitA<u8, u16, u32> for X {
+    //~^ ERROR not all trait items implemented
+}
+//~^ HELP implement the missing item: `fn baz<U: TraitC<I1 = u8, I2 = u16> + TraitD<I3 = u32>, V: TraitD<I3 = u8>>(_: U, _: V) -> Self where U: TraitE, U: TraitB, <U as TraitB>::Item: Copy { todo!() }`
+
+fn main() {}
diff --git a/tests/ui/suggestions/issue-98562.stderr b/tests/ui/suggestions/issue-98562.stderr
new file mode 100644
index 00000000000..7897fa441a2
--- /dev/null
+++ b/tests/ui/suggestions/issue-98562.stderr
@@ -0,0 +1,11 @@
+error[E0046]: not all trait items implemented, missing: `baz`
+  --> $DIR/issue-98562.rs:7:1
+   |
+LL | impl TraitA<u8, u16, u32> for X {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `baz` in implementation
+   |
+   = help: implement the missing item: `fn baz<U: TraitC<I1 = u8, I2 = u16> + TraitD<I3 = u32>, V: TraitD<I3 = u8>>(_: U, _: V) -> Self where U: TraitE, U: TraitB, <U as TraitB>::Item: Copy { todo!() }`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0046`.
diff --git a/tests/ui/suggestions/missing-assoc-fn.stderr b/tests/ui/suggestions/missing-assoc-fn.stderr
index 77fa9562878..84cb6e98553 100644
--- a/tests/ui/suggestions/missing-assoc-fn.stderr
+++ b/tests/ui/suggestions/missing-assoc-fn.stderr
@@ -28,7 +28,7 @@ error[E0046]: not all trait items implemented, missing: `from_iter`
 LL | impl FromIterator<()> for X {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `from_iter` in implementation
    |
-   = help: implement the missing item: `fn from_iter<T>(_: T) -> Self where T: IntoIterator, std::iter::IntoIterator::Item = () { todo!() }`
+   = help: implement the missing item: `fn from_iter<T: IntoIterator<Item = ()>>(_: T) -> Self { todo!() }`
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/symbol-names/basic.legacy.stderr b/tests/ui/symbol-names/basic.legacy.stderr
index c1cbefac828..61d27ec69f4 100644
--- a/tests/ui/symbol-names/basic.legacy.stderr
+++ b/tests/ui/symbol-names/basic.legacy.stderr
@@ -1,10 +1,10 @@
-error: symbol-name(_ZN5basic4main17h6fc0c8d27b1a289fE)
+error: symbol-name(_ZN5basic4main17h9308686d0228fa1dE)
   --> $DIR/basic.rs:8:1
    |
 LL | #[rustc_symbol_name]
    | ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling(basic::main::h6fc0c8d27b1a289f)
+error: demangling(basic::main::h9308686d0228fa1d)
   --> $DIR/basic.rs:8:1
    |
 LL | #[rustc_symbol_name]
diff --git a/tests/ui/symbol-names/issue-60925.legacy.stderr b/tests/ui/symbol-names/issue-60925.legacy.stderr
index 7dd68e6e3a8..eb65f3b58ff 100644
--- a/tests/ui/symbol-names/issue-60925.legacy.stderr
+++ b/tests/ui/symbol-names/issue-60925.legacy.stderr
@@ -1,10 +1,10 @@
-error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17hab58a402db4ebf3aE)
+error: symbol-name(_ZN11issue_609253foo37Foo$LT$issue_60925..llv$u6d$..Foo$GT$3foo17h84ab5dafbd2a1508E)
   --> $DIR/issue-60925.rs:21:9
    |
 LL |         #[rustc_symbol_name]
    |         ^^^^^^^^^^^^^^^^^^^^
 
-error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::hab58a402db4ebf3a)
+error: demangling(issue_60925::foo::Foo<issue_60925::llvm::Foo>::foo::h84ab5dafbd2a1508)
   --> $DIR/issue-60925.rs:21:9
    |
 LL |         #[rustc_symbol_name]
diff --git a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
index e311a4af2f4..6b54718e35c 100644
--- a/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
+++ b/tests/ui/traits/new-solver/auto-with-drop_tracking_mir.rs
@@ -1,4 +1,4 @@
-// compile-flags: -Ztrait-solver=next -Zdrop-tracking-mir
+// compile-flags: -Ztrait-solver=next
 // edition: 2021
 // revisions: pass fail
 //[pass] check-pass
diff --git a/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs b/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs
new file mode 100644
index 00000000000..27906392340
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.rs
@@ -0,0 +1,53 @@
+// compile-flags: -Ztrait-solver=next
+#![feature(rustc_attrs)]
+
+// Check that we correctly rerun the trait solver for heads of cycles,
+// even if they are not the root.
+
+struct A<T: ?Sized>(*const T);
+struct B<T: ?Sized>(*const T);
+struct C<T: ?Sized>(*const T);
+
+#[rustc_coinductive]
+trait Trait<'a, 'b> {}
+trait NotImplemented {}
+
+impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for A<T> where B<T>: Trait<'a, 'b> {}
+
+// With this the root of `B<T>` is `A<T>`, even if the other impl does
+// not have a cycle with `A<T>`. This candidate never applies because of
+// the `A<T>: NotImplemented` bound.
+impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for B<T>
+where
+    A<T>: Trait<'a, 'b>,
+    A<T>: NotImplemented,
+{
+}
+
+// This impl directly requires 'b to be equal to 'static.
+//
+// Because of the coinductive cycle through `C<T>` it also requires
+// 'a to be 'static.
+impl<'a, T: ?Sized> Trait<'a, 'static> for B<T>
+where
+    C<T>: Trait<'a, 'a>,
+{}
+
+// In the first iteration of `B<T>: Trait<'a, 'b>` we don't add any
+// constraints here, only after setting the provisional result to require
+// `'b == 'static` do we also add that constraint for `'a`.
+impl<'a, 'b, T: ?Sized> Trait<'a, 'b> for C<T>
+where
+    B<T>: Trait<'a, 'b>,
+{}
+
+fn impls_trait<'a, 'b, T: Trait<'a, 'b> + ?Sized>() {}
+
+fn check<'a, T: ?Sized>() {
+    impls_trait::<'a, 'static, A<T>>();
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {
+    check::<()>();
+}
diff --git a/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr b/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr
new file mode 100644
index 00000000000..4cbd0898148
--- /dev/null
+++ b/tests/ui/traits/new-solver/cycles/fixpoint-rerun-all-cycle-heads.stderr
@@ -0,0 +1,10 @@
+error: lifetime may not live long enough
+  --> $DIR/fixpoint-rerun-all-cycle-heads.rs:47:5
+   |
+LL | fn check<'a, T: ?Sized>() {
+   |          -- lifetime `'a` defined here
+LL |     impls_trait::<'a, 'static, A<T>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+
+error: aborting due to previous error
+
diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs
index 3cfe7ab87f6..f06b98a79cf 100644
--- a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs
+++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.rs
@@ -39,7 +39,7 @@ fn impls_ar<T: AR>() {}
 
 fn main() {
     impls_a::<()>();
-    // FIXME(-Ztrait-solver=next): This is broken and should error.
+    //~^ ERROR overflow evaluating the requirement `(): A`
 
     impls_ar::<()>();
     //~^ ERROR overflow evaluating the requirement `(): AR`
diff --git a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr
index 34115334063..859b3f3f1c7 100644
--- a/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr
+++ b/tests/ui/traits/new-solver/cycles/inductive-not-on-stack.stderr
@@ -1,3 +1,16 @@
+error[E0275]: overflow evaluating the requirement `(): A`
+  --> $DIR/inductive-not-on-stack.rs:41:15
+   |
+LL |     impls_a::<()>();
+   |               ^^
+   |
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`inductive_not_on_stack`)
+note: required by a bound in `impls_a`
+  --> $DIR/inductive-not-on-stack.rs:25:15
+   |
+LL | fn impls_a<T: A>() {}
+   |               ^ required by this bound in `impls_a`
+
 error[E0275]: overflow evaluating the requirement `(): AR`
   --> $DIR/inductive-not-on-stack.rs:44:16
    |
@@ -11,6 +24,6 @@ note: required by a bound in `impls_ar`
 LL | fn impls_ar<T: AR>() {}
    |                ^^ required by this bound in `impls_ar`
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0275`.
diff --git a/tests/ui/traits/unsend-future.rs b/tests/ui/traits/unsend-future.rs
index fbbc07b11e7..a8367573fbd 100644
--- a/tests/ui/traits/unsend-future.rs
+++ b/tests/ui/traits/unsend-future.rs
@@ -13,6 +13,7 @@ fn require_handler<H: Handler>(h: H) {}
 async fn handler() {
     let a = &1 as *const i32;
     async {}.await;
+    let b = a;
 }
 
 fn main() {
diff --git a/tests/ui/traits/unsend-future.stderr b/tests/ui/traits/unsend-future.stderr
index 6ce1cf452f4..01829021b4a 100644
--- a/tests/ui/traits/unsend-future.stderr
+++ b/tests/ui/traits/unsend-future.stderr
@@ -1,5 +1,5 @@
 error: future cannot be sent between threads safely
-  --> $DIR/unsend-future.rs:19:21
+  --> $DIR/unsend-future.rs:20:21
    |
 LL |     require_handler(handler)
    |                     ^^^^^^^ future returned by `handler` is not `Send`
@@ -12,8 +12,6 @@ LL |     let a = &1 as *const i32;
    |         - has type `*const i32` which is not `Send`
 LL |     async {}.await;
    |              ^^^^^ await occurs here, with `a` maybe used later
-LL | }
-   | - `a` is later dropped here
 note: required by a bound in `require_handler`
   --> $DIR/unsend-future.rs:11:23
    |
diff --git a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs
index 9a50c0f988a..31fea42fa5d 100644
--- a/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs
+++ b/tests/ui/type-alias-impl-trait/cross_inference_pattern_bug.rs
@@ -1,5 +1,5 @@
 // compile-flags: --edition=2021
-// check-pass
+// build-pass
 #![feature(type_alias_impl_trait)]
 
 fn main() {
diff --git a/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs b/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs
new file mode 100644
index 00000000000..7c2d68cceb8
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/destructure_tait-ice-113594.rs
@@ -0,0 +1,19 @@
+// build-pass
+// edition: 2021
+
+#![feature(type_alias_impl_trait)]
+
+pub struct Foo {
+    /// This type must have nontrivial drop glue
+    field: String,
+}
+
+pub type Tait = impl Sized;
+
+pub async fn ice_cold(beverage: Tait) {
+    // Must destructure at least one field of `Foo`
+    let Foo { field } = beverage;
+    _ = field;
+}
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs b/tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs
new file mode 100644
index 00000000000..8568b26bea2
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/destructure_tait-layout_of-ice-113594.rs
@@ -0,0 +1,23 @@
+// build-pass
+// edition: 2021
+
+#![feature(type_alias_impl_trait)]
+
+fn foo<T>(x: T) {
+    type Opaque<T> = impl Sized;
+    let foo: Opaque<T> = (x,);
+    let (a,): (T,) = foo;
+}
+
+const fn bar<T: Copy>(x: T) {
+    type Opaque<T: Copy> = impl Copy;
+    let foo: Opaque<T> = (x, 2u32);
+    let (a, b): (T, u32) = foo;
+}
+
+fn main() {
+    foo::<u32>(1);
+    bar::<u32>(1);
+    const CONST: () = bar::<u32>(42u32);
+    CONST
+}
diff --git a/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.rs b/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.rs
index baa22e1ce18..f6cbbf04d82 100644
--- a/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.rs
+++ b/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.rs
@@ -1,6 +1,6 @@
 // edition: 2021
 // build-fail
-//~^^ ERROR overflow evaluating the requirement `<() as Recur>::Recur == _`
+//~^^ ERROR cycle detected when computing layout of
 
 #![feature(impl_trait_in_assoc_type)]
 
diff --git a/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr b/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr
index 0238694c24d..2063becdb08 100644
--- a/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr
+++ b/tests/ui/type-alias-impl-trait/indirect-recursion-issue-112047.stderr
@@ -1,5 +1,19 @@
-error[E0275]: overflow evaluating the requirement `<() as Recur>::Recur == _`
+error[E0391]: cycle detected when computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}`
+   |
+   = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit<{async fn body@$DIR/indirect-recursion-issue-112047.rs:15:31: 17:2}>`...
+   = note: ...which requires computing layout of `core::mem::manually_drop::ManuallyDrop<{async fn body@$DIR/indirect-recursion-issue-112047.rs:15:31: 17:2}>`...
+   = note: ...which requires computing layout of `{async fn body@$DIR/indirect-recursion-issue-112047.rs:15:31: 17:2}`...
+   = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit<<() as Recur>::Recur>`...
+   = note: ...which requires computing layout of `core::mem::maybe_uninit::MaybeUninit<{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}>`...
+   = note: ...which requires computing layout of `core::mem::manually_drop::ManuallyDrop<{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}>`...
+   = note: ...which again requires computing layout of `{async block@$DIR/indirect-recursion-issue-112047.rs:23:9: 23:42}`, completing the cycle
+note: cycle used when elaborating drops for `<impl at $DIR/indirect-recursion-issue-112047.rs:19:1: 19:18>::recur`
+  --> $DIR/indirect-recursion-issue-112047.rs:22:5
+   |
+LL |     fn recur(self) -> Self::Recur {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error: aborting due to previous error
 
-For more information about this error, try `rustc --explain E0275`.
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/type/type-error-break-tail.stderr b/tests/ui/type/type-error-break-tail.stderr
index 16dc6475c6f..9a02bc28752 100644
--- a/tests/ui/type/type-error-break-tail.stderr
+++ b/tests/ui/type/type-error-break-tail.stderr
@@ -2,13 +2,16 @@ error[E0308]: mismatched types
   --> $DIR/type-error-break-tail.rs:3:20
    |
 LL | fn loop_ending() -> i32 {
-   |                     --- expected `i32` because of return type
+   |                     --- expected `i32` because of this return type
 LL |     loop {
+   |     ---- this loop is expected to be of type `i32`
 LL |         if false { break; }
-   |                    ^^^^^
-   |                    |
-   |                    expected `i32`, found `()`
-   |                    help: give it a value of the expected type: `break 42`
+   |                    ^^^^^ expected `i32`, found `()`
+   |
+help: give it a value of the expected type
+   |
+LL |         if false { break 42; }
+   |                          ++
 
 error: aborting due to previous error
 
diff --git a/triagebot.toml b/triagebot.toml
index dbced481993..648997ad6f0 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -542,6 +542,10 @@ cc = ["@davidtwco", "@compiler-errors", "@JohnTitor", "@TaKO8Ki"]
 message = "This PR changes Stable MIR"
 cc = ["@oli-obk", "@celinval", "@spastorino"]
 
+[mentions."compiler/stable_mir"]
+message = "This PR changes Stable MIR"
+cc = ["@oli-obk", "@celinval", "@spastorino"]
+
 [mentions."compiler/rustc_target/src/spec"]
 message = """
 These commits modify **compiler targets**.